From 4cf729cfac57c9aec692a52c1f3f95f2403e7958 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 29 May 2025 10:42:50 +0000 Subject: [PATCH 001/216] 8323497: On x64, use 32-bit immediate moves for narrow klass base if possible Reviewed-by: shade, kvn, rkennke --- src/hotspot/cpu/x86/compressedKlass_x86.cpp | 29 +++++++++++++------ src/hotspot/cpu/x86/macroAssembler_x86.cpp | 22 +++++++++----- src/hotspot/share/oops/compressedKlass.cpp | 4 +++ src/hotspot/share/oops/compressedKlass.hpp | 1 + ...essedCPUSpecificClassSpaceReservation.java | 7 +++-- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/hotspot/cpu/x86/compressedKlass_x86.cpp b/src/hotspot/cpu/x86/compressedKlass_x86.cpp index 8a06a7ba3d5..e88b7a3d4e1 100644 --- a/src/hotspot/cpu/x86/compressedKlass_x86.cpp +++ b/src/hotspot/cpu/x86/compressedKlass_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, 2025, Red Hat, Inc. All rights reserved. * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,6 +25,7 @@ #ifdef _LP64 +#include "memory/metaspace.hpp" #include "oops/compressedKlass.hpp" #include "utilities/globalDefinitions.hpp" @@ -32,15 +33,25 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size char* result = nullptr; - // Optimize for unscaled encoding; failing that, for zero-based encoding: - if (optimize_for_zero_base) { - result = reserve_address_space_for_unscaled_encoding(size, aslr); - if (result == nullptr) { - result = reserve_address_space_for_zerobased_encoding(size, aslr); - } - } // end: low-address reservation + assert(CompressedKlassPointers::narrow_klass_pointer_bits() == 32 || + CompressedKlassPointers::narrow_klass_pointer_bits() == 22, "Rethink if we ever use different nKlass bit sizes"); + + // Unconditionally attempting to reserve in lower 4G first makes always sense: + // -CDS -COH: Try to get unscaled mode (zero base, zero shift) + // +CDS -COH: No zero base possible (CDS prevents it); but we still benefit from small base pointers (imm32 movabs) + // -CDS +COH: No zero base possible (22bit nKlass + zero base zero shift = 4MB encoding range, way too small); + // but we still benefit from small base pointers (imm32 movabs) + // +CDS +COH: No zero base possible for multiple reasons (CDS prevents it and encoding range too small); + // but we still benefit from small base pointers (imm32 movabs) + + result = reserve_address_space_below_4G(size, aslr); + + if (result == nullptr && optimize_for_zero_base) { + // Failing that, if we are running without CDS, attempt to allocate below 32G. + // This allows us to use zero-based encoding with a non-zero shift. + result = reserve_address_space_for_zerobased_encoding(size, aslr); + } - // Nothing more to optimize for on x64. If base != 0, we will always emit the full 64-bit immediate. return result; } diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 30f06533c39..f58a8dca98e 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -5402,24 +5402,27 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) { } void MacroAssembler::encode_klass_not_null(Register r, Register tmp) { + BLOCK_COMMENT("encode_klass_not_null {"); assert_different_registers(r, tmp); if (CompressedKlassPointers::base() != nullptr) { if (AOTCodeCache::is_on_for_dump()) { movptr(tmp, ExternalAddress(CompressedKlassPointers::base_addr())); } else { - mov64(tmp, (int64_t)CompressedKlassPointers::base()); + movptr(tmp, (intptr_t)CompressedKlassPointers::base()); } subq(r, tmp); } if (CompressedKlassPointers::shift() != 0) { shrq(r, CompressedKlassPointers::shift()); } + BLOCK_COMMENT("} encode_klass_not_null"); } void MacroAssembler::encode_and_move_klass_not_null(Register dst, Register src) { + BLOCK_COMMENT("encode_and_move_klass_not_null {"); assert_different_registers(src, dst); if (CompressedKlassPointers::base() != nullptr) { - mov64(dst, -(int64_t)CompressedKlassPointers::base()); + movptr(dst, -(intptr_t)CompressedKlassPointers::base()); addq(dst, src); } else { movptr(dst, src); @@ -5427,9 +5430,11 @@ void MacroAssembler::encode_and_move_klass_not_null(Register dst, Register src) if (CompressedKlassPointers::shift() != 0) { shrq(dst, CompressedKlassPointers::shift()); } + BLOCK_COMMENT("} encode_and_move_klass_not_null"); } void MacroAssembler::decode_klass_not_null(Register r, Register tmp) { + BLOCK_COMMENT("decode_klass_not_null {"); assert_different_registers(r, tmp); // Note: it will change flags assert(UseCompressedClassPointers, "should only be used for compressed headers"); @@ -5443,13 +5448,15 @@ void MacroAssembler::decode_klass_not_null(Register r, Register tmp) { if (AOTCodeCache::is_on_for_dump()) { movptr(tmp, ExternalAddress(CompressedKlassPointers::base_addr())); } else { - mov64(tmp, (int64_t)CompressedKlassPointers::base()); + movptr(tmp, (intptr_t)CompressedKlassPointers::base()); } addq(r, tmp); } + BLOCK_COMMENT("} decode_klass_not_null"); } void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) { + BLOCK_COMMENT("decode_and_move_klass_not_null {"); assert_different_registers(src, dst); // Note: it will change flags assert (UseCompressedClassPointers, "should only be used for compressed headers"); @@ -5465,7 +5472,7 @@ void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) } else { if (CompressedKlassPointers::shift() <= Address::times_8) { if (CompressedKlassPointers::base() != nullptr) { - mov64(dst, (int64_t)CompressedKlassPointers::base()); + movptr(dst, (intptr_t)CompressedKlassPointers::base()); } else { xorq(dst, dst); } @@ -5477,9 +5484,9 @@ void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) } } else { if (CompressedKlassPointers::base() != nullptr) { - const uint64_t base_right_shifted = - (uint64_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift(); - mov64(dst, base_right_shifted); + const intptr_t base_right_shifted = + (intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift(); + movptr(dst, base_right_shifted); } else { xorq(dst, dst); } @@ -5487,6 +5494,7 @@ void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) shlq(dst, CompressedKlassPointers::shift()); } } + BLOCK_COMMENT("} decode_and_move_klass_not_null"); } void MacroAssembler::set_narrow_oop(Register dst, jobject obj) { diff --git a/src/hotspot/share/oops/compressedKlass.cpp b/src/hotspot/share/oops/compressedKlass.cpp index df639388a5e..a1a634b6aab 100644 --- a/src/hotspot/share/oops/compressedKlass.cpp +++ b/src/hotspot/share/oops/compressedKlass.cpp @@ -186,6 +186,10 @@ char* CompressedKlassPointers::reserve_address_space_X(uintptr_t from, uintptr_t return os::attempt_reserve_memory_between((char*)from, (char*)to, size, alignment, aslr); } +char* CompressedKlassPointers::reserve_address_space_below_4G(size_t size, bool aslr) { + return reserve_address_space_X(0, nth_bit(32), size, Metaspace::reserve_alignment(), aslr); +} + char* CompressedKlassPointers::reserve_address_space_for_unscaled_encoding(size_t size, bool aslr) { const size_t unscaled_max = nth_bit(narrow_klass_pointer_bits()); return reserve_address_space_X(0, unscaled_max, size, Metaspace::reserve_alignment(), aslr); diff --git a/src/hotspot/share/oops/compressedKlass.hpp b/src/hotspot/share/oops/compressedKlass.hpp index a07e758be7b..8666d4409e8 100644 --- a/src/hotspot/share/oops/compressedKlass.hpp +++ b/src/hotspot/share/oops/compressedKlass.hpp @@ -139,6 +139,7 @@ class CompressedKlassPointers : public AllStatic { // Helper function for common cases. static char* reserve_address_space_X(uintptr_t from, uintptr_t to, size_t size, size_t alignment, bool aslr); + static char* reserve_address_space_below_4G(size_t size, bool aslr); static char* reserve_address_space_for_unscaled_encoding(size_t size, bool aslr); static char* reserve_address_space_for_zerobased_encoding(size_t size, bool aslr); static char* reserve_address_space_for_16bit_move(size_t size, bool aslr); diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java index edb5ab9af06..622573fa709 100644 --- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java +++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Red Hat. All rights reserved. + * Copyright (c) 2023, 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 @@ -63,6 +64,7 @@ public class CompressedCPUSpecificClassSpaceReservation { OutputAnalyzer output = new OutputAnalyzer(pb.start()); final String tryReserveForUnscaled = "reserve_between (range [0x0000000000000000-0x0000000100000000)"; + final String tryReserveBelow4G = "reserve_between (range [0x0000000000000000-0x0000000100000000)"; final String tryReserveForZeroBased = "reserve_between (range [0x0000000100000000-0x0000000800000000)"; final String tryReserveFor16bitMoveIntoQ3 = "reserve_between (range [0x0000000100000000-0x0001000000000000)"; if (Platform.isAArch64()) { @@ -98,11 +100,10 @@ public class CompressedCPUSpecificClassSpaceReservation { } output.shouldContain(tryReserveFor16bitMoveIntoQ3); } else if (Platform.isX64()) { + output.shouldContain(tryReserveBelow4G); if (CDS) { - output.shouldNotContain(tryReserveForUnscaled); output.shouldNotContain(tryReserveForZeroBased); } else { - output.shouldContain(tryReserveForUnscaled); output.shouldContain(tryReserveForZeroBased); } } else { From d8a783020d247d2c01834db14b44d239ad1f2bf4 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 29 May 2025 15:06:51 +0000 Subject: [PATCH 002/216] 8357999: SA: FileMapInfo.metadataTypeArray initialization issue after JDK-8355003 Reviewed-by: ayang, iklam, kvn, sspitsyn --- .../share/classes/sun/jvm/hotspot/memory/FileMapInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java index f8500276779..9d5c0dec9fb 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java @@ -126,7 +126,7 @@ public class FileMapInfo { metadataTypeArray[4] = db.lookupType("InstanceRefKlass"); metadataTypeArray[5] = db.lookupType("InstanceStackChunkKlass"); metadataTypeArray[6] = db.lookupType("Method"); - metadataTypeArray[9] = db.lookupType("MethodData"); + metadataTypeArray[7] = db.lookupType("MethodData"); metadataTypeArray[8] = db.lookupType("MethodCounters"); metadataTypeArray[9] = db.lookupType("ObjArrayKlass"); metadataTypeArray[10] = db.lookupType("TypeArrayKlass"); From 79aff26c2880922b92863911d8a5a035ba9a1e75 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 29 May 2025 15:20:39 +0000 Subject: [PATCH 003/216] 8354724: Methods in java.io.Reader to read all characters and all lines Reviewed-by: rriggs, smarks, jpai, alanb --- .../share/classes/java/io/Reader.java | 120 +++++++++++++++++ test/jdk/java/io/Reader/ReadAll.java | 127 ++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 test/jdk/java/io/Reader/ReadAll.java diff --git a/src/java.base/share/classes/java/io/Reader.java b/src/java.base/share/classes/java/io/Reader.java index f882a939fbc..af5ac9f68ec 100644 --- a/src/java.base/share/classes/java/io/Reader.java +++ b/src/java.base/share/classes/java/io/Reader.java @@ -27,6 +27,7 @@ package java.io; import java.nio.CharBuffer; import java.nio.ReadOnlyBufferException; +import java.util.List; import java.util.Objects; /** @@ -198,6 +199,20 @@ public abstract class Reader implements Readable, Closeable { return n; } + @Override + public String readAllAsString() throws IOException { + ensureOpen(); + int len = cs.length(); + String result = cs.subSequence(next, len).toString(); + next += result.length(); + return result; + } + + @Override + public List readAllLines() throws IOException { + return readAllAsString().lines().toList(); + } + @Override public long skip(long n) throws IOException { ensureOpen(); @@ -382,6 +397,111 @@ public abstract class Reader implements Readable, Closeable { */ public abstract int read(char[] cbuf, int off, int len) throws IOException; + private String readAllCharsAsString() throws IOException { + StringBuilder result = new StringBuilder(); + char[] cbuf = new char[TRANSFER_BUFFER_SIZE]; + int nread; + while ((nread = read(cbuf, 0, cbuf.length)) != -1) { + result.append(cbuf, 0, nread); + } + return result.toString(); + } + + /** + * Reads all remaining characters as lines of text. This method blocks until + * all remaining characters have been read and end of stream is detected, + * or an exception is thrown. This method does not close the reader. + * + *

When this reader reaches the end of the stream, further + * invocations of this method will return an empty list. + * + *

A line is either a sequence of zero or more characters + * followed by a line terminator, or it is a sequence of one or + * more characters followed by the end of the stream. + * A line does not include the line terminator. + * + *

A line terminator is one of the following: + * a line feed character {@code "\n"} (U+000A), + * a carriage return character {@code "\r"} (U+000D), + * or a carriage return followed immediately by a line feed + * {@code "\r\n"} (U+000D U+000A). + * + *

The behavior for the case where the reader is + * asynchronously closed, or the thread interrupted during the + * read, is highly reader specific, and therefore not specified. + * + *

If an I/O error occurs reading from the stream then it + * may do so after some, but not all, characters have been read. + * Consequently the stream may not be at end of stream and may + * be in an inconsistent state. It is strongly recommended that the reader + * be promptly closed if an I/O error occurs. + * + * @apiNote + * This method is intended for simple cases where it is appropriate and + * convenient to read the entire input into a list of lines. It is not + * suitable for reading input from an unknown origin, as this may result + * in the allocation of an arbitrary amount of memory. + * + * @return the remaining characters as lines of text stored in an + * unmodifiable {@code List} of {@code String}s in the order + * they are read + * + * @throws IOException If an I/O error occurs + * @throws OutOfMemoryError If the number of remaining characters + * exceeds the implementation limit for {@code String}. + * + * @see String#lines + * @see #readAllAsString + * @see java.nio.file.Files#readAllLines + * + * @since 25 + */ + public List readAllLines() throws IOException { + return readAllCharsAsString().lines().toList(); + } + + /** + * Reads all remaining characters into a string. This method blocks until + * all remaining characters including all line separators have been read + * and end of stream is detected, or an exception is thrown. The resulting + * string will contain line separators as they appear in the stream. This + * method does not close the reader. + * + *

When this reader reaches the end of the stream, further + * invocations of this method will return an empty string. + * + *

The behavior for the case where the reader + * is asynchronously closed, or the thread interrupted during the + * read, is highly reader specific, and therefore not specified. + * + *

If an I/O error occurs reading from the stream then it + * may do so after some, but not all, characters have been read. + * Consequently the stream may not be at end of stream and may + * be in an inconsistent state. It is strongly recommended that the reader + * be promptly closed if an I/O error occurs. + * + * @apiNote + * This method is intended for simple cases where it is appropriate and + * convenient to read the entire input into a {@code String}. It is not + * suitable for reading input from an unknown origin, as this may result + * in the allocation of an arbitrary amount of memory. + * + * @return a {@code String} containing all remaining characters + * + * @throws IOException If an I/O error occurs + * @throws OutOfMemoryError If the number of remaining characters + * exceeds the implementation limit for + * {@code String}. + * + * @see #readAllLines + * @see java.nio.file.Files#readString + * + * @since 25 + */ + public String readAllAsString() throws IOException { + return readAllCharsAsString(); + } + /** Maximum skip-buffer size */ private static final int maxSkipBufferSize = 8192; diff --git a/test/jdk/java/io/Reader/ReadAll.java b/test/jdk/java/io/Reader/ReadAll.java new file mode 100644 index 00000000000..72fcf459eca --- /dev/null +++ b/test/jdk/java/io/Reader/ReadAll.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8354724 + * @summary Test Reader readAllLines and readAllAstring methods + * @library .. /test/lib + * @build jdk.test.lib.Platform jdk.test.lib.RandomFactory + * @run junit ReadAll + * @key randomness + */ + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import jdk.test.lib.RandomFactory; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ReadAll { + private static final String PHRASE = + "Ange plein de gaieté, connaissez-vous l'angoisse"; + + private static File file; + private static Path path; + private static Random rnd; + + @BeforeAll + public static void setup() throws IOException { + path = Files.createTempFile(Path.of("."), "foo", "bar"); + file = path.toFile(); + + rnd = RandomFactory.getRandom(); + int size = rnd.nextInt(2, 16386); + + int plen = PHRASE.length(); + List strings = new ArrayList(size); + while (strings.size() < size) { + int fromIndex = rnd.nextInt(0, plen / 2); + int toIndex = rnd.nextInt(fromIndex, plen); + strings.add(PHRASE.substring(fromIndex, toIndex)); + } + Files.write(path, strings); + System.out.println(strings.size() + " lines written"); + } + + @AfterAll + public static void cleanup() throws IOException { + if (file != null) + file.delete(); + } + + @Test + public void readAllLines() throws IOException { + // Reader implementation + List lines; + try (FileReader fr = new FileReader(file)) { + lines = fr.readAllLines(); + } + System.out.println(lines.size() + " lines read"); + + List linesExpected = Files.readAllLines(path); + assertEquals(linesExpected, lines); + + // Reader.of implementation + String stringExpected = Files.readString(path); + int n = rnd.nextInt(stringExpected.length()/2); + String substringExpected = stringExpected.substring(n); + linesExpected = substringExpected.lines().toList(); + try (Reader r = new StringReader(stringExpected)) { + r.skip(n); + lines = r.readAllLines(); + } + assertEquals(linesExpected, lines); + } + + @Test + public void readAllAsString() throws IOException { + // Reader implementation + String string; + try (FileReader fr = new FileReader(file)) { + string = fr.readAllAsString(); + } + String stringExpected = Files.readString(path); + assertEquals(stringExpected, string); + + // Reader.of implementation + int n = rnd.nextInt(stringExpected.length()/2); + try (Reader r = Reader.of(stringExpected)) { + r.skip(n); + string = r.readAllAsString(); + } + assertEquals(stringExpected.substring(n), string); + } +} From f318868268f32934a2f0c4e26a6c75360d8e74b1 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Thu, 29 May 2025 17:01:28 +0000 Subject: [PATCH 004/216] 8348328: Update IANA Language Subtag Registry to Version 2025-05-15 Reviewed-by: iris, naoto --- .../data/lsrdata/language-subtag-registry.txt | 122 +++++++++++++++++- .../Locale/LanguageSubtagRegistryTest.java | 28 +++- 2 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/data/lsrdata/language-subtag-registry.txt b/src/java.base/share/data/lsrdata/language-subtag-registry.txt index b00ea67e7e8..64c40f28162 100644 --- a/src/java.base/share/data/lsrdata/language-subtag-registry.txt +++ b/src/java.base/share/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2024-11-19 +File-Date: 2025-05-15 %% Type: language Subtag: aa @@ -5950,6 +5950,7 @@ Added: 2009-07-29 %% Type: language Subtag: bql +Description: Karian Description: Bilakura Added: 2009-07-29 %% @@ -9083,6 +9084,7 @@ Scope: collection %% Type: language Subtag: daz +Description: Moi-Wadea Description: Dao Added: 2009-07-29 %% @@ -9290,6 +9292,8 @@ Type: language Subtag: dek Description: Dek Added: 2009-07-29 +Deprecated: 2024-12-12 +Preferred-Value: sqm %% Type: language Subtag: del @@ -14082,6 +14086,12 @@ Added: 2009-07-29 Macrolanguage: hmn %% Type: language +Subtag: hnm +Description: Hainanese +Added: 2024-12-12 +Macrolanguage: zh +%% +Type: language Subtag: hnn Description: Hanunoo Added: 2009-07-29 @@ -16421,6 +16431,7 @@ Added: 2009-07-29 %% Type: language Subtag: kci +Description: Ngyian Description: Kamantan Added: 2009-07-29 %% @@ -21081,6 +21092,12 @@ Description: Laua Added: 2009-07-29 %% Type: language +Subtag: luh +Description: Leizhou Chinese +Added: 2024-12-12 +Macrolanguage: zh +%% +Type: language Subtag: lui Description: Luiseno Added: 2005-10-16 @@ -22850,6 +22867,8 @@ Added: 2009-07-29 %% Type: language Subtag: mmi +Description: Hember Avu +Description: Amben Description: Musar Added: 2009-07-29 %% @@ -25197,8 +25216,9 @@ Added: 2009-07-29 %% Type: language Subtag: new -Description: Newari Description: Nepal Bhasa +Description: Newar +Description: Newari Added: 2005-10-16 %% Type: language @@ -26641,6 +26661,8 @@ Type: language Subtag: nte Description: Nathembo Added: 2009-07-29 +Deprecated: 2024-12-12 +Preferred-Value: eko %% Type: language Subtag: ntg @@ -27185,6 +27207,12 @@ Description: Oroch Added: 2009-07-29 %% Type: language +Subtag: oak +Description: Noakhali +Description: Noakhailla +Added: 2025-05-14 +%% +Type: language Subtag: oar Description: Old Aramaic (up to 700 BCE) Description: Ancient Aramaic (up to 700 BCE) @@ -32147,6 +32175,12 @@ Description: Sajau Basap Added: 2009-07-29 %% Type: language +Subtag: sjc +Description: Shaojiang Chinese +Added: 2024-12-12 +Macrolanguage: zh +%% +Type: language Subtag: sjd Description: Kildin Sami Added: 2009-07-29 @@ -41302,6 +41336,11 @@ Description: Aluo Added: 2009-07-29 %% Type: language +Subtag: ynb +Description: Yamben +Added: 2025-02-06 +%% +Type: language Subtag: ynd Description: Yandruwandha Added: 2009-07-29 @@ -43616,6 +43655,14 @@ Preferred-Value: hks Prefix: sgn %% Type: extlang +Subtag: hnm +Description: Hainanese +Added: 2024-12-12 +Preferred-Value: hnm +Prefix: zh +Macrolanguage: zh +%% +Type: extlang Subtag: hos Description: Ho Chi Minh City Sign Language Added: 2009-07-29 @@ -43958,6 +44005,14 @@ Prefix: lv Macrolanguage: lv %% Type: extlang +Subtag: luh +Description: Leizhou Chinese +Added: 2024-12-12 +Preferred-Value: luh +Prefix: zh +Macrolanguage: zh +%% +Type: extlang Subtag: lvs Description: Standard Latvian Added: 2010-03-11 @@ -44393,6 +44448,14 @@ Prefix: ar Macrolanguage: ar %% Type: extlang +Subtag: sjc +Description: Shaojiang Chinese +Added: 2024-12-12 +Preferred-Value: sjc +Prefix: zh +Macrolanguage: zh +%% +Type: extlang Subtag: slf Description: Swiss-Italian Sign Language Added: 2009-07-29 @@ -44844,6 +44907,11 @@ Description: Bangla Added: 2005-10-16 %% Type: script +Subtag: Berf +Description: Beria Erfe +Added: 2025-02-06 +%% +Type: script Subtag: Bhks Description: Bhaiksuki Added: 2015-07-24 @@ -45132,6 +45200,12 @@ Description: Nyiakeng Puachue Hmong Added: 2017-08-13 %% Type: script +Subtag: Hntl +Description: Han (Traditional variant) with Latin (alias for Hant + + Latn) +Added: 2025-05-14 +%% +Type: script Subtag: Hrkt Description: Japanese syllabaries (alias for Hiragana + Katakana) Added: 2005-10-16 @@ -45636,6 +45710,12 @@ Description: Saurashtra Added: 2006-07-21 %% Type: script +Subtag: Seal +Description: Seal +Description: Small Seal +Added: 2025-05-14 +%% +Type: script Subtag: Sgnw Description: SignWriting Added: 2006-10-17 @@ -47919,6 +47999,12 @@ Comments: Written standard developed by Romanilha in 1853 and used by dóu Po, Escolo Gaston Febus, and others %% Type: variant +Subtag: hanoi +Description: The Hà Nội variant of Vietnamese +Added: 2025-03-10 +Prefix: vi +%% +Type: variant Subtag: hepburn Description: Hepburn romanization Added: 2009-10-01 @@ -47949,6 +48035,12 @@ Added: 2017-03-14 Prefix: eo %% Type: variant +Subtag: huett +Description: The Huế (province Thừa Thiên) variant of Vietnamese +Added: 2025-03-10 +Prefix: vi +%% +Type: variant Subtag: ijekavsk Description: Serbian with Ijekavian pronunciation Prefix: sr @@ -48024,6 +48116,13 @@ Prefix: sa Comments: Preferred tag is cls %% Type: variant +Subtag: leidentr +Description: Ancient Egyptian in Leiden Unified Transliteration +Added: 2025-02-06 +Prefix: egy +Comments: Recommended by the International Association of Egyptologists +%% +Type: variant Subtag: lemosin Description: Limousin Added: 2018-04-22 @@ -48068,6 +48167,19 @@ Comments: Russian orthography as established by the 1917/1918 orthographic reforms %% Type: variant +Subtag: mdcegyp +Description: Ancient Egyptian hieroglyphs encoded in Manuel de Codage +Added: 2025-02-06 +Prefix: egy +%% +Type: variant +Subtag: mdctrans +Description: Ancient Egyptian transliteration encoded in Manuel de + Codage +Added: 2025-02-06 +Prefix: egy +%% +Type: variant Subtag: metelko Description: Slovene in Metelko alphabet Added: 2012-06-27 @@ -48255,6 +48367,12 @@ Prefix: rm Comments: Supraregional Romansh written standard %% Type: variant +Subtag: saigon +Description: The Sài Gòn variant of Vietnamese +Added: 2025-03-10 +Prefix: vi +%% +Type: variant Subtag: scotland Description: Scottish Standard English Added: 2007-08-31 diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index d143e025dd5..12f5a96d3fb 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,9 +25,9 @@ * @test * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322 - * 8327631 8332424 8334418 8344589 + * 8327631 8332424 8334418 8344589 8348328 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2024-11-19) with Locale and Locale.LanguageRange + * (LSR Revision: 2025-05-15) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ @@ -45,9 +45,9 @@ public class LanguageSubtagRegistryTest { static boolean err = false; private static final String ACCEPT_LANGUAGE = - "Accept-Language: aam, adp, aeb, ajs, aog, apc, ajp, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, ema," - + " en-gb-oed, gti, iba, ilw, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, meg, mtm," - + " ngv, nns, ola, oyb, pat, pcr, phr, plu, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," + "Accept-Language: aam, adp, aeb, ajs, aog, apc, ajp, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, eko, ema," + + " en-gb-oed, gti, hnm, iba, ilw, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, luh, lvi, meg, mtm," + + " ngv, nns, ola, oyb, pat, pcr, phr, plu, pnd, pub, rib, rnb, rsn, scv, sjc, snz, sqm, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," + " umi, uss, uth, xia, yos, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; private static final List EXPECTED_RANGE_LIST = List.of( new LanguageRange("aam", 1.0), @@ -94,12 +94,16 @@ public class LanguageSubtagRegistryTest { new LanguageRange("sgn-dsz", 1.0), new LanguageRange("ehs", 1.0), new LanguageRange("sgn-ehs", 1.0), + new LanguageRange("eko", 1.0), + new LanguageRange("nte", 1.0), new LanguageRange("ema", 1.0), new LanguageRange("uok", 1.0), new LanguageRange("en-gb-oed", 1.0), new LanguageRange("en-gb-oxendict", 1.0), new LanguageRange("gti", 1.0), new LanguageRange("nyc", 1.0), + new LanguageRange("hnm", 1.0), + new LanguageRange("zh-hnm", 1.0), new LanguageRange("iba", 1.0), new LanguageRange("snb", 1.0), new LanguageRange("blg", 1.0), @@ -142,6 +146,8 @@ public class LanguageSubtagRegistryTest { new LanguageRange("sgn-lsv", 1.0), new LanguageRange("lsw", 1.0), new LanguageRange("sgn-lsw", 1.0), + new LanguageRange("luh", 1.0), + new LanguageRange("zh-luh", 1.0), new LanguageRange("lvi", 1.0), new LanguageRange("meg", 1.0), new LanguageRange("cir", 1.0), @@ -176,8 +182,12 @@ public class LanguageSubtagRegistryTest { new LanguageRange("sgn-rsn", 1.0), new LanguageRange("scv", 1.0), new LanguageRange("zir", 1.0), + new LanguageRange("sjc", 1.0), + new LanguageRange("zh-sjc", 1.0), new LanguageRange("snz", 1.0), new LanguageRange("asd", 1.0), + new LanguageRange("sqm", 1.0), + new LanguageRange("dek", 1.0), new LanguageRange("sqx", 1.0), new LanguageRange("sgn-sqx", 1.0), new LanguageRange("suj", 1.0), @@ -264,12 +274,18 @@ public class LanguageSubtagRegistryTest { System.err.println(" Expected size=" + expectedSize); for (LanguageRange lr : expected) { + if (!got.contains(lr)) { + System.err.print("Error - Actual does not contain:"); + } System.err.println(" range=" + lr.getRange() + ", weight=" + lr.getWeight()); } System.err.println(" Actual size=" + actualSize); for (LanguageRange lr : got) { + if (!expected.contains(lr)) { + System.err.print("Error - Expected does not contain:"); + } System.err.println(" range=" + lr.getRange() + ", weight=" + lr.getWeight()); } From e306367813db7c8a3ecac5e46740600b7ab04f9d Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Thu, 29 May 2025 17:06:42 +0000 Subject: [PATCH 005/216] 8357693: AOTCodeCompressedOopsTest.java failed with -XX:+UseLargePages Reviewed-by: kvn, shade --- src/hotspot/share/cds/filemap.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 375a3ccffbc..723b5298646 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1666,10 +1666,13 @@ bool FileMapInfo::map_heap_region_impl() { char* addr = (char*)_mapped_heap_memregion.start(); char* base; - if (MetaspaceShared::use_windows_memory_mapping()) { + if (MetaspaceShared::use_windows_memory_mapping() || UseLargePages) { + // With UseLargePages, memory mapping may fail on some OSes if the size is not + // large page aligned, so let's use read() instead. In this case, the memory region + // is already commited by G1 so we don't need to commit it again. if (!read_region(MetaspaceShared::hp, addr, align_up(_mapped_heap_memregion.byte_size(), os::vm_page_size()), - /* do_commit = */ true)) { + /* do_commit = */ !UseLargePages)) { dealloc_heap_region(); aot_log_error(aot)("Failed to read archived heap region into " INTPTR_FORMAT, p2i(addr)); return false; From e509997fe87a09513b8f79d303cc69392d2cb7b0 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Thu, 29 May 2025 17:39:08 +0000 Subject: [PATCH 006/216] 8357275: Locale.Builder.setLanguageTag should mention conversions made on language tag Reviewed-by: naoto --- .../share/classes/java/util/Locale.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index fa13afcc310..a5ac0ae5bf7 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -1800,7 +1800,7 @@ public final class Locale implements Cloneable, Serializable { * to {@link Locale.Builder#setLanguageTag(String)} which throws an exception * in this case. * - *

The following conversions are performed:

    + *

    The following conversions are performed:

      * *
    • The language code "und" is mapped to language "". * @@ -1826,13 +1826,19 @@ public final class Locale implements Cloneable, Serializable { * loc.getExtension('x'); // returns "urp" * } * - *
    • When the languageTag argument contains an extlang subtag, - * the first such subtag is used as the language, and the primary - * language subtag and other extlang subtags are ignored: + *
    • BCP 47 language tags permit up to three extlang subtags. However, + * the second and third extlang subtags are always ignored. As such, + * the first extlang subtag in {@code languageTag} is used as the language, + * and the primary language subtag and other extlang subtags are ignored. + * Language tags that exceed three extlang subtags are considered + * ill-formed starting at the offending extlang subtag. * * {@snippet lang=java : * Locale.forLanguageTag("ar-aao").getLanguage(); // returns "aao" * Locale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US" + * Locale.forLanguageTag("zh-yue-gan-cmn-czh-CN").toString(); + * // returns "yue"; "czh" exceeds the extlang limit, and subsequent + * // subtags are considered ill-formed * } * *
    • Case is normalized except for variant tags, which are left @@ -2787,6 +2793,9 @@ public final class Locale implements Cloneable, Serializable { * just discards ill-formed and following portions of the * tag). * + *

      See {@link Locale##langtag_conversions converions} for a full list + * of conversions that are performed on {@code languageTag}. + * * @param languageTag the language tag * @return This builder. * @throws IllformedLocaleException if {@code languageTag} is ill-formed From d922e318bc2104d69c46403bceb609d538f3259a Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Thu, 29 May 2025 20:09:01 +0000 Subject: [PATCH 007/216] 8349400: Improve startup speed via eliminating nested classes Reviewed-by: valeriep, rriggs --- .../classes/sun/security/util/KnownOIDs.java | 74 +++++++------------ 1 file changed, 25 insertions(+), 49 deletions(-) diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java index 9435a7a9d39..8e764b75730 100644 --- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,10 +91,7 @@ public enum KnownOIDs { ipsecEndSystem("1.3.6.1.5.5.7.3.5"), ipsecTunnel("1.3.6.1.5.5.7.3.6"), ipsecUser("1.3.6.1.5.5.7.3.7"), - KP_TimeStamping("1.3.6.1.5.5.7.3.8", "timeStamping") { - @Override - boolean registerNames() { return false; } - }, + KP_TimeStamping("1.3.6.1.5.5.7.3.8", "timeStamping", false), OCSPSigning("1.3.6.1.5.5.7.3.9"), // access descriptors - PKIX.48.* OCSP("1.3.6.1.5.5.7.48.1"), @@ -102,10 +99,7 @@ public enum KnownOIDs { OCSPNonceExt("1.3.6.1.5.5.7.48.1.2"), OCSPNoCheck("1.3.6.1.5.5.7.48.1.5"), caIssuers("1.3.6.1.5.5.7.48.2"), - AD_TimeStamping("1.3.6.1.5.5.7.48.3", "timeStamping") { - @Override - boolean registerNames() { return false; } - }, + AD_TimeStamping("1.3.6.1.5.5.7.48.3", "timeStamping", false), caRepository("1.3.6.1.5.5.7.48.5", "caRepository"), // NIST -- @@ -189,10 +183,7 @@ public enum KnownOIDs { // RSASecurity // PKCS1 1.2.840.113549.1.1.* - PKCS1("1.2.840.113549.1.1", "RSA") { // RSA KeyPairGenerator and KeyFactory - @Override - boolean registerNames() { return false; } - }, + PKCS1("1.2.840.113549.1.1", "RSA", false), // RSA KeyPairGenerator and KeyFactory RSA("1.2.840.113549.1.1.1"), // RSA encryption MD2withRSA("1.2.840.113549.1.1.2"), @@ -322,10 +313,7 @@ public enum KnownOIDs { SpecifiedSHA2withECDSA("1.2.840.10045.4.3"), // X9.42 1.2.840.10046.2.* - X942_DH("1.2.840.10046.2.1", "DiffieHellman") { // unused by JDK providers - @Override - boolean registerNames() { return false; } - }, + X942_DH("1.2.840.10046.2.1", "DiffieHellman", false), // unused by JDK providers // Teletrust 1.3.36.* brainpoolP160r1("1.3.36.3.3.2.8.1.1.1"), @@ -375,34 +363,19 @@ public enum KnownOIDs { // OIW secsig 1.3.14.3.* OIW_DES_CBC("1.3.14.3.2.7", "DES/CBC", "DES"), - OIW_DSA("1.3.14.3.2.12", "DSA") { - @Override - boolean registerNames() { return false; } - }, + OIW_DSA("1.3.14.3.2.12", "DSA", false), - OIW_JDK_SHA1withDSA("1.3.14.3.2.13", "SHA1withDSA") { - @Override - boolean registerNames() { return false; } - }, + OIW_JDK_SHA1withDSA("1.3.14.3.2.13", "SHA1withDSA", false), - OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA") { - @Override - boolean registerNames() { return false; } - }, + OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA", false), DESede("1.3.14.3.2.17", "DESede"), SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"), - OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") { - @Override - boolean registerNames() { return false; } - }, + OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA", false), - OIW_SHA1withRSA("1.3.14.3.2.29", "SHA1withRSA") { - @Override - boolean registerNames() { return false; } - }, + OIW_SHA1withRSA("1.3.14.3.2.29", "SHA1withRSA", false), // Thawte 1.3.101.* X25519("1.3.101.110"), @@ -426,11 +399,9 @@ public enum KnownOIDs { // Consider removing them in future releases when their usage // have died out - ITUX509_RSA("2.5.8.1.1", "RSA") { // unused by JDK providers - // defined in X.509 for RSA keys - @Override // with modulus length as its parameter - boolean registerNames() { return false; } - }, + ITUX509_RSA("2.5.8.1.1", "RSA", false), // unused by JDK providers + // defined in X.509 for RSA keys + // with modulus length as its parameter SkipIPAddress("1.3.6.1.4.1.42.2.11.2.1"), JAVASOFT_JDKKeyProtector("1.3.6.1.4.1.42.2.17.1.1"), @@ -442,6 +413,7 @@ public enum KnownOIDs { private final String stdName; private final String oid; private final String[] aliases; + private final boolean registerNames; // find the matching enum using either name or oid string // return null if no match found @@ -476,9 +448,8 @@ public enum KnownOIDs { } else if (debug != null) { debug.println(o.oid + " => " + o.name()); } - // only register the stdName and aliases if o.registerNames() - // returns true - if (o.registerNames()) { + // only register the stdName and aliases if o.registerNames is true + if (o.registerNames) { String stdNameUpper = o.stdName.toUpperCase(Locale.ENGLISH); if (Objects.nonNull(name2enum.put(stdNameUpper, o))) { throw new RuntimeException("ERROR: Duplicate " + @@ -505,12 +476,21 @@ public enum KnownOIDs { this.oid = oid; this.stdName = name(); // defaults to enum name this.aliases = new String[0]; + this.registerNames = true; } KnownOIDs(String oid, String stdName, String... aliases) { this.oid = oid; this.stdName = stdName; this.aliases = aliases; + this.registerNames = true; + } + + KnownOIDs(String oid, String stdName, boolean registerNames) { + this.oid = oid; + this.stdName = stdName; + this.aliases = new String[0]; + this.registerNames = registerNames; } // returns the oid string associated with this enum @@ -527,8 +507,4 @@ public enum KnownOIDs { public String[] aliases() { return aliases; } - - boolean registerNames() { - return true; - } } From 727412d1b5f0764363ebd2ff600d4b7f0c99bb9b Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Thu, 29 May 2025 20:09:58 +0000 Subject: [PATCH 008/216] 8357690: Add @Stable and final to java.lang.CharacterDataLatin1 and other CharacterData classes Reviewed-by: naoto --- .../build/tools/generatecharacter/GenerateCharacter.java | 6 +++--- src/java.base/share/classes/java/lang/CharacterData.java | 6 ++++-- .../share/classes/java/lang/CharacterData00.java.template | 4 +++- .../share/classes/java/lang/CharacterData01.java.template | 8 +++++--- .../share/classes/java/lang/CharacterData02.java.template | 8 +++++--- .../share/classes/java/lang/CharacterData03.java.template | 8 +++++--- .../share/classes/java/lang/CharacterData0E.java.template | 8 +++++--- .../classes/java/lang/CharacterDataLatin1.java.template | 7 +++++-- .../share/classes/java/lang/CharacterDataPrivateUse.java | 4 ++-- .../share/classes/java/lang/CharacterDataUndefined.java | 4 ++-- 10 files changed, 39 insertions(+), 24 deletions(-) diff --git a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java index 8d6a703f1c9..a2f37db72d9 100644 --- a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java +++ b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1190,7 +1190,7 @@ OUTER: for (int i = 0; i < n; i += m) { if (Csyntax) result.append(" static "); else - result.append(" static final "); + result.append(" @Stable static final "); result.append(atype); result.append(" ").append(name).append("["); if (Csyntax) @@ -1347,7 +1347,7 @@ OUTER: for (int i = 0; i < n; i += m) { } static void genCaseMapTableDeclaration(StringBuffer result) { - result.append(" static final char[][][] charMap;\n"); + result.append(" @Stable static final char[][][] charMap;\n"); } static void genCaseMapTable(StringBuffer result, SpecialCaseMap[] specialCaseMaps){ diff --git a/src/java.base/share/classes/java/lang/CharacterData.java b/src/java.base/share/classes/java/lang/CharacterData.java index d75853fe9ca..6631b7c204e 100644 --- a/src/java.base/share/classes/java/lang/CharacterData.java +++ b/src/java.base/share/classes/java/lang/CharacterData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,7 +25,9 @@ package java.lang; -abstract class CharacterData { +abstract sealed class CharacterData + permits CharacterData00, CharacterData01, CharacterData02, CharacterData03, + CharacterData0E, CharacterDataLatin1, CharacterDataPrivateUse, CharacterDataUndefined { abstract int getProperties(int ch); abstract int getType(int ch); abstract boolean isDigit(int ch); diff --git a/src/java.base/share/classes/java/lang/CharacterData00.java.template b/src/java.base/share/classes/java/lang/CharacterData00.java.template index db496250201..247a3ec7050 100644 --- a/src/java.base/share/classes/java/lang/CharacterData00.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData00.java.template @@ -25,12 +25,14 @@ package java.lang; +import jdk.internal.vm.annotation.Stable; + /** * The CharacterData00 class encapsulates the large tables once found in * java.lang.Character */ -class CharacterData00 extends CharacterData { +final class CharacterData00 extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property 4 bits directionality property diff --git a/src/java.base/share/classes/java/lang/CharacterData01.java.template b/src/java.base/share/classes/java/lang/CharacterData01.java.template index 0c25f633391..e634e3486e8 100644 --- a/src/java.base/share/classes/java/lang/CharacterData01.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData01.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -25,11 +25,13 @@ package java.lang; -/** The CharacterData class encapsulates the large tables once found in +import jdk.internal.vm.annotation.Stable; + +/** The CharacterData01 class encapsulates the large tables once found in * java.lang.Character. */ -class CharacterData01 extends CharacterData { +final class CharacterData01 extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property 4 bits directionality property diff --git a/src/java.base/share/classes/java/lang/CharacterData02.java.template b/src/java.base/share/classes/java/lang/CharacterData02.java.template index ff5a1c30189..65570ae3f5b 100644 --- a/src/java.base/share/classes/java/lang/CharacterData02.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData02.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -25,10 +25,12 @@ package java.lang; -/** The CharacterData class encapsulates the large tables found in +import jdk.internal.vm.annotation.Stable; + +/** The CharacterData02 class encapsulates the large tables found in Java.lang.Character. */ -class CharacterData02 extends CharacterData { +final class CharacterData02 extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property 4 bits directionality property diff --git a/src/java.base/share/classes/java/lang/CharacterData03.java.template b/src/java.base/share/classes/java/lang/CharacterData03.java.template index 27d1f4b9a69..6b7d037fbc3 100644 --- a/src/java.base/share/classes/java/lang/CharacterData03.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData03.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,12 @@ package java.lang; -/** The CharacterData class encapsulates the large tables found in +import jdk.internal.vm.annotation.Stable; + +/** The CharacterData03 class encapsulates the large tables found in Java.lang.Character. */ -class CharacterData03 extends CharacterData { +final class CharacterData03 extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property 4 bits directionality property diff --git a/src/java.base/share/classes/java/lang/CharacterData0E.java.template b/src/java.base/share/classes/java/lang/CharacterData0E.java.template index f2ac14682ac..6e4858e4d3d 100644 --- a/src/java.base/share/classes/java/lang/CharacterData0E.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData0E.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -25,10 +25,12 @@ package java.lang; -/** The CharacterData class encapsulates the large tables found in +import jdk.internal.vm.annotation.Stable; + +/** The CharacterData0E class encapsulates the large tables found in Java.lang.Character. */ -class CharacterData0E extends CharacterData { +final class CharacterData0E extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property 4 bits directionality property diff --git a/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template b/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template index 3f162e6cc16..8316164c7c5 100644 --- a/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template +++ b/src/java.base/share/classes/java/lang/CharacterDataLatin1.java.template @@ -26,11 +26,12 @@ package java.lang; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.Stable; -/** The CharacterData class encapsulates the large tables found in +/** The CharacterDataLatin1 class encapsulates the large tables found in Java.lang.Character. */ -class CharacterDataLatin1 extends CharacterData { +final class CharacterDataLatin1 extends CharacterData { /* The character properties are currently encoded into 32 bits in the following manner: 1 bit mirrored property @@ -230,6 +231,7 @@ class CharacterDataLatin1 extends CharacterData { // // Analysis has shown that generating the whole array allows the JIT to generate // better code compared to a slimmed down array, such as one cutting off after 'z' + @Stable private static final byte[] DIGITS = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -314,6 +316,7 @@ class CharacterDataLatin1 extends CharacterData { return mapChar; } + @Stable static char[] sharpsMap = new char[] {'S', 'S'}; char[] toUpperCaseCharArray(int ch) { diff --git a/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java b/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java index 9e6c446f86a..22eae86f4a3 100644 --- a/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java +++ b/src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java @@ -25,10 +25,10 @@ package java.lang; -/** The CharacterData class encapsulates the large tables found in +/** The CharacterDataPrivateUse class encapsulates the large tables found in Java.lang.Character. */ -class CharacterDataPrivateUse extends CharacterData { +final class CharacterDataPrivateUse extends CharacterData { int getProperties(int ch) { return 0; diff --git a/src/java.base/share/classes/java/lang/CharacterDataUndefined.java b/src/java.base/share/classes/java/lang/CharacterDataUndefined.java index 58c74b658b1..4db9ff4ed3c 100644 --- a/src/java.base/share/classes/java/lang/CharacterDataUndefined.java +++ b/src/java.base/share/classes/java/lang/CharacterDataUndefined.java @@ -25,10 +25,10 @@ package java.lang; -/** The CharacterData class encapsulates the large tables found in +/** The CharacterDataUndefined class encapsulates the large tables found in Java.lang.Character. */ -class CharacterDataUndefined extends CharacterData { +final class CharacterDataUndefined extends CharacterData { int getProperties(int ch) { return 0; From cb8eea4ecd12669e361baac8bb6e71cde7937812 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Thu, 29 May 2025 21:29:35 +0000 Subject: [PATCH 009/216] 8356095: AArch64: Obsolete -XX:+NearCPool option Reviewed-by: aph --- src/hotspot/cpu/aarch64/globals_aarch64.hpp | 2 -- src/hotspot/share/runtime/arguments.cpp | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp index 800e7718921..632bba728a1 100644 --- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp @@ -83,8 +83,6 @@ define_pd_global(intx, InlineSmallCode, 1000); range, \ constraint) \ \ - product(bool, NearCpool, true, \ - "constant pool is close to instructions") \ product(bool, UseCRC32, false, \ "Use CRC32 instructions for CRC32 computation") \ product(bool, UseCryptoPmullForCRC32, false, \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index b7ce095b41b..7592d233f0c 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -545,6 +545,9 @@ static SpecialFlag const special_jvm_flags[] = { { "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() }, { "ZGenerational", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::undefined() }, { "ZMarkStackSpaceLimit", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::undefined() }, +#if defined(AARCH64) + { "NearCpool", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::undefined() }, +#endif #ifdef ASSERT { "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() }, From 648c337bea5ec65908cab02eaf232243ccf2d4bf Mon Sep 17 00:00:00 2001 From: Dean Long Date: Thu, 29 May 2025 21:41:49 +0000 Subject: [PATCH 010/216] 8356648: runtime/Thread/AsyncExceptionTest.java fails with +StressCompiledExceptionHandlers Reviewed-by: thartmann, kvn --- src/hotspot/share/c1/c1_Runtime1.cpp | 2 +- .../runtime/Thread/AsyncExceptionTest.java | 51 +++++++++---------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 4bf056fe312..93b8ed4410b 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -508,7 +508,7 @@ static nmethod* counter_overflow_helper(JavaThread* current, int branch_bci, Met JRT_BLOCK_ENTRY(address, Runtime1::counter_overflow(JavaThread* current, int bci, Method* method)) nmethod* osr_nm; - JRT_BLOCK + JRT_BLOCK_NO_ASYNC osr_nm = counter_overflow_helper(current, bci, method); if (osr_nm != nullptr) { RegisterMap map(current, diff --git a/test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java b/test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java index e1296ab81e9..c7d0d1a27f0 100644 --- a/test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java +++ b/test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,17 @@ * @requires vm.compiler1.enabled | vm.compiler2.enabled * @summary Stress delivery of asynchronous exceptions. * @library /test/hotspot/jtreg/testlibrary + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+StressCompiledExceptionHandlers + * -Xcomp -XX:TieredStopAtLevel=3 + * -XX:CompileCommand=dontinline,AsyncExceptionTest::internalRun2 + * -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun1 + * -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun2 + * AsyncExceptionTest * @run main/othervm -Xcomp - -XX:CompileCommand=dontinline,AsyncExceptionTest::internalRun2 - -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun1 - -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun2 - AsyncExceptionTest + * -XX:CompileCommand=dontinline,AsyncExceptionTest::internalRun2 + * -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun1 + * -XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun2 + * AsyncExceptionTest */ import jvmti.JVMTIUtils; @@ -42,19 +48,19 @@ public class AsyncExceptionTest extends Thread { private final static int DEF_TIME_MAX = 30; // default max # secs to test private final static String PROG_NAME = "AsyncExceptionTest"; - public CountDownLatch exitSyncObj = new CountDownLatch(1); public CountDownLatch startSyncObj = new CountDownLatch(1); private boolean firstEntry = true; private boolean receivedThreadDeathinInternal1 = false; private boolean receivedThreadDeathinInternal2 = false; + private volatile RuntimeException error = null; @Override public void run() { try { internalRun1(); } catch (ThreadDeath td) { - throw new RuntimeException("Caught ThreadDeath in run() instead of internalRun2() or internalRun1().\n" + error = new RuntimeException("Caught ThreadDeath in run() instead of internalRun2() or internalRun1().\n" + "receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1 + "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2); } catch (NoClassDefFoundError ncdfe) { @@ -62,11 +68,10 @@ public class AsyncExceptionTest extends Thread { } if (receivedThreadDeathinInternal2 == false && receivedThreadDeathinInternal1 == false) { - throw new RuntimeException("Didn't catch ThreadDeath in internalRun2() nor in internalRun1().\n" + error = new RuntimeException("Didn't catch ThreadDeath in internalRun2() nor in internalRun1().\n" + "receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1 + "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2); } - exitSyncObj.countDown(); } public void internalRun1() { @@ -123,18 +128,9 @@ public class AsyncExceptionTest extends Thread { try { // Wait for the worker thread to get going. thread.startSyncObj.await(); - while (true) { - // Send async exception and wait until it is thrown - JVMTIUtils.stopThread(thread); - thread.exitSyncObj.await(); - Thread.sleep(100); - - if (!thread.isAlive()) { - // Done with Thread.stop() calls since - // thread is not alive. - break; - } - } + // Send async exception and wait until it is thrown + JVMTIUtils.stopThread(thread); + thread.join(); } catch (InterruptedException e) { throw new Error("Unexpected: " + e); } catch (NoClassDefFoundError ncdfe) { @@ -143,11 +139,14 @@ public class AsyncExceptionTest extends Thread { // in a worker thread can subsequently be seen in the // main thread. } - - try { - thread.join(); - } catch (InterruptedException e) { - throw new Error("Unexpected: " + e); + if (thread.isAlive()) { + // Really shouldn't be possible after join() above... + throw new RuntimeException("Thread did not exit.\n" + + "receivedThreadDeathinInternal1=" + thread.receivedThreadDeathinInternal1 + + "; receivedThreadDeathinInternal2=" + thread.receivedThreadDeathinInternal2); + } + if (thread.error != null) { + throw thread.error; } } From a05f9dea18ec812abad1dbe0084c0c58384a9076 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 29 May 2025 21:44:47 +0000 Subject: [PATCH 011/216] 8358017: Various enhancements of jpackage test helpers Reviewed-by: almatvee --- .../jdk/jpackage/test/AnnotationsTest.java | 2 +- .../jdk/jpackage/test/JUnitAdapter.java | 33 +++++++---- .../jdk/jpackage/test/FileAssociations.java | 16 +++++- .../helpers/jdk/jpackage/test/HelloApp.java | 25 ++++++-- .../jdk/jpackage/test/JPackageCommand.java | 18 +++--- .../helpers/jdk/jpackage/test/JavaTool.java | 4 +- .../helpers/jdk/jpackage/test/MacSign.java | 2 +- .../jdk/jpackage/test/MacSignVerify.java | 2 +- .../jpackage/test/RunnablePackageTest.java | 6 +- .../helpers/jdk/jpackage/test/TKit.java | 48 +++++++++++++++- .../jdk/jpackage/test/TestBuilder.java | 22 ++++--- .../jdk/jpackage/test/TestInstance.java | 57 +++++++++---------- .../jdk/jpackage/test/TestMethodSupplier.java | 16 +++--- 13 files changed, 172 insertions(+), 79 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java index fdbd30ac7e9..e16b175ab8a 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java @@ -225,7 +225,7 @@ public class AnnotationsTest extends JUnitAdapter { ); } - private final static TestExecutionRecorder staticRecorder = new TestExecutionRecorder(ParameterizedInstanceTest.class); + private static final TestExecutionRecorder staticRecorder = new TestExecutionRecorder(ParameterizedInstanceTest.class); } public static class IfOSTest extends TestExecutionRecorder { diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java index 7bf1f57a254..b7c50285797 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JUnitAdapter.java @@ -22,8 +22,6 @@ */ package jdk.jpackage.test; -import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable; - import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -33,28 +31,39 @@ import java.io.PrintStream; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; import jdk.jpackage.internal.util.function.ThrowingRunnable; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; public class JUnitAdapter { - JUnitAdapter() { + static { if (System.getProperty("test.src") == null) { // Was called by somebody else but not by jtreg System.setProperty("test.src", Path.of("@@openJdkDir@@/test/jdk/tools/jpackage").toString()); } } - @Test - void runJPackageTests(@TempDir Path workDir) throws Throwable { - if (!getClass().equals(JUnitAdapter.class)) { - Main.main(TestBuilder.build().workDirRoot(workDir), new String [] { - "--jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault", - "--jpt-run=" + getClass().getName() - }); + public static Stream createJPackageTests(ClassLoader testClassLoader, String... args) throws Throwable { + final List tests = new ArrayList<>(); + try (final var testBuilder = TestBuilder.build().workDirRoot(Path.of("")).testClassLoader(testClassLoader).testConsumer(tests::add).create()) { + for (final var arg : args) { + testBuilder.processCmdLineArg(arg); + } } + return tests.stream().map(test -> { + return DynamicTest.dynamicTest(test.fullName(), () -> { + TKit.runAdhocTest(test); + }); + }); + } + + @TestFactory + Stream createJPackageTests() throws Throwable { + return createJPackageTests(getClass().getClassLoader(), "--jpt-run=" + getClass().getName()); } static List captureJPackageTestLog(ThrowingRunnable runnable) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java index 091a2206b17..f8dc10c3dd0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; import jdk.jpackage.internal.util.PathUtils; @@ -142,7 +143,18 @@ public final class FileAssociations { switch (invocationType) { case DesktopOpenAssociatedFile: { TKit.trace(String.format("Use desktop to open [%s] file", testFile)); - Desktop.getDesktop().open(testFile.toFile()); + if (!HelloApp.CLEAR_JAVA_ENV_VARS) { + Desktop.getDesktop().open(testFile.toFile()); + } else { + final var jsScript = TKit.createTempFile(Path.of("fa-scripts", testFile.getFileName().toString() + ".jsh")); + TKit.createTextFile(jsScript, List.of( + "import java.awt.Desktop", + "import java.io.File", + String.format("Desktop.getDesktop().open(new File(\"%s\"))", testFile.toString().replace('\\', '/')), + "/exit")); + final var exec = Executor.of(JavaTool.JSHELL.getPath().toString(), jsScript.toString()); + HelloApp.configureEnvironment(exec).dumpOutput().execute(); + } return List.of(testFile.toString()); } case WinCommandLine: { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index 7ac4159c2a6..69ea4ecfaa0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.function.Supplier; @@ -514,16 +515,25 @@ public final class HelloApp { } } - private static Executor configureEnvironment(Executor executor) { + static Executor configureEnvironment(Executor executor) { if (CLEAR_JAVA_ENV_VARS) { - executor.removeEnvVar("JAVA_TOOL_OPTIONS"); - executor.removeEnvVar("_JAVA_OPTIONS"); + JAVA_ENV_VARS.forEach(executor::removeEnvVar); } return executor; } + private static boolean javaEnvVariablesContainsModulePath() { + return JAVA_ENV_VARS.stream().map(System::getenv).filter(Objects::nonNull).anyMatch(HelloApp::containsModulePath); + } + + private static boolean containsModulePath(String value) { + return value.contains("--module-path"); + } + static final String OUTPUT_FILENAME = "appOutput.txt"; + private static final Set JAVA_ENV_VARS = Set.of("JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS"); + private final JavaAppDesc appDesc; private static final Path HELLO_JAVA = TKit.TEST_SRC_ROOT.resolve( @@ -532,6 +542,11 @@ public final class HelloApp { private static final String CLASS_NAME = HELLO_JAVA.getFileName().toString().split( "\\.", 2)[0]; - private static final boolean CLEAR_JAVA_ENV_VARS = Optional.ofNullable( - TKit.getConfigProperty("clear-app-launcher-java-env-vars")).map(Boolean::parseBoolean).orElse(false); + // + // Runtime in the app image normally doesn't have .jmod files. Because of this `--module-path` + // option will cause failure at app launcher startup. + // Java environment variables containing this option should be removed from the + // environment in which app launchers are started. + // + static final boolean CLEAR_JAVA_ENV_VARS = javaEnvVariablesContainsModulePath(); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index bab752affb8..7f9feb986b4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -52,6 +52,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.regex.Pattern; +import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.util.function.ThrowingConsumer; @@ -664,12 +665,16 @@ public class JPackageCommand extends CommandArguments { return hasArgument(UNPACKED_PATH_ARGNAME); } + public static void useToolProviderByDefault(ToolProvider jpackageToolProvider) { + defaultToolProvider = Optional.of(jpackageToolProvider); + } + public static void useToolProviderByDefault() { - defaultWithToolProvider = true; + useToolProviderByDefault(JavaTool.JPACKAGE.asToolProvider()); } public static void useExecutableByDefault() { - defaultWithToolProvider = false; + defaultToolProvider = Optional.empty(); } public JPackageCommand useToolProvider(boolean v) { @@ -778,8 +783,7 @@ public class JPackageCommand extends CommandArguments { } public boolean isWithToolProvider() { - return Optional.ofNullable(withToolProvider).orElse( - defaultWithToolProvider); + return Optional.ofNullable(withToolProvider).orElseGet(defaultToolProvider::isPresent); } public JPackageCommand executePrerequisiteActions() { @@ -800,7 +804,7 @@ public class JPackageCommand extends CommandArguments { .addArguments(args); if (isWithToolProvider()) { - exec.setToolProvider(JavaTool.JPACKAGE); + exec.setToolProvider(defaultToolProvider.orElseGet(JavaTool.JPACKAGE::asToolProvider)); } else { exec.setExecutable(JavaTool.JPACKAGE); if (TKit.isWindows()) { @@ -973,7 +977,7 @@ public class JPackageCommand extends CommandArguments { return getPaths.apply(cmd).stream().toList(); } - private final static class Builder { + private static final class Builder { Builder(String argName) { this.argName = Objects.requireNonNull(argName); @@ -1472,7 +1476,7 @@ public class JPackageCommand extends CommandArguments { private Set readOnlyPathAsserts = Set.of(ReadOnlyPathAssert.values()); private Set appLayoutAsserts = Set.of(AppLayoutAssert.values()); private List>> outputValidators = new ArrayList<>(); - private static boolean defaultWithToolProvider; + private static Optional defaultToolProvider = Optional.empty(); private static final Map PACKAGE_TYPES = Functional.identity( () -> { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java index 7b217b2431c..0bbf71fe0cd 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, 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 @@ -29,7 +29,7 @@ import java.nio.file.Path; import java.util.spi.ToolProvider; public enum JavaTool { - JAVA, JAVAC, JPACKAGE, JAR, JLINK, JMOD; + JAVA, JAVAC, JPACKAGE, JAR, JLINK, JMOD, JSHELL; JavaTool() { this.path = Path.of(System.getProperty("java.home")).resolve( diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java index a97969e00b7..af9f57c4f7f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java @@ -1037,7 +1037,7 @@ public final class MacSign { return !missingKeychain && !missingCertificates && !invalidCertificates; } - public final static class ResolvedKeychain { + public static final class ResolvedKeychain { public ResolvedKeychain(KeychainWithCertsSpec spec) { this.spec = Objects.requireNonNull(spec); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java index 88b41c2e469..432433b4fd0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java @@ -83,7 +83,7 @@ public final class MacSignVerify { return value; } - final private String value; + private final String value; } public static final String ADHOC_SIGN_ORIGIN = "-"; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java index 9f307989715..5337651bddc 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java @@ -71,7 +71,7 @@ public abstract class RunnablePackageTest { /** * Test action. */ - static public enum Action { + public static enum Action { /** * Init test. */ @@ -114,7 +114,7 @@ public abstract class RunnablePackageTest { return name().toLowerCase().replace('_', '-'); } - public final static Action[] CREATE_AND_UNPACK = new Action[] { + public static final Action[] CREATE_AND_UNPACK = new Action[] { CREATE, UNPACK, VERIFY_INSTALL }; }; @@ -143,7 +143,7 @@ public abstract class RunnablePackageTest { return groups; } - private final static List DEFAULT_ACTIONS; + private static final List DEFAULT_ACTIONS; static { final String propertyName = "action"; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 6c424e21d5f..2508db00295 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -25,6 +25,7 @@ package jdk.jpackage.test; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import static java.util.stream.Collectors.toSet; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import java.io.Closeable; import java.io.FileOutputStream; @@ -126,7 +127,19 @@ public final class TKit { } } + enum RunTestMode { + FAIL_FAST; + + static final Set DEFAULTS = Set.of(); + } + static void runTests(List tests) { + runTests(tests, RunTestMode.DEFAULTS); + } + + static void runTests(List tests, Set modes) { + Objects.requireNonNull(tests); + Objects.requireNonNull(modes); if (currentTest != null) { throw new IllegalStateException( "Unexpected nested or concurrent Test.run() call"); @@ -136,7 +149,11 @@ public final class TKit { tests.stream().forEach(test -> { currentTest = test; try { - ignoreExceptions(test).run(); + if (modes.contains(RunTestMode.FAIL_FAST)) { + ThrowingRunnable.toRunnable(test::run).run(); + } else { + ignoreExceptions(test).run(); + } } finally { currentTest = null; if (extraLogStream != null) { @@ -147,6 +164,35 @@ public final class TKit { }); } + static T runAdhocTest(ThrowingSupplier action) { + final List box = new ArrayList<>(); + runAdhocTest(() -> { + box.add(action.get()); + }); + return box.getFirst(); + } + + static void runAdhocTest(ThrowingRunnable action) { + Objects.requireNonNull(action); + + final Path workDir = toSupplier(() -> Files.createTempDirectory("jdk.jpackage-test")).get(); + + final TestInstance test; + if (action instanceof TestInstance ti) { + test = new TestInstance(ti, workDir); + } else { + test = new TestInstance(() -> { + try { + action.run(); + } finally { + TKit.deleteDirectoryRecursive(workDir); + } + }, workDir); + } + + runTests(List.of(test), Set.of(RunTestMode.FAIL_FAST)); + } + static Runnable ignoreExceptions(ThrowingRunnable action) { return () -> { try { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java index db4810ce5e2..227c73bc68e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java @@ -60,7 +60,7 @@ final class TestBuilder implements AutoCloseable { return new Builder(); } - final static class Builder { + static final class Builder { private Builder() { } @@ -74,17 +74,24 @@ final class TestBuilder implements AutoCloseable { return this; } + Builder testClassLoader(ClassLoader v) { + testClassLoader = v; + return this; + } + TestBuilder create() { - return new TestBuilder(testConsumer, workDirRoot); + return new TestBuilder(testConsumer, workDirRoot, testClassLoader); } private Consumer testConsumer; private Path workDirRoot = Path.of(""); + private ClassLoader testClassLoader = TestBuilder.class.getClassLoader(); } - private TestBuilder(Consumer testConsumer, Path workDirRoot) { + private TestBuilder(Consumer testConsumer, Path workDirRoot, ClassLoader testClassLoader) { this.testMethodSupplier = TestBuilderConfig.getDefault().createTestMethodSupplier(); this.workDirRoot = Objects.requireNonNull(workDirRoot); + this.testClassLoader = Objects.requireNonNull(testClassLoader); argProcessors = Map.of( CMDLINE_ARG_PREFIX + "after-run", arg -> getJavaMethodsFromArg(arg).map( @@ -233,9 +240,9 @@ final class TestBuilder implements AutoCloseable { testGroup = null; } - private static Class probeClass(String name) { + private static Class probeClass(String name, ClassLoader classLoader) { try { - return Class.forName(name); + return Class.forName(name, true, classLoader); } catch (ClassNotFoundException ex) { return null; } @@ -254,7 +261,7 @@ final class TestBuilder implements AutoCloseable { String defaultClassName = null; for (String token : argValue.split(",")) { - Class testSet = probeClass(token); + Class testSet = probeClass(token, testClassLoader); if (testSet != null) { if (testMethodSupplier.isTestClass(testSet)) { toConsumer(testMethodSupplier::verifyTestClass).accept(testSet); @@ -297,7 +304,7 @@ final class TestBuilder implements AutoCloseable { try { return testMethodSupplier.findNullaryLikeMethods( - fromQualifiedMethodName(qualifiedMethodName)); + fromQualifiedMethodName(qualifiedMethodName), testClassLoader); } catch (NoSuchMethodException ex) { throw new ParseException(ex.getMessage() + ";", ex); } @@ -371,6 +378,7 @@ final class TestBuilder implements AutoCloseable { private final Map> argProcessors; private final Consumer testConsumer; private final Path workDirRoot; + private final ClassLoader testClassLoader; private List testGroup; private List> beforeActions; private List> afterActions; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java index bef75e7280a..4445a194ee7 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java @@ -48,8 +48,16 @@ import jdk.jpackage.internal.util.function.ThrowingSupplier; final class TestInstance implements ThrowingRunnable { - static class TestDesc { - private TestDesc() { + static final class TestDesc { + private TestDesc(Class clazz, String functionName, String functionArgs, String instanceArgs) { + this.clazz = Objects.requireNonNull(clazz); + this.functionName = functionName; + this.functionArgs = functionArgs; + this.instanceArgs = instanceArgs; + } + + private TestDesc(Class clazz) { + this(clazz, null, null, null); } String testFullName() { @@ -93,16 +101,11 @@ final class TestInstance implements ThrowingRunnable { @Override public TestDesc get() { - TestDesc desc = new TestDesc(); if (method == null) { - desc.clazz = enclosingMainMethodClass(); + return new TestDesc(enclosingMainMethodClass()); } else { - desc.clazz = method.getDeclaringClass(); - desc.functionName = method.getName(); - desc.functionArgs = formatArgs(methodArgs); - desc.instanceArgs = formatArgs(ctorArgs); + return new TestDesc(method.getDeclaringClass(), method.getName(), formatArgs(methodArgs), formatArgs(ctorArgs)); } - return desc; } private static String formatArgs(List values) { @@ -140,27 +143,10 @@ final class TestInstance implements ThrowingRunnable { private static final HexFormat ARGS_CHAR_FORMATTER = HexFormat.of().withUpperCase(); } - static TestDesc create(Method m, Object... args) { - TestDesc desc = new TestDesc(); - desc.clazz = m.getDeclaringClass(); - desc.functionName = m.getName(); - if (args.length != 0) { - desc.functionArgs = Stream.of(args).map(v -> { - if (v.getClass().isArray()) { - return String.format("%s(length=%d)", - Arrays.deepToString((Object[]) v), - Array.getLength(v)); - } - return String.format("%s", v); - }).collect(Collectors.joining(", ")); - } - return desc; - } - - private Class clazz; - private String functionName; - private String functionArgs; - private String instanceArgs; + private final Class clazz; + private final String functionName; + private final String functionArgs; + private final String instanceArgs; } TestInstance(ThrowingRunnable testBody, Path workDirRoot) { @@ -186,6 +172,17 @@ final class TestInstance implements ThrowingRunnable { this.workDir = workDirRoot.resolve(createWorkDirPath(testDesc)); } + TestInstance(TestInstance other, Path workDirRoot) { + assertCount = 0; + this.testConstructor = other.testConstructor; + this.testBody = other.testBody; + this.beforeActions = other.beforeActions; + this.afterActions = other.afterActions; + this.testDesc = other.testDesc; + this.dryRun = other.dryRun; + this.workDir = workDirRoot.resolve(createWorkDirPath(other.testDesc)); + } + void notifyAssert() { assertCount++; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java index 8b92ae7ca46..36ae81b7db4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java @@ -62,8 +62,8 @@ final class TestMethodSupplier { record MethodQuery(String className, String methodName) { - List lookup() throws ClassNotFoundException { - final Class methodClass = Class.forName(className); + List lookup(ClassLoader classLoader) throws ClassNotFoundException { + final Class methodClass = Class.forName(className, true, classLoader); // Get the list of all public methods as need to deal with overloads. return Stream.of(methodClass.getMethods()).filter(method -> { @@ -84,11 +84,11 @@ final class TestMethodSupplier { } } - List findNullaryLikeMethods(MethodQuery query) throws NoSuchMethodException { + List findNullaryLikeMethods(MethodQuery query, ClassLoader classLoader) throws NoSuchMethodException { List methods; try { - methods = query.lookup(); + methods = query.lookup(classLoader); } catch (ClassNotFoundException ex) { throw new NoSuchMethodException( String.format("Class [%s] not found", query.className())); @@ -273,8 +273,10 @@ final class TestMethodSupplier { final Method supplierMethod; try { - final var parameterSupplierCandidates = findNullaryLikeMethods(methodQuery); - final Function> classForName = toFunction(Class::forName); + final var parameterSupplierCandidates = findNullaryLikeMethods(methodQuery, execClass.getClassLoader()); + final Function> classForName = toFunction(name -> { + return Class.forName(name, true, execClass.getClassLoader()); + }); final var supplierMethodClass = classForName.apply(methodQuery.className()); if (parameterSupplierCandidates.isEmpty()) { throw new RuntimeException(String.format( @@ -284,7 +286,7 @@ final class TestMethodSupplier { var allParameterSuppliers = filterParameterSuppliers(supplierMethodClass).toList(); - supplierMethod = findNullaryLikeMethods(methodQuery) + supplierMethod = findNullaryLikeMethods(methodQuery, execClass.getClassLoader()) .stream() .filter(allParameterSuppliers::contains) .findFirst().orElseThrow(() -> { From 64503c784bbddc638ce0098f5c6ef0cb81cbf938 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 30 May 2025 02:06:56 +0000 Subject: [PATCH 012/216] 8357299: Graphics copyArea doesn't copy any pixels when there is overflow Reviewed-by: achung, kizune, prr --- .../share/native/libawt/java2d/loops/Blit.c | 21 +++---- .../java/awt/Graphics/BrokenBoundsClip.java | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/awt/Graphics/BrokenBoundsClip.java diff --git a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c index 8a41584deef..cbba3e4cacb 100644 --- a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c +++ b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -74,19 +74,16 @@ Java_sun_java2d_loops_Blit_Blit srcInfo.bounds.x1 = srcx; srcInfo.bounds.y1 = srcy; - if (UNSAFE_TO_ADD(srcx, width) || - UNSAFE_TO_ADD(srcy, height) || - UNSAFE_TO_ADD(dstx, width) || - UNSAFE_TO_ADD(dsty, height)) { - return; - } - - srcInfo.bounds.x2 = srcx + width; - srcInfo.bounds.y2 = srcy + height; + srcInfo.bounds.x2 = UNSAFE_TO_ADD(srcx, width) + ? clipInfo.bounds.x2 : (srcx + width); + srcInfo.bounds.y2 = UNSAFE_TO_ADD(srcy, height) + ? clipInfo.bounds.y2 : (srcy + height); dstInfo.bounds.x1 = dstx; dstInfo.bounds.y1 = dsty; - dstInfo.bounds.x2 = dstx + width; - dstInfo.bounds.y2 = dsty + height; + dstInfo.bounds.x2 = UNSAFE_TO_ADD(dstx, width) + ? clipInfo.bounds.x2 : (dstx + width); + dstInfo.bounds.y2 = UNSAFE_TO_ADD(dsty, height) + ? clipInfo.bounds.y2 : (dsty + height); if (UNSAFE_TO_SUB(srcx, dstx) || UNSAFE_TO_SUB(srcy, dsty)) { return; diff --git a/test/jdk/java/awt/Graphics/BrokenBoundsClip.java b/test/jdk/java/awt/Graphics/BrokenBoundsClip.java new file mode 100644 index 00000000000..3ba8ebe2e3f --- /dev/null +++ b/test/jdk/java/awt/Graphics/BrokenBoundsClip.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8357299 + * @summary Verifies if Graphics copyArea doesn't copy any pixels + * when there is overflow + * @run main BrokenBoundsClip + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import static java.awt.image.BufferedImage.TYPE_INT_RGB; + +public final class BrokenBoundsClip { + + public static final int SIZE = 100; + + public static void main(String[] args) { + BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB); + + Graphics2D g2d = bi.createGraphics(); + g2d.setColor(Color.RED); + g2d.fillRect(SIZE / 2, SIZE / 2, SIZE / 2, SIZE / 2); + + g2d.copyArea(bi.getWidth() / 2, bi.getHeight() / 2, + Integer.MAX_VALUE , Integer.MAX_VALUE , + -bi.getWidth() / 2, -bi.getHeight() / 2); + int actual = bi.getRGB(0, 0); + int expected = Color.RED.getRGB(); + if (actual != expected) { + System.err.println("Actual: " + Integer.toHexString(actual)); + System.err.println("Expected: " + Integer.toHexString(expected)); + throw new RuntimeException("Wrong color"); + } + } +} From fd51b03910ba90ca1c46a4204b8940421338e22e Mon Sep 17 00:00:00 2001 From: Alexander Matveev Date: Fri, 30 May 2025 03:07:04 +0000 Subject: [PATCH 013/216] 8351369: [macos] Use --install-dir option with DMG packaging Reviewed-by: asemenyuk --- .../internal/MacDmgPackageBuilder.java | 8 --- .../jdk/jpackage/internal/MacDmgPackager.java | 4 +- .../jpackage/internal/resources/DMGsetup.scpt | 7 ++- .../resources/MacResources.properties | 1 - .../tools/jpackage/share/InstallDirTest.java | 50 ++++--------------- 5 files changed, 18 insertions(+), 52 deletions(-) diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackageBuilder.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackageBuilder.java index 0ee1756b235..d453bb59184 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackageBuilder.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackageBuilder.java @@ -54,14 +54,6 @@ final class MacDmgPackageBuilder { MacDmgPackage create() throws ConfigException { final var superPkgBuilder = pkgBuilder.pkgBuilder(); - superPkgBuilder.installDir().ifPresent(installDir -> { - final var defaultInstallDirLocation = superPkgBuilder.defaultInstallDir().map(Path::getParent).orElseThrow(); - if (!defaultInstallDirLocation.equals(installDir)) { - Log.info(I18N.format("message.install-dir-ignored", defaultInstallDirLocation)); - superPkgBuilder.installDir(defaultInstallDirLocation); - } - }); - final var pkg = pkgBuilder.create(); return MacDmgPackage.create(pkg, new MacDmgPackageMixin.Stub( diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackager.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackager.java index b37fa6979de..eb3ad3a76c8 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackager.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgPackager.java @@ -285,7 +285,9 @@ record MacDmgPackager(MacDmgPackage pkg, BuildEnv env, Path hdiutil, Path output // Return "Applications" for "/Applications/foo.app" return defaultInstallDir.getParent().getFileName().toString(); } else { - return pkg.installDir().getParent().toString(); + // If we returning full path we need to replace '/' with ':'. + // In this case macOS will display link name as "/Users/USER/MyCompany/MyApp". + return pkg.installDir().getParent().toString().replace('/', ':'); } } diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt index ab87a7bd700..112b7239103 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt @@ -17,7 +17,7 @@ tell application "Finder" set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE" -- Create alias for install location - make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_LOCATION_DISPLAY_NAME"} + do shell script "(cd 'DEPLOY_VOLUME_PATH' && ln -s 'DEPLOY_INSTALL_LOCATION' 'DEPLOY_INSTALL_LOCATION_DISPLAY_NAME')" set allTheFiles to the name of every item of theWindow set xpos to 120 @@ -28,7 +28,10 @@ tell application "Finder" set theFilePath to POSIX path of theFile set appFilePath to POSIX path of "/DEPLOY_TARGET" if theFilePath ends with "DEPLOY_INSTALL_LOCATION_DISPLAY_NAME" then - -- Position install location + -- Position install location for default install dir + set position of item theFile of theWindow to {390, 130} + else if theFilePath ends with "DEPLOY_INSTALL_LOCATION" then + -- Position install location for custom install dir set position of item theFile of theWindow to {390, 130} else if theFilePath ends with appFilePath then -- Position application or runtime diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties index e7e4b2adb61..1325e3be4f4 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties @@ -80,7 +80,6 @@ message.preparing-scripts=Preparing package scripts. message.preparing-distribution-dist=Preparing distribution.dist: {0}. message.signing.pkg=Warning: For signing PKG, you might need to set "Always Trust" for your certificate using "Keychain Access" tool. message.setfile.dmg=Setting custom icon on DMG file skipped because 'SetFile' utility was not found. Installing Xcode with Command Line Tools should resolve this issue. -message.install-dir-ignored=Warning: "--install-dir" option is ignored for DMG packaging. The installation directory will default to {0}. message.codesign.failed.reason.app.content="codesign" failed and additional application content was supplied via the "--app-content" parameter. Probably the additional content broke the integrity of the application bundle and caused the failure. Ensure content supplied via the "--app-content" parameter does not break the integrity of the application bundle, or add it in the post-processing step. message.codesign.failed.reason.xcode.tools=Possible reason for "codesign" failure is missing Xcode with command line developer tools. Install Xcode with command line developer tools to see if it resolves the problem. warning.unsigned.app.image=Warning: Using unsigned app-image to build signed {0}. diff --git a/test/jdk/tools/jpackage/share/InstallDirTest.java b/test/jdk/tools/jpackage/share/InstallDirTest.java index 2c14e863910..bbdc118d60b 100644 --- a/test/jdk/tools/jpackage/share/InstallDirTest.java +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java @@ -113,7 +113,7 @@ public class InstallDirTest { .run(); } - record DmgTestSpec(Path installDir, boolean installDirIgnored, boolean runtimeInstaller) { + record DmgTestSpec(Path installDir, boolean runtimeInstaller) { DmgTestSpec { Objects.requireNonNull(installDir); @@ -125,15 +125,8 @@ public class InstallDirTest { static final class Builder { - Builder ignoredInstallDir(String v) { - installDir = Path.of(v); - installDirIgnored = true; - return this; - } - Builder acceptedInstallDir(String v) { installDir = Path.of(v); - installDirIgnored = false; return this; } @@ -143,11 +136,10 @@ public class InstallDirTest { } DmgTestSpec create() { - return new DmgTestSpec(installDir, installDirIgnored, runtimeInstaller); + return new DmgTestSpec(installDir, runtimeInstaller); } private Path installDir; - private boolean installDirIgnored; private boolean runtimeInstaller; } @@ -155,9 +147,6 @@ public class InstallDirTest { public String toString() { final var sb = new StringBuilder(); sb.append(installDir); - if (installDirIgnored) { - sb.append(", ignore"); - } if (runtimeInstaller) { sb.append(", runtime"); } @@ -176,27 +165,8 @@ public class InstallDirTest { test.addInitializer(JPackageCommand::setFakeRuntime).addInitializer(cmd -> { cmd.addArguments("--install-dir", installDir); - cmd.validateOutput(createInstallDirWarningVerifier()); }).run(Action.CREATE_AND_UNPACK); } - - private TextStreamVerifier createInstallDirWarningVerifier() { - final var verifier = TKit.assertTextStream( - JPackageStringBundle.MAIN.cannedFormattedString("message.install-dir-ignored", defaultDmgInstallDir()).getValue()); - if (installDirIgnored) { - return verifier; - } else { - return verifier.negate(); - } - } - - private String defaultDmgInstallDir() { - if (runtimeInstaller) { - return "/Library/Java/JavaVirtualMachines"; - } else { - return "/Applications"; - } - } } @Test(ifOS = OperatingSystem.MACOS) @@ -207,19 +177,19 @@ public class InstallDirTest { public static List testDmg() { return Stream.of( - DmgTestSpec.build().ignoredInstallDir("/foo"), - DmgTestSpec.build().ignoredInstallDir("/foo/bar"), - DmgTestSpec.build().ignoredInstallDir("/foo").runtimeInstaller(), - DmgTestSpec.build().ignoredInstallDir("/foo/bar").runtimeInstaller(), + DmgTestSpec.build().acceptedInstallDir("/foo"), + DmgTestSpec.build().acceptedInstallDir("/foo/bar"), + DmgTestSpec.build().acceptedInstallDir("/foo").runtimeInstaller(), + DmgTestSpec.build().acceptedInstallDir("/foo/bar").runtimeInstaller(), - DmgTestSpec.build().ignoredInstallDir("/Library/Java/JavaVirtualMachines"), - DmgTestSpec.build().ignoredInstallDir("/Applications").runtimeInstaller(), + DmgTestSpec.build().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), + DmgTestSpec.build().acceptedInstallDir("/Applications").runtimeInstaller(), DmgTestSpec.build().acceptedInstallDir("/Applications"), - DmgTestSpec.build().ignoredInstallDir("/Applications/foo/bar/buz"), + DmgTestSpec.build().acceptedInstallDir("/Applications/foo/bar/buz"), DmgTestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines"), - DmgTestSpec.build().runtimeInstaller().ignoredInstallDir("/Library/Java/JavaVirtualMachines/foo/bar/buz") + DmgTestSpec.build().runtimeInstaller().acceptedInstallDir("/Library/Java/JavaVirtualMachines/foo/bar/buz") ).map(DmgTestSpec.Builder::create).map(testSpec -> { return new Object[] { testSpec }; }).toList(); From 20005511e3612d6a5f12fa83066f02c88c628e8b Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Fri, 30 May 2025 03:50:43 +0000 Subject: [PATCH 014/216] 8353500: [s390x] Intrinsify Unsafe::setMemory Reviewed-by: lucy, mdoerr --- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 119 ++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index b46393f543e..1e9136cdca9 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -1468,11 +1468,120 @@ class StubGenerator: public StubCodeGenerator { return __ addr_at(start_off); } + // + // Generate 'unsafe' set memory stub + // Though just as safe as the other stubs, it takes an unscaled + // size_t (# bytes) argument instead of an element count. + // + // Input: + // Z_ARG1 - destination array address + // Z_ARG2 - byte count (size_t) + // Z_ARG3 - byte value + // + address generate_unsafe_setmemory(address unsafe_byte_fill) { + __ align(CodeEntryAlignment); + StubCodeMark mark(this, StubGenStubId::unsafe_setmemory_id); + unsigned int start_off = __ offset(); + + // bump this on entry, not on exit: + // inc_counter_np(SharedRuntime::_unsafe_set_memory_ctr); + + const Register dest = Z_ARG1; + const Register size = Z_ARG2; + const Register byteVal = Z_ARG3; + NearLabel tail, finished; + // fill_to_memory_atomic(unsigned char*, unsigned long, unsigned char) + + // Mark remaining code as such which performs Unsafe accesses. + UnsafeMemoryAccessMark umam(this, true, false); + + __ z_vlvgb(Z_V0, byteVal, 0); + __ z_vrepb(Z_V0, Z_V0, 0); + + __ z_aghi(size, -32); + __ z_brl(tail); + + { + NearLabel again; + __ bind(again); + __ z_vst(Z_V0, Address(dest, 0)); + __ z_vst(Z_V0, Address(dest, 16)); + __ z_aghi(dest, 32); + __ z_aghi(size, -32); + __ z_brnl(again); + } + + __ bind(tail); + + { + NearLabel dont; + __ testbit(size, 4); + __ z_brz(dont); + __ z_vst(Z_V0, Address(dest, 0)); + __ z_aghi(dest, 16); + __ bind(dont); + } + + { + NearLabel dont; + __ testbit(size, 3); + __ z_brz(dont); + __ z_vsteg(Z_V0, 0, Z_R0, dest, 0); + __ z_aghi(dest, 8); + __ bind(dont); + } + + __ z_tmll(size, 7); + __ z_brc(Assembler::bcondAllZero, finished); + + { + NearLabel dont; + __ testbit(size, 2); + __ z_brz(dont); + __ z_vstef(Z_V0, 0, Z_R0, dest, 0); + __ z_aghi(dest, 4); + __ bind(dont); + } + + { + NearLabel dont; + __ testbit(size, 1); + __ z_brz(dont); + __ z_vsteh(Z_V0, 0, Z_R0, dest, 0); + __ z_aghi(dest, 2); + __ bind(dont); + } + + { + NearLabel dont; + __ testbit(size, 0); + __ z_brz(dont); + __ z_vsteb(Z_V0, 0, Z_R0, dest, 0); + __ bind(dont); + } + + __ bind(finished); + __ z_br(Z_R14); + + return __ addr_at(start_off); + } + + // This is common errorexit stub for UnsafeMemoryAccess. + address generate_unsafecopy_common_error_exit() { + unsigned int start_off = __ offset(); + __ z_lghi(Z_RET, 0); // return 0 + __ z_br(Z_R14); + return __ addr_at(start_off); + } void generate_arraycopy_stubs() { // Note: the disjoint stubs must be generated first, some of // the conjoint stubs use them. + + address ucm_common_error_exit = generate_unsafecopy_common_error_exit(); + UnsafeMemoryAccess::set_common_exit_stub_pc(ucm_common_error_exit); + StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jbyte_disjoint_arraycopy_id); StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_nonoop_copy(StubGenStubId::jshort_disjoint_arraycopy_id); StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_nonoop_copy (StubGenStubId::jint_disjoint_arraycopy_id); @@ -1500,6 +1609,12 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_nonoop_copy(StubGenStubId::arrayof_jlong_arraycopy_id); StubRoutines::_arrayof_oop_arraycopy = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_id); StubRoutines::_arrayof_oop_arraycopy_uninit = generate_conjoint_oop_copy(StubGenStubId::arrayof_oop_arraycopy_uninit_id); + +#ifdef COMPILER2 + StubRoutines::_unsafe_setmemory = + VM_Version::has_VectorFacility() ? generate_unsafe_setmemory(StubRoutines::_jbyte_fill) : nullptr; + +#endif // COMPILER2 } // Call interface for AES_encryptBlock, AES_decryptBlock stubs. @@ -3184,6 +3299,10 @@ class StubGenerator: public StubCodeGenerator { //---------------------------------------------------------------------- // Entry points that are platform specific. + if (UnsafeMemoryAccess::_table == nullptr) { + UnsafeMemoryAccess::create_table(4); // 4 for setMemory + } + if (UseCRC32Intrinsics) { StubRoutines::_crc_table_adr = (address)StubRoutines::zarch::_crc_table; StubRoutines::_updateBytesCRC32 = generate_CRC32_updateBytes(); From 6f9e1175a983c735c1beed755ec5b14b476858d7 Mon Sep 17 00:00:00 2001 From: Daniel Skantz Date: Fri, 30 May 2025 06:23:11 +0000 Subject: [PATCH 015/216] 8356246: C2: Compilation fails with "assert(bol->is_Bool()) failed: unexpected if shape" in StringConcat::eliminate_unneeded_control Reviewed-by: rcastanedalo, kvn --- src/hotspot/share/opto/stringopts.cpp | 7 +++ .../TestStackedConcatsSharedTest.java | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsSharedTest.java diff --git a/src/hotspot/share/opto/stringopts.cpp b/src/hotspot/share/opto/stringopts.cpp index cde6c1634ba..641634b906e 100644 --- a/src/hotspot/share/opto/stringopts.cpp +++ b/src/hotspot/share/opto/stringopts.cpp @@ -256,6 +256,13 @@ void StringConcat::eliminate_unneeded_control() { assert(n->req() == 3 && n->in(2)->in(0) == iff, "not a diamond"); assert(iff->is_If(), "no if for the diamond"); Node* bol = iff->in(1); + if (bol->is_Con()) { + // A BoolNode shared by two diamond Region/If sub-graphs + // was replaced by a constant zero in a previous call to this method. + // Do nothing as the transformation in the previous call ensures both are folded away. + assert(bol == _stringopts->gvn()->intcon(0), "shared condition should have been set to false"); + continue; + } assert(bol->is_Bool(), "unexpected if shape"); Node* cmp = bol->in(1); assert(cmp->is_Cmp(), "unexpected if shape"); diff --git a/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsSharedTest.java b/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsSharedTest.java new file mode 100644 index 00000000000..15fc0303674 --- /dev/null +++ b/test/hotspot/jtreg/compiler/stringopts/TestStackedConcatsSharedTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8356246 + * @summary Test stacked string concatenations where the toString of the first StringBuilder + * is used as a shared test by two diamond Ifs in the second StringBuilder. + * @run main/othervm compiler.stringopts.TestStackedConcatsSharedTest + * @run main/othervm -XX:-TieredCompilation -Xcomp + * -XX:CompileOnly=compiler.stringopts.TestStackedConcatsSharedTest::* + * compiler.stringopts.TestStackedConcatsSharedTest + */ + +package compiler.stringopts; + +public class TestStackedConcatsSharedTest { + + public static void main(String... args) { + f(); // one warmup call + String s = f(); + if (!s.equals("")) { + throw new RuntimeException("wrong result"); + } + } + + static String f() { + String s = ""; + s = new StringBuilder().toString(); + // Warming up with many iterations invalidated the optimization due to an unstable If + // associated with the valueOf calls below. Using -Xcomp for the test. + s = new StringBuilder(String.valueOf(s)).append(String.valueOf(s)).toString(); + return s; + } +} From e33eeeea04fc7899bf66b0a2fdaccc30060854b4 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 30 May 2025 06:25:08 +0000 Subject: [PATCH 016/216] 8341311: [Accessibility,macOS,VoiceOver] VoiceOver announces incorrect number of items in submenu of JPopupMenu Reviewed-by: asemenov, kizune --- .../sun/lwawt/macosx/CAccessibility.java | 32 ++++- .../libawt_lwawt/awt/a11y/MenuAccessibility.m | 33 +++++- .../TestPopupMenuChildCount.java | 109 ++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 test/jdk/javax/accessibility/TestPopupMenuChildCount.java diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java index 417750507aa..0017c39bfda 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, 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 @@ -60,9 +60,11 @@ import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JLabel; +import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JTextArea; import javax.swing.JList; +import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.KeyStroke; @@ -856,6 +858,34 @@ class CAccessibility implements PropertyChangeListener { }, c); } + private static Accessible getCurrentAccessiblePopupMenu(Accessible a, Component c) { + if (a == null) return null; + + return invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return traversePopupMenu(a); + } + }, c); + } + + private static Accessible traversePopupMenu(Accessible a) { + // a is root level popupmenu + AccessibleContext ac = a.getAccessibleContext(); + if (ac != null) { + for (int i = 0; i < ac.getAccessibleChildrenCount(); i++) { + Accessible child = ac.getAccessibleChild(i); + if (child instanceof JMenu subMenu) { + JPopupMenu popup = subMenu.getPopupMenu(); + if (popup.isVisible()) { + return traversePopupMenu((Accessible) popup); + } + } + } + } + return a; + } + @Native private static final int JAVA_AX_ROWS = 1; @Native private static final int JAVA_AX_COLS = 2; diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m index e8b28d93068..90a147aa5a2 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -24,6 +24,10 @@ */ #import "MenuAccessibility.h" +#import "ThreadUtilities.h" +#import "sun_lwawt_macosx_CAccessibility.h" + +static jclass sjc_CAccessibility = NULL; /* * Implementing a protocol that represents menus both as submenu and as a @@ -51,4 +55,31 @@ return NULL; } +/* + * Return all non-ignored children. + */ +- (NSArray *)accessibilityChildren { + JNIEnv *env = [ThreadUtilities getJNIEnv]; + GET_CACCESSIBILITY_CLASS_RETURN(nil); + DECLARE_STATIC_METHOD_RETURN(sjm_getCurrentAccessiblePopupMenu, sjc_CAccessibility, + "getCurrentAccessiblePopupMenu", + "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;", nil); + jobject axComponent = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, + sjm_getCurrentAccessiblePopupMenu, + fAccessible, fComponent); + + CommonComponentAccessibility *currentElement = [CommonComponentAccessibility createWithAccessible:axComponent + withEnv:env withView:self->fView isCurrent:YES]; + + NSArray *children = [CommonComponentAccessibility childrenOfParent:currentElement + withEnv:env + withChildrenCode:sun_lwawt_macosx_CAccessibility_JAVA_AX_ALL_CHILDREN + allowIgnored:NO]; + + if ([children count] == 0) { + return nil; + } else { + return children; + } +} @end diff --git a/test/jdk/javax/accessibility/TestPopupMenuChildCount.java b/test/jdk/javax/accessibility/TestPopupMenuChildCount.java new file mode 100644 index 00000000000..f59b7007145 --- /dev/null +++ b/test/jdk/javax/accessibility/TestPopupMenuChildCount.java @@ -0,0 +1,109 @@ +/* + * 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. + */ + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +/* + * @test + * @bug 8341311 + * @summary Verifies that VoiceOver announces correct number of child for PopupMenu on macOS + * @requires os.family == "mac" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestPopupMenuChildCount + */ + +public class TestPopupMenuChildCount { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test is applicable only on macOS. + + Test UI contains an empty JFrame. On press of left/right mouse button, + a PopupMenu will be visible. + + Follow these steps to test the behaviour: + + 1. Start the VoiceOver (Press Command + F5) application + 2. Press Left/Right mouse button inside test frame window to open + the PopupMenu + 3. VO should announce "Menu" with number of child items of the Popupmenu + 4. Press Up/Down arrow to traverse popupmenu child items + 5. Press Right arrow key to open submenu + 6. VO should announce "Menu" with correct number of child items + for the submenu (For e.g. When Submenu-1 is open, VO should announce + "Menu 4 items") + 7. Repeat the process for other submenus + 8. Press Pass if you are able to hear correct announcements + else Fail"""; + + PassFailJFrame.builder() + .instructions(INSTRUCTIONS) + .columns(45) + .testUI(TestPopupMenuChildCount::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("Test Frame"); + + JPopupMenu popupmenu = new JPopupMenu(); + JMenuItem mi1 = new JMenuItem("MenuItem-1"); + JMenuItem mi2 = new JMenuItem("MenuItem-2"); + JMenuItem mi3 = new JMenuItem("MenuItem-3"); + popupmenu.add(mi1); + popupmenu.add(mi2); + popupmenu.add(mi3); + + JMenu submenu1 = new JMenu("Submenu-1"); + submenu1.add("subOne"); + submenu1.add("subTwo"); + submenu1.add("subThree"); + + JMenu submenu2 = new JMenu("Submenu-2"); + submenu2.add("subOne"); + submenu2.add("subTwo"); + + JMenu submenu3 = new JMenu ("Submenu-3"); + submenu3.add("subOne"); + submenu1.add(submenu3); + + popupmenu.add(submenu1); + popupmenu.add(submenu2); + + frame.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + popupmenu.show(e.getComponent(), e.getX(), e.getY()); + } + }); + frame.setSize(300, 300); + return frame; + } +} From 566e3b21ed14748cb0d9117b6bd58b4bfcf625c6 Mon Sep 17 00:00:00 2001 From: nibjen Date: Fri, 30 May 2025 09:22:16 +0000 Subject: [PATCH 017/216] 8357253: Test test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java writes in src dir Reviewed-by: coffeys --- .../ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java index b3c66eb9bcd..c9768c1756c 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java @@ -65,16 +65,10 @@ public class ResumeClientTLS12withSNI { /* * The following is to set up the keystores. */ - private static final String pathToStores = System.getProperty("test.src", "."); - private static final String keyStoreFile = "ks_san.p12"; - private static final String trustStoreFile = "ks_san.p12"; + private static final String keyFilename = "ks_san.p12"; + private static final String trustFilename = "ks_san.p12"; private static final char[] passphrase = "123456".toCharArray(); - private static final String keyFilename = - pathToStores + "/" + keyStoreFile; - private static final String trustFilename = - pathToStores + "/" + trustStoreFile; - private static final String HOST_NAME = "arf.yak.foo.localhost123456.localhost123456.localhost123456.localhost123456.localhost123456.localhost123456." + "localhost123456.localhost123456.localhost123456.localhost123456.localhost123456.localhost123456"; private static final SNIMatcher SNI_MATCHER = SNIHostName.createSNIMatcher("arf\\.yak\\.foo.*"); @@ -118,7 +112,7 @@ public class ResumeClientTLS12withSNI { private static KeyManagerFactory makeKeyManagerFactory(String ksPath, char[] pass) throws GeneralSecurityException, IOException { KeyManagerFactory kmf; - KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ks = KeyStore.getInstance("PKCS12"); try (FileInputStream fsIn = new FileInputStream(ksPath)) { ks.load(fsIn, pass); From a0eb1900c91531db26d1086a3b251bce0cf7c141 Mon Sep 17 00:00:00 2001 From: Qizheng Xing Date: Fri, 30 May 2025 09:41:08 +0000 Subject: [PATCH 018/216] 8358104: Fix ZGC compilation error on GCC 10.2 Reviewed-by: kbarrett, jsikstro --- src/hotspot/share/gc/z/zMappedCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/z/zMappedCache.cpp b/src/hotspot/share/gc/z/zMappedCache.cpp index 252219572b5..3fc54087daa 100644 --- a/src/hotspot/share/gc/z/zMappedCache.cpp +++ b/src/hotspot/share/gc/z/zMappedCache.cpp @@ -556,7 +556,7 @@ size_t ZMappedCache::remove_discontiguous_with_strategy(size_t size, ZArray Date: Fri, 30 May 2025 10:56:37 +0000 Subject: [PATCH 019/216] 8357626: RISC-V: Tighten up template interpreter method entry code Reviewed-by: fyang, fjiang --- .../templateInterpreterGenerator_riscv.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index d63953232c5..75469ea40e9 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -765,6 +765,10 @@ void TemplateInterpreterGenerator::lock_method() { // xcpool: cp cache // stack_pointer: previous sp void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { + // Save ConstMethod* in x15_const_method for later use to avoid loading multiple times + Register x15_const_method = x15; + __ ld(x15_const_method, Address(xmethod, Method::const_offset())); + // initialize fixed part of activation frame if (native_call) { __ subi(esp, sp, 14 * wordSize); @@ -775,8 +779,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ sd(zr, Address(sp, 12 * wordSize)); } else { __ subi(esp, sp, 12 * wordSize); - __ ld(t0, Address(xmethod, Method::const_offset())); // get ConstMethod - __ add(xbcp, t0, in_bytes(ConstMethod::codes_offset())); // get codebase + __ add(xbcp, x15_const_method, in_bytes(ConstMethod::codes_offset())); // get codebase __ subi(sp, sp, 12 * wordSize); } __ sd(xbcp, Address(sp, wordSize)); @@ -798,9 +801,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ sd(fp, Address(sp, 10 * wordSize)); __ la(fp, Address(sp, 12 * wordSize)); // include ra & fp - __ ld(xcpool, Address(xmethod, Method::const_offset())); - __ ld(xcpool, Address(xcpool, ConstMethod::constants_offset())); - __ ld(xcpool, Address(xcpool, ConstantPool::cache_offset())); + // Save ConstantPool* in x28_constants for later use to avoid loading multiple times + Register x28_constants = x28; + __ ld(x28_constants, Address(x15_const_method, ConstMethod::constants_offset())); + __ ld(xcpool, Address(x28_constants, ConstantPool::cache_offset())); __ sd(xcpool, Address(sp, 3 * wordSize)); __ sub(t0, xlocals, fp); __ srai(t0, t0, Interpreter::logStackElementSize); // t0 = xlocals - fp(); @@ -812,13 +816,15 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ sd(x19_sender_sp, Address(sp, 9 * wordSize)); __ sd(zr, Address(sp, 8 * wordSize)); - // Get mirror and store it in the frame as GC root for this Method* - __ load_mirror(t2, xmethod, x15, t1); + // Get mirror, Resolve ConstantPool* -> InstanceKlass* -> Java mirror + // and store it in the frame as GC root for this Method* + __ ld(t2, Address(x28_constants, ConstantPool::pool_holder_offset())); + __ ld(t2, Address(t2, in_bytes(Klass::java_mirror_offset()))); + __ resolve_oop_handle(t2, t0, t1); __ sd(t2, Address(sp, 4 * wordSize)); if (!native_call) { - __ ld(t0, Address(xmethod, Method::const_offset())); - __ lhu(t0, Address(t0, ConstMethod::max_stack_offset())); + __ lhu(t0, Address(x15_const_method, ConstMethod::max_stack_offset())); __ add(t0, t0, MAX2(3, Method::extra_stack_entries())); __ slli(t0, t0, 3); __ sub(t0, sp, t0); From 12ee80cac754c1a6dd37191a9f80c01de8b659ad Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Fri, 30 May 2025 13:31:35 +0000 Subject: [PATCH 020/216] 8357675: Amend headless message Reviewed-by: prr, shade --- .../unix/classes/sun/awt/PlatformGraphicsInfo.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java index 1ff871f9efc..9c2f51cc94f 100644 --- a/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java +++ b/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -85,7 +85,6 @@ public final class PlatformGraphicsInfo { No X11 DISPLAY variable was set, or no headful library support was found, - but this program performed an operation which requires it, - """; + but this program performed an operation which requires it."""; } } From ae3d96a4ec87262bc2f01d87fe91daa5d0d3966f Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Fri, 30 May 2025 13:40:25 +0000 Subject: [PATCH 021/216] 8357683: (process) SIGQUIT still blocked after JDK-8234262 with jdk.lang.Process.launchMechanism=FORK or VFORK Reviewed-by: rriggs --- .../unix/native/jspawnhelper/jspawnhelper.c | 6 ------ src/java.base/unix/native/libjava/childproc.c | 8 ++++++++ .../lang/ProcessBuilder/UnblockSignals.java | 20 +++++++++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c index de85d917811..071be59504d 100644 --- a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c +++ b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +144,6 @@ int main(int argc, char *argv[]) { struct stat buf; /* argv[1] contains the fd number to read all the child info */ int r, fdinr, fdinw, fdout; - sigset_t unblock_signals; #ifdef DEBUG jtregSimulateCrash(0, 4); @@ -173,10 +171,6 @@ int main(int argc, char *argv[]) { shutItDown(); } - // Reset any mask signals from parent - sigemptyset(&unblock_signals); - sigprocmask(SIG_SETMASK, &unblock_signals, NULL); - // Close the writing end of the pipe we use for reading from the parent. // We have to do this before we start reading from the parent to avoid // blocking in the case the parent exits before we finished reading from it. diff --git a/src/java.base/unix/native/libjava/childproc.c b/src/java.base/unix/native/libjava/childproc.c index 1543e269223..7a21b86565f 100644 --- a/src/java.base/unix/native/libjava/childproc.c +++ b/src/java.base/unix/native/libjava/childproc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -405,6 +406,13 @@ childProcess(void *arg) if (p->pdir != NULL && chdir(p->pdir) < 0) goto WhyCantJohnnyExec; + // Reset any mask signals from parent, but not in VFORK mode + if (p->mode != MODE_VFORK) { + sigset_t unblock_signals; + sigemptyset(&unblock_signals); + sigprocmask(SIG_SETMASK, &unblock_signals, NULL); + } + if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) goto WhyCantJohnnyExec; diff --git a/test/jdk/java/lang/ProcessBuilder/UnblockSignals.java b/test/jdk/java/lang/ProcessBuilder/UnblockSignals.java index 3f82bed8708..d2625518b6d 100644 --- a/test/jdk/java/lang/ProcessBuilder/UnblockSignals.java +++ b/test/jdk/java/lang/ProcessBuilder/UnblockSignals.java @@ -24,15 +24,27 @@ import java.io.IOException; /* - * @test - * @summary Verify Signal mask is cleared by ProcessBuilder start + * @test id=posix_spawn + * @summary Verify Signal mask is cleared by ProcessBuilder start when using posix_spawn mode * @bug 8234262 * @requires (os.family == "linux" | os.family == "mac") * @comment Don't allow -Xcomp, it disturbs the relative timing of the sleep and kill commands * @requires (vm.compMode != "Xcomp") - * @run main/othervm UnblockSignals - * @run main/othervm -Xrs UnblockSignals + * @run main/othervm -Djdk.lang.Process.launchMechanism=POSIX_SPAWN UnblockSignals + * @run main/othervm -Djdk.lang.Process.launchMechanism=POSIX_SPAWN -Xrs UnblockSignals */ + +/* + * @test id=fork + * @summary Verify Signal mask is cleared by ProcessBuilder start when using fork mode + * @bug 8357683 + * @requires (os.family == "linux" | os.family == "mac") + * @comment Don't allow -Xcomp, it disturbs the relative timing of the sleep and kill commands + * @requires (vm.compMode != "Xcomp") + * @run main/othervm -Djdk.lang.Process.launchMechanism=FORK UnblockSignals + * @run main/othervm -Djdk.lang.Process.launchMechanism=FORK -Xrs UnblockSignals + */ + public class UnblockSignals { public static void main(String[] args) throws IOException, InterruptedException { // Check that SIGQUIT is not masked, in previous releases it was masked From 26275a10b2aa75f0d4ff49248a3309f9d7b19bf3 Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Fri, 30 May 2025 14:42:36 +0000 Subject: [PATCH 022/216] 8355753: @SuppressWarnings("this-escape") not respected for indirect leak via field Reviewed-by: vromero --- .../tools/javac/comp/ThisEscapeAnalyzer.java | 440 ++++++++++-------- .../tools/javac/warnings/ThisEscape.java | 51 +- .../tools/javac/warnings/ThisEscape.out | 3 +- 3 files changed, 302 insertions(+), 192 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 77ddd5c6583..9119278660f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -25,9 +25,7 @@ package com.sun.tools.javac.comp; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.EnumSet; import java.util.HashSet; @@ -35,12 +33,13 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.BiPredicate; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collector; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import com.sun.tools.javac.code.Directive; @@ -52,21 +51,20 @@ import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.resources.CompilerProperties.LintWarnings; -import com.sun.tools.javac.resources.CompilerProperties.Warnings; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.JCDiagnostic; -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import com.sun.tools.javac.util.JCDiagnostic.LintWarning; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Pair; import static com.sun.tools.javac.code.Kinds.Kind.*; +import static com.sun.tools.javac.code.Lint.LintCategory.THIS_ESCAPE; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -164,7 +162,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { /** Environment for symbol lookup. */ - private Env attrEnv; + private Env topLevelEnv; /** Maps symbols of all methods to their corresponding declarations. */ @@ -185,30 +183,25 @@ public class ThisEscapeAnalyzer extends TreeScanner { /** Snapshots of {@link #callStack} where possible 'this' escapes occur. */ - private final ArrayList warningList = new ArrayList<>(); + private final ArrayList warningList = new ArrayList<>(); // These fields are scoped to the constructor being analyzed - /** The declaring class of the "invoked" method we're currently analyzing. + /** The method we're currently analyzing. * This is either the analyzed constructor or some method it invokes. */ - private JCClassDecl methodClass; + private MethodInfo currentMethod; - /** The current "call stack" during our analysis. The first entry is some method - * invoked from the target constructor; if empty, we're still in the constructor. + /** The current "call stack" during our analysis. The first entry is the initial + * constructor we started with, and subsequent entries correspond to invoked methods. + * If we're still in the initial constructor, the list will be empty. */ - private final ArrayDeque callStack = new ArrayDeque<>(); + private final ArrayList callStack = new ArrayList<>(); /** Used to terminate recursion in {@link #invokeInvokable invokeInvokable()}. */ private final Set>> invocations = new HashSet<>(); - /** Snapshot of {@link #callStack} where a possible 'this' escape occurs. - * If non-null, a 'this' escape warning has been found in the current - * constructor statement, initialization block statement, or field initializer. - */ - private DiagnosticPosition[] pendingWarning; - // These fields are scoped to the constructor or invoked method being analyzed /** Current lexical scope depth in the constructor or method we're currently analyzing. @@ -246,18 +239,18 @@ public class ThisEscapeAnalyzer extends TreeScanner { // public void analyzeTree(Env env) { + topLevelEnv = env; try { doAnalyzeTree(env); } finally { - attrEnv = null; + topLevelEnv = null; methodMap.clear(); nonPublicOuters.clear(); targetClass = null; warningList.clear(); - methodClass = null; + currentMethod = null; callStack.clear(); invocations.clear(); - pendingWarning = null; depth = -1; refs = null; } @@ -270,7 +263,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { Assert.check(methodMap.isEmpty()); // we are not prepared to be used more than once // Short circuit if warnings are totally disabled - if (!lint.isEnabled(Lint.LintCategory.THIS_ESCAPE)) + if (!lint.isEnabled(THIS_ESCAPE)) return; // Determine which packages are exported by the containing module, if any. @@ -324,7 +317,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { try { // Track warning suppression of fields - if (tree.sym.owner.kind == TYP && !lint.isEnabled(Lint.LintCategory.THIS_ESCAPE)) + if (tree.sym.owner.kind == TYP && !lint.isEnabled(THIS_ESCAPE)) suppressed.add(tree.sym); // Recurse @@ -341,23 +334,23 @@ public class ThisEscapeAnalyzer extends TreeScanner { try { // Track warning suppression of constructors - if (TreeInfo.isConstructor(tree) && !lint.isEnabled(Lint.LintCategory.THIS_ESCAPE)) + if (TreeInfo.isConstructor(tree) && !lint.isEnabled(THIS_ESCAPE)) suppressed.add(tree.sym); + // Gather some useful info + boolean constructor = TreeInfo.isConstructor(tree); + boolean extendableClass = currentClassIsExternallyExtendable(); + boolean nonPrivate = (tree.sym.flags() & (Flags.PUBLIC | Flags.PROTECTED)) != 0; + boolean finalish = (tree.mods.flags & (Flags.STATIC | Flags.PRIVATE | Flags.FINAL)) != 0; + // Determine if this is a constructor we should analyze - boolean extendable = currentClassIsExternallyExtendable(); - boolean analyzable = extendable && - TreeInfo.isConstructor(tree) && - (tree.sym.flags() & (Flags.PUBLIC | Flags.PROTECTED)) != 0 && - !suppressed.contains(tree.sym); + boolean analyzable = extendableClass && constructor && nonPrivate; - // Determine if this method is "invokable" in an analysis (can't be overridden) - boolean invokable = !extendable || - TreeInfo.isConstructor(tree) || - (tree.mods.flags & (Flags.STATIC | Flags.PRIVATE | Flags.FINAL)) != 0; + // Determine if it's safe to "invoke" the method in an analysis (i.e., it can't be overridden) + boolean invokable = !extendableClass || constructor || finalish; - // Add method or constructor to map - methodMap.put(tree.sym, new MethodInfo(currentClass, tree, analyzable, invokable)); + // Add this method or constructor to our map + methodMap.put(tree.sym, new MethodInfo(currentClass, tree, constructor, analyzable, invokable)); // Recurse super.visitMethodDef(tree); @@ -377,106 +370,54 @@ public class ThisEscapeAnalyzer extends TreeScanner { } }.scan(env.tree); - // Analyze non-static field initializers and initialization blocks, - // but only for classes having at least one analyzable constructor. + // Analyze the analyzable constructors we found methodMap.values().stream() - .filter(MethodInfo::analyzable) - .map(MethodInfo::declaringClass) - .distinct() - .forEach(klass -> { - for (List defs = klass.defs; defs.nonEmpty(); defs = defs.tail) { + .filter(MethodInfo::analyzable) + .forEach(this::analyzeConstructor); - // Ignore static stuff - if ((TreeInfo.flags(defs.head) & Flags.STATIC) != 0) - continue; + // Manually apply any Lint suppression + filterWarnings(warning -> !warning.isSuppressed()); - // Handle field initializers - if (defs.head instanceof JCVariableDecl vardef) { - visitTopLevel(env, klass, () -> { - scan(vardef); - copyPendingWarning(); - }); - continue; - } + // Field intitializers and initialization blocks will generate a separate warning for each primary constructor. + // Trim off stack frames up through the super() call so these will have identical stacks and get de-duplicated below. + warningList.forEach(Warning::trimInitializerFrames); - // Handle initialization blocks - if (defs.head instanceof JCBlock block) { - visitTopLevel(env, klass, () -> analyzeStatements(block.stats)); - continue; - } - } - }); - - // Analyze all of the analyzable constructors we found - methodMap.values().stream() - .filter(MethodInfo::analyzable) - .forEach(methodInfo -> { - visitTopLevel(env, methodInfo.declaringClass(), - () -> analyzeStatements(methodInfo.declaration().body.stats)); - }); - - // Eliminate duplicate warnings. Warning B duplicates warning A if the stack trace of A is a prefix - // of the stack trace of B. For example, if constructor Foo(int x) has a leak, and constructor - // Foo() invokes this(0), then emitting a warning for Foo() would be redundant. - BiPredicate extendsAsPrefix = (warning1, warning2) -> { - if (warning2.length < warning1.length) + // Sort warnings so redundant warnings immediately follow whatever they are redundant for, then remove them + warningList.sort(Warning::sortByStackFrames); + AtomicReference previousRef = new AtomicReference<>(); + filterWarnings(warning -> { + Warning previous = previousRef.get(); + if (previous != null && warning.isRedundantWith(previous)) return false; - for (int index = 0; index < warning1.length; index++) { - if (warning2[index].getPreferredPosition() != warning1[index].getPreferredPosition()) - return false; - } + previousRef.set(warning); return true; - }; + }); - // Stack traces are ordered top to bottom, and so duplicates always have the same first element(s). - // Sort the stack traces lexicographically, so that duplicates immediately follow what they duplicate. - Comparator ordering = (warning1, warning2) -> { - for (int index1 = 0, index2 = 0; true; index1++, index2++) { - boolean end1 = index1 >= warning1.length; - boolean end2 = index2 >= warning2.length; - if (end1 && end2) - return 0; - if (end1) - return -1; - if (end2) - return 1; - int posn1 = warning1[index1].getPreferredPosition(); - int posn2 = warning2[index2].getPreferredPosition(); - int diff = Integer.compare(posn1, posn2); - if (diff != 0) - return diff; - } - }; - warningList.sort(ordering); + // Limit output to one warning per constructor, field initializer, or initializer block + Set thingsWarnedAbout = new HashSet<>(); + filterWarnings(warning -> thingsWarnedAbout.add(warning.origin)); - // Now emit the warnings, but skipping over duplicates as we go through the list - DiagnosticPosition[] previous = null; - for (DiagnosticPosition[] warning : warningList) { - - // Skip duplicates - if (previous != null && extendsAsPrefix.test(previous, warning)) - continue; - previous = warning; - - // Emit warnings showing the entire stack trace - JCDiagnostic.Warning key = LintWarnings.PossibleThisEscape; - int remain = warning.length; - do { - DiagnosticPosition pos = warning[--remain]; - log.warning(pos, key); + // Emit warnings + for (Warning warning : warningList) { + LintWarning key = LintWarnings.PossibleThisEscape; + for (StackFrame frame : warning.stack) { + log.warning(frame.site.pos(), key); key = LintWarnings.PossibleThisEscapeLocation; - } while (remain > 0); + } } + + // Done warningList.clear(); } - // Analyze statements, but stop at (and record) the first warning generated - private void analyzeStatements(List stats) { - for (JCStatement stat : stats) { - scan(stat); - if (copyPendingWarning()) - break; + // Warning list editor (this is slightly more efficient than removeIf()) + private void filterWarnings(Predicate filter) { + int numRetained = 0; + for (Warning warning : warningList) { + if (filter.test(warning)) + warningList.set(numRetained++, warning); } + warningList.subList(numRetained, warningList.size()).clear(); } @Override @@ -542,10 +483,6 @@ public class ThisEscapeAnalyzer extends TreeScanner { private void visitVarDef(VarSymbol sym, JCExpression expr) { - // Skip if ignoring warnings for this field - if (suppressed.contains(sym)) - return; - // Scan initializer, if any scan(expr); if (isParamOrVar(sym)) @@ -579,19 +516,43 @@ public class ThisEscapeAnalyzer extends TreeScanner { } else refs.discardExprs(depth); - // If "super()": ignore - we don't try to track into superclasses - if (TreeInfo.name(invoke.meth) == names._super) + // If "super()": we don't invoke it (we don't track into superclasses) but we do execute any + // non-static field initializers and initialization blocks because this is when they happen. + if (TreeInfo.name(invoke.meth) == names._super) { + currentMethod.declaringClass.defs.stream() + .filter(def -> (TreeInfo.flags(def) & Flags.STATIC) == 0) + .forEach(def -> { + switch (def) { + case JCBlock block -> analyzeInitializer(invoke, block, receiverRefs, () -> visitBlock(block)); + case JCVariableDecl varDecl -> analyzeInitializer(invoke, varDecl, receiverRefs, () -> scan(varDecl)); + default -> { } + } + }); return; + } // "Invoke" the method invoke(invoke, sym, invoke.args, receiverRefs); } - private void invoke(JCTree site, Symbol sym, List args, RefSet receiverRefs) { + // Analyze a field initializer or initialization block after encountering a super() invocation + private void analyzeInitializer(JCMethodInvocation site, JCTree initializer, RefSet receiverRefs, Runnable action) { + RefSet refsPrev = refs; + refs = RefSet.newEmpty(); + int depthPrev = depth; + depth = 0; + callStack.add(new StackFrame(currentMethod, initializer, site)); + try { + refs.addAll(receiverRefs); + action.run(); + } finally { + callStack.remove(callStack.size() - 1); + depth = depthPrev; + refs = refsPrev; + } + } - // Skip if ignoring warnings for a constructor invoked via 'this()' - if (suppressed.contains(sym)) - return; + private void invoke(JCTree site, Symbol sym, List args, RefSet receiverRefs) { // Ignore final methods in java.lang.Object (getClass(), notify(), etc.) if (sym != null && @@ -627,7 +588,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { } // Analyze method if possible, otherwise assume nothing - if (methodInfo != null && methodInfo.invokable()) + if (methodInfo != null && methodInfo.invokable) invokeInvokable(site, args, receiverRefs, methodInfo); else invokeUnknown(site, args, receiverRefs); @@ -644,12 +605,11 @@ public class ThisEscapeAnalyzer extends TreeScanner { } // Handle the invocation of a local analyzable method or constructor - private void invokeInvokable(JCTree site, List args, - RefSet receiverRefs, MethodInfo methodInfo) { - Assert.check(methodInfo.invokable()); + private void invokeInvokable(JCTree site, List args, RefSet receiverRefs, MethodInfo methodInfo) { + Assert.check(methodInfo.invokable); // Collect 'this' references found in method parameters - JCMethodDecl method = methodInfo.declaration(); + JCMethodDecl method = methodInfo.declaration; RefSet paramRefs = RefSet.newEmpty(); List params = method.params; while (args.nonEmpty() && params.nonEmpty()) { @@ -663,13 +623,13 @@ public class ThisEscapeAnalyzer extends TreeScanner { } // "Invoke" the method - JCClassDecl methodClassPrev = methodClass; - methodClass = methodInfo.declaringClass(); + MethodInfo currentMethodPrev = currentMethod; + currentMethod = methodInfo; RefSet refsPrev = refs; refs = RefSet.newEmpty(); int depthPrev = depth; depth = 0; - callStack.push(site); + callStack.add(new StackFrame(currentMethodPrev, null, site)); try { // Add initial references from method receiver @@ -706,10 +666,10 @@ public class ThisEscapeAnalyzer extends TreeScanner { .map(ref -> new ExprRef(depthPrev, ref)) .forEach(refsPrev::add); } finally { - callStack.pop(); + callStack.remove(callStack.size() - 1); depth = depthPrev; refs = refsPrev; - methodClass = methodClassPrev; + currentMethod = currentMethodPrev; } } @@ -755,7 +715,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { RefSet receiverRefs = receiverRefsForConstructor(tree.encl, tsym); // "Invoke" the constructor - if (methodInfo != null && methodInfo.invokable()) + if (methodInfo != null && methodInfo.invokable) invokeInvokable(tree, tree.args, receiverRefs, methodInfo); else invokeUnknown(tree, tree.args, receiverRefs); @@ -787,9 +747,10 @@ public class ThisEscapeAnalyzer extends TreeScanner { // Determine if an unqualified "new Foo()" constructor gets 'this' as an implicit outer instance private boolean hasImplicitOuterInstance(TypeSymbol tsym) { - return tsym != methodClass.sym + ClassSymbol currentClassSym = currentMethod.declaringClass.sym; + return tsym != currentClassSym && tsym.hasOuterInstance() - && tsym.isEnclosedBy(methodClass.sym); + && tsym.isEnclosedBy(currentClassSym); } // @@ -824,18 +785,18 @@ public class ThisEscapeAnalyzer extends TreeScanner { Type elemType = types.elemtype(tree.expr.type); // If not array, resolve the Iterable and Iterator methods - record ForeachMethods(MethodSymbol iterator, MethodSymbol hasNext, MethodSymbol next) { }; + record ForeachMethods(MethodSymbol iterator, MethodSymbol hasNext, MethodSymbol next) { } MethodSymbol iterator = null; MethodSymbol hasNext = null; MethodSymbol next = null; if (elemType == null) { - Symbol iteratorSym = rs.resolveQualifiedMethod(tree.expr.pos(), attrEnv, + Symbol iteratorSym = rs.resolveQualifiedMethod(tree.expr.pos(), topLevelEnv, tree.expr.type, names.iterator, List.nil(), List.nil()); if (iteratorSym instanceof MethodSymbol) { iterator = (MethodSymbol)iteratorSym; - Symbol hasNextSym = rs.resolveQualifiedMethod(tree.expr.pos(), attrEnv, + Symbol hasNextSym = rs.resolveQualifiedMethod(tree.expr.pos(), topLevelEnv, iterator.getReturnType(), names.hasNext, List.nil(), List.nil()); - Symbol nextSym = rs.resolveQualifiedMethod(tree.expr.pos(), attrEnv, + Symbol nextSym = rs.resolveQualifiedMethod(tree.expr.pos(), topLevelEnv, iterator.getReturnType(), names.next, List.nil(), List.nil()); if (hasNextSym instanceof MethodSymbol) hasNext = (MethodSymbol)hasNextSym; @@ -974,7 +935,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { Stream methodRefs = refs.removeExprs(depth); // Explicit 'this' reference? The expression references whatever 'this' references - Type.ClassType currentClassType = (Type.ClassType)methodClass.sym.type; + Type.ClassType currentClassType = (Type.ClassType)currentMethod.declaringClass.sym.type; if (TreeInfo.isExplicitThisReference(types, currentClassType, tree)) { refs.find(ThisRef.class) .map(ref -> new ExprRef(depth, ref)) @@ -1059,7 +1020,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { MethodSymbol sym = (MethodSymbol)tree.sym; // Check for implicit 'this' reference - ClassSymbol methodClassSym = methodClass.sym; + ClassSymbol methodClassSym = currentMethod.declaringClass.sym; if (methodClassSym.isSubClass(sym.owner, types)) { refs.find(ThisRef.class) .map(ref -> new ExprRef(depth, ref)) @@ -1243,53 +1204,49 @@ public class ThisEscapeAnalyzer extends TreeScanner { // Helper methods - private void visitTopLevel(Env env, JCClassDecl klass, Runnable action) { - Assert.check(attrEnv == null); + private void analyzeConstructor(MethodInfo constructor) { Assert.check(targetClass == null); - Assert.check(methodClass == null); + Assert.check(currentMethod == null); Assert.check(depth == -1); Assert.check(refs == null); - attrEnv = env; - targetClass = klass; - methodClass = klass; + targetClass = constructor.declaringClass; + currentMethod = constructor; try { // Add the initial 'this' reference refs = RefSet.newEmpty(); refs.add(new ThisRef(targetClass.sym, EnumSet.of(Indirection.DIRECT))); - // Perform action - this.visitScoped(false, action); + // Analyze constructor + visitScoped(false, () -> scan(constructor.declaration.body)); } finally { Assert.check(depth == -1); - attrEnv = null; - methodClass = null; + currentMethod = null; targetClass = null; refs = null; } } // Recurse through indirect code that might get executed later, e.g., a lambda. - // We stash any pending warning and the current RefSet, then recurse into the deferred - // code (still using the current RefSet) to see if it would leak. Then we restore the - // pending warning and the current RefSet. Finally, if the deferred code would have - // leaked, we create an indirect ExprRef because it must be holding a 'this' reference. - // If the deferred code would not leak, then obviously no leak is possible, period. + // We record the current number of (real) warnings, then recurse into the deferred + // code (still using the current RefSet) to see if that number increases, i.e., to + // see if it would leak. Then we discard any new warnings and the lambda's RefSet. + // Finally, if the deferred code would have leaked, we create an indirect ExprRef + // because the lambda must be holding a 'this' reference. If not, no leak is possible. private void visitDeferred(Runnable deferredCode) { - DiagnosticPosition[] pendingWarningPrev = pendingWarning; - pendingWarning = null; + int numWarningsPrev = warningList.size(); RefSet refsPrev = refs.clone(); boolean deferredCodeLeaks; try { deferredCode.run(); - deferredCodeLeaks = pendingWarning != null; + deferredCodeLeaks = warningList.size() > numWarningsPrev; // There can be ExprRef's if the deferred code returns something. // Don't let them escape unnoticed. deferredCodeLeaks |= refs.discardExprs(depth); } finally { refs = refsPrev; - pendingWarning = pendingWarningPrev; + warningList.subList(numWarningsPrev, warningList.size()).clear(); } if (deferredCodeLeaks) refs.add(new ExprRef(depth, syms.objectType.tsym, EnumSet.of(Indirection.INDIRECT))); @@ -1341,24 +1298,9 @@ public class ThisEscapeAnalyzer extends TreeScanner { // Note a possible 'this' reference leak at the specified location private void leakAt(JCTree tree) { - - // Generate at most one warning per statement - if (pendingWarning != null) - return; - - // Snapshot the current stack trace - callStack.push(tree.pos()); - pendingWarning = callStack.toArray(new DiagnosticPosition[0]); - callStack.pop(); - } - - // Copy pending warning, if any, to the warning list and reset - private boolean copyPendingWarning() { - if (pendingWarning == null) - return false; - warningList.add(pendingWarning); - pendingWarning = null; - return true; + callStack.add(new StackFrame(currentMethod, null, tree)); // include the point of leakage in the stack + warningList.add(new Warning(targetClass, new ArrayList<>(callStack))); + callStack.remove(callStack.size() - 1); } // Does the symbol correspond to a parameter or local variable (not a field)? @@ -1398,7 +1340,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { private boolean checkInvariants(boolean analyzing, boolean allowExpr) { Assert.check(analyzing == isAnalyzing()); if (isAnalyzing()) { - Assert.check(methodClass != null); + Assert.check(currentMethod != null); Assert.check(targetClass != null); Assert.check(refs != null); Assert.check(depth >= 0); @@ -1409,7 +1351,6 @@ public class ThisEscapeAnalyzer extends TreeScanner { Assert.check(refs == null); Assert.check(depth == -1); Assert.check(callStack.isEmpty()); - Assert.check(pendingWarning == null); Assert.check(invocations.isEmpty()); } return true; @@ -1788,12 +1729,130 @@ public class ThisEscapeAnalyzer extends TreeScanner { } } +// StackFrame + + // Information about one frame on the call stack + private class StackFrame { + + final MethodInfo method; // the method containing the statement + final JCTree site; // the call site within the method + final JCTree initializer; // originating field or initialization block, else null + final boolean suppressible; // whether warning can be suppressed at this frame + + StackFrame(MethodInfo method, JCTree initializer, JCTree site) { + this.method = method; + this.initializer = initializer; + this.site = site; + this.suppressible = initializer != null || (method.constructor && method.declaringClass == targetClass); + } + + boolean isSuppressed() { + return suppressible && + suppressed.contains(initializer instanceof JCVariableDecl v ? v.sym : method.declaration.sym); + } + + int comparePos(StackFrame that) { + return Integer.compare(this.site.pos().getPreferredPosition(), that.site.pos().getPreferredPosition()); + } + + @Override + public String toString() { + return "StackFrame" + + "[" + method.declaration.sym + "@" + site.pos().getPreferredPosition() + + (initializer != null ? ",init@" + initializer.pos().getPreferredPosition() : "") + + "]"; + } + } + +// Warning + + // Information about one warning we have generated + private class Warning { + + final JCClassDecl declaringClass; // the class whose instance is leaked + final ArrayList stack; // the call stack where the leak happens + final JCTree origin; // the originating ctor, field, or init block + + Warning(JCClassDecl declaringClass, ArrayList stack) { + this.declaringClass = declaringClass; + this.stack = stack; + this.origin = stack.stream() + .map(frame -> frame.initializer) + .filter(Objects::nonNull) + .findFirst() + .orElseGet(() -> stack.get(0).method.declaration); // default to the initial constructor + } + + // Used to eliminate redundant warnings. Warning A is redundant with warning B if the call stack of A includes + // the call stack of B plus additional initial frame(s). For example, if constructor B = Foo(int x) generates a + // warning, then generating warning for some other constructor A when it invokes this(123) would be redundant. + boolean isRedundantWith(Warning that) { + int numExtra = this.stack.size() - that.stack.size(); + return numExtra >= 0 && + IntStream.range(0, that.stack.size()) + .allMatch(index -> this.stack.get(numExtra + index).comparePos(that.stack.get(index)) == 0); + } + + // Order warnings by their stack frames, lexicographically in reverse calling order, which will cause + // all warnings that are isRedundantWith() some other warning to immediately follow that warning. + static int sortByStackFrames(Warning warning1, Warning warning2) { + int index1 = warning1.stack.size(); + int index2 = warning2.stack.size(); + while (true) { + boolean end1 = --index1 < 0; + boolean end2 = --index2 < 0; + if (end1 && end2) + return 0; + if (end1) + return -1; + if (end2) + return 1; + int diff = warning1.stack.get(index1).comparePos(warning2.stack.get(index2)); + if (diff != 0) + return diff; + } + } + + // Determine whether this warning is suppressed. A single "this-escape" warning involves multiple source code + // positions, so we must determine suppression manually. We do this as follows: A warning is suppressed if + // "this-escape" is disabled at any position in the stack where that stack frame corresponds to a constructor + // or field initializer in the target class. That means, for example, @SuppressWarnings("this-escape") annotations + // on regular methods are ignored. Here we work our way back up the call stack from the point of the leak until + // we encounter a suppressible stack frame. + boolean isSuppressed() { + for (int index = stack.size() - 1; index >= 0; index--) { + if (stack.get(index).isSuppressed()) + return true; + } + return false; + } + + // If this is a field or initializer warning, trim the initial stack frame(s) up through the super() call + void trimInitializerFrames() { + for (int i = 0; i < stack.size(); i++) { + if (stack.get(i).initializer != null) { + stack.subList(0, i + 1).clear(); + break; + } + } + } + + @Override + public String toString() { + return "Warning" + + "[class=" + declaringClass.sym.flatname + + ",stack=[\n " + stack.stream().map(StackFrame::toString).collect(Collectors.joining("\n ")) + "]" + + "]"; + } + } + // MethodInfo // Information about a constructor or method in the compilation unit private record MethodInfo( JCClassDecl declaringClass, // the class declaring "declaration" JCMethodDecl declaration, // the method or constructor itself + boolean constructor, // the method is a constructor boolean analyzable, // it's a constructor that we should analyze boolean invokable) { // it may be safely "invoked" during analysis @@ -1801,6 +1860,7 @@ public class ThisEscapeAnalyzer extends TreeScanner { public String toString() { return "MethodInfo" + "[method=" + declaringClass.sym.flatname + "." + declaration.sym + + ",constructor=" + constructor + ",analyzable=" + analyzable + ",invokable=" + invokable + "]"; diff --git a/test/langtools/tools/javac/warnings/ThisEscape.java b/test/langtools/tools/javac/warnings/ThisEscape.java index 93ccb6e0830..f9280b5b1ae 100644 --- a/test/langtools/tools/javac/warnings/ThisEscape.java +++ b/test/langtools/tools/javac/warnings/ThisEscape.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8015831 + * @bug 8015831 8355753 * @compile/ref=ThisEscape.out -Xlint:this-escape -XDrawDiagnostics ThisEscape.java * @summary Verify 'this' escape detection */ @@ -765,4 +765,53 @@ public class ThisEscape { return this.obj; } } + + // JDK-8355753 - @SuppressWarnings("this-escape") not respected for indirect leak via field + public static class SuppressedIndirectLeakViaField { + + private final int x = this.mightLeak(); // this leak should be suppressed + private int y; + + { + y = this.mightLeak(); // this leak should be suppressed + } + + public SuppressedIndirectLeakViaField() { + this(""); + } + + @SuppressWarnings("this-escape") + private SuppressedIndirectLeakViaField(String s) { + } + + public int mightLeak() { + return 0; + } + } + + public static class UnsuppressedIndirectLeakViaField { + + private final int x = this.mightLeak(); // this leak should not be suppressed + + public UnsuppressedIndirectLeakViaField() { + this(""); // this constructor does not trigger the warning + } + + @SuppressWarnings("this-escape") + private UnsuppressedIndirectLeakViaField(String s) { + // this constructor does not trigger the warning (obviously; it's directly suppressed) + } + + public UnsuppressedIndirectLeakViaField(int z) { + // this constructor triggers the warning + } + + public UnsuppressedIndirectLeakViaField(float z) { + // this constructor also triggers the warning, but should not create a duplicate + } + + public int mightLeak() { + return 0; + } + } } diff --git a/test/langtools/tools/javac/warnings/ThisEscape.out b/test/langtools/tools/javac/warnings/ThisEscape.out index a444c2828b7..b866c4a7731 100644 --- a/test/langtools/tools/javac/warnings/ThisEscape.out +++ b/test/langtools/tools/javac/warnings/ThisEscape.out @@ -35,4 +35,5 @@ ThisEscape.java:652:55: compiler.warn.possible.this.escape ThisEscape.java:672:18: compiler.warn.possible.this.escape ThisEscape.java:669:48: compiler.warn.possible.this.escape.location ThisEscape.java:726:32: compiler.warn.possible.this.escape -37 warnings +ThisEscape.java:794:45: compiler.warn.possible.this.escape +38 warnings From 99048c3d4a66be9bf586949bd08e33cb091fa6bf Mon Sep 17 00:00:00 2001 From: Artur Barashev Date: Fri, 30 May 2025 16:03:13 +0000 Subject: [PATCH 023/216] 8357033: Reduce stateless session ticket size Reviewed-by: wetmore, djelinski, ascarpino --- .../security/ssl/PreSharedKeyExtension.java | 10 +- .../sun/security/ssl/SSLSessionImpl.java | 351 ++++++++---------- .../security/ssl/SessionTicketExtension.java | 90 ++++- .../SSLSessionImpl/ResumeChecksServer.java | 42 ++- .../ResumeChecksServerStateless.java | 6 +- 5 files changed, 261 insertions(+), 238 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java b/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java index f9c78774bc9..76bb64a66c3 100644 --- a/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java @@ -443,12 +443,6 @@ final class PreSharedKeyExtension { result = false; } - // Make sure that the server handshake context's - // localSupportedCertSignAlgs field is populated. This is particularly - // important when client authentication was used in an initial session, - // and it is now being resumed. - SignatureScheme.updateHandshakeLocalSupportedAlgs(shc); - // Validate the required client authentication. if (result && (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) { @@ -464,7 +458,9 @@ final class PreSharedKeyExtension { result = false; } - // Make sure the list of supported signature algorithms matches + // Make sure the list of supported signature algorithms matches. + // HandshakeContext's localSupportedCertSignAlgs has been already + // updated when we set the negotiated protocol. Collection sessionSigAlgs = s.getLocalSupportedSignatureSchemes(); if (result && diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java index f5e173c636a..032aa7de5b3 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -24,34 +24,33 @@ */ package sun.security.ssl; -import sun.security.provider.X509Factory; - import java.io.IOException; import java.net.InetAddress; import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; -import java.util.Queue; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantLock; +import java.util.zip.Adler32; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.ExtendedSSLSession; import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIServerName; -import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSessionBindingEvent; import javax.net.ssl.SSLSessionBindingListener; import javax.net.ssl.SSLSessionContext; +import sun.security.provider.X509Factory; +import sun.security.ssl.X509Authentication.X509Possession; /** * Implements the SSL session interface, and exposes the session context @@ -256,59 +255,51 @@ final class SSLSessionImpl extends ExtendedSSLSession { } /** + * Reassemble new session ticket. + *

      * < 2 bytes > protocolVersion * < 2 bytes > cipherSuite * < 1 byte > localSupportedSignAlgs entries * < 2 bytes per entries > localSupportedSignAlgs - * < 1 bytes > peerSupportedSignAlgs entries - * < 2 bytes per entries > peerSupportedSignAlgs - * < 2 bytes > preSharedKey length - * < length in bytes > preSharedKey - * < 1 byte > pskIdentity length - * < length in bytes > pskIdentity - * < 1 byte > masterSecret length - * < 1 byte > masterSecret algorithm length - * < length in bytes > masterSecret algorithm - * < 2 bytes > masterSecretKey length - * < length in bytes> masterSecretKey - * < 1 byte > useExtendedMasterSecret + * select (protocolVersion) + * case TLS13Plus: + * < 2 bytes > preSharedKey length + * < length in bytes > preSharedKey + * case non-TLS13Plus: + * < 2 bytes > masterSecretKey length + * < length in bytes> masterSecretKey + * < 1 byte > useExtendedMasterSecret * < 1 byte > identificationProtocol length - * < length in bytes > identificationProtocol + * < length in bytes > identificationProtocol * < 1 byte > serverNameIndication length - * < length in bytes > serverNameIndication + * < length in bytes > serverNameIndication * < 1 byte > Number of requestedServerNames entries - * < 1 byte > ServerName length - * < length in bytes > ServerName + * For each entry { + * < 1 byte > ServerName length + * < length in bytes > ServerName + * } * < 4 bytes > maximumPacketSize * < 4 bytes > negotiatedMaxFragSize * < 4 bytes > creationTime - * < 2 byte > status response length - * < 2 byte > status response entry length - * < length in byte > status response entry * < 1 byte > Length of peer host * < length in bytes > peer host * < 2 bytes> peer port - * < 1 byte > Number of peerCerts entries - * < 4 byte > peerCert length - * < length in bytes > peerCert - * < 1 byte > localCerts type (Cert, PSK, Anonymous) - * Certificate - * < 1 byte > Number of Certificate entries - * < 4 byte> Certificate length - * < length in bytes> Certificate - * PSK - * < 1 byte > Number of PSK entries - * < 1 bytes > PSK algorithm length - * < length in bytes > PSK algorithm string - * < 4 bytes > PSK key length - * < length in bytes> PSK key - * < 4 bytes > PSK identity length - * < length in bytes> PSK identity - * Anonymous - * < 1 byte > + * < 1 byte > Number of Peer Certificate entries + * For each entry { + * < 4 bytes > Peer certificate length + * < length in bytes> Peer certificate + * } + * < 1 byte > Number of Local Certificate entries + * For each entry { + * < 1 byte > Local Certificate algorithm length + * < length in bytes> Local Certificate algorithm + * < 4 bytes > Certificate checksum + * } */ SSLSessionImpl(HandshakeContext hc, ByteBuffer buf) throws IOException { + int len; + byte[] b; boundValues = new ConcurrentHashMap<>(); this.protocolVersion = ProtocolVersion.valueOf(Record.getInt16(buf)); @@ -321,51 +312,36 @@ final class SSLSessionImpl extends ExtendedSSLSession { CipherSuite.valueOf(Record.getInt16(buf)); // Local Supported signature algorithms - ArrayList list = new ArrayList<>(); - int i = Record.getInt8(buf); - while (i-- > 0) { + List list = new ArrayList<>(); + len = Record.getInt8(buf); + while (len-- > 0) { list.add(SignatureScheme.valueOf( Record.getInt16(buf))); } this.localSupportedSignAlgs = Collections.unmodifiableCollection(list); - // Peer Supported signature algorithms - i = Record.getInt8(buf); - list.clear(); - while (i-- > 0) { - list.add(SignatureScheme.valueOf( - Record.getInt16(buf))); - } - this.peerSupportedSignAlgs = Collections.unmodifiableCollection(list); - - // PSK - byte[] b = Record.getBytes16(buf); - if (b.length > 0) { + if (protocolVersion.useTLS13PlusSpec()) { + // PSK b = Record.getBytes16(buf); - this.preSharedKey = new SecretKeySpec(b, "TlsMasterSecret"); - } else { - this.preSharedKey = null; - } + if (b.length > 0) { + this.preSharedKey = new SecretKeySpec(b, "TlsMasterSecret"); + } else { + this.preSharedKey = null; + } - // PSK identity - b = Record.getBytes8(buf); - if (b.length > 0) { - this.pskIdentity = b; + this.useExtendedMasterSecret = false; } else { - this.pskIdentity = null; - } - - // Master secret length of secret key algorithm (one byte) - b = Record.getBytes8(buf); - if (b.length > 0) { + // Master secret b = Record.getBytes16(buf); - this.masterSecret = new SecretKeySpec(b, "TlsMasterSecret"); - } else { - this.masterSecret = null; - } + if (b.length > 0) { + this.masterSecret = new SecretKeySpec(b, "TlsMasterSecret"); + } else { + this.masterSecret = null; + } - // Use extended master secret - this.useExtendedMasterSecret = (Record.getInt8(buf) != 0); + // Extended master secret usage. + this.useExtendedMasterSecret = (Record.getInt8(buf) != 0); + } // Identification Protocol b = Record.getBytes8(buf); @@ -384,7 +360,7 @@ final class SSLSessionImpl extends ExtendedSSLSession { } // List of SNIServerName - int len = Record.getInt16(buf); + len = Record.getInt16(buf); if (len == 0) { this.requestedServerNames = Collections.emptyList(); } else { @@ -401,20 +377,6 @@ final class SSLSessionImpl extends ExtendedSSLSession { // Get creation time this.creationTime = buf.getLong(); - // Get Buffer sizes - - // Status Response - len = Record.getInt16(buf); - if (len == 0) { - statusResponses = Collections.emptyList(); - } else { - statusResponses = new ArrayList<>(); - } - while (len-- > 0) { - b = Record.getBytes16(buf); - statusResponses.add(b); - } - // Get Peer host & port b = Record.getBytes8(buf); if (b.length == 0) { @@ -424,71 +386,89 @@ final class SSLSessionImpl extends ExtendedSSLSession { } this.port = Record.getInt16(buf); - // Peer certs - i = Record.getInt8(buf); - if (i == 0) { + // Peer certs. + len = Record.getInt8(buf); + if (len == 0) { this.peerCerts = null; } else { - this.peerCerts = new X509Certificate[i]; - int j = 0; - while (i > j) { + this.peerCerts = new X509Certificate[len]; + for (int i = 0; len > i; i++) { b = new byte[buf.getInt()]; buf.get(b); try { - this.peerCerts[j] = X509Factory.cachedGetX509Cert(b); + this.peerCerts[i] = X509Factory.cachedGetX509Cert(b); } catch (Exception e) { throw new IOException(e); } - j++; } } - // Get local certs of PSK - switch (Record.getInt8(buf)) { - case 0: - break; - case 1: - // number of certs - len = buf.get(); - this.localCerts = new X509Certificate[len]; - i = 0; - while (len > i) { - b = new byte[buf.getInt()]; - buf.get(b); + // Restore local certificates if cert algorithm(s) present. + len = Record.getInt8(buf); + if (len == 0) { + this.localCerts = null; + } else { + String[] certAlgs = new String[len]; + int[] certCheckSums = new int[len]; + + for (int i = 0; len > i; i++) { + certAlgs[i] = new String(Record.getBytes8(buf)); + certCheckSums[i] = Record.getInt32(buf); + } + + SSLPossession pos = X509Authentication.createPossession( + hc, certAlgs); + boolean same = false; + + if (pos instanceof X509Possession x509Pos + && x509Pos.popCerts != null + && x509Pos.popCerts.length == len) { + // Make sure we got the exact same cert chain. + for (int i = 0; i < x509Pos.popCerts.length; i++) { try { - this.localCerts[i] = X509Factory.cachedGetX509Cert(b); + byte[] encoded = x509Pos.popCerts[i].getEncoded(); + String popAlg = x509Pos.popCerts[i] + .getPublicKey().getAlgorithm(); + + if (certCheckSums[i] == getChecksum(encoded) + && certAlgs[i].equals(popAlg)) { + // Use certs from cache. + x509Pos.popCerts[i] = + X509Factory.cachedGetX509Cert(encoded); + same = true; + } else { + same = false; + break; + } } catch (Exception e) { throw new IOException(e); } - i++; } - break; - case 2: - // pre-shared key - // Length of pre-shared key algorithm (one byte) - b = Record.getBytes8(buf); - String alg = new String(b); - // Get encoding - b = Record.getBytes16(buf); - this.preSharedKey = new SecretKeySpec(b, alg); - // Get identity len - i = Record.getInt8(buf); - if (i > 0) { - this.pskIdentity = Record.getBytes8(buf); - } else { - this.pskIdentity = null; + } + + if (same) { + this.localCerts = ((X509Possession) pos).popCerts; + if (SSLLogger.isOn && SSLLogger.isOn("ssl,session")) { + SSLLogger.fine("Restored " + len + + " local certificates from session ticket" + + " for algorithms " + Arrays.toString(certAlgs)); } - break; - default: - throw new SSLException("Failed local certs of session."); + } else { + this.localCerts = null; + this.invalidated = true; + if (SSLLogger.isOn && SSLLogger.isOn("ssl,session")) { + SSLLogger.warning("Local certificates can not be restored " + + "from session ticket " + + "for algorithms " + Arrays.toString(certAlgs)); + } + } } - context = (SSLSessionContextImpl) + this.context = (SSLSessionContextImpl) hc.sslContext.engineGetServerSessionContext(); this.lastUsedTime = System.currentTimeMillis(); } - // Some situations we cannot provide a stateless ticket, but after it // has been negotiated boolean isStatelessable() { @@ -529,49 +509,25 @@ final class SSLSessionImpl extends ExtendedSSLSession { hos.putInt16(s.id); } - // Peer Supported signature algorithms - hos.putInt8(peerSupportedSignAlgs.size()); - for (SignatureScheme s : peerSupportedSignAlgs) { - hos.putInt16(s.id); - } - - // PSK - if (preSharedKey == null || - preSharedKey.getAlgorithm() == null) { - hos.putInt16(0); - } else { - hos.putInt16(preSharedKey.getAlgorithm().length()); - if (preSharedKey.getAlgorithm().length() != 0) { - hos.write(preSharedKey.getAlgorithm().getBytes()); + // PreSharedKey is only needed by TLSv1.3, + // masterSecret is only needed by pre-TLSv1.3. + if (protocolVersion.useTLS13PlusSpec()) { + // PSK + if (preSharedKey == null) { + hos.putInt16(0); + } else { + hos.putBytes16(preSharedKey.getEncoded()); } - b = preSharedKey.getEncoded(); - hos.putInt16(b.length); - hos.write(b, 0, b.length); - } - - // PSK Identity - if (pskIdentity == null) { - hos.putInt8(0); } else { - hos.putInt8(pskIdentity.length); - hos.write(pskIdentity, 0, pskIdentity.length); - } - - // Master Secret - if (getMasterSecret() == null || - getMasterSecret().getAlgorithm() == null) { - hos.putInt8(0); - } else { - hos.putInt8(getMasterSecret().getAlgorithm().length()); - if (getMasterSecret().getAlgorithm().length() != 0) { - hos.write(getMasterSecret().getAlgorithm().getBytes()); + // Master Secret + if (getMasterSecret() == null) { + hos.putInt16(0); + } else { + hos.putBytes16(masterSecret.getEncoded()); } - b = getMasterSecret().getEncoded(); - hos.putInt16(b.length); - hos.write(b, 0, b.length); - } - hos.putInt8(useExtendedMasterSecret ? 1 : 0); + hos.putInt8(useExtendedMasterSecret ? 1 : 0); + } // Identification Protocol if (identificationProtocol == null) { @@ -605,20 +561,11 @@ final class SSLSessionImpl extends ExtendedSSLSession { hos.putInt32(maximumPacketSize); hos.putInt32(negotiatedMaxFragLen); - // creation time + // Creation time ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); hos.writeBytes(buffer.putLong(creationTime).array()); - // Status Responses - List list = getStatusResponses(); - int l = list.size(); - hos.putInt16(l); - for (byte[] e : list) { - hos.putInt16(e.length); - hos.write(e); - } - - // peer Host & Port + // Peer Host & Port if (host == null || host.length() == 0) { hos.putInt8(0); } else { @@ -627,7 +574,7 @@ final class SSLSessionImpl extends ExtendedSSLSession { } hos.putInt16(port); - // Peer cert + // Peer certs. if (peerCerts == null || peerCerts.length == 0) { hos.putInt8(0); } else { @@ -639,34 +586,28 @@ final class SSLSessionImpl extends ExtendedSSLSession { } } - // Client identity - if (localCerts != null && localCerts.length > 0) { - // certificate based - hos.putInt8(1); + // Local certificates' algorithms and checksums. + // We don't include the complete local certificates in a session ticket + // to decrease the size of ClientHello message. + if (localCerts == null || localCerts.length == 0) { + hos.putInt8(0); + } else { hos.putInt8(localCerts.length); for (X509Certificate c : localCerts) { - b = c.getEncoded(); - hos.putInt32(b.length); - hos.writeBytes(b); + hos.putBytes8(c.getPublicKey().getAlgorithm().getBytes()); + hos.putInt32(getChecksum(c.getEncoded())); } - } else if (preSharedKey != null) { - // pre-shared key - hos.putInt8(2); - hos.putInt8(preSharedKey.getAlgorithm().length()); - hos.write(preSharedKey.getAlgorithm().getBytes()); - b = preSharedKey.getEncoded(); - hos.putInt32(b.length); - hos.writeBytes(b); - hos.putInt32(pskIdentity.length); - hos.writeBytes(pskIdentity); - } else { - // anonymous - hos.putInt8(0); } return hos.toByteArray(); } + private static int getChecksum(byte[] input) { + Adler32 adler32 = new Adler32(); + adler32.update(input); + return (int) adler32.getValue(); + } + void setMasterSecret(SecretKey secret) { masterSecret = secret; } diff --git a/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java b/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java index 6cf930619f7..c0d2bea77ca 100644 --- a/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java @@ -25,12 +25,16 @@ package sun.security.ssl; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.text.MessageFormat; import java.util.Locale; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; @@ -70,6 +74,9 @@ final class SessionTicketExtension { new T12SHSessionTicketConsumer(); static final SSLStringizer steStringizer = new SessionTicketStringizer(); + // No need to compress a ticket if it can fit in a single packet. + // Besides, small buffers often end up to be larger when compressed. + static final int MIN_COMPRESS_SIZE = 600; // Time in milliseconds until key is changed for encrypting session state private static final int TIMEOUT_DEFAULT = 3600 * 1000; @@ -196,7 +203,7 @@ final class SessionTicketExtension { data = buf; } - public byte[] encrypt(HandshakeContext hc, SSLSessionImpl session) { + byte[] encrypt(HandshakeContext hc, SSLSessionImpl session) { byte[] encrypted; if (!hc.statelessResumption || @@ -213,26 +220,34 @@ final class SessionTicketExtension { Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, key.key, new GCMParameterSpec(GCM_TAG_LEN, iv)); - c.updateAAD(new byte[] { - (byte)(key.num >>> 24), - (byte)(key.num >>> 16), - (byte)(key.num >>> 8), - (byte)(key.num)} - ); + byte[] data = session.write(); if (data.length == 0) { return data; } + + // Compress the session before encryption if needed. + byte compressed = 0; + if (data.length >= MIN_COMPRESS_SIZE) { + data = compress(data); + compressed = 1; + } + + ByteBuffer aad = ByteBuffer.allocate(Integer.BYTES + 1); + aad.putInt(key.num).put(compressed); + c.updateAAD(aad); + encrypted = c.doFinal(data); byte[] result = new byte[encrypted.length + Integer.BYTES + - iv.length]; + iv.length + 1]; result[0] = (byte)(key.num >>> 24); result[1] = (byte)(key.num >>> 16); result[2] = (byte)(key.num >>> 8); result[3] = (byte)(key.num); System.arraycopy(iv, 0, result, Integer.BYTES, iv.length); + result[Integer.BYTES + iv.length] = compressed; System.arraycopy(encrypted, 0, result, - Integer.BYTES + iv.length, encrypted.length); + Integer.BYTES + iv.length + 1, encrypted.length); return result; } catch (Exception e) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -257,26 +272,67 @@ final class SessionTicketExtension { Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.DECRYPT_MODE, key.key, new GCMParameterSpec(GCM_TAG_LEN, iv)); - c.updateAAD(new byte[] { - (byte)(keyID >>> 24), - (byte)(keyID >>> 16), - (byte)(keyID >>> 8), - (byte)(keyID)} - ); - ByteBuffer out; - out = ByteBuffer.allocate(data.remaining() - GCM_TAG_LEN / 8); + byte compressed = data.get(); + ByteBuffer aad = ByteBuffer.allocate(Integer.BYTES + 1); + aad.putInt(keyID).put(compressed); + c.updateAAD(aad); + + ByteBuffer out = ByteBuffer.allocate( + data.remaining() - GCM_TAG_LEN / 8); c.doFinal(data, out); out.flip(); + + // Decompress the session after decryption if needed. + if (compressed == 1) { + out = decompress(out); + } + return out; } catch (Exception e) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine("Decryption failed." + e.getMessage()); } } + return null; } + private static byte[] compress(byte[] input) throws IOException { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(baos)) { + final int decompressedLen = input.length; + gos.write(input, 0, decompressedLen); + gos.finish(); + + if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { + SSLLogger.fine("decompressed bytes: " + decompressedLen + + "; compressed bytes: " + baos.size()); + } + + return baos.toByteArray(); + } + } + + private static ByteBuffer decompress(ByteBuffer input) + throws IOException { + final int compressedLen = input.remaining(); + byte[] bytes = new byte[compressedLen]; + input.get(bytes); + + try (GZIPInputStream gis = new GZIPInputStream( + new ByteArrayInputStream(bytes))) { + byte[] out = gis.readAllBytes(); + + if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { + SSLLogger.fine("compressed bytes: " + compressedLen + + "; decompressed bytes: " + out.length); + } + + return ByteBuffer.wrap(out); + } + } + byte[] getEncoded() { byte[] out = new byte[data.capacity()]; data.duplicate().get(out); diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServer.java b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServer.java index 0d5413d1fa2..341dfb11d77 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServer.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @bug 8206929 * @summary ensure that server only resumes a session if certain properties * of the session are compatible with the new connection + * @modules java.base/sun.security.x509 * @library /javax/net/ssl/templates * @run main/othervm -Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=false ResumeChecksServer BASIC * @run main/othervm -Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=false ResumeChecksServer BASIC @@ -48,6 +49,7 @@ import java.io.*; import java.security.*; import java.net.*; import java.util.*; +import sun.security.x509.X509CertImpl; public class ResumeChecksServer extends SSLContextTemplate { @@ -57,7 +59,8 @@ public class ResumeChecksServer extends SSLContextTemplate { VERSION_2_TO_3, VERSION_3_TO_2, CIPHER_SUITE, - SIGNATURE_SCHEME + SIGNATURE_SCHEME, + LOCAL_CERTS } public static void main(String[] args) throws Exception { @@ -71,6 +74,7 @@ public class ResumeChecksServer extends SSLContextTemplate { } private void run() throws Exception { + SSLSession firstSession; SSLSession secondSession = null; SSLContext sslContext = createServerSSLContext(); @@ -81,7 +85,7 @@ public class ResumeChecksServer extends SSLContextTemplate { Client client = startClient(ssock.getLocalPort()); try { - connect(client, ssock, testMode, false); + firstSession = connect(client, ssock, testMode, null); } catch (Exception ex) { throw new RuntimeException(ex); } @@ -89,7 +93,7 @@ public class ResumeChecksServer extends SSLContextTemplate { long secondStartTime = System.currentTimeMillis(); Thread.sleep(10); try { - secondSession = connect(client, ssock, testMode, true); + secondSession = connect(client, ssock, testMode, firstSession); } catch (SSLHandshakeException ex) { // this is expected } catch (Exception ex) { @@ -105,6 +109,14 @@ public class ResumeChecksServer extends SSLContextTemplate { if (secondSession.getCreationTime() > secondStartTime) { throw new RuntimeException("Session was not reused"); } + + // Fail if session's certificates are not restored correctly. + if (!java.util.Arrays.equals( + firstSession.getLocalCertificates(), + secondSession.getLocalCertificates())) { + throw new RuntimeException("Certificates do not match"); + } + break; case CLIENT_AUTH: // throws an exception if the client is not authenticated @@ -114,6 +126,7 @@ public class ResumeChecksServer extends SSLContextTemplate { case VERSION_3_TO_2: case CIPHER_SUITE: case SIGNATURE_SCHEME: + case LOCAL_CERTS: // fail if a new session is not created if (secondSession.getCreationTime() <= secondStartTime) { throw new RuntimeException("Existing session was used"); @@ -153,7 +166,9 @@ public class ResumeChecksServer extends SSLContextTemplate { } private static SSLSession connect(Client client, SSLServerSocket ssock, - TestMode mode, boolean second) throws Exception { + TestMode mode, SSLSession firstSession) throws Exception { + + boolean second = firstSession != null; try { client.signal(); @@ -200,9 +215,22 @@ public class ResumeChecksServer extends SSLContextTemplate { AlgorithmConstraints constraints = params.getAlgorithmConstraints(); if (second) { - params.setAlgorithmConstraints(new NoSig("ecdsa")); + params.setAlgorithmConstraints( + new NoSig("ecdsa_secp384r1_sha384")); } else { - params.setAlgorithmConstraints(new NoSig("rsa")); + params.setAlgorithmConstraints( + new NoSig("ecdsa_secp521r1_sha512")); + } + break; + case LOCAL_CERTS: + if (second) { + // Add first session's certificate signature + // algorithm to constraints so local certificates + // can't be restored from the session ticket. + params.setAlgorithmConstraints( + new NoSig(X509CertImpl.toImpl((X509CertImpl) + firstSession.getLocalCertificates()[0]) + .getSigAlgName())); } break; default: diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServerStateless.java b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServerStateless.java index 8071bb1ced8..f68af24ea93 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServerStateless.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeChecksServerStateless.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,9 +23,10 @@ /* * @test - * @bug 8211018 + * @bug 8211018 8357033 * @summary ensure that server only resumes a session if certain properties * of the session are compatible with the new connection + * @modules java.base/sun.security.x509 * @library /javax/net/ssl/templates * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 ResumeChecksServer BASIC * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 ResumeChecksServer CLIENT_AUTH @@ -33,4 +34,5 @@ * @run main/othervm ResumeChecksServer VERSION_3_TO_2 * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 ResumeChecksServer CIPHER_SUITE * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 ResumeChecksServer SIGNATURE_SCHEME + * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 ResumeChecksServer LOCAL_CERTS */ From 81464cd1141ebdf0cdde22e7388b97224d810f4a Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Fri, 30 May 2025 17:13:04 +0000 Subject: [PATCH 024/216] 8358089: Remove the GenerateKeyList.java test tool Reviewed-by: naoto --- .../jdk/java/util/Locale/GenerateKeyList.java | 90 ------------------- 1 file changed, 90 deletions(-) delete mode 100644 test/jdk/java/util/Locale/GenerateKeyList.java diff --git a/test/jdk/java/util/Locale/GenerateKeyList.java b/test/jdk/java/util/Locale/GenerateKeyList.java deleted file mode 100644 index 32598b8a759..00000000000 --- a/test/jdk/java/util/Locale/GenerateKeyList.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2007, 2022, 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. - */ -/** - * This is a simple program that will generate a key list that can be used as the basis - * for a LocaleData file suitable for use with LocaleDataTest. It always sends its - * output to standard out. - */ -import java.util.Locale; -import java.util.ResourceBundle; -import java.util.Enumeration; -import java.io.PrintStream; - -public class GenerateKeyList { - public static void main(String[] args) throws Exception { - doOutputFor("sun.util.resources", "CalendarData", System.out); - doOutputFor("sun.util.resources", "CurrencyNames", System.out); - doOutputFor("sun.util.resources", "LocaleNames", System.out); - doOutputFor("sun.util.resources", "TimeZoneNames", System.out); - doOutputFor("sun.text.resources", "CollationData", System.out); - doOutputFor("sun.text.resources", "FormatData", System.out); - }; - - public static void doOutputFor(String packageName, - String resourceBundleName, PrintStream out) - throws Exception { - Locale[] availableLocales = Locale.getAvailableLocales(); - - ResourceBundle bundle = ResourceBundle.getBundle(packageName + - resourceBundleName, Locale.of("")); - dumpResourceBundle(resourceBundleName + "/", bundle, out); - for (int i = 0; i < availableLocales.length; i++) { - bundle = ResourceBundle.getBundle(packageName + resourceBundleName, - availableLocales[i]); - dumpResourceBundle(resourceBundleName + "/" + availableLocales[i].toString(), - bundle, out); - } - } - - public static void dumpResourceBundle(String pathName, ResourceBundle bundle, - PrintStream out) throws Exception { - Enumeration keys = bundle.getKeys(); - while(keys.hasMoreElements()) { - String key = (String)(keys.nextElement()); - dumpResource(pathName + "/" + key, bundle.getObject(key), out); - } - } - - public static void dumpResource(String pathName, Object resource, PrintStream out) - throws Exception { - if (resource instanceof String[]) { - String[] stringList = (String[])resource; - for (int i = 0; i < stringList.length; i++) - out.println(pathName + "/" + i); - } - else if (resource instanceof String[][]) { - String[][] stringArray = (String[][])resource; - if (pathName.startsWith("TimeZoneNames")) { - for (int i = 0; i < stringArray.length; i++) - for (int j = 0; j < stringArray[i].length; j++) - out.println(pathName + "/" + i + "/" + j); - } - else { - for (int i = 0; i < stringArray.length; i++) - out.println(pathName + "/" + stringArray[i][0]); - } - } - else - out.println(pathName); - } -} From eaf7815ea6854de603a1b5c179799a9ef5d37f42 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Fri, 30 May 2025 17:22:51 +0000 Subject: [PATCH 025/216] 8357886: Remove TimeZoneNames_* of the COMPAT locale data provider Reviewed-by: joehw, jlu --- .../util/resources/ext/TimeZoneNames_de.java | 1046 ---------------- .../resources/ext/TimeZoneNames_en_CA.java | 51 - .../resources/ext/TimeZoneNames_en_GB.java | 54 - .../resources/ext/TimeZoneNames_en_IE.java | 54 - .../util/resources/ext/TimeZoneNames_es.java | 1046 ---------------- .../util/resources/ext/TimeZoneNames_fr.java | 1046 ---------------- .../util/resources/ext/TimeZoneNames_hi.java | 49 - .../util/resources/ext/TimeZoneNames_it.java | 1046 ---------------- .../util/resources/ext/TimeZoneNames_ja.java | 1046 ---------------- .../util/resources/ext/TimeZoneNames_ko.java | 1046 ---------------- .../resources/ext/TimeZoneNames_pt_BR.java | 1046 ---------------- .../util/resources/ext/TimeZoneNames_sv.java | 1046 ---------------- .../resources/ext/TimeZoneNames_zh_CN.java | 1046 ---------------- .../resources/ext/TimeZoneNames_zh_HK.java | 59 - .../resources/ext/TimeZoneNames_zh_TW.java | 1048 ----------------- 15 files changed, 10729 deletions(-) delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_CA.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_GB.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_IE.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_hi.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_HK.java delete mode 100644 src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java deleted file mode 100644 index 5cc8a38892d..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_de extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Acre Normalzeit", "ACT", - "Acre Sommerzeit", "ACST", - "Acre Normalzeit", "ACT"}; - String ADELAIDE[] = new String[] {"Zentrale Normalzeit (S\u00FCdaustralien)", "ACST", - "Zentrale Sommerzeit (S\u00FCdaustralien)", "ACDT", - "Zentrale Zeitzone (S\u00FCdaustralien)", "ACT"}; - String AGT[] = new String[] {"Argentinische Zeit", "ART", - "Argentinische Sommerzeit", "ARST", - "Argentinische Zeit", "ART"}; - String AKST[] = new String[] {"Alaska Normalzeit", "AKST", - "Alaska Sommerzeit", "AKDT", - "Zeitzone f\u00FCr Alaska", "AKT"}; - String AMT[] = new String[] {"Amazonas Normalzeit", "AMT", - "Amazonas Sommerzeit", "AMST", - "Amazonas Normalzeit", "AMT"}; - String ARAST[] = new String[] {"Arabische Normalzeit", "AST", - "Arabische Sommerzeit", "ADT", - "Zeitzone f\u00FCr Arabische Halbinsel", "AT"}; - String ARMT[] = new String[] {"Armenische Zeit", "AMT", - "Armenische Sommerzeit", "AMST", - "Armenische Zeit", "AMT"}; - String AST[] = new String[] {"Atlantik Normalzeit", "AST", - "Atlantik Sommerzeit", "ADT", - "Zeitzone Atlantik", "AT"}; - String BDT[] = new String[] {"Bangladesch Zeit", "BDT", - "Bangladesch Sommerzeit", "BDST", - "Bangladesch Zeit", "BDT"}; - String BRISBANE[] = new String[] {"\u00D6stliche Normalzeit (Queensland)", "AEST", - "\u00D6stliche Sommerzeit (Queensland)", "AEDT", - "\u00D6stliche Zeitzone (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Zentrale Normalzeit (S\u00FCdaustralien/New South Wales)", "ACST", - "Zentrale Sommerzeit (S\u00FCdaustralien/New South Wales)", "ACDT", - "Zentrale Zeitzone (S\u00FCdaustralien/New South Wales)", "ACT"}; - String BRT[] = new String[] {"Brasilianische Zeit", "BRT", - "Brasilianische Sommerzeit", "BRST", - "Brasilianische Zeit", "BRT"}; - String BTT[] = new String[] {"Bhutanische Zeit", "BTT", - "Bhutanische Sommerzeit", "BTST", - "Bhutanische Zeit", "BTT"}; - String CAT[] = new String[] {"Zentralafrikanische Zeit", "CAT", - "Zentralafrikanische Sommerzeit", "CAST", - "Zentralafrikanische Zeit", "CAT"}; - String CET[] = new String[] {"Mitteleurop\u00e4ische Zeit", "MEZ", - "Mitteleurop\u00e4ische Sommerzeit", "MESZ", - "Mitteleurop\u00E4ische Zeit", "MEZ"}; - String CHAST[] = new String[] {"Chatham Normalzeit", "CHAST", - "Chatham Sommerzeit", "CHADT", - "Zeitzone f\u00FCr Chatham-Inseln", "CHAT"}; - String CHUT[] = new String[] {"Chuuk Zeit", "CHUT", - "Chuuk Sommerzeit", "CHUST", - "Chuuk Zeit", "CHUT"}; - String CIT[] = new String[] {"Zentralindonesische Zeit", "WITA", - "Zentralindonesische Sommerzeit", "CIST", - "Zentralindonesische Zeit", "WITA"}; - String CLT[] = new String[] {"Chilenische Zeit", "CLT", - "Chilenische Sommerzeit", "CLST", - "Chilenische Zeit", "CLT"}; - String CST[] = new String[] {"Zentrale Normalzeit", "CST", - "Zentrale Sommerzeit", "CDT", - "Zentrale Zeitzone", "CT"}; - String CTT[] = new String[] {"Chinesische Normalzeit", "CST", - "Chinesische Sommerzeit", "CDT", - "Zeitzone f\u00FCr China", "CT"}; - String CUBA[] = new String[] {"Kubanische Normalzeit", "CST", - "Kubanische Sommerzeit", "CDT", - "Kubanische Normalzeit", "CT"}; - String DARWIN[] = new String[] {"Zentrale Normalzeit (Northern Territory)", "ACST", - "Zentrale Sommerzeit (Northern Territory)", "ACDT", - "Zentrale Zeitzone (Northern Territory)", "ACT"}; - String DUBLIN[] = new String[] {"Greenwich Zeit", "GMT", - "Irische Sommerzeit", "IST", - "Irische Zeit", "IT"}; - String EAT[] = new String[] {"Ostafrikanische Zeit", "EAT", - "Ostafrikanische Sommerzeit", "EAST", - "Ostafrikanische Zeit", "EAT"}; - String EASTER[] = new String[] {"Osterinseln Zeit", "EAST", - "Osterinseln Sommerzeit", "EASST", - "Osterinseln Zeit", "EAST"}; - String EET[] = new String[] {"Osteurop\u00e4ische Zeit", "OEZ", - "Osteurop\u00e4ische Sommerzeit", "OESZ", - "Osteurop\u00e4ische Zeit", "OEZ"}; - String EGT[] = new String[] {"Ostgr\u00f6nl\u00e4ndische Zeit", "EGT", - "Ostgr\u00f6nl\u00e4ndische Sommerzeit", "EGST", - "Ostgr\u00F6nl\u00E4ndische Zeit", "EGT"}; - String EST[] = new String[] {"\u00d6stliche Normalzeit", "EST", - "\u00d6stliche Sommerzeit", "EDT", - "\u00D6stliche Zeitzone", "ET"}; - String EST_NSW[] = new String[] {"\u00D6stliche Normalzeit (New South Wales)", "AEST", - "\u00D6stliche Sommerzeit (New South Wales)", "AEDT", - "\u00D6stliche Zeitzone (New South Wales)", "AET"}; - String FET[] = new String[] {"Kaliningrader Zeit", "FET", - "Kaliningrader Sommerzeit", "FEST", - "Kaliningrader Zeit", "FET"}; - String GHMT[] = new String[] {"Ghanaische Normalzeit", "GMT", - "Ghanaische Sommerzeit", "GHST", - "Ghanaische Normalzeit", "GMT"}; - String GAMBIER[] = new String[] {"Gambier Zeit", "GAMT", - "Gambier Sommerzeit", "GAMST", - "Gambier Zeit", "GAMT"}; - String GMT[] = new String[] {"Greenwich Zeit", "GMT", - "Greenwich Zeit", "GMT", - "Greenwich Zeit", "GMT"}; - String GMTBST[] = new String[] {"Greenwich Zeit", "GMT", - "Britische Sommerzeit", "BST", - "Britische Zeit", "BT"}; - String GST[] = new String[] {"Golf Normalzeit", "GST", - "Golf Sommerzeit", "GDT", - "Zeitzone f\u00FCr Persischen Golf", "GT"}; - String HKT[] = new String[] {"Hongkong Zeit", "HKT", - "Hongkong Sommerzeit", "HKST", - "Hongkong Zeit", "HKT"}; - String HST[] = new String[] {"Hawaii Normalzeit", "HST", - "Hawaii Sommerzeit", "HDT", - "Zeitzone f\u00FCr Hawaii", "HT"}; - String ICT[] = new String[] {"Indochina Zeit", "ICT", - "Indochina Sommerzeit", "ICST", - "Indochina Zeit", "ICT"}; - String IRKT[] = new String[] {"Irkutsk Zeit", "IRKT", - "Irkutsk Sommerzeit", "IRKST", - "Irkutsk Zeit", "IRKT"}; - String IRT[] = new String[] {"Iranische Normalzeit", "IRST", - "Iranische Sommerzeit", "IRDT", - "Iranische Zeit", "IRT"}; - String ISRAEL[] = new String[] {"Israelische Normalzeit", "IST", - "Israelische Sommerzeit", "IDT", - "Zeitzone f\u00FCr Israel", "IT"}; - String IST[] = new String[] {"Indische Normalzeit", "IST", - "Indische Sommerzeit", "IDT", - "Zeitzone f\u00FCr Indien", "IT"}; - String JST[] = new String[] {"Japanische Normalzeit", "JST", - "Japanische Sommerzeit", "JDT", - "Zeitzone f\u00FCr Japan", "JT"}; - String KRAT[] = new String[] {"Krasnojarsker Zeit", "KRAT", - "Krasnojarsker Sommerzeit", "KRAST", - "Krasnojarsker Zeit", "KRAT"}; - String KST[] = new String[] {"Koreanische Normalzeit", "KST", - "Koreanische Sommerzeit", "KDT", - "Zeitzone f\u00FCr Korea", "KT"}; - String LORD_HOWE[] = new String[] {"Lord Howe Normalzeit", "LHST", - "Lord Howe Sommerzeit", "LHDT", - "Lord-Howe Normalzeit", "LHT"}; - String MHT[] = new String[] {"Marshallinseln Zeit", "MHT", - "Marshallinseln Sommerzeit", "MHST", - "Marshallinseln Zeit", "MHT"}; - String MMT[] = new String[] {"Myanmar Zeit", "MMT", - "Myanmar Sommerzeit", "MMST", - "Myanmar Zeit", "MMT"}; - String MSK[] = new String[] {"Moskauer Normalzeit", "MSK", - "Moskauer Sommerzeit", "MSD", - "Zeitzone f\u00FCr Moskau", "MT"}; - String MST[] = new String[] {"Rocky Mountains Normalzeit", "MST", - "Rocky Mountains Sommerzeit", "MDT", - "Zeitzone Mountain", "MT"}; - String MYT[] = new String[] {"Malaysische Zeit", "MYT", - "Malaysische Sommerzeit", "MYST", - "Malaysische Zeit", "MYT"}; - String NORONHA[] = new String[] {"Fernando de Noronha Zeit", "FNT", - "Fernando de Noronha Sommerzeit", "FNST", - "Fernando de Noronha Zeit", "FNT"}; - String NOVT[] = new String[] {"Nowosibirsker Zeit", "NOVT", - "Nowosibirsker Sommerzeit", "NOVST", - "Nowosibirsker Zeit", "NOVT"}; - String NPT[] = new String[] {"Nepalesische Zeit", "NPT", - "Nepalesische Sommerzeit", "NPST", - "Nepalesische Zeit", "NPT"}; - String NST[] = new String[] {"Neufundland Normalzeit", "NST", - "Neufundland Sommerzeit", "NDT", - "Zeitzone f\u00FCr Neufundland", "NT"}; - String NZST[] = new String[] {"Neuseeland Normalzeit", "NZST", - "Neuseeland Sommerzeit", "NZDT", - "Zeitzone f\u00FCr Neuseeland", "NZT"}; - String PITCAIRN[] = new String[] {"Pitcairn Normalzeit", "PST", - "Pitcairn Sommerzeit", "PDT", - "Zeitzone f\u00FCr Pitcairn", "PT"}; - String PKT[] = new String[] {"Pakistanische Zeit", "PKT", - "Pakistanische Sommerzeit", "PKST", - "Pakistanische Zeit", "PKT"}; - String PONT[] = new String[] {"Pohnpei Zeit", "PONT", - "Pohnpei Sommerzeit", "PONST", - "Pohnpei-Inseln Zeit", "PONT"}; - String PST[] = new String[] {"Pazifische Normalzeit", "PST", - "Pazifische Sommerzeit", "PDT", - "Zeitzone Pazifik", "PT"}; - String SAST[] = new String[] {"S\u00fcdafrikanische Normalzeit", "SAST", - "S\u00fcdafrikanische Sommerzeit", "SAST", - "Zeitzone f\u00FCr S\u00FCdafrika", "SAT"}; - String SBT[] = new String[] {"Salomoninseln Zeit", "SBT", - "Salomoninseln Sommerzeit", "SBST", - "Salomoninseln Zeit", "SBT"}; - String SGT[] = new String[] {"Singapur Zeit", "SGT", - "Singapur Sommerzeit", "SGST", - "Singapur Zeit", "SGT"}; - String TASMANIA[] = new String[] {"\u00D6stliche Normalzeit (Tasmanien)", "AEST", - "\u00D6stliche Sommerzeit (Tasmanien)", "AEDT", - "\u00D6stliche Zeitzone (Tasmanien)", "AET"}; - String TMT[] = new String[] {"Turkmenische Zeit", "TMT", - "Turkmenische Sommerzeit", "TMST", - "Turkmenische Zeit", "TMT"}; - String ULAT[]= new String[] {"Ulaanbaatar Zeit", "ULAT", - "Ulaanbaatar Sommerzeit", "ULAST", - "Ulaanbaatar Zeit", "ULAT"}; - String WAT[] = new String[] {"Westafrikanische Zeit", "WAT", - "Westafrikanische Sommerzeit", "WAST", - "Westafrikanische Zeit", "WAT"}; - String WET[] = new String[] {"Westeurop\u00e4ische Zeit", "WEZ", - "Westeurop\u00e4ische Sommerzeit", "WESZ", - "Westeurop\u00E4ische Zeit", "WEZ"}; - String WGT[] = new String[] {"Westgr\u00f6nl\u00e4ndische Zeit", "WGT", - "Westgr\u00f6nl\u00e4ndische Sommerzeit", "WGST", - "Westgr\u00F6nl\u00E4ndische Zeit", "WGT"}; - String WIT[] = new String[] {"Westindonesische Zeit", "WIB", - "Westindonesische Sommerzeit", "WIST", - "Westindonesische Zeit", "WIB"}; - String WST_AUS[] = new String[] {"Westliche Normalzeit (Australien)", "AWST", - "Westliche Sommerzeit (Australien)", "AWDT", - "Westliche Zeitzone (Australien)", "AWT"}; - String SAMOA[] = new String[] {"Samoa Normalzeit", "SST", - "Samoa Sommerzeit", "SDT", - "Zeitzone f\u00FCr Samoa", "ST"}; - String WST_SAMOA[] = new String[] {"West Samoa Zeit", "WSST", - "West Samoa Sommerzeit", "WSDT", - "West Samoa Zeit", "WST"}; - String ChST[] = new String[] {"Chamorro Normalzeit", "ChST", - "Chamorro Sommerzeit", "ChDT", - "Zeitzone f\u00FCr die Marianen", "ChT"}; - String VICTORIA[] = new String[] {"\u00D6stliche Normalzeit (Victoria)", "AEST", - "\u00D6stliche Sommerzeit (Victoria)", "AEDT", - "\u00D6stliche Zeitzone (Victoria)", "AET"}; - String UTC[] = new String[] {"Koordinierte Universalzeit", "UTC", - "Koordinierte Universalzeit", "UTC", - "Koordinierte Universalzeit", "UTC"}; - String UZT[] = new String[] {"Usbekistan Zeit", "UZT", - "Usbekistan Sommerzeit", "UZST", - "Usbekistan Zeit", "UZT"}; - String XJT[] = new String[] {"Chinesische Normalzeit", "XJT", - "Chinesische Sommerzeit", "XJDT", - "Zeitzone f\u00FCr China", "XJT"}; - String YAKT[] = new String[] {"Jakutsk Zeit", "YAKT", - "Jakutsk Sommerzeit", "YAKST", - "Jakutsk Zeit", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Paraguay Zeit", "PYT", - "Paraguay Sommerzeit", "PYST", - "Paraguay Zeit", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Kolumbianische Zeit", "COT", - "Kolumbianische Sommerzeit", "COST", - "Kolumbianische Zeit", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Venezuelanische Zeit", "VET", - "Venezuelanische Sommerzeit", "VEST", - "Venezuelanische Zeit", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Franz\u00f6sisch-Guiana Zeit", "GFT", - "Franz\u00f6sisch-Guiana Sommerzeit", "GFST", - "Franz\u00F6sisch-Guiana Zeit", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Ecuadorianische Zeit", "ECT", - "Ecuadorianische Sommerzeit", "ECST", - "Ecuadorianische Zeit", "ECT"}}, - {"America/Guyana", new String[] {"Guyanische Zeit", "GYT", - "Guyanische Sommerzeit", "GYST", - "Guyanische Zeit", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Bolivianische Zeit", "BOT", - "Bolivianische Sommerzeit", "BOST", - "Bolivianische Zeit", "BOT"}}, - {"America/Lima", new String[] {"Peruanische Zeit", "PET", - "Peruanische Sommerzeit", "PEST", - "Peruanische Zeit", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Pierre & Miquelon Normalzeit", "PMST", - "Pierre & Miquelon Sommerzeit", "PMDT", - "Zeitzone f\u00FCr St. Pierre und Miquelon", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Uruguayische Zeit", "UYT", - "Uruguayische Sommerzeit", "UYST", - "Uruguayanische Zeit", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Suriname Zeit", "SRT", - "Suriname Sommerzeit", "SRST", - "Suriname Zeit", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT", - "Davis Sommerzeit", "DAVST", - "Davis Zeit", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT", - "Dumont-d'Urville Sommerzeit", "DDUST", - "Dumont-d'Urville Zeit", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Mawson Zeit", "MAWT", - "Mawson Sommerzeit", "MAWST", - "Mawson Zeit", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Rothera Zeit", "ROTT", - "Rothera Sommerzeit", "ROTST", - "Rothera Zeit", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Syowa Zeit", "SYOT", - "Syowa Sommerzeit", "SYOST", - "Syowa Zeit", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Koordinierte Universalzeit", "UTC", - "Mitteleurop\u00e4ische Sommerzeit", "MESZ", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Vostok Zeit", "VOST", - "Vostok Sommerzeit", "VOSST", - "Vostok Zeit", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Alma Ata Zeit", "ALMT", - "Alma-Ata Sommerzeit", "ALMST", - "Alma Ata Zeit", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Anadyr Zeit", "ANAT", - "Anadyr Sommerzeit", "ANAST", - "Anadyr Zeit", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Aqtau Zeit", "AQTT", - "Aqtau Sommerzeit", "AQTST", - "Aqtau Zeit", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Aqtobe Zeit", "AQTT", - "Aqtobe Sommerzeit", "AQTST", - "Aqtobe Zeit", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Aserbaidschanische Zeit", "AZT", - "Aserbaidschanische Sommerzeit", "AZST", - "Aserbaidschanische Zeit", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Kirgisische Zeit", "KGT", - "Kirgisische Sommerzeit", "KGST", - "Kirgisische Zeit", "KGT"}}, - {"Asia/Brunei", new String[] {"Brunei Zeit", "BNT", - "Brunei Sommerzeit", "BNST", - "Brunei Zeit", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Choibalsan Zeit", "CHOT", - "Choibalsan Sommerzeit", "CHOST", - "Choibalsan Zeit", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Timor-Leste Normalzeit", "TLT", - "Timor-Leste Sommerzeit", "TLST", - "Timor-Leste Normalzeit", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Tadschikische Zeit", "TJT", - "Tadschikische Sommerzeit", "TJST", - "Tadschikische Zeit", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Hovd Zeit", "HOVT", - "Hovd Sommerzeit", "HOVST", - "Hovd Zeit", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"Ostindonesische Zeit", "WIT", - "Ostindonesische Sommerzeit", "EIST", - "Ostindonesische Zeit", "WIT"}}, - {"Asia/Kabul", new String[] {"Afghanistanische Zeit", "AFT", - "Afghanistanische Sommerzeit", "AFST", - "Afghanistanische Zeit", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Petropawlowsk-Kamtschatkische Zeit", "PETT", - "Petropawlowsk-Kamtschatkische Sommerzeit", "PETST", - "Petropawlowsk-Kamtschatkische Zeit", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Magadanische Zeit", "MAGT", - "Magadanische Sommerzeit", "MAGST", - "Magadanische Zeit", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Oral Zeit", "ORAT", - "Oral Sommerzeit", "ORAST", - "Oral Zeit", "ORAT"}}, - {"Asia/Omsk", new String[] {"Omsk Zeit", "OMST", - "Omsk Sommerzeit", "OMSST", - "Omsk Zeit", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Qyzylorda Zeit", "QYZT", - "Qyzylorda Sommerzeit", "QYZST", - "Qyzylorda Zeit", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Sakhalin Zeit", "SAKT", - "Sakhalin Sommerzeit", "SAKST", - "Sakhalin Zeit", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Georgische Zeit", "GET", - "Georgische Sommerzeit", "GEST", - "Georgische Zeit", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Ust-Nera Zeit", "VLAT", - "Ust-Nera Sommerzeit", "VLAST", - "Ust-Nera Zeit", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Wladiwostok Zeit", "VLAT", - "Wladiwostok Sommerzeit", "VLAST", - "Wladiwostok Zeit", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Jekaterinburger Zeit", "YEKT", - "Jekaterinburger Sommerzeit", "YEKST", - "Jekaterinburger Zeit", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Azoren Zeit", "AZOT", - "Azoren Sommerzeit", "AZOST", - "Azoren Zeit", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Kap Verde Zeit", "CVT", - "Kap Verde Sommerzeit", "CVST", - "Kap Verde Zeit", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"South Georgia Normalzeit", "GST", - "South Georgia Sommerzeit", "GDT", - "Zeitzone f\u00FCr S\u00FCdgeorgien", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Falkland Inseln Zeit", "FKT", - "Falkland Inseln Sommerzeit", "FKST", - "Falkland Inseln Zeit", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Zentral-Westliche Normalzeit (Australien)", "ACWST", - "Zentral-Westliche Sommerzeit (Australien)", "ACWDT", - "Zentral-Westliche Normalzeit (Australien)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Samarische Zeit", "SAMT", - "Samarische Sommerzeit", "SAMST", - "Samarische Zeit", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Indischer Ozean Territorium Zeit", "IOT", - "Indischer Ozean Territorium Sommerzeit", "IOST", - "Indischer Ozean Territorium Zeit", "IOT"}}, - {"Indian/Christmas", new String[] {"Christmas Island Zeit", "CXT", - "Christmas Island Sommerzeit", "CXST", - "Weihnachtsinseln Zeit", "CIT"}}, - {"Indian/Cocos", new String[] {"Cocos Islands Zeit", "CCT", - "Cocos Islands Sommerzeit", "CCST", - "Kokos-Inseln Zeit", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Franz\u00f6sisch S\u00fcd- u. Antarktische Landzeit", "TFT", - "Franz\u00f6sisch S\u00fcd- u. Antarktische Landsommerzeit", "TFST", - "Franz\u00F6sisch S\u00FCd- u. Antarktische Landzeit", "TFT"}}, - {"Indian/Mahe", new String[] {"Seychellen Zeit", "SCT", - "Seychellen Sommerzeit", "SCST", - "Seychellen Zeit", "SCT"}}, - {"Indian/Maldives", new String[] {"Maledivische Zeit", "MVT", - "Maledivische Sommerzeit", "MVST", - "Maledivische Zeit", "MVT"}}, - {"Indian/Mauritius", new String[] {"Mauritius Zeit", "MUT", - "Mauritius Sommerzeit", "MUST", - "Mauritius Zeit", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Reunion Zeit", "RET", - "Reunion Sommerzeit", "REST", - "R\u00E9union Zeit", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Vanuatu Zeit", "VUT", - "Vanuatu Sommerzeit", "VUST", - "Vanuatu Zeit", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Phoenix Inseln Zeit", "PHOT", - "Phoenix Inseln Sommerzeit", "PHOST", - "Phoenix Inseln Zeit", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Tokelau Zeit", "TKT", - "Tokelau Sommerzeit", "TKST", - "Tokelau Zeit", "TKT"}}, - {"Pacific/Fiji", new String[] {"Fidschi Zeit", "FJT", - "Fidschi Sommerzeit", "FJST", - "Fidschi Zeit", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Tuvalu Zeit", "TVT", - "Tuvalu Sommerzeit", "TVST", - "Tuvalu Zeit", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Galapagos Zeit", "GALT", - "Galapagos Sommerzeit", "GALST", - "Galapagos Zeit", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Line Inseln Zeit", "LINT", - "Line Inseln Sommerzeit", "LINST", - "Line Inseln Zeit", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Kosrae Zeit", "KOST", - "Kosrae Sommerzeit", "KOSST", - "Kosrae Zeit", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Marquesas Zeit", "MART", - "Marquesas Sommerzeit", "MARST", - "Marquesas Zeit", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Nauru Zeit", "NRT", - "Nauru Sommerzeit", "NRST", - "Nauru Zeit", "NRT"}}, - {"Pacific/Niue", new String[] {"Niue Zeit", "NUT", - "Niue Sommerzeit", "NUST", - "Niue Zeit", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Norfolk Zeit", "NFT", - "Norfolk Sommerzeit", "NFST", - "Norfolk Zeit", "NFT"}}, - {"Pacific/Noumea", new String[] {"Neukaledonische Zeit", "NCT", - "Neukaledonische Sommerzeit", "NCST", - "Neukaledonische Zeit", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Palau Zeit", "PWT", - "Palau Sommerzeit", "PWST", - "Palau Zeit", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Papua-Neuguinea Zeit", "PGT", - "Papua-Neuguinea Sommerzeit", "PGST", - "Papua-Neuguinea Zeit", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Cook-Inseln Zeit", "CKT", - "Cook-Inseln Sommerzeit", "CKHST", - "Cook-Inseln Zeit", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Tahiti Zeit", "TAHT", - "Tahiti Sommerzeit", "TAHST", - "Tahiti Zeit", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Gilbert-Inseln Zeit", "GILT", - "Gilbert-Inseln Sommerzeit", "GILST", - "Gilbert-Inseln Zeit", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Tonga Zeit", "TOT", - "Tonga Sommerzeit", "TOST", - "Tonga Zeit", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"Wake Zeit", "WAKT", - "Wake Sommerzeit", "WAKST", - "Wake Zeit", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Wallis u. Futuna Zeit", "WFT", - "Wallis u. Futuna Sommerzeit", "WFST", - "Wallis u. Futuna Zeit", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_CA.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_CA.java deleted file mode 100644 index 0e35d5045d0..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_CA.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_en_CA extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - return new Object[][] { - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_GB.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_GB.java deleted file mode 100644 index 43922dcb032..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_GB.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_en_GB extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - return new Object[][] { - {"Europe/London", new String[] {"Greenwich Mean Time", "GMT", - "British Summer Time", "BST", - "British Time", "BT"}}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_IE.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_IE.java deleted file mode 100644 index e41f889190c..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_en_IE.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_en_IE extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - return new Object[][] { - {"Europe/London", new String[] {"Greenwich Mean Time", "GMT", - "Irish Summer Time", "IST", /*Dublin*/ - "Irish Time", "IT" /*Dublin*/}}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java deleted file mode 100644 index 92dcaca5b1f..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_es extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Hora de Acre", "ACT", - "Hora de verano de Acre", "ACST", - "Hora de Acre", "ACT"}; - String ADELAIDE[] = new String[] {"Hora est\u00E1ndar Central (Sur de Australia)", "ACST", - "Hora de verano Central (Sur de Australia)", "ACDT", - "Hora Central (Australia del Sur)", "ACT"}; - String AGT[] = new String[] {"Hora de Argentina", "ART", - "Hora de verano de Argentina", "ARST", - "Hora de Argentina", "ART"}; - String AKST[] = new String[] {"Hora est\u00e1ndar de Alaska", "AKST", - "Hora de verano de Alaska", "AKDT", - "Hora de Alaska", "AKT"}; - String AMT[] = new String[] {"Hora est\u00e1ndar de Amazonia", "AMT", - "Hora de verano de Amazonia", "AMST", - "Hora est\u00E1ndar de Amazonia", "AMT"}; - String ARAST[] = new String[] {"Hora est\u00e1ndar de Arabia", "AST", - "Hora de verano de Arabia", "ADT", - "Hora de Arabia", "AT"}; - String ARMT[] = new String[] {"Hora de Armenia", "AMT", - "Hora de verano de Armenia", "AMST", - "Hora de Armenia", "AMT"}; - String AST[] = new String[] {"Hora est\u00e1ndar Atl\u00e1ntico", "AST", - "Hora de verano Atl\u00e1ntico", "ADT", - "Hora del Atl\u00E1ntico", "AT"}; - String BDT[] = new String[] {"Hora de Bangladesh", "BDT", - "Hora de verano de Bangladesh", "BDST", - "Hora de Bangladesh", "BDT"}; - String BRISBANE[] = new String[] {"Hora est\u00E1ndar del Este (Queensland)", "AEST", - "Hora est\u00E1ndar de verano del Este (Queensland)", "AEDT", - "Hora Oriental (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Hora est\u00E1ndar Central (Sur de Australia/Nueva Gales del Sur)", "ACST", - "Hora de verano Central (Sur de Australia/Nueva Gales del Sur)", "ACDT", - "Hora Central (Australia del Sur/Nueva Gales del Sur)", "ACT"}; - String BRT[] = new String[] {"Hora de Brasil", "BRT", - "Hora de verano de Brasil", "BRST", - "Hora de Brasil", "BRT"}; - String BTT[] = new String[] {"Hora de But\u00e1n", "BTT", - "Hora de verano de But\u00e1n", "BTST", - "Hora de But\u00E1n", "BTT"}; - String CAT[] = new String[] {"Hora de \u00c1frica Central", "CAT", - "Hora de verano de \u00c1frica Central", "CAST", - "Hora de \u00C1frica Central", "CAT"}; - String CET[] = new String[] {"Hora de Europa Central", "CET", - "Hora de verano de Europa Central", "CEST", - "Hora de Europa Central", "CET"}; - String CHAST[] = new String[] {"Hora est\u00e1ndar de Chatham", "CHAST", - "Hora de verano de Chatham", "CHADT", - "Hora de Chatam", "CHAT"}; - String CHUT[] = new String[] {"Hora de Chuuk", "CHUT", - "Hora de verano de Chuuk", "CHUST", - "Hora de Chuuk", "CHUT"}; - String CIT[] = new String[] {"Hora de Indonesia Central", "WITA", - "Hora de verano de Indonesia Central", "CIST", - "Hora de Indonesia Central", "WITA"}; - String CLT[] = new String[] {"Hora de Chile", "CLT", - "Hora de verano de Chile", "CLST", - "Hora de Chile", "CLT"}; - String CST[] = new String[] {"Hora est\u00e1ndar Central", "CST", - "Hora de verano Central", "CDT", - "Hora Central", "CT"}; - String CTT[] = new String[] {"Hora est\u00e1ndar de China", "CST", - "Hora de verano de China", "CDT", - "Hora de China", "CT"}; - String CUBA[] = new String[] {"Hora est\u00e1ndar de Cuba", "CST", - "Hora de verano de Cuba", "CDT", - "Hora de Cuba", "CT"}; - String DARWIN[] = new String[] {"Hora est\u00E1ndar Central (territorio del Norte)", "ACST", - "Hora de verano Central (territorio del Norte)", "ACDT", - "Hora Central (Territorio Septentrional)", "ACT"}; - String DUBLIN[] = new String[] {"Hora del Meridiano de Greenwich", "GMT", - "Hora de verano de Irlanda", "IST", - "Hora de Irlanda", "IT"}; - String EAT[] = new String[] {"Hora de \u00c1frica Oriental", "EAT", - "Hora de verano de \u00c1frica Oriental", "EAST", - "Hora de \u00C1frica Oriental", "EAT"}; - String EASTER[] = new String[] {"Hora de la Isla de Pascua", "EAST", - "Hora de verano de la Isla de Pascua", "EASST", - "Hora de la Isla de Pascua", "EAST"}; - String EET[] = new String[] {"Hora de Europa Oriental", "EET", - "Hora de verano de Europa Oriental", "EEST", - "Hora de Europa Oriental", "EET"}; - String EGT[] = new String[] {"Hora de Groenlandia Oriental", "EGT", - "Hora de verano de Groenlandia Oriental", "EGST", - "Hora de Groenlandia Oriental", "EGT"}; - String EST[] = new String[] {"Hora est\u00e1ndar Oriental", "EST", - "Hora de verano Oriental", "EDT", - "Hora Oriental", "ET"}; - String EST_NSW[] = new String[] {"Hora est\u00E1ndar Oriental (Nueva Gales del Sur)", "AEST", - "Hora de verano Oriental (Nueva Gales del Sur)", "AEDT", - "Hora Oriental (Nueva Gales del Sur)", "AET"}; - String FET[] = new String[] {"Hora de Europa m\u00E1s Oriental", "FET", - "Hora de verano de Europa m\u00E1s Oriental", "FEST", - "Hora de Europa m\u00E1s Oriental", "FET"}; - String GHMT[] = new String[] {"Hora central de Ghana", "GMT", - "Hora de verano de Ghana", "GHST", - "Hora central de Ghana", "GMT"}; - String GAMBIER[] = new String[] {"Hora de Gambier", "GAMT", - "Hora de verano de Gambier", "GAMST", - "Hora de Gambier", "GAMT"}; - String GMT[] = new String[] {"Hora del Meridiano de Greenwich", "GMT", - "Hora del Meridiano de Greenwich", "GMT", - "Hora del Meridiano de Greenwich", "GMT"}; - String GMTBST[] = new String[] {"Hora del Meridiano de Greenwich", "GMT", - "Hora de verano de Gran Breta\u00f1a", "BST", - "Hora de Gran Breta\u00F1a", "BT"}; - String GST[] = new String[] {"Hora est\u00e1ndar del Golfo", "GST", - "Hora de verano del Golfo", "GDT", - "Hora del Golfo", "GT"}; - String HKT[] = new String[] {"Hora de Hong Kong", "HKT", - "Hora de verano de Hong Kong", "HKST", - "Hora de Hong Kong", "HKT"}; - String HST[] = new String[] {"Hora est\u00e1ndar de Hawaii", "HST", - "Hora de verano de Hawaii", "HDT", - "Hora de Hawaii", "HT"}; - String ICT[] = new String[] {"Hora de Indochina", "ICT", - "Hora de verano de Indochina", "ICST", - "Hora de Indochina", "ICT"}; - String IRKT[] = new String[] {"Hora de Irkutsk", "IRKT", - "Hora de verano de Irkutsk", "IRKST", - "Hora de Irkutsk", "IRKT"}; - String IRT[] = new String[] {"Hora est\u00e1ndar de Ir\u00e1n", "IRST", - "Hora de verano de Ir\u00e1n", "IRDT", - "Hora de Ir\u00E1n", "IRT"}; - String ISRAEL[] = new String[] {"Hora est\u00e1ndar de Israel", "IST", - "Hora de verano de Israel", "IDT", - "Hora de Israel", "IT"}; - String IST[] = new String[] {"Hora est\u00e1ndar de India", "IST", - "Hora de verano de India", "IDT", - "Hora de India", "IT"}; - String JST[] = new String[] {"Hora est\u00e1ndar de Jap\u00f3n", "JST", - "Hora de verano de Jap\u00f3n", "JDT", - "Hora de Jap\u00F3n", "JT"}; - String KRAT[] = new String[] {"Hora de Krasnoyarsk", "KRAT", - "Hora de verano de Krasnoyarsk", "KRAST", - "Hora de Krasnoyarsk", "KRAT"}; - String KST[] = new String[] {"Hora est\u00e1ndar de Corea", "KST", - "Hora de verano de Corea", "KDT", - "Hora de Corea", "KT"}; - String LORD_HOWE[] = new String[] {"Hora est\u00e1ndar de Lord Howe", "LHST", - "Hora de verano de Lord Howe", "LHDT", - "Hora de Lord Howe", "LHT"}; - String MHT[] = new String[] {"Hora de las Islas Marshall", "MHT", - "Hora de verano de las Islas Marshall", "MHST", - "Hora de Islas Marshall", "MHT"}; - String MMT[] = new String[] {"Hora de Myanmar", "MMT", - "Hora de verano de Myanmar", "MMST", - "Hora de Myanmar", "MMT"}; - String MSK[] = new String[] {"Hora est\u00e1ndar de Mosc\u00fa", "MSK", - "Hora de verano de Mosc\u00fa", "MSD", - "Hora de Mosc\u00FA", "MT"}; - String MST[] = new String[] {"Hora est\u00e1ndar de las Rocosas", "MST", - "Hora de verano de las Rocosas", "MDT", - "Hora de las Monta\u00F1as Rocosas", "MT"}; - String MYT[] = new String[] {"Hora de Malasia", "MYT", - "Hora de verano de Malasia", "MYST", - "Hora de Malasia", "MYT"}; - String NORONHA[] = new String[] {"Hora de Fernando de Noronha", "FNT", - "Hora de verano de Fernando de Noronha", "FNST", - "Hora de Fernando de Noronha", "FNT"}; - String NOVT[] = new String[] {"Hora de Novosibirsk", "NOVT", - "Hora de verano de Novosibirsk", "NOVST", - "Hora de Novosibirsk", "NOVT"}; - String NPT[] = new String[] {"Hora de Nepal", "NPT", - "Hora de verano de Nepal", "NPST", - "Hora de Nepal", "NPT"}; - String NST[] = new String[] {"Hora est\u00e1ndar de Terranova", "NST", - "Hora de verano de Terranova", "NDT", - "Hora de Terranova", "NT"}; - String NZST[] = new String[] {"Hora est\u00e1ndar de Nueva Zelanda", "NZST", - "Hora de verano de Nueva Zelanda", "NZDT", - "Hora de Nueva Zelanda", "NZT"}; - String PITCAIRN[] = new String[] {"Hora est\u00e1ndar de Pitcairn", "PST", - "Hora de verano de Pitcairn", "PDT", - "Hora de Islas Pitcairn", "PT"}; - String PKT[] = new String[] {"Hora de Pakist\u00e1n", "PKT", - "Hora de verano de Pakist\u00e1n", "PKST", - "Hora de Pakist\u00E1n", "PKT"}; - String PONT[] = new String[] {"Hora de Pohnpei", "PONT", - "Hora de verano de Pohnpei", "PONST", - "Hora de Pohnpei", "PONT"}; - String PST[] = new String[] {"Hora est\u00e1ndar del Pac\u00edfico", "PST", - "Hora de verano del Pac\u00edfico", "PDT", - "Hora del Pac\u00EDfico", "PT"}; - String SAST[] = new String[] {"Hora est\u00e1ndar de Sud\u00e1frica", "SAST", - "Hora de verano de Sud\u00e1frica", "SAST", - "Hora de Sud\u00E1frica", "SAT"}; - String SBT[] = new String[] {"Hora de las Islas Solomon", "SBT", - "Hora de verano de las Islas Solomon", "SBST", - "Hora de las Islas Solomon", "SBT"}; - String SGT[] = new String[] {"Hora de Singapur", "SGT", - "Hora de verano de Singapur", "SGST", - "Hora de Singapur", "SGT"}; - String TASMANIA[] = new String[] {"Hora est\u00E1ndar del Este (Tasmania)", "AEST", - "Hora de verano del Este (Tasmania)", "AEDT", - "Hora Oriental (Tasmania)", "AET"}; - String TMT[] = new String[] {"Hora de Turkmenist\u00e1n", "TMT", - "Hora de verano de Turkmenist\u00e1n", "TMST", - "Hora de Turkmenist\u00E1n", "TMT"}; - String ULAT[]= new String[] {"Hora de Ulan Bator", "ULAT", - "Hora de verano de Ulan Bator", "ULAST", - "Hora de Ulan Bator", "ULAT"}; - String WAT[] = new String[] {"Hora de \u00c1frica Occidental", "WAT", - "Hora de verano de \u00c1frica Occidental", "WAST", - "Hora de \u00C1frica Occidental", "WAT"}; - String WET[] = new String[] {"Hora de Europa Occidental", "WET", - "Hora de verano de Europa Occidental", "WEST", - "Hora de Europa Occidental", "WET"}; - String WGT[] = new String[] {"Hora de Groenlandia Occidental", "WGT", - "Hora de verano de Groenlandia Occidental", "WGST", - "Hora de Groenlandia Occidental", "WGT"}; - String WIT[] = new String[] {"Hora de Indonesia Occidental", "WIB", - "Indonesia Hora de verano de Indonesia Occidental", "WIST", - "Hora de Indonesia Occidental", "WIB"}; - String WST_AUS[] = new String[] {"Hora est\u00E1ndar Occidental (Australia)", "AWST", - "Hora de verano Occidental (Australia)", "AWDT", - "Hora Occidental (Australia)", "AWT"}; - String SAMOA[] = new String[] {"Hora est\u00e1ndar de Samoa", "SST", - "Hora de verano de Samoa", "SDT", - "Hora de Samoa", "ST"}; - String WST_SAMOA[] = new String[] {"Hora de Samoa Occidental", "WSST", - "Hora de verano de Samoa Occidental", "WSDT", - "Hora de Samoa Occidental", "WST"}; - String ChST[] = new String[] {"Hora est\u00e1ndar de Chamorro", "ChST", - "Hora de verano de Chamorro", "ChDT", - "Hora de Chamorro", "ChT"}; - String VICTORIA[] = new String[] {"Hora est\u00E1ndar del Este (Victoria)", "AEST", - "Hora de verano del Este (Victoria)", "AEDT", - "Hora Oriental (Victoria)", "AET"}; - String UTC[] = new String[] {"Hora Universal Coordinada", "UTC", - "Hora Universal Coordinada", "UTC", - "Hora Universal Coordinada", "UTC"}; - String UZT[] = new String[] {"Hora de Uzbekist\u00e1n", "UZT", - "Hora de verano de Uzbekist\u00e1n", "UZST", - "Hora de Uzbekist\u00E1n", "UZT"}; - String XJT[] = new String[] {"Hora est\u00e1ndar de China", "XJT", - "Hora de verano de China", "XJDT", - "Hora de China", "XJT"}; - String YAKT[] = new String[] {"Hora de Yakutsk", "YAKT", - "Hora de verano de Yakutsk", "YAKST", - "Hora de Yakutsk", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Hora de Paraguay", "PYT", - "Hora de verano de Paraguay", "PYST", - "Hora de Paraguay", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Hora de Colombia", "COT", - "Hora de verano de Colombia", "COST", - "Hora de Colombia", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Hora de Venezuela", "VET", - "Hora de verano de Venezuela", "VEST", - "Hora de Venezuela", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Hora de la Guayana Francesa", "GFT", - "Hora de verano de la Guayana Francesa", "GFST", - "Hora de la Guayana Francesa", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Hora de Ecuador", "ECT", - "Hora de verano de Ecuador", "ECST", - "Hora de Ecuador", "ECT"}}, - {"America/Guyana", new String[] {"Hora de Guyana", "GYT", - "Hora de verano de Guyana", "GYST", - "Hora de Guyana", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Hora de Bolivia", "BOT", - "Hora de verano de Bolivia", "BOST", - "Hora de Bolivia", "BOT"}}, - {"America/Lima", new String[] {"Hora de Per\u00fa", "PET", - "Hora de verano de Per\u00fa", "PEST", - "Hora de Per\u00FA", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Hora est\u00e1ndar de Pierre & Miquelon", "PMST", - "Hora de verano de Pierre & Miquelon", "PMDT", - "Hora de San Pedro y Miquel\u00F3n", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Hora de Uruguay", "UYT", - "Hora de verano de Uruguay", "UYST", - "Hora de Uruguay", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Hora de Surinam", "SRT", - "Hora de verano de Surinam", "SRST", - "Hora de Surinam", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT", - "Hora de verano de Davis", "DAVST", - "Hora de Davis", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT", - "Hora de verano de Dumont-d'Urville", "DDUST", - "Hora de Dumont-d'Urville", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Hora de Mawson", "MAWT", - "Hora de verano de Mawson", "MAWST", - "Hora de Mawson", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Hora de Rothera", "ROTT", - "Hora de verano de Rothera", "ROTST", - "Hora de Rothera", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Hora de Syowa", "SYOT", - "Hora de verano de Syowa", "SYOST", - "Hora de Syowa", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Hora Universal Coordinada", "UTC", - "Hora de verano de Europa Central", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Hora de Vostok", "VOST", - "Hora de verano de Vostok", "VOSST", - "Hora de Vostok", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Hora de Alma-Ata", "ALMT", - "Hora de verano de Alma-Ata", "ALMST", - "Hora de Alma-Ata", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Hora de Anadyr", "ANAT", - "Hora de verano de Anadyr", "ANAST", - "Hora de Anadyr", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Hora de Aqtau", "AQTT", - "Hora de verano de Aqtau", "AQTST", - "Hora de Aqtau", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Hora de Aqtobe", "AQTT", - "Hora de verano de Aqtobe", "AQTST", - "Hora de Aqtobe", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Hora de Azerbaiy\u00e1n", "AZT", - "Hora de verano de Azerbaiy\u00e1n", "AZST", - "Hora de Azerbaiy\u00E1n", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Hora de Kirguizist\u00e1n", "KGT", - "Hora de verano de Kirguizist\u00e1n", "KGST", - "Hora de Kirguizist\u00E1n", "KGT"}}, - {"Asia/Brunei", new String[] {"Hora de Brunei", "BNT", - "Hora de verano de Brunei", "BNST", - "Hora de Brunei", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Hora de Choibalsan", "CHOT", - "Hora de verano de Choibalsan", "CHOST", - "Hora de Choibalsan", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Hora de Timor Leste", "TLT", - "Hora de verano de Timor Leste", "TLST", - "Hora de Timor Leste", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Hora de Tajikist\u00e1n", "TJT", - "Hora de verano de Tajikist\u00e1n", "TJST", - "Hora de Tajikist\u00E1n", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Hora de Hovd", "HOVT", - "Hora de verano de Hovd", "HOVST", - "Hora de Hovd", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"Hora de Indonesia Oriental", "WIT", - "Hora de verano de Indonesia Oriental", "EIST", - "Hora de Indonesia Oriental", "WIT"}}, - {"Asia/Kabul", new String[] {"Hora de Afganist\u00e1n", "AFT", - "Hora de verano de Afganist\u00e1n", "AFST", - "Hora de Afganist\u00E1n", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Hora de Petropavlovsk-Kamchatski", "PETT", - "Hora de verano de Petropavlovsk-Kamchatski", "PETST", - "Hora de Petropavlovsk-Kamchatski", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Hora de Magad\u00e1n", "MAGT", - "Hora de verano de Magad\u00e1n", "MAGST", - "Hora de Magad\u00E1n", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT", - "Hora de verano de Uralsk", "ORAST", - "Hora de Uralsk", "ORAT"}}, - {"Asia/Omsk", new String[] {"Hora de Omsk", "OMST", - "Hora de verano de Omsk", "OMSST", - "Hora de Omsk", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Hora de Qyzylorda", "QYZT", - "Hora de verano de Qyzylorda", "QYZST", - "Hora de Qyzylorda", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Hora de Sajalin", "SAKT", - "Hora de verano de Sajalin", "SAKST", - "Hora de Sajalin", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Hora de Georgia", "GET", - "Hora de verano de Georgia", "GEST", - "Hora de Georgia", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Hora de Ust-Nera", "VLAT", - "Hora de verano de Ust-Nera", "VLAST", - "Hora de Ust-Nera", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Hora de Vladivostok", "VLAT", - "Hora de verano de Vladivostok", "VLAST", - "Hora de Vladivostok", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Hora de Ekaterinburgo", "YEKT", - "Hora de verano de Ekaterinburgo", "YEKST", - "Hora de Ekaterinburgo", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Hora de Azores", "AZOT", - "Hora de verano de Azores", "AZOST", - "Hora de Azores", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Hora de Cabo Verde", "CVT", - "Hora de verano de Cabo Verde", "CVST", - "Hora de Cabo Verde", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"Hora est\u00e1ndar de Georgia del Sur", "GST", - "Hora de verano de Georgia del Sur", "GDT", - "Hora de Georgia del Sur", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Hora de las islas Malvinas", "FKT", - "Hora de verano de las islas Malvinas", "FKST", - "Hora de las islas Malvinas", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Hora est\u00E1ndar de Australia Central y Occidental", "ACWST", - "Hora est\u00E1ndar de verano de Australia Central y Occidental", "ACWDT", - "Hora de Australia Central y Occidental", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Hora de Samara", "SAMT", - "Hora de verano de Samara", "SAMST", - "Hora de Samara", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Hora del Territorio del Oc\u00e9ano \u00cdndico", "IOT", - "Hora de verano del Territorio del Oc\u00e9ano \u00cdndico", "IOST", - "Hora del Territorio del Oc\u00E9ano \u00CDndico", "IOT"}}, - {"Indian/Christmas", new String[] {"Hora de la isla de Christmas", "CXT", - "Hora de verano de la isla de Christmas", "CXST", - "Hora de la isla de Christmas", "CIT"}}, - {"Indian/Cocos", new String[] {"Hora de las islas Cocos", "CCT", - "Hora de verano de las islas Cocos", "CCST", - "Hora de las islas Cocos", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Hora de los Territorios Franceses del Sur y de la Ant\u00e1rtida", "TFT", - "Hora de verano de los Territorios Franceses del Sur y de la Ant\u00e1rtida", "TFST", - "Hora de los Territorios Franceses del Sur y de la Ant\u00E1rtida", "TFT"}}, - {"Indian/Mahe", new String[] {"Hora de Seychelles", "SCT", - "Hora de verano de Seychelles", "SCST", - "Hora de Seychelles", "SCT"}}, - {"Indian/Maldives", new String[] {"Hora de Maldivas", "MVT", - "Hora de verano de Maldivas", "MVST", - "Hora de Maldivas", "MVT"}}, - {"Indian/Mauritius", new String[] {"Hora de Mauricio", "MUT", - "Hora de verano de Mauricio", "MUST", - "Hora de Mauricio", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Hora de Reuni\u00f3n", "RET", - "Hora de verano de Reuni\u00f3n", "REST", - "Hora de Reuni\u00F3n", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Hora de Vanuatu", "VUT", - "Hora de verano de Vanuatu", "VUST", - "Hora de Vanuatu", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Hora de la isla Phoenix", "PHOT", - "Hora de verano de la isla Phoenix", "PHOST", - "Hora de la isla Phoenix", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Hora de Tokelau", "TKT", - "Hora de verano de Tokelau", "TKST", - "Hora de Tokelau", "TKT"}}, - {"Pacific/Fiji", new String[] {"Hora de Fiji", "FJT", - "Hora de verano de Fiji", "FJST", - "Hora de Fiji", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Hora de Tuvalu", "TVT", - "Hora de verano de Tuvalu", "TVST", - "Hora de Tuvalu", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Hora de Gal\u00e1pagos", "GALT", - "Hora de verano de Gal\u00e1pagos", "GALST", - "Hora de Gal\u00E1pagos", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Hora de las islas Line", "LINT", - "Hora de verano de las islas Line", "LINST", - "Hora de las islas Line", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Hora de Kosrae", "KOST", - "Hora de verano de Kosrae", "KOSST", - "Hora de Kosrae", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Hora de Marquesas", "MART", - "Hora de verano de Marquesas", "MARST", - "Hora de Marquesas", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Hora de Nauru", "NRT", - "Hora de verano de Nauru", "NRST", - "Hora de Nauru", "NRT"}}, - {"Pacific/Niue", new String[] {"Hora de Niue", "NUT", - "Hora de verano de Niue", "NUST", - "Hora de Niue", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Hora de Norfolk", "NFT", - "Hora de verano de Norfolk", "NFST", - "Hora de Norfolk", "NFT"}}, - {"Pacific/Noumea", new String[] {"Hora de Nueva Caledonia", "NCT", - "Hora de verano de Nueva Caledonia", "NCST", - "Hora de Nueva Caledonia", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Hora de Palau", "PWT", - "Hora de verano de Palau", "PWST", - "Hora de Palau", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Hora de Pap\u00faa-Nueva Guinea", "PGT", - "Hora de verano de Pap\u00faa-Nueva Guinea", "PGST", - "Hora de Pap\u00FAa-Nueva Guinea", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Hora de las islas Cook", "CKT", - "Hora de verano de las islas Cook", "CKHST", - "Hora de las islas Cook", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Hora de Tahit\u00ed", "TAHT", - "Hora de verano de Tahit\u00ed", "TAHST", - "Hora de Tahit\u00ED", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Hora de las islas Gilbert", "GILT", - "Hora de verano de las islas Gilbert", "GILST", - "Hora de las islas Gilbert", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Hora de Tonga", "TOT", - "Hora de verano de Tonga", "TOST", - "Hora de Tonga", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"Hora de Wake", "WAKT", - "Hora de verano de Wake", "WAKST", - "Hora de Wake", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Hora de Wallis y Futuna", "WFT", - "Hora de verano de Wallis y Futuna", "WFST", - "Hora de Wallis y Futuna", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java deleted file mode 100644 index 7eb166300c2..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_fr extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Heure de l'Acre", "ACT", - "Heure d'\u00e9t\u00e9 de l'Acre", "ACST", - "Heure de l'Acre", "ACT"}; - String ADELAIDE[] = new String[] {"Heure standard d'Australie centrale (Australie du sud)", "ACST", - "Heure d'\u00E9t\u00E9 d'Australie centrale (Australie du sud)", "ACDT", - "Centre (Australie-M\u00E9ridionale)", "ACT"}; - String AGT[] = new String[] {"Heure D'Argentine", "ART", - "Heure d'\u00e9t\u00e9 D'Argentine", "ARST", - "Heure d'Argentine", "ART"} ; - String AKST[] = new String[] {"Heure normale d'Alaska", "AKST", - "Heure avanc\u00e9e d'Alaska", "AKDT", - "Alaska", "AKT"} ; - String AMT[] = new String[] {"Heure normale d'Amazonie", "AMT", - "Heure d'\u00e9t\u00e9 d'Amazonie", "AMST", - "Heure d'Amazonie", "AMT"} ; - String ARAST[] = new String[] {"Heure normale d'Arabie", "AST", - "Heure avanc\u00e9e d'Arabie", "ADT", - "Arabie", "AT"} ; - String ARMT[] = new String[] {"Heure d'Arm\u00e9nie", "AMT", - "Heure d'\u00e9t\u00e9 d'Arm\u00e9nie", "AMST", - "Heure d'Arm\u00E9nie", "AMT"} ; - String AST[] = new String[] {"Heure normale de l'Atlantique", "AST", - "Heure avanc\u00e9e de l'Atlantique", "ADT", - "Atlantique", "AT"} ; - String BDT[] = new String[] {"Heure du Bangladesh", "BDT", - "Heure d'\u00e9t\u00e9 du Bangladesh", "BDST", - "Heure du Bangladesh", "BDT"} ; - String BRISBANE[] = new String[] {"Heure standard d'Australie orientale (Queensland)", "AEST", - "Heure d'\u00E9t\u00E9 d'Australie orientale (Queensland)", "AEDT", - "C\u00F4te Est (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Heure standard d'Australie centrale (Australie du sud/Nouvelle-Galles du sud)", "ACST", - "Heure d'\u00E9t\u00E9 d'Australie centrale (Australie du sud/Nouvelle-Galles du sud)", "ACDT", - "Centre (Australie-M\u00E9ridionale/Nouvelle-Galles du Sud)", "ACT"}; - String BRT[] = new String[] {"Heure du Br\u00e9sil", "BRT", - "Heure d'\u00e9t\u00e9 du Br\u00e9sil", "BRST", - "Heure du Br\u00E9sil", "BRT"} ; - String BTT[] = new String[] {"Heure du Bhoutan", "BTT", - "Heure d'\u00e9t\u00e9 du Bhoutan", "BTST", - "Heure du Bhoutan", "BTT"} ; - String CAT[] = new String[] {"Heure d'Afrique centrale", "CAT", - "Heure d'\u00e9t\u00e9 d'Afrique centrale", "CAST", - "Heure d'Afrique centrale", "CAT"} ; - String CET[] = new String[] {"Heure d'Europe centrale", "CET", - "Heure d'\u00e9t\u00e9 d'Europe centrale", "CEST", - "Heure d'Europe centrale", "CET"} ; - String CHAST[] = new String[] {"Heure standard de Chatham", "CHAST", - "Heure avanc\u00e9e de Chatham", "CHADT", - "Chatham", "CHAT"}; - String CHUT[] = new String[] {"Heure de Chuuk", "CHUT", - "Heure d'\u00E9t\u00E9 de Chuuk", "CHUST", - "Heure de Chuuk", "CHUT"}; - String CIT[] = new String[] {"Heure d'Indon\u00e9sie centrale", "WITA", - "Heure d'\u00e9t\u00e9 d'Indon\u00e9sie centrale", "CIST", - "Heure d'Indon\u00E9sie centrale", "WITA"}; - String CLT[] = new String[] {"Heure du Chili", "CLT", - "Heure d'\u00e9t\u00e9 du Chili", "CLST", - "Heure du Chili", "CLT"} ; - String CST[] = new String[] {"Heure normale du Centre", "CST", - "Heure avanc\u00e9e du Centre", "CDT", - "Centre", "CT"} ; - String CTT[] = new String[] {"Heure normale de Chine", "CST", - "Heure avanc\u00e9e de Chine", "CDT", - "Chine", "CT"} ; - String CUBA[] = new String[] {"Heure standard de Cuba", "CST", - "Heure d'\u00e9t\u00e9 de Cuba", "CDT", - "Heure de Cuba", "CT"}; - String DARWIN[] = new String[] {"Heure standard d'Australie centrale (Territoire du Nord)", "ACST", - "Heure d'\u00E9t\u00E9 d'Australie centrale (Territoire du Nord)", "ACDT", - "Centre (Territoire du Nord)", "ACT"}; - String DUBLIN[] = new String[] {"Heure du m\u00e9ridien de Greenwich", "GMT", - "Heure d'\u00e9t\u00e9 irlandaise", "IST", - "Heure irlandaise", "IT"}; - String EAT[] = new String[] {"Heure d'Afrique de l'Est", "EAT", - "Heure d'\u00e9t\u00e9 d'Afrique de l'Est", "EAST", - "Heure d'Afrique de l'Est", "EAT"} ; - String EASTER[] = new String[] {"Heure de l'Ile de P\u00e2ques", "EAST", - "Heure d'\u00e9t\u00e9 de l'Ile de P\u00e2ques", "EASST", - "Heure de l'Ile de P\u00E2ques", "EAST"}; - String EET[] = new String[] {"Heure d'Europe de l'Est", "EET", - "Heure d'\u00e9t\u00e9 d'Europe de l'Est", "EEST", - "Heure d'Europe de l'Est", "EET"} ; - String EGT[] = new String[] {"Heure du Groenland de l'Est", "EGT", - "Heure d'\u00e9t\u00e9 du Groenland de l'Est", "EGST", - "Heure du Groenland de l'Est", "EGT"} ; - String EST[] = new String[] {"Heure normale de l'Est", "EST", - "Heure avanc\u00e9e de l'Est", "EDT", - "C\u00F4te Est", "ET"} ; - String EST_NSW[] = new String[] {"Heure normale de l'Est (Nouvelle-Galles du Sud)", "AEST", - "Heure d'\u00E9t\u00E9 de l'Est (Nouvelle-Galles du Sud)", "AEDT", - "C\u00F4te Est (Nouvelle-Galles du Sud)", "AET"} ; - String FET[] = new String[] {"Heure d'Europe de l'Est UTC+3", "FET", - "Heure d'\u00E9t\u00E9 d'Europe de l'Est UTC+3", "FEST", - "Heure d'Europe de l'Est UTC+3", "FET"}; - String GHMT[] = new String[] {"Heure du Ghana", "GMT", - "Heure d'\u00e9t\u00e9 du Ghana", "GHST", - "Heure du Ghana", "GMT"}; - String GAMBIER[] = new String[] {"Heure de Gambi", "GAMT", - "Heure d'\u00e9t\u00e9 de Gambi", "GAMST", - "Heure de Gambi", "GAMT"}; - String GMT[] = new String[] {"Heure de Greenwich", "GMT", - "Heure de Greenwich", "GMT", - "Heure de Greenwich", "GMT"} ; - String GMTBST[] = new String[] {"Heure du m\u00e9ridien de Greenwich", "GMT", - "Heure d'\u00e9t\u00e9 britannique", "BST", - "Heure britannique", "BT"}; - String GST[] = new String[] {"Heure normale du Golfe", "GST", - "Heure avanc\u00e9e du Golfe", "GDT", - "Golfe", "GT"} ; - String HKT[] = new String[] {"Heure de Hong Kong", "HKT", - "Heure d'\u00e9t\u00e9 de Hong Kong", "HKST", - "Heure de Hong-Kong", "HKT"}; - String HST[] = new String[] {"Heure normale d'Hawa\u00ef", "HST", - "Heure avanc\u00e9e d'Hawa\u00ef", "HDT", - "Hawa\u00EF", "HT"} ; - String ICT[] = new String[] {"Heure d'Indochine", "ICT", - "Heure d'\u00e9t\u00e9 d'Indochine", "ICST", - "Heure d'Indochine", "ICT"} ; - String IRKT[] = new String[] {"Heure d'Irkutsk", "IRKT", - "Heure d'\u00e9t\u00e9 d'Irkutsk", "IRKST", - "Heure d'Irkutsk", "IRKT"}; - String IRT[] = new String[] {"Heure normale d'Iran", "IRST", - "Heure avanc\u00e9e d'Iran", "IRDT", - "Heure d'Iran", "IRT"} ; - String ISRAEL[] = new String[] {"Heure standard d'Isra\u00ebl", "IST", - "Heure avanc\u00e9e d'Isra\u00ebl", "IDT", - "Isra\u00EBl", "IT"}; - String IST[] = new String[] {"Heure normale d'Inde", "IST", - "Heure avanc\u00e9e d'Inde", "IDT", - "Inde", "IT"} ; - String JST[] = new String[] {"Heure normale du Japon", "JST", - "Heure avanc\u00e9e du Japon", "JDT", - "Japon", "JT"} ; - String KRAT[] = new String[] {"Heure de Krasno\u00efarsk", "KRAT", - "Heure d'\u00e9t\u00e9 de Krasno\u00efarsk", "KRAST", - "Heure de Krasno\u00EFarsk", "KRAT"}; - String KST[] = new String[] {"Heure normale de Cor\u00e9e", "KST", - "Heure avanc\u00e9e de Cor\u00e9e", "KDT", - "Cor\u00E9e", "KT"} ; - String LORD_HOWE[] = new String[] {"Heure standard de Lord Howe", "LHST", - "Heure d'\u00e9t\u00e9 de Lord Howe", "LHDT", - "Heure de Lord Howe", "LHT"}; - String MHT[] = new String[] {"Heure des Iles Marshall", "MHT", - "Heure d'\u00e9t\u00e9 des Iles Marshall", "MHST", - "Heure des Iles Marshall", "MHT"}; - String MMT[] = new String[] {"Heure de Myanmar", "MMT", - "Heure d'\u00e9t\u00e9 de Myanmar", "MMST", - "Heure de Myanmar", "MMT"}; - String MSK[] = new String[] {"Heure standard de Moscou", "MSK", - "Heure avanc\u00e9e de Moscou", "MSD", - "Moscou", "MT"}; - String MST[] = new String[] {"Heure normale des Rocheuses", "MST", - "Heure avanc\u00e9e des Rocheuses", "MDT", - "Rocheuses", "MT"} ; - String MYT[] = new String[] {"Heure de Malaisie", "MYT", - "Heure d'\u00e9t\u00e9 de Malaisie", "MYST", - "Heure de Malaisie", "MYT"}; - String NORONHA[] = new String[] {"Heure de Fernando de Noronha", "FNT", - "Heure d'\u00e9t\u00e9 de Fernando de Noronha", "FNST", - "Heure de Fernando de Noronha", "FNT"}; - String NOVT[] = new String[] {"Heure de Novossibirsk", "NOVT", - "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST", - "Heure de Novossibirsk", "NOVT"}; - String NPT[] = new String[] {"Heure du N\u00e9pal", "NPT", - "Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST", - "Heure du N\u00E9pal", "NPT"}; - String NST[] = new String[] {"Heure normale de Terre-Neuve", "NST", - "Heure avanc\u00e9e de Terre-Neuve", "NDT", - "Terre-Neuve", "NT"} ; - String NZST[] = new String[] {"Heure normale de Nouvelle-Z\u00e9lande", "NZST", - "Heure avanc\u00e9e de Nouvelle-Z\u00e9lande", "NZDT", - "Nouvelle-Z\u00E9lande", "NZT"} ; - String PITCAIRN[] = new String[] {"Heure standard des Pitcairn", "PST", - "heure avanc\u00e9e des Pitcairn", "PDT", - "Pitcairn", "PT"}; - String PKT[] = new String[] {"Heure du Pakistan", "PKT", - "Heure d'\u00e9t\u00e9 du Pakistan", "PKST", - "Heure du Pakistan", "PKT"} ; - String PONT[] = new String[] {"Heure de Pohnpei", "PONT", - "Heure d'\u00E9t\u00E9 de Pohnpei", "PONST", - "Ponape", "PONT"}; - String PST[] = new String[] {"Heure normale du Pacifique", "PST", - "Heure avanc\u00e9e du Pacifique", "PDT", - "Pacifique", "PT"} ; - String SAST[] = new String[] {"Heure normale d'Afrique du Sud", "SAST", - "Heure d'\u00e9t\u00e9 d'Afrique du Sud", "SAST", - "Afrique du Sud", "SAT"} ; - String SBT[] = new String[] {"Heure des \u00celes Salomon", "SBT", - "Heure d'\u00e9t\u00e9 des \u00celes Salomon", "SBST", - "Heure des Iles Salomon", "SBT"} ; - String SGT[] = new String[] {"Heure de Singapour", "SGT", - "Heure d'\u00e9t\u00e9 de Singapour", "SGST", - "Heure de Singapour", "SGT"}; - String TASMANIA[] = new String[] {"Heure standard d'Australie orientale (Tasmanie)", "AEST", - "Heure d'\u00E9t\u00E9 d'Australie orientale (Tasmanie)", "AEDT", - "C\u00F4te Est (Tasmanie)", "AET"}; - String TMT[] = new String[] {"Heure du Turkm\u00e9nistan", "TMT", - "Heure d'\u00e9t\u00e9 du Turkm\u00e9nistan", "TMST", - "Heure du Turkm\u00E9nistan", "TMT"} ; - String ULAT[]= new String[] {"Heure de l'Ulaanbaatar", "ULAT", - "Heure d'\u00e9t\u00e9 de l'Ulaanbaatar", "ULAST", - "Heure de l'Ulaanbaatar", "ULAT"} ; - String WAT[] = new String[] {"Heure d'Afrique de l'Ouest", "WAT", - "Heure d'\u00e9t\u00e9 d'Afrique de l'Ouest", "WAST", - "Heure d'Afrique de l'Ouest", "WAT"} ; - String WET[] = new String[] {"Heure d'Europe de l'Ouest", "WET", - "Heure d'\u00e9t\u00e9 d'Europe de l'Ouest", "WEST", - "Heure d'Europe de l'Ouest", "WET"} ; - String WGT[] = new String[] {"Heure du Groenland de l'Ouest", "WGT", - "Heure d'\u00e9t\u00e9 du Groenland de l'Ouest", "WGST", - "Heure du Groenland de l'Ouest", "WGT"}; - String WIT[] = new String[] {"Heure de l'Indon\u00e9sie occidentale", "WIB", - "Heure d'\u00e9t\u00e9 de l'Indon\u00e9sie occidentale", "WIST", - "Heure de l'Indon\u00E9sie occidentale", "WIB"}; - String WST_AUS[] = new String[] {"Heure normale de l'Ouest (Australie)", "AWST", - "Heure d'\u00E9t\u00E9 de l'Ouest (Australie)", "AWDT", - "Ouest (Australie)", "AWT"} ; - String SAMOA[] = new String[] {"Heure standard de Samoa", "SST", - "Heure avanc\u00e9e de Samoa", "SDT", - "Samoa", "ST"}; - String WST_SAMOA[] = new String[] {"Heure des Samoas occidentales", "WSST", - "Heure d'\u00e9t\u00e9 des Samoas occidentales", "WSDT", - "Heure des Samoas occidentales", "WST"} ; - String ChST[] = new String[] {"Heure normale des \u00eeles Mariannes", "ChST", - "Heure d'\u00e9t\u00e9 des \u00eeles Mariannes", "ChDT", - "Chamorro", "ChT"}; - String VICTORIA[] = new String[] {"Heure standard d'Australie orientale (Victoria)", "AEST", - "Heure d'\u00E9t\u00E9 d'Australie orientale (Victoria)", "AEDT", - "C\u00F4te Est (Victoria)", "AET"}; - String UTC[] = new String[] {"Temps universel coordonn\u00e9", "UTC", - "Temps universel coordonn\u00e9", "UTC", - "Temps universel coordonn\u00E9", "UTC"}; - String UZT[] = new String[] {"Heure de l'Ouzb\u00e9kistan", "UZT", - "Heure d'\u00e9t\u00e9 de l'Ouzb\u00e9kistan", "UZST", - "Heure de l'Ouzb\u00E9kistan", "UZT"}; - String XJT[] = new String[] {"Heure normale de Chine", "XJT", - "Heure avanc\u00e9e de Chine", "XJDT", - "Chine", "XJT"}; - String YAKT[] = new String[] {"Heure du Iakoutsk", "YAKT", - "Heure d'\u00e9t\u00e9 du Iakoutsk", "YAKST", - "Heure du Iakoutsk", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Heure du Paraguay", "PYT", - "Heure d'\u00e9t\u00e9 du Paraguay", "PYST", - "Heure du Paraguay", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Heure de Colombie", "COT", - "Heure d'\u00e9t\u00e9 de Colombie", "COST", - "Heure de Colombie", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Heure du Venezuela", "VET", - "Heure d'\u00e9t\u00e9 du Venezuela", "VEST", - "Heure du Venezuela", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Heure de Guyane fran\u00e7aise", "GFT", - "Heure d'\u00e9t\u00e9 de Guyane fran\u00e7aise", "GFST", - "Heure de Guyane fran\u00E7aise", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Heure de l'\u00c9quateur", "ECT", - "Heure d'\u00e9t\u00e9 de l'\u00c9quateur", "ECST", - "Heure de l'Equateur", "ECT"}}, - {"America/Guyana", new String[] {"Heure de Guyana", "GYT", - "Heure d'\u00e9t\u00e9 de Guyana", "GYST", - "Heure de Guyana", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Heure de Bolivie", "BOT", - "Heure d'\u00e9t\u00e9 de Bolivie", "BOST", - "Heure de Bolivie", "BOT"}}, - {"America/Lima", new String[] {"Heure du P\u00e9rou", "PET", - "Heure d'\u00e9t\u00e9 du P\u00e9rou", "PEST", - "Heure du P\u00E9rou", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Heure normale de Saint-Pierre et Miquelon", "PMST", - "Heure avanc\u00e9e de Saint-Pierre et Miquelon", "PMDT", - "Saint-Pierre-et-Miquelon", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Heure de l'Uruguay", "UYT", - "Heure d'\u00e9t\u00e9 de l'Uruguay", "UYST", - "Heure de l'Uruguay", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Heure du Surinam", "SRT", - "Heure d'\u00e9t\u00e9 du Surinam", "SRST", - "Heure du Surinam", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT", - "Heure d'\u00e9t\u00e9 de Davis", "DAVST", - "Heure de Davis", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT", - "Heure d'\u00e9t\u00e9 de Dumont-d'Urville", "DDUST", - "Heure de Dumont-d'Urville", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Heure de Mawson", "MAWT", - "Heure d'\u00e9t\u00e9 de Mawson", "MAWST", - "Heure de Mawson", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Heure de Rothera", "ROTT", - "Heure d'\u00e9t\u00e9 de Rothera", "ROTST", - "Heure de Rothera", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Heure de Syowa", "SYOT", - "Heure d'\u00e9t\u00e9 de Syowa", "SYOST", - "Heure de Syowa", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Temps universel coordonn\u00e9", "UTC", - "Heure d'\u00e9t\u00e9 d'Europe centrale", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Heure de Vostok", "VOST", - "Heure d'\u00e9t\u00e9 de Vostok", "VOSST", - "Heure de Vostok", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Heure d'Alma-Ata", "ALMT", - "Heure d'\u00e9t\u00e9 d'Alma-Ata", "ALMST", - "Heure d'Alma-Ata", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Heure d'Anadyr", "ANAT", - "Heure d'\u00e9t\u00e9 d'Anadyr", "ANAST", - "Heure d'Anadyr", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Heure d'Aqtau", "AQTT", - "Heure d'\u00e9t\u00e9 d'Aqtau", "AQTST", - "Heure d'Aqtau", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Heure d'Aqtobe", "AQTT", - "Heure d'\u00e9t\u00e9 d'Aqtobe", "AQTST", - "Heure d'Aqtobe", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Heure d'Azerba\u00efdjan", "AZT", - "Heure d'\u00e9t\u00e9 d'Azerba\u00efdjan", "AZST", - "Heure d'Azerba\u00EFdjan", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Heure du Kirghizistan", "KGT", - "Heure d'\u00e9t\u00e9 du Kirghizistan", "KGST", - "Heure du Kirghizistan", "KGT"}}, - {"Asia/Brunei", new String[] {"Heure du Brunei", "BNT", - "Heure d'\u00e9t\u00e9 du Brunei", "BNST", - "Heure du Brunei", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Heure de Choibalsan", "CHOT", - "Heure d'\u00e9t\u00e9 de Choibalsan", "CHOST", - "Heure de Choibalsan", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Heure de Timor-Leste", "TLT", - "Heure d'\u00e9t\u00e9 de Timor-Leste", "TLST", - "Heure de Timor-Leste", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Heure du Tadjikistan", "TJT", - "Heure d'\u00e9t\u00e9 du Tadjikistan", "TJST", - "Heure du Tadjikistan", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Heure de Hovd", "HOVT", - "Heure d'\u00e9t\u00e9 de Hovd", "HOVST", - "Heure de Hovd", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"Heure d'Indon\u00e9sie orientale", "WIT", - "Heure d'\u00e9t\u00e9 d'Indon\u00e9sie orientale", "EIST", - "Heure d'Indon\u00E9sie orientale", "WIT"}}, - {"Asia/Kabul", new String[] {"Heure d'Afghanistan", "AFT", - "Heure d'\u00e9t\u00e9 d'Afghanistan", "AFST", - "Heure d'Afghanistan", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Heure de Petropavlovsk-Kamchatski", "PETT", - "Heure d'\u00e9t\u00e9 de Petropavlovsk-Kamchatski", "PETST", - "Heure de Petropavlovsk-Kamchatski", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Heure de Magadan", "MAGT", - "Heure d'\u00e9t\u00e9 de Magadan", "MAGST", - "Heure de Magadan", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Heure d'Oral", "ORAT", - "Heure d'\u00e9t\u00e9 d'Oral", "ORAST", - "Heure d'Oral", "ORAT"}}, - {"Asia/Omsk", new String[] {"Heure d'Omsk", "OMST", - "Heure d'\u00e9t\u00e9 d'Omsk", "OMSST", - "Heure d'Omsk", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Heure de Kyzylorda", "QYZT", - "Heure d'\u00e9t\u00e9 de Kyzylorda", "QYZST", - "Heure de Kyzylorda", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Heure de Sakhalin", "SAKT", - "Heure d'\u00e9t\u00e9 de Sakhalin", "SAKST", - "Heure de Sakhalin", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Heure de G\u00e9orgie", "GET", - "Heure d'\u00e9t\u00e9 de G\u00e9orgie", "GEST", - "Heure de G\u00E9orgie", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Heure d'Ust-Nera", "VLAT", - "Heure d'\u00E9t\u00E9 d'Ust-Nera", "VLAST", - "Heure d'Ust-Nera", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Heure de Vladivostok", "VLAT", - "Heure d'\u00e9t\u00e9 de Vladivostok", "VLAST", - "Heure de Vladivostok", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Heure de Yekaterinburg", "YEKT", - "Heure d'\u00e9t\u00e9 de Yekaterinburg", "YEKST", - "Heure de Yekaterinburg", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Heure des A\u00e7ores", "AZOT", - "Heure d'\u00e9t\u00e9 des A\u00e7ores", "AZOST", - "Heure des A\u00E7ores", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Heure de Cap-Vert", "CVT", - "Heure d'\u00e9t\u00e9 de Cap-Vert", "CVST", - "Heure de Cap-Vert", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"Heure normale de G\u00e9orgie du Sud", "GST", - "Heure avanc\u00e9e de G\u00e9orgie du Sud", "GDT", - "G\u00E9orgie du Sud", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Heure des \u00eeles Falkland", "FKT", - "Heure d'\u00e9t\u00e9 des \u00eeles Falkland", "FKST", - "Heure des \u00EEles Falkland", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Heure standard de l'Australie occidentale (centre)", "ACWST", - "Heure d'\u00E9t\u00E9 de l'Australie occidentale (centre)", "ACWDT", - "Heure de l'Australie occidentale (centre)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Heure normale de Samara", "SAMT", - "Heure d'\u00e9t\u00e9 de Samara", "SAMST", - "Heure de Samara", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Heure de l'oc\u00e9an Indien", "IOT", - "Heure d'\u00e9t\u00e9 de l'oc\u00e9an Indien", "IOST", - "Heure de l'oc\u00E9an Indien", "IOT"}}, - {"Indian/Christmas", new String[] {"Heure de l'\u00cele Christmas", "CXT", - "Heure d'\u00e9t\u00e9 de l'\u00cele Christmas", "CXST", - "Heure de l'Ile Christmas", "CIT"}}, - {"Indian/Cocos", new String[] {"Heure des \u00celes Cocos", "CCT", - "Heure d'\u00e9t\u00e9 des \u00celes Cocos", "CCST", - "Heure des Iles Cocos", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Heure des Terres australes antartiques fran\u00e7aises", "TFT", - "Heure d'\u00e9t\u00e9 des Terres australes antartiques fran\u00e7aises", "TFST", - "Heure des Terres australes antarctiques fran\u00E7aises", "TFT"}}, - {"Indian/Mahe", new String[] {"Heure des Seychelles", "SCT", - "Heure d'\u00e9t\u00e9 des Seychelles", "SCST", - "Heure des Seychelles", "SCT"}}, - {"Indian/Maldives", new String[] {"Heure des Maldives", "MVT", - "Heure d'\u00e9t\u00e9 des Maldives", "MVST", - "Heure des Maldives", "MVT"}}, - {"Indian/Mauritius", new String[] {"Heure de Maurice", "MUT", - "Heure d'\u00e9t\u00e9 de Maurice", "MUST", - "Heure de Maurice", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Heure de la R\u00e9union", "RET", - "Heure d'\u00e9t\u00e9 de la R\u00e9union", "REST", - "Heure de la R\u00E9union", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Heure du Vanuatu", "VUT", - "Heure d'\u00e9t\u00e9 du Vanuatu", "VUST", - "Heure du Vanuatu", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Heure de l'\u00cele de Phoenix", "PHOT", - "Heure d'\u00e9t\u00e9 de l'\u00cele de Phoenix", "PHOST", - "Heure de l'Ile de Phoenix", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Heure de Tokelau", "TKT", - "Heure d'\u00e9t\u00e9 de Tokelau", "TKST", - "Heure de Tokelau", "TKT"}}, - {"Pacific/Fiji", new String[] {"Heure de Fidji", "FJT", - "Heure d'\u00e9t\u00e9 de Fidji", "FJST", - "Heure de Fidji", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Heure de Tuvalu", "TVT", - "Heure d'\u00e9t\u00e9 de Tuvalu", "TVST", - "Heure de Tuvalu", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Heure des Galapagos", "GALT", - "Heure d'\u00e9t\u00e9 des Galapagos", "GALST", - "Heure des Galapagos", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Heure de l'\u00cele de Line", "LINT", - "Heure d'\u00e9t\u00e9 de l'\u00cele de Line", "LINST", - "Heure de l'Ile de Line", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Heure de Kusaie", "KOST", - "Heure d'\u00e9t\u00e9 de Kusaie", "KOSST", - "Heure de Kusaie", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Heure des Marquises", "MART", - "Heure d'\u00e9t\u00e9 des Marquises", "MARST", - "Heure des Marquises", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Heure de Nauru", "NRT", - "Heure d'\u00e9t\u00e9 de Nauru", "NRST", - "Heure de Nauru", "NRT"}}, - {"Pacific/Niue", new String[] {"Heure de Niue", "NUT", - "Heure d'\u00e9t\u00e9 de Niue", "NUST", - "Heure de Niue", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Heure de Norfolk", "NFT", - "Heure d'\u00e9t\u00e9 de Norfolk", "NFST", - "Heure de Norfolk", "NFT"}}, - {"Pacific/Noumea", new String[] {"Heure de Nouvelle-Cal\u00e9donie", "NCT", - "Heure d'\u00e9t\u00e9 de Nouvelle-Cal\u00e9donie", "NCST", - "Heure de Nouvelle-Cal\u00E9donie", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Heure de Palaos", "PWT", - "Heure d'\u00e9t\u00e9 de Palaos", "PWST", - "Heure de Palaos", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Heure de Papouasie-Nouvelle-Guin\u00e9e", "PGT", - "Heure d'\u00e9t\u00e9 de de Papouasie-Nouvelle-Guin\u00e9e", "PGST", - "Heure de Papouasie-Nouvelle-Guin\u00E9e", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Heure des \u00celes Cook", "CKT", - "Heure d'\u00e9t\u00e9 des \u00celes Cook", "CKHST", - "Heure des Iles Cook", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Heure de Tahiti", "TAHT", - "Heure d'\u00e9t\u00e9 de Tahiti", "TAHST", - "Heure de Tahiti", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Heure de Kiribati", "GILT", - "Heure d'\u00e9t\u00e9 de Kiribati", "GILST", - "Heure de Kiribati", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Heure de Tonga", "TOT", - "Heure d'\u00e9t\u00e9 de Tonga", "TOST", - "Heure de Tonga", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"Heure de Wake", "WAKT", - "Heure d'\u00e9t\u00e9 de Wake", "WAKST", - "Heure de Wake", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Heure de Wallis et Futuna", "WFT", - "Heure d'\u00e9t\u00e9 de Wallis et Futuna", "WFST", - "Heure de Wallis-et-Futuna", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_hi.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_hi.java deleted file mode 100644 index f47c414938a..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_hi.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * Copyright (c) 1998 International Business Machines. - * All Rights Reserved. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_hi extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - return new Object[][] { - {"Asia/Calcutta", - new String[] { - "\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST", - "\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST", - "\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IT" - } - }, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java deleted file mode 100644 index 90d3c2927dc..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_it extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Ora di Acre", "ACT", - "Ora estiva di Acre", "ACST", - "Ora di Acre", "ACT"}; - String ADELAIDE[] = new String[] {"Ora standard centrale (Australia del Sud)", "ACST", - "Ora estiva centrale (Australia del Sud)", "ACDT", - "Ora fuso centrale (Australia del Sud)", "ACT"}; - String AGT[] = new String[] {"Ora dell'Argentina", "ART", - "Ora estiva dell'Argentina", "ARST", - "Ora dell'Argentina", "ART"}; - String AKST[] = new String[] {"Ora solare dell'Alaska", "AKST", - "Ora legale dell'Alaska", "AKDT", - "Ora Alaska", "AKT"}; - String AMT[] = new String[] {"Ora solare dell'Amazzonia", "AMT", - "Ora estiva dell'Amazzonia", "AMST", - "Ora dell'Amazzonia", "AMT"}; - String ARAST[] = new String[] {"Ora solare dell'Arabia", "AST", - "Ora legale dell'Arabia", "ADT", - "Ora Arabia Saudita", "AT"}; - String ARMT[] = new String[] {"Ora dell'Armenia", "AMT", - "Ora estiva dell'Armenia", "AMST", - "Ora dell'Armenia", "AMT"}; - String AST[] = new String[] {"Ora solare dell'Atlantico occidentale", "AST", - "Ora legale dell'Atlantico occidentale", "ADT", - "Fuso dell'Atlantico", "AT"}; - String BDT[] = new String[] {"Ora del Bangladesh", "BDT", - "Ora estiva del Bangladesh", "BDST", - "Ora del Bangladesh", "BDT"}; - String BRISBANE[] = new String[] {"Ora standard orientale (Queensland)", "AEST", - "Ora estiva orientale (Queensland)", "AEDT", - "Ora fuso orientale (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Ora standard centrale (Australia del Sud/Nuovo Galles del Sud)", "ACST", - "Ora estiva centrale (Australia del Sud/Nuovo Galles del Sud)", "ACDT", - "Ora fuso centrale (Australia del Sud/Nuovo Galles del Sud)", "ACT"}; - String BRT[] = new String[] {"Ora del Brasile", "BRT", - "Ora estiva del Brasile", "BRST", - "Ora di Brasilia", "BRT"}; - String BTT[] = new String[] {"Ora del Bhutan", "BTT", - "Ora estiva del Bhutan", "BTST", - "Ora del Bhutan", "BTT"}; - String CAT[] = new String[] {"Ora dell'Africa centrale", "CAT", - "Ora estiva dell'Africa centrale", "CAST", - "Ora dell'Africa centrale", "CAT"}; - String CET[] = new String[] {"Ora dell'Europa centrale", "CET", - "Ora estiva dell'Europa centrale", "CEST", - "Ora dell'Europa centrale", "CET"}; - String CHAST[] = new String[] {"Ora di Chatham standard", "CHAST", - "Ora legale di Chatham", "CHADT", - "Ora Chatham", "CHAT"}; - String CHUT[] = new String[] {"Ora di Chuuk", "CHUT", - "Ora estiva di Chuuk", "CHUST", - "Ora di Chuuk", "CHUT"}; - String CIT[] = new String[] {"Ora dell'Indonesia centrale", "WITA", - "Ora estiva dell'Indonesia centrale", "CIST", - "Ora dell'Indonesia centrale", "WITA"}; - String CLT[] = new String[] {"Ora del Cile", "CLT", - "Ora estiva del Cile", "CLST", - "Ora del Cile", "CLT"}; - String CST[] = new String[] {"Ora solare USA centrale", "CST", - "Ora legale USA centrale", "CDT", - "Ora fuso centrale", "CT"}; - String CTT[] = new String[] {"Ora solare della Cina", "CST", - "Ora legale della Cina", "CDT", - "Ora Cina", "CT"}; - String CUBA[] = new String[] {"Ora solare Cuba", "CST", - "Ora legale Cuba", "CDT", - "Ora di Cuba", "CT"}; - String DARWIN[] = new String[] {"Ora standard centrale (Territori del Nord)", "ACST", - "Ora estiva centrale (Territori del Nord)", "ACDT", - "Ora fuso centrale (Territori del Nord)", "ACT"}; - String DUBLIN[] = new String[] {"Ora media di Greenwich", "GMT", - "Ora estiva irlandese", "IST", - "Ora irlandese", "IT"}; - String EAT[] = new String[] {"Ora dell'Africa orientale", "EAT", - "Ora estiva dell'Africa orientale", "EAST", - "Ora dell'Africa orientale", "EAT"}; - String EASTER[] = new String[] {"Ora dell'Isola di Pasqua", "EAST", - "Ora estiva dell'Isola di Pasqua", "EASST", - "Ora dell'Isola di Pasqua", "EAST"}; - String EET[] = new String[] {"Ora dell'Europa orientale", "EET", - "Ora estiva dell'Europa orientale", "EEST", - "Ora dell'Europa orientale", "EET"}; - String EGT[] = new String[] {"Ora della Groenlandia orientale", "EGT", - "Ora estiva della Groenlandia orientale", "EGST", - "Ora della Groenlandia orientale", "EGT"}; - String EST[] = new String[] {"Ora solare USA orientale", "EST", - "Ora legale USA orientale", "EDT", - "Fuso orientale", "ET"}; - String EST_NSW[] = new String[] {"Ora standard dell'Australia orientale (Nuovo Galles del Sud)", "AEST", - "Ora estiva dell'Australia orientale (Nuovo Galles del Sud)", "AEDT", - "Ora fuso orientale (Nuovo Galles del Sud)", "AET"}; - String FET[] = new String[] {"Ora dei paesi europei pi\u00F9 orientali", "FET", - "Ora estiva dei paesi europei pi\u00F9 orientali", "FEST", - "Ora dei paesi europei pi\u00F9 orientali", "FET"}; - String GHMT[] = new String[] {"Ora media del Ghana", "GMT", - "Ora legale del Ghana", "GHST", - "Ora media del Ghana", "GMT"}; - String GAMBIER[] = new String[] {"Ora di Gambier", "GAMT", - "Ora estiva di Gambier", "GAMST", - "Ora di Gambier", "GAMT"}; - String GMT[] = new String[] {"Ora media di Greenwich", "GMT", - "Ora media di Greenwich", "GMT", - "Ora media di Greenwich", "GMT"}; - String GMTBST[] = new String[] {"Ora media di Greenwich", "GMT", - "Ora estiva britannica", "BST", - "Ora britannica", "BT"}; - String GST[] = new String[] {"Ora solare del golfo", "GST", - "Ora legale del golfo", "GDT", - "Ora del golfo", "GT"}; - String HKT[] = new String[] {"Ora di Hong Kong", "HKT", - "Ora estiva di Hong Kong", "HKST", - "Ora di Hong Kong", "HKT"}; - String HST[] = new String[] {"Ora solare delle Isole Hawaii", "HST", - "Ora legale delle Isole Hawaii", "HDT", - "Ora Hawaii", "HT"}; - String ICT[] = new String[] {"Ora dell'Indocina", "ICT", - "Ora estiva dell'Indocina", "ICST", - "Ora dell'Indocina", "ICT"}; - String IRKT[] = new String[] {"Ora di Irkutsk", "IRKT", - "Ora estiva di Irkutsk", "IRKST", - "Ora di Irkutsk", "IRKT"}; - String IRT[] = new String[] {"Ora solare Iran", "IRST", - "Ora legale Iran", "IRDT", - "Ora Iran", "IRT"}; - String ISRAEL[] = new String[] {"Ora standard di Israele", "IST", - "Ora legale di Israele", "IDT", - "Ora Israele", "IT"}; - String IST[] = new String[] {"Ora solare dell'India", "IST", - "Ora legale dell'India", "IDT", - "Ora India", "IT"}; - String JST[] = new String[] {"Ora solare del Giappone", "JST", - "Ora legale del Giappone", "JDT", - "Ora Giappone", "JT"}; - String KRAT[] = new String[] {"Ora di Krasnojarsk", "KRAT", - "Ora estiva di Krasnojarsk", "KRAST", - "Ora di Krasnojarsk", "KRAT"}; - String KST[] = new String[] {"Ora solare della Corea", "KST", - "Ora legale della Corea", "KDT", - "Ora Corea", "KT"}; - String LORD_HOWE[] = new String[] {"Ora standard di Lord Howe", "LHST", - "Ora estiva di Lord Howe", "LHDT", - "Ora di Lord Howe", "LHT"}; - String MHT[] = new String[] {"Ora delle Isole Marshall", "MHT", - "Ora estiva delle Isole Marshall", "MHST", - "Ora delle Isole Marshall", "MHT"}; - String MMT[] = new String[] {"Ora della Birmania/Myanmar", "MMT", - "Ora estiva della Birmania/Myanmar", "MMST", - "Ora della Birmania/Myanmar", "MMT"}; - String MSK[] = new String[] {"Ora standard di Mosca", "MSK", - "Ora legale di Mosca", "MSD", - "Ora Mosca", "MT"}; - String MST[] = new String[] {"Ora solare USA occidentale", "MST", - "Ora legale USA occidentale", "MDT", - "Ora fuso occidentale", "MT"}; - String MYT[] = new String[] {"Ora della Malaysia", "MYT", - "Ora estiva della Malaysia", "MYST", - "Ora della Malaysia", "MYT"}; - String NORONHA[] = new String[] {"Ora di Fernando de Noronha", "FNT", - "Ora estiva di Fernando de Noronha", "FNST", - "Ora di Fernando de Noronha", "FNT"}; - String NOVT[] = new String[] {"Ora di Novosibirsk", "NOVT", - "Ora estiva di Novosibirsk", "NOVST", - "Ora di Novosibirsk", "NOVT"}; - String NPT[] = new String[] {"Ora del Nepal", "NPT", - "Ora estiva del Nepal", "NPST", - "Ora del Nepal", "NPT"}; - String NST[] = new String[] {"Ora solare di Terranova", "NST", - "Ora legale di Terranova", "NDT", - "Ora Terranova", "NT"}; - String NZST[] = new String[] {"Ora solare della Nuova Zelanda", "NZST", - "Ora legale della Nuova Zelanda", "NZDT", - "Ora Nuova Zelanda", "NZT"}; - String PITCAIRN[] = new String[] {"Ora standard di Pitcairn", "PST", - "Ora legale di Pitcairn", "PDT", - "Ora Pitcairn", "PT"}; - String PKT[] = new String[] {"Ora del Pakistan", "PKT", - "Ora estiva del Pakistan", "PKST", - "Ora del Pakistan", "PKT"}; - String PONT[] = new String[] {"Ora di Pohnpei", "PONT", - "Ora estiva di Pohnpei", "PONST", - "Ora Ponape", "PONT"}; - String PST[] = new String[] {"Ora solare della costa occidentale USA", "PST", - "Ora legale della costa occidentale USA", "PDT", - "Fuso del Pacifico", "PT"}; - String SAST[] = new String[] {"Ora solare del Sudafrica", "SAST", - "Ora estiva del Sudafrica", "SAST", - "Ora Sudafrica", "SAT"}; - String SBT[] = new String[] {"Ora delle Isole Salomone", "SBT", - "Ora estiva delle Isole Salomone", "SBST", - "Ora delle Isole Salomone", "SBT"}; - String SGT[] = new String[] {"Ora di Singapore", "SGT", - "Ora estiva di Singapore", "SGST", - "Ora di Singapore", "SGT"}; - String TASMANIA[] = new String[] {"Ora standard orientale (Tasmania)", "AEST", - "Ora estiva orientale (Tasmania)", "AEDT", - "Ora fuso orientale (Tasmania)", "AET"}; - String TMT[] = new String[] {"Ora del Turkmenistan", "TMT", - "Ora estiva del Turkmenistan", "TMST", - "Ora del Turkmenistan", "TMT"}; - String ULAT[]= new String[] {"Ora di Ulaanbaatar", "ULAT", - "Ora estiva di Ulaanbaatar", "ULAST", - "Ora di Ulaanbaatar", "ULAT"}; - String WAT[] = new String[] {"Ora dell'Africa occidentale", "WAT", - "Ora estiva dell'Africa occidentale", "WAST", - "Ora dell'Africa occidentale", "WAT"}; - String WET[] = new String[] {"Ora dell'Europa occidentale", "WET", - "Ora estiva dell'Europa occidentale", "WEST", - "Ora dell'Europa occidentale", "WET"}; - String WGT[] = new String[] {"Ora della Groenlandia occidentale", "WGT", - "Ora estiva della Groenlandia occidentale", "WGST", - "Ora della Groenlandia occidentale", "WGT"}; - String WIT[] = new String[] {"Ora dell'Indonesia occidentale", "WIB", - "Ora estiva dell'Indonesia occidentale", "WIST", - "Ora dell'Indonesia occidentale", "WIB"}; - String WST_AUS[] = new String[] {"Ora standard dell'Australia occidentale", "AWST", - "Ora estiva dell'Australia occidentale", "AWDT", - "Ora Australia occidentale", "AWT"}; - String SAMOA[] = new String[] {"Ora standard di Samoa", "SST", - "Ora legale di Samoa", "SDT", - "Ora Samoa", "ST"}; - String WST_SAMOA[] = new String[] {"Ora di Samoa", "WSST", - "Ora estiva di Samoa", "WSDT", - "Ora di Samoa occidentale", "WST"}; - String ChST[] = new String[] {"Ora standard di Chamorro", "ChST", - "Ora legale di Chamorro", "ChDT", - "Ora Chamorro", "ChT"}; - String VICTORIA[] = new String[] {"Ora standard orientale (Victoria)", "AEST", - "Ora estiva orientale (Victoria)", "AEDT", - "Ora fuso orientale (Victoria)", "AET"}; - String UTC[] = new String[] {"Tempo universale coordinato", "UTC", - "Tempo universale coordinato", "UTC", - "Tempo universale coordinato", "UTC"}; - String UZT[] = new String[] {"Ora dell'Uzbekistan", "UZT", - "Ora estiva dell'Uzbekistan", "UZST", - "Ora dell'Uzbekistan", "UZT"}; - String XJT[] = new String[] {"Ora solare della Cina", "XJT", - "Ora legale della Cina", "XJDT", - "Ora Cina", "XJT"}; - String YAKT[] = new String[] {"Ora di Jakutsk", "YAKT", - "Ora estiva di Jakutsk", "YAKST", - "Ora di Yakutsk", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Ora del Paraguay", "PYT", - "Ora estiva del Paraguay", "PYST", - "Ora del Paraguay", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Ora della Colombia", "COT", - "Ora estiva della Colombia", "COST", - "Ora della Colombia", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Ora del Venezuela", "VET", - "Ora estiva del Venezuela", "VEST", - "Ora del Venezuela", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Ora della Guyana Francese", "GFT", - "Ora estiva della Guyana Francese", "GFST", - "Ora della Guyana Francese", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Ora dell'Ecuador", "ECT", - "Ora estiva dell'Ecuador", "ECST", - "Ora dell'Ecuador", "ECT"}}, - {"America/Guyana", new String[] {"Ora della Guyana", "GYT", - "Ora estiva della Guyana", "GYST", - "Ora della Guyana", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Ora della Bolivia", "BOT", - "Ora estiva della Bolivia", "BOST", - "Ora della Bolivia", "BOT"}}, - {"America/Lima", new String[] {"Ora del Per\u00f9", "PET", - "Ora estiva del Per\u00f9", "PEST", - "Ora del Per\u00F9", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Ora solare di Saint-Pierre e Miquelon", "PMST", - "Ora legale di Saint-Pierre e Miquelon", "PMDT", - "Ora Saint-Pierre e Miquelon", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Ora dell'Uruguay", "UYT", - "Ora estiva dell'Uruguay", "UYST", - "Ora dell'Uruguay", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Ora di Suriname", "SRT", - "Ora estiva di Suriname", "SRST", - "Ora di Suriname", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT", - "Ora estiva di Davis", "DAVST", - "Ora di Davis", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT", - "Ora estiva di Dumont-d'Urville", "DDUST", - "Ora di Dumont-d'Urville", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Ora di Mawson", "MAWT", - "Ora estiva di Mawson", "MAWST", - "Ora di Mawson", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Ora di Rothera", "ROTT", - "Ora estiva di Rothera", "ROTST", - "Ora di Rothera", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Ora di Syowa", "SYOT", - "Ora estiva di Syowa", "SYOST", - "Ora di Syowa", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Tempo universale coordinato", "UTC", - "Ora estiva dell'Europa centrale", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Ora di Vostok", "VOST", - "Ora estiva di Vostok", "VOSST", - "Ora di Vostok", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Ora di Alma-Ata", "ALMT", - "Ora estiva di Alma-Ata", "ALMST", - "Ora di Alma-Ata", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Ora di Anadyr", "ANAT", - "Ora estiva di Anadyr", "ANAST", - "Ora di Anadyr", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Ora di Aqtau", "AQTT", - "Ora estiva di Aqtau", "AQTST", - "Ora di Aqtau", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Ora di Aqtobe", "AQTT", - "Ora estiva di Aqtobe", "AQTST", - "Ora di Aqtobe", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Ora dell'Azerbaigian", "AZT", - "Ora estiva dell'Azerbaigian", "AZST", - "Ora dell'Azerbaigian", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Ora del Kirghizistan", "KGT", - "Ora estiva del Kirghizistan", "KGST", - "Ora del Kirghizistan", "KGT"}}, - {"Asia/Brunei", new String[] {"Ora del Brunei", "BNT", - "Ora estiva del Brunei", "BNST", - "Ora del Brunei", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Ora di Choibalsan", "CHOT", - "Ora estiva di Choibalsan", "CHOST", - "Ora di Choibalsan", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Ora di Timor Leste", "TLT", - "Ora estiva di Timor Leste", "TLST", - "Ora di Timor Est", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Ora del Tagikistan", "TJT", - "Ora estiva del Tagikistan", "TJST", - "Ora del Tagikistan", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Ora di Hovd", "HOVT", - "Ora estiva di Hovd", "HOVST", - "Ora di Hovd", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"Ora dell'Indonesia orientale", "WIT", - "Ora estiva dell'Indonesia orientale", "EIST", - "Ora dell'Indonesia orientale", "WIT"}}, - {"Asia/Kabul", new String[] {"Ora dell'Afghanistan", "AFT", - "Ora estiva dell'Afghanistan", "AFST", - "Ora dell'Afghanistan", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Ora di Petropavlovsk-Kamchatski", "PETT", - "Ora estiva di Petropavlovsk-Kamchatski", "PETST", - "Ora di Petropavlovsk-Kamchatski", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Kolkata", IST}, - {"Asia/Khandyga", YAKT}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Ora di Magadan", "MAGT", - "Ora estiva di Magadan", "MAGST", - "Ora di Magadan", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Ora di Oral", "ORAT", - "Ora estiva di Oral", "ORAST", - "Ora di Oral", "ORAT"}}, - {"Asia/Omsk", new String[] {"Ora di Omsk", "OMST", - "Ora estiva di Omsk", "OMSST", - "Ora di Omsk", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Ora di Qyzylorda", "QYZT", - "Ora estiva di Qyzylorda", "QYZST", - "Ora di Qyzylorda", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Ora di Sakhalin", "SAKT", - "Ora estiva di Sakhalin", "SAKST", - "Ora di Sakhalin", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Ora della Georgia", "GET", - "Ora estiva della Georgia", "GEST", - "Ora della Georgia", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Ora di Ust-Nera", "VLAT", - "Ora estiva di Ust-Nera", "VLAST", - "Ora di Ust-Nera", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Ora di Vladivostok", "VLAT", - "Ora estiva di Vladivostok", "VLAST", - "Ora di Vladivostok", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Ora di Ekaterinburg", "YEKT", - "Ora estiva di Ekaterinburg", "YEKST", - "Ora di Ekaterinburg", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Ora delle Azzorre", "AZOT", - "Ora estiva delle Azzorre", "AZOST", - "Ora delle Azzorre", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Ora di Capo Verde", "CVT", - "Ora estiva di Capo Verde", "CVST", - "Ora di Capo Verde", "CVT"}}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"Ora solare della Georgia Australe", "GST", - "Ora legale della Georgia Australe", "GDT", - "Ora Georgia del Sud", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Ora delle Falkland", "FKT", - "Ora estiva delle Falkland", "FKST", - "Ora delle Falkland", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Ora standard Australia centro-occidentale", "ACWST", - "Ora estiva Australia centro-occidentale", "ACWDT", - "Ora Australia centro-occidentale", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Ora di Samara", "SAMT", - "Ora estiva di Samara", "SAMST", - "Ora di Samara", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Ora del Terr. Britannico dell'Oceano Indiano", "IOT", - "Ora estiva del Terr. Britannico dell'Oceano Indiano", "IOST", - "Ora del Territorio Britannico dell'Oceano Indiano", "IOT"}}, - {"Indian/Christmas", new String[] {"Ora dell'Isola Christmas", "CXT", - "Ora estiva dell'Isola Christmas", "CXST", - "Ora dell'Isola Christmas", "CIT"}}, - {"Indian/Cocos", new String[] {"Ora delle Isole Cocos", "CCT", - "Ora estiva delle Isole Cocos", "CCST", - "Ora delle Isole Cocos", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Ora delle Terre Australi e Antartiche Francesi", "TFT", - "Ora estiva delle Terre Australi Antartiche Francesi", "TFST", - "Ora delle Terre Australi e Antartiche Francesi", "TFT"}}, - {"Indian/Mahe", new String[] {"Ora delle Seychelles", "SCT", - "Ora estiva delle Seychelles", "SCST", - "Ora delle Seychelles", "SCT"}}, - {"Indian/Maldives", new String[] {"Ora delle Maldive", "MVT", - "Ora estiva delle Maldive", "MVST", - "Ora delle Maldive", "MVT"}}, - {"Indian/Mauritius", new String[] {"Ora di Mauritius", "MUT", - "Ora estiva di Mauritius", "MUST", - "Ora di Mauritius", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Ora di Reunion", "RET", - "Ora estiva di Reunion", "REST", - "Ora di Reunion", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Ora di Vanuatu", "VUT", - "Ora estiva di Vanuatu", "VUST", - "Ora di Vanuatu", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Ora dell'Isola della Fenice", "PHOT", - "Ora estiva dell'Isola della Fenice", "PHOST", - "Ora delle Isole Phoenix", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Ora di Tokelau", "TKT", - "Ora estiva di Tokelau", "TKST", - "Ora di Tokelau", "TKT"}}, - {"Pacific/Fiji", new String[] {"Ora di Figi", "FJT", - "Ora estiva di Figi", "FJST", - "Ora di Figi", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Ora di Tuvalu", "TVT", - "Ora estiva di Tuvalu", "TVST", - "Ora di Tuvalu", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Ora delle Galapagos", "GALT", - "Ora estiva delle Galapagos", "GALST", - "Ora delle Galapagos", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Ora delle Line Islands", "LINT", - "Ora estiva delle Line Islands", "LINST", - "Ora delle Line Islands", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Ora di Kosrae", "KOST", - "Ora estiva di Kosrae", "KOSST", - "Ora di Kosrae", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Ora delle Isole Marchesi", "MART", - "Ora estiva delle Isole Marchesi", "MARST", - "Ora delle Isole Marchesi", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Ora di Nauru", "NRT", - "Ora estiva di Nauru", "NRST", - "Ora di Nauru", "NRT"}}, - {"Pacific/Niue", new String[] {"Ora di Niue", "NUT", - "Ora estiva di Niue", "NUST", - "Ora di Niue", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Ora di Norfolk", "NFT", - "Ora estiva di Norfolk", "NFST", - "Ora di Norfolk", "NFT"}}, - {"Pacific/Noumea", new String[] {"Ora della Nuova Caledonia", "NCT", - "Ora estiva della Nuova Caledonia", "NCST", - "Ora della Nuova Caledonia", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Ora di Palau", "PWT", - "Ora estiva di Palau", "PWST", - "Ora di Palau", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Ora di Papua Nuova Guinea", "PGT", - "Ora estiva di Papua Nuova Guinea", "PGST", - "Ora di Papua Nuova Guinea", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Ora delle Isole Cook", "CKT", - "Ora estiva delle Isole Cook", "CKHST", - "Ora delle Isole Cook", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Ora di Tahiti", "TAHT", - "Ora estiva di Tahiti", "TAHST", - "Ora di Tahiti", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Ora delle Isole Gilbert", "GILT", - "Ora estiva delle Isole Gilbert", "GILST", - "Ora delle Isole Gilbert", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Ora di Tonga", "TOT", - "Ora estiva di Tonga", "TOST", - "Ora di Tonga", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"Ora di Wake", "WAKT", - "Ora estiva di Wake", "WAKST", - "Ora di Wake", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Ora di Wallis e Futuna", "WFT", - "Ora estiva di Wallis e Futuna", "WFST", - "Ora di Wallis e Futuna", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java deleted file mode 100644 index 22db0a4f35e..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_ja extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"\u30a2\u30af\u30ec\u6642\u9593", "ACT", - "\u30a2\u30af\u30ec\u590f\u6642\u9593", "ACST", - "\u30a2\u30af\u30ec\u6642\u9593", "ACT"}; - String ADELAIDE[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACST", - "\u4E2D\u90E8\u590F\u6642\u9593(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACDT", - "\u4E2D\u90E8\u6A19\u6E96\u6642(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACT"}; - String AGT[] = new String[] {"\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "ART", - "\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u590f\u6642\u9593", "ARST", - "\u30A2\u30EB\u30BC\u30F3\u30C1\u30F3\u6642\u9593", "ART"}; - String AKST[] = new String[] {"\u30a2\u30e9\u30b9\u30ab\u6a19\u6e96\u6642", "AKST", - "\u30a2\u30e9\u30b9\u30ab\u590f\u6642\u9593", "AKDT", - "\u30A2\u30E9\u30B9\u30AB\u6642\u9593", "AKT"}; - String AMT[] = new String[] {"\u30a2\u30de\u30be\u30f3\u6642\u9593", "AMT", - "\u30a2\u30de\u30be\u30f3\u590f\u6642\u9593", "AMST", - "\u30A2\u30DE\u30BE\u30F3\u6642\u9593", "AMT"}; - String ARAST[] = new String[] {"\u30a2\u30e9\u30d3\u30a2\u6a19\u6e96\u6642", "AST", - "\u30a2\u30e9\u30d3\u30a2\u590f\u6642\u9593", "ADT", - "\u30A2\u30E9\u30D3\u30A2\u6642\u9593", "AT"}; - String ARMT[] = new String[] {"\u30a2\u30eb\u30e1\u30cb\u30a2\u6642\u9593", "AMT", - "\u30a2\u30eb\u30e1\u30cb\u30a2\u590f\u6642\u9593", "AMST", - "\u30A2\u30EB\u30E1\u30CB\u30A2\u6642\u9593", "AMT"}; - String AST[] = new String[] {"\u5927\u897f\u6d0b\u6a19\u6e96\u6642", "AST", - "\u5927\u897f\u6d0b\u590f\u6642\u9593", "ADT", - "\u5927\u897F\u6D0B\u6A19\u6E96\u6642", "AT"}; - String BDT[] = new String[] {"\u30d0\u30f3\u30b0\u30e9\u30c7\u30b7\u30e5\u6642\u9593", "BDT", - "\u30d0\u30f3\u30b0\u30e9\u30c7\u30b7\u30e5\u590f\u6642\u9593", "BDST", - "\u30D0\u30F3\u30B0\u30E9\u30C7\u30B7\u30E5\u6642\u9593", "BDT"}; - String BRISBANE[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642(\u30AF\u30A4\u30FC\u30F3\u30BA\u30E9\u30F3\u30C9)", "AEST", - "\u6771\u90E8\u590F\u6642\u9593(\u30AF\u30A4\u30FC\u30F3\u30BA\u30E9\u30F3\u30C9)", "AEDT", - "\u6771\u90E8\u6A19\u6E96\u6642(\u30AF\u30A4\u30FC\u30F3\u30BA\u30E9\u30F3\u30C9)", "AET"}; - String BROKEN_HILL[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2/\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "ACST", - "\u4E2D\u90E8\u590F\u6642\u9593(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2/\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "ACDT", - "\u4E2D\u90E8\u6A19\u6E96\u6642(\u5357\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2/\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "ACT"}; - String BRT[] = new String[] {"\u30d6\u30e9\u30b8\u30eb\u6642\u9593", "BRT", - "\u30d6\u30e9\u30b8\u30eb\u590f\u6642\u9593", "BRST", - "\u30D6\u30E9\u30B8\u30EA\u30A2\u6642\u9593", "BRT"}; - String BTT[] = new String[] {"\u30d6\u30fc\u30bf\u30f3\u6642\u9593", "BTT", - "\u30d6\u30fc\u30bf\u30f3\u590f\u6642\u9593", "BTST", - "\u30D6\u30FC\u30BF\u30F3\u6642\u9593", "BTT"}; - String CAT[] = new String[] {"\u4e2d\u90e8\u30a2\u30d5\u30ea\u30ab\u6642\u9593", "CAT", - "\u4e2d\u90e8\u30a2\u30d5\u30ea\u30ab\u590f\u6642\u9593", "CAST", - "\u4E2D\u90E8\u30A2\u30D5\u30EA\u30AB\u6642\u9593", "CAT"}; - String CET[] = new String[] {"\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u6642\u9593", "CET", - "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "CEST", - "\u4E2D\u90E8\u30E8\u30FC\u30ED\u30C3\u30D1\u6642\u9593", "CET"}; - String CHAST[] = new String[] {"\u30c1\u30e3\u30bf\u30e0\u6a19\u6e96\u6642", "CHAST", - "\u30c1\u30e3\u30bf\u30e0\u590f\u6642\u9593", "CHADT", - "\u30C1\u30E3\u30BF\u30E0\u6642\u9593", "CHAT"}; - String CHUT[] = new String[] {"\u30C1\u30E5\u30FC\u30AF\u6642\u9593", "CHUT", - "Chuuk Time", "CHUST", - "\u30C1\u30E5\u30FC\u30AF\u6642\u9593", "CHUT"}; - String CIT[] = new String[] {"\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "WITA", - "\u4e2d\u592e\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "CIST", - "\u4E2D\u90E8\u30A4\u30F3\u30C9\u30CD\u30B7\u30A2\u6642\u9593", "WITA"}; - String CLT[] = new String[] {"\u30c1\u30ea\u6642\u9593", "CLT", - "\u30c1\u30ea\u590f\u6642\u9593", "CLST", - "\u30C1\u30EA\u6642\u9593", "CLT"}; - String CST[] = new String[] {"\u4e2d\u90e8\u6a19\u6e96\u6642", "CST", - "\u4e2d\u90e8\u590f\u6642\u9593", "CDT", - "\u4E2D\u90E8\u6A19\u6E96\u6642", "CT"}; - String CTT[] = new String[] {"\u4e2d\u56fd\u6a19\u6e96\u6642", "CST", - "\u4e2d\u56fd\u590f\u6642\u9593", "CDT", - "\u4E2D\u56FD\u6642\u9593", "CT"}; - String CUBA[] = new String[] {"\u30ad\u30e5\u30fc\u30d0\u6a19\u6e96\u6642", "CST", - "\u30ad\u30e5\u30fc\u30d0\u590f\u6642\u9593", "CDT", - "\u30AD\u30E5\u30FC\u30D0\u6642\u9593", "CT"}; - String DARWIN[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642(\u30CE\u30FC\u30B6\u30F3\u30C6\u30EA\u30C8\u30EA\u30FC)", "ACST", - "\u4E2D\u90E8\u590F\u6642\u9593(\u30CE\u30FC\u30B6\u30F3\u30C6\u30EA\u30C8\u30EA\u30FC)", "ACDT", - "\u4E2D\u90E8\u6A19\u6E96\u6642(\u30CE\u30FC\u30B6\u30F3\u30C6\u30EA\u30C8\u30EA\u30FC)", "ACT"}; - String DUBLIN[] = new String[] {"\u30b0\u30ea\u30cb\u30c3\u30b8\u6a19\u6e96\u6642", "GMT", - "\u30a2\u30a4\u30eb\u30e9\u30f3\u30c9\u590f\u6642\u9593", "IST", - "\u30A2\u30A4\u30EB\u30E9\u30F3\u30C9\u6642\u9593", "IT"}; - String EAT[] = new String[] {"\u6771\u30a2\u30d5\u30ea\u30ab\u6642\u9593", "EAT", - "\u6771\u30a2\u30d5\u30ea\u30ab\u590f\u6642\u9593", "EAST", - "\u6771\u90E8\u30A2\u30D5\u30EA\u30AB\u6642\u9593", "EAT"}; - String EASTER[] = new String[] {"\u30a4\u30fc\u30b9\u30bf\u30fc\u5cf6\u6642\u9593", "EAST", - "\u30a4\u30fc\u30b9\u30bf\u30fc\u5cf6\u590f\u6642\u9593", "EASST", - "\u30A4\u30FC\u30B9\u30BF\u30FC\u5CF6\u6642\u9593", "EAST"}; - String EET[] = new String[] {"\u6771\u30e8\u30fc\u30ed\u30c3\u30d1\u6642\u9593", "EET", - "\u6771\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "EEST", - "\u6771\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u6642\u9593", "EET"}; - String EGT[] = new String[] {"\u6771\u30b0\u30ea\u30fc\u30f3\u30e9\u30f3\u30c9\u6642\u9593", "EGT", - "\u6771\u30b0\u30ea\u30fc\u30f3\u30e9\u30f3\u30c9\u590f\u6642\u9593", "EGST", - "\u6771\u90E8\u30B0\u30EA\u30FC\u30F3\u30E9\u30F3\u30C9\u6642\u9593", "EGT"}; - String EST[] = new String[] {"\u6771\u90e8\u6a19\u6e96\u6642", "EST", - "\u6771\u90e8\u590f\u6642\u9593", "EDT", - "\u6771\u90E8\u6A19\u6E96\u6642", "ET"}; - String EST_NSW[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642(\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "AEST", - "\u6771\u90E8\u590F\u6642\u9593(\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "AEDT", - "\u6771\u90E8\u6A19\u6E96\u6642(\u30CB\u30E5\u30FC\u30B5\u30A6\u30B9\u30A6\u30A7\u30FC\u30EB\u30BA)", "AET"}; - String FET[] = new String[] {"\u6975\u6771\u30E8\u30FC\u30ED\u30C3\u30D1\u6642\u9593", "FET", - "\u6975\u6771\u30E8\u30FC\u30ED\u30C3\u30D1\u590F\u6642\u9593", "FEST", - "\u6975\u6771\u30E8\u30FC\u30ED\u30C3\u30D1\u6642\u9593", "FET"}; - String GHMT[] = new String[] {"\u30ac\u30fc\u30ca\u6a19\u6e96\u6642", "GMT", - "\u30ac\u30fc\u30ca\u590f\u6642\u9593", "GHST", - "\u30AC\u30FC\u30CA\u6A19\u6E96\u6642", "GMT"}; - String GAMBIER[] = new String[] {"\u30ac\u30f3\u30d3\u30a2\u6642\u9593", "GAMT", - "\u30ac\u30f3\u30d3\u30a2\u590f\u6642\u9593", "GAMST", - "\u30AC\u30F3\u30D3\u30A8\u6642\u9593", "GAMT"}; - String GMT[] = new String[] {"\u30b0\u30ea\u30cb\u30c3\u30b8\u6a19\u6e96\u6642", "GMT", - "\u30b0\u30ea\u30cb\u30c3\u30b8\u6a19\u6e96\u6642", "GMT", - "\u30B0\u30EA\u30CB\u30C3\u30B8\u6A19\u6E96\u6642", "GMT"}; - String GMTBST[] = new String[] {"\u30b0\u30ea\u30cb\u30c3\u30b8\u6a19\u6e96\u6642", "GMT", - "\u82f1\u56fd\u590f\u6642\u9593", "BST", - "\u30A4\u30AE\u30EA\u30B9\u6642\u9593", "BT"}; - String GST[] = new String[] {"\u6e7e\u5cb8\u6a19\u6e96\u6642", "GST", - "\u6e7e\u5cb8\u590f\u6642\u9593", "GDT", - "\u6E7E\u5CB8\u6642\u9593", "GT"}; - String HKT[] = new String[] {"\u9999\u6e2f\u6642\u9593", "HKT", - "\u9999\u6e2f\u590f\u6642\u9593", "HKST", - "\u9999\u6E2F\u6642\u9593", "HKT"}; - String HST[] = new String[] {"\u30cf\u30ef\u30a4\u6a19\u6e96\u6642", "HST", - "\u30cf\u30ef\u30a4\u590f\u6642\u9593", "HDT", - "\u30CF\u30EF\u30A4\u6642\u9593", "HT"}; - String ICT[] = new String[] {"\u30a4\u30f3\u30c9\u30b7\u30ca\u6642\u9593", "ICT", - "\u30a4\u30f3\u30c9\u30b7\u30ca\u590f\u6642\u9593", "ICST", - "\u30A4\u30F3\u30C9\u30B7\u30CA\u6642\u9593", "ICT"}; - String IRKT[] = new String[] {"\u30a4\u30eb\u30af\u30fc\u30c4\u30af\u6642\u9593", "IRKT", - "\u30a4\u30eb\u30af\u30fc\u30c4\u30af\u590f\u6642\u9593", "IRKST", - "\u30A4\u30EB\u30AF\u30FC\u30C4\u30AF\u6642\u9593", "IRKT"}; - String IRT[] = new String[] {"\u30a4\u30e9\u30f3\u6a19\u6e96\u6642", "IRST", - "\u30a4\u30e9\u30f3\u590f\u6642\u9593", "IRDT", - "\u30A4\u30E9\u30F3\u6642\u9593", "IRT"}; - String ISRAEL[] = new String[] {"\u30a4\u30b9\u30e9\u30a8\u30eb\u6a19\u6e96\u6642", "IST", - "\u30a4\u30b9\u30e9\u30a8\u30eb\u590f\u6642\u9593", "IDT", - "\u30A4\u30B9\u30E9\u30A8\u30EB\u6642\u9593", "IT"}; - String IST[] = new String[] {"\u30a4\u30f3\u30c9\u6a19\u6e96\u6642", "IST", - "\u30a4\u30f3\u30c9\u590f\u6642\u9593", "IDT", - "\u30A4\u30F3\u30C9\u6642\u9593", "IT"}; - String JST[] = new String[] {"\u65e5\u672c\u6a19\u6e96\u6642", "JST", - "\u65e5\u672c\u590f\u6642\u9593", "JDT", - "\u65E5\u672C\u6642\u9593", "JT"}; - String KRAT[] = new String[] {"\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u6642\u9593", "KRAT", - "\u30af\u30e9\u30b9\u30ce\u30e4\u30eb\u30b9\u30af\u590f\u6642\u9593", "KRAST", - "\u30AF\u30E9\u30B9\u30CE\u30E4\u30EB\u30B9\u30AF\u6642\u9593", "KRAT"}; - String KST[] = new String[] {"\u97d3\u56fd\u6a19\u6e96\u6642", "KST", - "\u97d3\u56fd\u590f\u6642\u9593", "KDT", - "\u97D3\u56FD\u6642\u9593", "KT"}; - String LORD_HOWE[] = new String[] {"\u30ed\u30fc\u30c9\u30cf\u30a6\u5cf6\u6a19\u6e96\u6642", "LHST", - "\u30ed\u30fc\u30c9\u30cf\u30a6\u5cf6\u590f\u6642\u9593", "LHDT", - "\u30ED\u30FC\u30C9\u30CF\u30A6\u6642\u9593", "LHT"}; - String MHT[] = new String[] {"\u30de\u30fc\u30b7\u30e3\u30eb\u5cf6\u6642\u9593", "MHT", - "\u30de\u30fc\u30b7\u30e3\u30eb\u5cf6\u590f\u6642\u9593", "MHST", - "\u30DE\u30FC\u30B7\u30E3\u30EB\u8AF8\u5CF6\u6642\u9593", "MHT"}; - String MMT[] = new String[] {"\u30df\u30e3\u30f3\u30de\u30fc\u6642\u9593", "MMT", - "\u30df\u30e3\u30f3\u30de\u30fc\u590f\u6642\u9593", "MMST", - "\u30DF\u30E3\u30F3\u30DE\u30FC\u6642\u9593", "MMT"}; - String MSK[] = new String[] {"\u30e2\u30b9\u30af\u30ef\u6a19\u6e96\u6642", "MSK", - "\u30e2\u30b9\u30af\u30ef\u590f\u6642\u9593", "MSD", - "\u30E2\u30B9\u30AF\u30EF\u6642\u9593", "MT"}; - String MST[] = new String[] {"\u5c71\u5730\u6a19\u6e96\u6642", "MST", - "\u5c71\u5730\u590f\u6642\u9593", "MDT", - "\u5C71\u5730\u6A19\u6E96\u6642", "MT"}; - String MYT[] = new String[] {"\u30de\u30ec\u30fc\u30b7\u30a2\u6642\u9593", "MYT", - "\u30de\u30ec\u30fc\u30b7\u30a2\u590f\u6642\u9593", "MYST", - "\u30DE\u30EC\u30FC\u30B7\u30A2\u6642\u9593", "MYT"}; - String NORONHA[] = new String[] {"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u6642\u9593", "FNT", - "\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u590f\u6642\u9593", "FNST", - "\u30D5\u30A7\u30EB\u30CA\u30F3\u30C9\u30FB\u30C7\u30FB\u30CE\u30ED\u30FC\u30CB\u30E3\u6642\u9593", "FNT"}; - String NOVT[] = new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT", - "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST", - "\u30CE\u30F4\u30A9\u30B7\u30D3\u30EB\u30B9\u30AF\u6642\u9593", "NOVT"}; - String NPT[] = new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT", - "\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST", - "\u30CD\u30D1\u30FC\u30EB\u6642\u9593", "NPT"}; - String NST[] = new String[] {"\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NST", - "\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u590f\u6642\u9593", "NDT", - "\u30CB\u30E5\u30FC\u30D5\u30A1\u30F3\u30C9\u30E9\u30F3\u30C9\u6642\u9593", "NT"}; - String NZST[] = new String[] {"\u30cb\u30e5\u30fc\u30b8\u30fc\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NZST", - "\u30cb\u30e5\u30fc\u30b8\u30fc\u30e9\u30f3\u30c9\u590f\u6642\u9593", "NZDT", - "\u30CB\u30E5\u30FC\u30B8\u30FC\u30E9\u30F3\u30C9\u6642\u9593", "NZT"}; - String PITCAIRN[] = new String[] {"\u30d4\u30c8\u30b1\u30eb\u30f3\u5cf6\u6a19\u6e96\u6642", "PST", - "\u30d4\u30c8\u30b1\u30eb\u30f3\u5cf6\u590f\u6642\u9593", "PDT", - "\u30D4\u30C8\u30B1\u30A2\u30F3\u6642\u9593", "PT"}; - String PKT[] = new String[] {"\u30d1\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "PKT", - "\u30d1\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "PKST", - "\u30D1\u30AD\u30B9\u30BF\u30F3\u6642\u9593", "PKT"}; - String PONT[] = new String[] {"\u30DD\u30F3\u30DA\u30A4\u6642\u9593", "PONT", - "\u30DD\u30F3\u30DA\u30A4\u590F\u6642\u9593", "PONST", - "\u30DD\u30CA\u30DA\u6642\u9593", "PONT"}; - String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "PST", - "\u592a\u5e73\u6d0b\u590f\u6642\u9593", "PDT", - "\u592A\u5E73\u6D0B\u6A19\u6E96\u6642", "PT"}; - String SAST[] = new String[] {"\u5357\u30a2\u30d5\u30ea\u30ab\u6a19\u6e96\u6642", "SAST", - "\u5357\u30a2\u30d5\u30ea\u30ab\u590f\u6642\u9593", "SAST", - "\u5357\u30A2\u30D5\u30EA\u30AB\u6642\u9593", "SAT"}; - String SBT[] = new String[] {"\u30bd\u30ed\u30e2\u30f3\u8af8\u5cf6\u6642\u9593", "SBT", - "\u30bd\u30ed\u30e2\u30f3\u8af8\u5cf6\u590f\u6642\u9593", "SBST", - "\u30BD\u30ED\u30E2\u30F3\u8AF8\u5CF6\u6642\u9593", "SBT"}; - String SGT[] = new String[] {"\u30b7\u30f3\u30ac\u30dd\u30fc\u30eb\u6642\u9593", "SGT", - "\u30b7\u30f3\u30ac\u30dd\u30fc\u30eb\u590f\u6642\u9593", "SGST", - "\u30B7\u30F3\u30AC\u30DD\u30FC\u30EB\u6642\u9593", "SGT"}; - String TASMANIA[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642(\u30BF\u30B9\u30DE\u30CB\u30A2)", "AEST", - "\u6771\u90E8\u590F\u6642\u9593(\u30BF\u30B9\u30DE\u30CB\u30A2)", "AEDT", - "\u6771\u90E8\u6A19\u6E96\u6642(\u30BF\u30B9\u30DE\u30CB\u30A2)", "AET"}; - String TMT[] = new String[] {"\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u6642\u9593", "TMT", - "\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3\u590f\u6642\u9593", "TMST", - "\u30C8\u30EB\u30AF\u30E1\u30CB\u30B9\u30BF\u30F3\u6642\u9593", "TMT"}; - String ULAT[]= new String[] {"\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u6642\u9593", "ULAT", - "\u30a6\u30e9\u30fc\u30f3\u30d0\u30fc\u30c8\u30eb\u590f\u6642\u9593", "ULAST", - "\u30A6\u30E9\u30F3\u30D0\u30FC\u30C8\u30EB\u6642\u9593", "ULAT"}; - String WAT[] = new String[] {"\u897f\u30a2\u30d5\u30ea\u30ab\u6642\u9593", "WAT", - "\u897f\u30a2\u30d5\u30ea\u30ab\u590f\u6642\u9593", "WAST", - "\u897F\u90E8\u30A2\u30D5\u30EA\u30AB\u6642\u9593", "WAT"}; - String WET[] = new String[] {"\u897f\u30e8\u30fc\u30ed\u30c3\u30d1\u6642\u9593", "WET", - "\u897f\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "WEST", - "\u897F\u90E8\u30E8\u30FC\u30ED\u30C3\u30D1\u6642\u9593", "WET"}; - String WGT[] = new String[] {"\u897f\u30b0\u30ea\u30fc\u30f3\u30e9\u30f3\u30c9\u6642\u9593", "WGT", - "\u897f\u30b0\u30ea\u30fc\u30f3\u30e9\u30f3\u30c9\u590f\u6642\u9593", "WGST", - "\u897F\u90E8\u30B0\u30EA\u30FC\u30F3\u30E9\u30F3\u30C9\u6642\u9593", "WGT"}; - String WIT[] = new String[] {"\u897f\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "WIB", - "\u897f\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "WIST", - "\u897F\u90E8\u30A4\u30F3\u30C9\u30CD\u30B7\u30A2\u6642\u9593", "WIB"}; - String WST_AUS[] = new String[] {"\u897F\u90E8\u6A19\u6E96\u6642(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "AWST", - "\u897F\u90E8\u590F\u6642\u9593(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "AWDT", - "\u897F\u90E8\u6642\u9593(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "AWT"}; - String SAMOA[] = new String[] {"\u30b5\u30e2\u30a2\u6a19\u6e96\u6642", "SST", - "\u30b5\u30e2\u30a2\u590f\u6642\u9593", "SDT", - "\u30B5\u30E2\u30A2\u6642\u9593", "ST"}; - String WST_SAMOA[] = new String[] {"\u897f\u30b5\u30e2\u30a2\u6642\u9593", "WSST", - "\u897f\u30b5\u30e2\u30a2\u590f\u6642\u9593", "WSDT", - "\u897F\u30B5\u30E2\u30A2\u6642\u9593", "WST"}; - String ChST[] = new String[] {"\u30b0\u30a2\u30e0\u6a19\u6e96\u6642", "ChST", - "\u30b0\u30a2\u30e0\u590f\u6642\u9593", "ChDT", - "\u30C1\u30E3\u30E2\u30ED\u6642\u9593", "ChT"}; - String VICTORIA[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642(\u30D3\u30AF\u30C8\u30EA\u30A2)", "AEST", - "\u6771\u90E8\u590F\u6642\u9593(\u30D3\u30AF\u30C8\u30EA\u30A2)", "AEDT", - "\u6771\u90E8\u6A19\u6E96\u6642(\u30D3\u30AF\u30C8\u30EA\u30A2)", "AET"}; - String UTC[] = new String[] {"\u5354\u5b9a\u4e16\u754c\u6642", "UTC", - "\u5354\u5b9a\u4e16\u754c\u6642", "UTC", - "\u5354\u5B9A\u4E16\u754C\u6642", "UTC"}; - String UZT[] = new String[] {"\u30a6\u30ba\u30d9\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "UZT", - "\u30a6\u30ba\u30d9\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "UZST", - "\u30A6\u30BA\u30D9\u30AD\u30B9\u30BF\u30F3\u6642\u9593", "UZT"}; - String XJT[] = new String[] {"\u4e2d\u56fd\u6a19\u6e96\u6642", "XJT", - "\u4e2d\u56fd\u590f\u6642\u9593", "XJDT", - "\u4E2D\u56FD\u6642\u9593", "XJT"}; - String YAKT[] = new String[] {"\u30e4\u30af\u30fc\u30c4\u30af\u6642\u9593", "YAKT", - "\u30e4\u30af\u30fc\u30c4\u30af\u590f\u6642\u9593", "YAKST", - "\u30E4\u30AF\u30FC\u30C4\u30AF\u6642\u9593", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"\u30d1\u30e9\u30b0\u30a2\u30a4\u6642\u9593", "PYT", - "\u30d1\u30e9\u30b0\u30a2\u30a4\u590f\u6642\u9593", "PYST", - "\u30D1\u30E9\u30B0\u30A2\u30A4\u6642\u9593", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"\u30b3\u30ed\u30f3\u30d3\u30a2\u6642\u9593", "COT", - "\u30b3\u30ed\u30f3\u30d3\u30a2\u590f\u6642\u9593", "COST", - "\u30B3\u30ED\u30F3\u30D3\u30A2\u6642\u9593", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u30d9\u30cd\u30ba\u30a8\u30e9\u6642\u9593", "VET", - "\u30d9\u30cd\u30ba\u30a8\u30e9\u590f\u6642\u9593", "VEST", - "\u30D9\u30CD\u30BA\u30A8\u30E9\u6642\u9593", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"\u4ecf\u9818\u30ae\u30a2\u30ca\u6642\u9593", "GFT", - "\u4ecf\u9818\u30ae\u30a2\u30ca\u590f\u6642\u9593", "GFST", - "\u30D5\u30E9\u30F3\u30B9\u9818\u30AE\u30A2\u30CA\u6642\u9593", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"\u30a8\u30af\u30a2\u30c9\u30eb\u6642\u9593", "ECT", - "\u30a8\u30af\u30a2\u30c9\u30eb\u590f\u6642\u9593", "ECST", - "\u30A8\u30AF\u30A2\u30C9\u30EB\u6642\u9593", "ECT"}}, - {"America/Guyana", new String[] {"\u30ac\u30a4\u30a2\u30ca\u6642\u9593", "GYT", - "\u30ac\u30a4\u30a2\u30ca\u590f\u6642\u9593", "GYST", - "\u30AC\u30A4\u30A2\u30CA\u6642\u9593", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"\u30dc\u30ea\u30d3\u30a2\u6642\u9593", "BOT", - "\u30dc\u30ea\u30d3\u30a2\u590f\u6642\u9593", "BOST", - "\u30DC\u30EA\u30D3\u30A2\u6642\u9593", "BOT"}}, - {"America/Lima", new String[] {"\u30da\u30eb\u30fc\u6642\u9593", "PET", - "\u30da\u30eb\u30fc\u590f\u6642\u9593", "PEST", - "\u30DA\u30EB\u30FC\u6642\u9593", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"\u30b5\u30f3\u30d4\u30a8\u30fc\u30eb\u30fb\u30df\u30af\u30ed\u30f3\u8af8\u5cf6\u6a19\u6e96\u6642", "PMST", - "\u30b5\u30f3\u30d4\u30a8\u30fc\u30eb\u30fb\u30df\u30af\u30ed\u30f3\u8af8\u5cf6\u590f\u6642\u9593", "PMDT", - "\u30D4\u30A8\u30FC\u30EB\u30FB\u30DF\u30AF\u30ED\u30F3\u6642\u9593", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"\u30a6\u30eb\u30b0\u30a2\u30a4\u6642\u9593", "UYT", - "\u30a6\u30eb\u30b0\u30a2\u30a4\u590f\u6642\u9593", "UYST", - "\u30A6\u30EB\u30B0\u30A2\u30A4\u6642\u9593", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"\u30b9\u30ea\u30ca\u30e0\u6642\u9593", "SRT", - "\u30b9\u30ea\u30ca\u30e0\u590f\u6642\u9593", "SRST", - "\u30B9\u30EA\u30CA\u30E0\u6642\u9593", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT", - "\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST", - "\u30C7\u30FC\u30D3\u30B9\u6642\u9593", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT", - "\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u590f\u6642\u9593", "DDUST", - "\u30C7\u30E5\u30E2\u30F3\u30FB\u30C7\u30E5\u30EB\u30D3\u30EB\u6642\u9593", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"\u30e2\u30fc\u30bd\u30f3\u6642\u9593", "MAWT", - "\u30e2\u30fc\u30bd\u30f3\u590f\u6642\u9593", "MAWST", - "\u30E2\u30FC\u30BD\u30F3\u6642\u9593", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"\u30ed\u30bc\u30e9\u6642\u9593", "ROTT", - "\u30ed\u30bc\u30e9\u590f\u6642\u9593", "ROTST", - "\u30ED\u30BC\u30E9\u6642\u9593", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"\u662d\u548c\u57fa\u5730\u6642\u9593", "SYOT", - "\u662d\u548c\u57fa\u5730\u590f\u6642\u9593", "SYOST", - "\u662D\u548C\u57FA\u5730\u6642\u9593", "SYOT"}}, - {"Antarctica/Troll", new String[] {"\u5354\u5b9a\u4e16\u754c\u6642", "UTC", - "\u4e2d\u90e8\u30e8\u30fc\u30ed\u30c3\u30d1\u590f\u6642\u9593", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"\u30dc\u30b9\u30c8\u30fc\u30af\u57fa\u5730\u6642\u9593", "VOST", - "\u30dc\u30b9\u30c8\u30fc\u30af\u57fa\u5730\u590f\u6642\u9593", "VOSST", - "\u30DC\u30B9\u30C8\u30FC\u30AF\u6642\u9593", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"\u30a2\u30eb\u30de\u30a2\u30bf\u6642\u9593", "ALMT", - "\u30a2\u30eb\u30de\u30a2\u30bf\u590f\u6642\u9593", "ALMST", - "\u30A2\u30EB\u30DE\u30A2\u30BF\u6642\u9593", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"\u30a2\u30ca\u30c9\u30a5\u30a4\u30ea\u6642\u9593", "ANAT", - "\u30a2\u30ca\u30c9\u30a5\u30a4\u30ea\u590f\u6642\u9593", "ANAST", - "\u30A2\u30CA\u30C7\u30A3\u30EA\u6642\u9593", "ANAT"}}, - {"Asia/Aqtau", new String[] {"\u30a2\u30af\u30bf\u30a6\u6642\u9593", "AQTT", - "\u30a2\u30af\u30bf\u30a6\u590f\u6642\u9593", "AQTST", - "\u30A2\u30AF\u30BF\u30A6\u6642\u9593", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"\u30a2\u30af\u30c8\u30d9\u6642\u9593", "AQTT", - "\u30a2\u30af\u30c8\u30d9\u590f\u6642\u9593", "AQTST", - "\u30A2\u30AF\u30C8\u30D9\u6642\u9593", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"\u30a2\u30bc\u30eb\u30d0\u30a4\u30b8\u30e3\u30f3\u6642\u9593", "AZT", - "\u30a2\u30bc\u30eb\u30d0\u30a4\u30b8\u30e3\u30f3\u590f\u6642\u9593", "AZST", - "\u30A2\u30BC\u30EB\u30D0\u30A4\u30B8\u30E3\u30F3\u6642\u9593", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"\u30ad\u30eb\u30ae\u30b9\u30bf\u30f3\u6642\u9593", "KGT", - "\u30ad\u30eb\u30ae\u30b9\u30bf\u30f3\u590f\u6642\u9593", "KGST", - "\u30AD\u30EB\u30AE\u30B9\u6642\u9593", "KGT"}}, - {"Asia/Brunei", new String[] {"\u30d6\u30eb\u30cd\u30a4\u6642\u9593", "BNT", - "\u30d6\u30eb\u30cd\u30a4\u590f\u6642\u9593", "BNST", - "\u30D6\u30EB\u30CD\u30A4\u6642\u9593", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"\u30c1\u30e7\u30a4\u30d0\u30eb\u30b5\u30f3\u6642\u9593", "CHOT", - "\u30c1\u30e7\u30a4\u30d0\u30eb\u30b5\u30f3\u590f\u6642\u9593", "CHOST", - "\u30C1\u30E7\u30A4\u30D0\u30EB\u30B5\u30F3\u6642\u9593", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"\u6771\u30c6\u30a3\u30e2\u30fc\u30eb\u6642\u9593", "TLT", - "\u6771\u30c6\u30a3\u30e2\u30fc\u30eb\u590f\u6642\u9593", "TLST", - "\u6771\u30C6\u30A3\u30E2\u30FC\u30EB\u6642\u9593", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"\u30bf\u30b8\u30ad\u30b9\u30bf\u30f3\u6642\u9593", "TJT", - "\u30bf\u30b8\u30ad\u30b9\u30bf\u30f3\u590f\u6642\u9593", "TJST", - "\u30BF\u30B8\u30AD\u30B9\u30BF\u30F3\u6642\u9593", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"\u30db\u30d6\u30c9\u6642\u9593", "HOVT", - "\u30db\u30d6\u30c9\u590f\u6642\u9593", "HOVST", - "\u30DB\u30D6\u30C9\u6642\u9593", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"\u6771\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u6642\u9593", "WIT", - "\u6771\u30a4\u30f3\u30c9\u30cd\u30b7\u30a2\u590f\u6642\u9593", "EIST" , - "\u6771\u90E8\u30A4\u30F3\u30C9\u30CD\u30B7\u30A2\u6642\u9593", "WIT"}}, - {"Asia/Kabul", new String[] {"\u30a2\u30d5\u30ac\u30cb\u30b9\u30bf\u30f3\u6642\u9593", "AFT", - "\u30a2\u30d5\u30ac\u30cb\u30b9\u30bf\u30f3\u590f\u6642\u9593", "AFST", - "\u30A2\u30D5\u30AC\u30CB\u30B9\u30BF\u30F3\u6642\u9593", "AFT"}}, - {"Asia/Kamchatka", new String[] {"\u30da\u30c8\u30ed\u30d1\u30d6\u30ed\u30d5\u30b9\u30af\u30ab\u30e0\u30c1\u30e3\u30c4\u30ad\u30fc\u6642\u9593", "PETT", - "\u30da\u30c8\u30ed\u30d1\u30d6\u30ed\u30d5\u30b9\u30af\u30ab\u30e0\u30c1\u30e3\u30c4\u30ad\u30fc\u590f\u6642\u9593", "PETST", - "\u30DA\u30C8\u30ED\u30D1\u30D6\u30ED\u30D5\u30B9\u30AF\u30FB\u30AB\u30E0\u30C1\u30E3\u30C4\u30AD\u30FC\u6642\u9593", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"\u30de\u30ac\u30c0\u30f3\u6642\u9593", "MAGT", - "\u30de\u30ac\u30c0\u30f3\u590f\u6642\u9593", "MAGST", - "\u30DE\u30AC\u30C0\u30F3\u6642\u9593", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"\u30aa\u30e9\u30eb\u6642\u9593", "ORAT", - "\u30aa\u30e9\u30eb\u590f\u6642\u9593", "ORAST", - "\u30AA\u30E9\u30EB\u6642\u9593", "ORAT"}}, - {"Asia/Omsk", new String[] {"\u30aa\u30e0\u30b9\u30af\u6642\u9593", "OMST", - "\u30aa\u30e0\u30b9\u30af\u590f\u6642\u9593", "OMSST", - "\u30AA\u30E0\u30B9\u30AF\u6642\u9593", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"\u30ad\u30b8\u30eb\u30aa\u30eb\u30c0\u6642\u9593", "QYZT", - "\u30ad\u30b8\u30eb\u30aa\u30eb\u30c0\u590f\u6642\u9593", "QYZST", - "\u30AF\u30BA\u30ED\u30EB\u30C0\u6642\u9593", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"\u6a3a\u592a\u6642\u9593", "SAKT", - "\u6a3a\u592a\u590f\u6642\u9593", "SAKST", - "\u30B5\u30CF\u30EA\u30F3\u6642\u9593", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"\u30b0\u30eb\u30b8\u30a2\u6642\u9593", "GET", - "\u30b0\u30eb\u30b8\u30a2\u590f\u6642\u9593", "GEST", - "\u30B0\u30EB\u30B8\u30A2\u6642\u9593", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"\u30A6\u30B9\u30C1\u30CD\u30E9\u6642\u9593", "VLAT", - "\u30A6\u30B9\u30C1\u30CD\u30E9\u590F\u6642\u9593", "VLAST", - "\u30A6\u30B9\u30C1\u30CD\u30E9\u6642\u9593", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"\u30a6\u30e9\u30b8\u30aa\u30b9\u30c8\u30af\u6642\u9593", "VLAT", - "\u30a6\u30e9\u30b8\u30aa\u30b9\u30c8\u30af\u590f\u6642\u9593", "VLAST", - "\u30A6\u30E9\u30B8\u30AA\u30B9\u30C8\u30AF\u6642\u9593", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"\u30a8\u30ab\u30c6\u30ea\u30f3\u30d6\u30eb\u30b0\u6642\u9593", "YEKT", - "\u30a8\u30ab\u30c6\u30ea\u30f3\u30d6\u30eb\u30b0\u590f\u6642\u9593", "YEKST", - "\u30A8\u30AB\u30C6\u30EA\u30F3\u30D6\u30EB\u30AF\u6642\u9593", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"\u30a2\u30be\u30ec\u30b9\u6642\u9593", "AZOT", - "\u30a2\u30be\u30ec\u30b9\u590f\u6642\u9593", "AZOST", - "\u30A2\u30BE\u30EC\u30B9\u6642\u9593", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"\u30ab\u30fc\u30dc\u30d9\u30eb\u30c7\u6642\u9593", "CVT", - "\u30ab\u30fc\u30dc\u30d9\u30eb\u30c7\u590f\u6642\u9593", "CVST", - "\u30AB\u30FC\u30DC\u30D9\u30EB\u30C7\u6642\u9593", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"\u5357\u30b8\u30e7\u30fc\u30b8\u30a2\u5cf6\u6a19\u6e96\u6642", "GST", - "\u5357\u30b8\u30e7\u30fc\u30b8\u30a2\u5cf6\u590f\u6642\u9593", "GDT", - "\u5357\u30B8\u30E7\u30FC\u30B8\u30A2\u6642\u9593", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"\u30d5\u30a9\u30fc\u30af\u30e9\u30f3\u30c9\u8af8\u5cf6\u6642\u9593", "FKT", - "\u30d5\u30a9\u30fc\u30af\u30e9\u30f3\u30c9\u8af8\u5cf6\u590f\u6642\u9593", "FKST", - "\u30D5\u30A9\u30FC\u30AF\u30E9\u30F3\u30C9\u8AF8\u5CF6\u6642\u9593", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"\u4E2D\u897F\u90E8\u6A19\u6E96\u6642(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACWST", - "\u4E2D\u897F\u90E8\u590F\u6642\u9593(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACWDT", - "\u4E2D\u897F\u90E8\u6642\u9593(\u30AA\u30FC\u30B9\u30C8\u30E9\u30EA\u30A2)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"\u30b5\u30de\u30e9\u6642\u9593", "SAMT", - "\u30b5\u30de\u30e9\u590f\u6642\u9593", "SAMST", - "\u30B5\u30DE\u30E9\u6642\u9593", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"\u30a4\u30f3\u30c9\u6d0b\u5730\u57df\u6642\u9593", "IOT", - "\u30a4\u30f3\u30c9\u6d0b\u5730\u57df\u590f\u6642\u9593", "IOST", - "\u30A4\u30F3\u30C9\u6D0B\u5730\u57DF\u6642\u9593", "IOT"}}, - {"Indian/Christmas", new String[] {"\u30af\u30ea\u30b9\u30de\u30b9\u8af8\u5cf6\u6642\u9593", "CXT", - "\u30af\u30ea\u30b9\u30de\u30b9\u8af8\u5cf6\u590f\u6642\u9593", "CXST", - "\u30AF\u30EA\u30B9\u30DE\u30B9\u5CF6\u6642\u9593", "CIT"}}, - {"Indian/Cocos", new String[] {"\u30b3\u30b3\u30b9\u8af8\u5cf6\u6642\u9593", "CCT", - "\u30b3\u30b3\u30b9\u8af8\u5cf6\u590f\u6642\u9593", "CCST", - "\u30B3\u30B3\u30B9\u8AF8\u5CF6\u6642\u9593", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"\u4ecf\u5357\u65b9\u9818\u304a\u3088\u3073\u5357\u6975\u6642\u9593", "TFT", - "\u4ecf\u5357\u65b9\u9818\u304a\u3088\u3073\u5357\u6975\u590f\u6642\u9593", "TFST", - "\u30D5\u30E9\u30F3\u30B9\u9818\u5357\u65B9\u304A\u3088\u3073\u5357\u6975\u5927\u9678\u6642\u9593", "TFT"}}, - {"Indian/Mahe", new String[] {"\u30bb\u30a4\u30b7\u30a7\u30eb\u6642\u9593", "SCT", - "\u30bb\u30a4\u30b7\u30a7\u30eb\u590f\u6642\u9593", "SCST", - "\u30BB\u30FC\u30B7\u30A7\u30EB\u6642\u9593", "SCT"}}, - {"Indian/Maldives", new String[] {"\u30e2\u30eb\u30b8\u30d6\u6642\u9593", "MVT", - "\u30e2\u30eb\u30b8\u30d6\u590f\u6642\u9593", "MVST", - "\u30E2\u30EB\u30B8\u30D6\u6642\u9593", "MVT"}}, - {"Indian/Mauritius", new String[] {"\u30e2\u30fc\u30ea\u30b7\u30e3\u30b9\u6642\u9593", "MUT", - "\u30e2\u30fc\u30ea\u30b7\u30e3\u30b9\u590f\u6642\u9593", "MUST", - "\u30E2\u30FC\u30EA\u30B7\u30E3\u30B9\u6642\u9593", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"\u30ec\u30e6\u30cb\u30aa\u30f3\u6642\u9593", "RET", - "\u30ec\u30e6\u30cb\u30aa\u30f3\u590f\u6642\u9593", "REST", - "\u30EC\u30E6\u30CB\u30AA\u30F3\u6642\u9593", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"\u30d0\u30cc\u30a2\u30c4\u6642\u9593", "VUT", - "\u30d0\u30cc\u30a2\u30c4\u590f\u6642\u9593", "VUST", - "\u30D0\u30CC\u30A2\u30C4\u6642\u9593", "VUT"}}, - {"Pacific/Enderbury", new String[] {"\u30d5\u30a7\u30cb\u30c3\u30af\u30b9\u8af8\u5cf6\u6642\u9593", "PHOT", - "\u30d5\u30a7\u30cb\u30c3\u30af\u30b9\u8af8\u5cf6\u590f\u6642\u9593", "PHOST", - "\u30D5\u30A7\u30CB\u30C3\u30AF\u30B9\u8AF8\u5CF6\u6642\u9593", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"\u30c8\u30b1\u30e9\u30a6\u8af8\u5cf6\u6642\u9593", "TKT", - "\u30c8\u30b1\u30e9\u30a6\u8af8\u5cf6\u590f\u6642\u9593", "TKST", - "\u30C8\u30B1\u30E9\u30A6\u6642\u9593", "TKT"}}, - {"Pacific/Fiji", new String[] {"\u30d5\u30a3\u30b8\u30fc\u6642\u9593", "FJT", - "\u30d5\u30a3\u30b8\u30fc\u590f\u6642\u9593", "FJST", - "\u30D5\u30A3\u30B8\u30FC\u6642\u9593", "FJT"}}, - {"Pacific/Funafuti", new String[] {"\u30c4\u30d0\u30eb\u6642\u9593", "TVT", - "\u30c4\u30d0\u30eb\u590f\u6642\u9593", "TVST", - "\u30C4\u30D0\u30EB\u6642\u9593", "TVT"}}, - {"Pacific/Galapagos", new String[] {"\u30ac\u30e9\u30d1\u30b4\u30b9\u6642\u9593", "GALT", - "\u30ac\u30e9\u30d1\u30b4\u30b9\u590f\u6642\u9593", "GALST", - "\u30AC\u30E9\u30D1\u30B4\u30B9\u6642\u9593", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"\u30e9\u30a4\u30f3\u8af8\u5cf6\u6642\u9593", "LINT", - "\u30e9\u30a4\u30f3\u8af8\u5cf6\u590f\u6642\u9593", "LINST", - "\u30E9\u30A4\u30F3\u8AF8\u5CF6\u6642\u9593", "LINT"}}, - {"Pacific/Kosrae", new String[] {"\u30b3\u30b9\u30e9\u30a8\u6642\u9593", "KOST", - "\u30b3\u30b9\u30e9\u30a8\u590f\u6642\u9593", "KOSST", - "\u30B3\u30B9\u30E9\u30A8\u6642\u9593", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"\u30de\u30eb\u30b1\u30b5\u30b9\u6642\u9593", "MART", - "\u30de\u30eb\u30b1\u30b5\u30b9\u590f\u6642\u9593", "MARST", - "\u30DE\u30EB\u30AD\u30FC\u30BA\u6642\u9593", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"\u30ca\u30a6\u30eb\u6642\u9593", "NRT", - "\u30ca\u30a6\u30eb\u590f\u6642\u9593", "NRST", - "\u30CA\u30A6\u30EB\u6642\u9593", "NRT"}}, - {"Pacific/Niue", new String[] {"\u30cb\u30a6\u30a8\u5cf6\u6642\u9593", "NUT", - "\u30cb\u30a6\u30a8\u5cf6\u590f\u6642\u9593", "NUST", - "\u30CB\u30A6\u30A8\u6642\u9593", "NUT"}}, - {"Pacific/Norfolk", new String[] {"\u30ce\u30fc\u30d5\u30a9\u30fc\u30af\u6642\u9593", "NFT", - "\u30ce\u30fc\u30d5\u30a9\u30fc\u30af\u590f\u6642\u9593", "NFST", - "\u30CE\u30FC\u30D5\u30A9\u30FC\u30AF\u6642\u9593", "NFT"}}, - {"Pacific/Noumea", new String[] {"\u30cb\u30e5\u30fc\u30ab\u30ec\u30c9\u30cb\u30a2\u6642\u9593", "NCT", - "\u30cb\u30e5\u30fc\u30ab\u30ec\u30c9\u30cb\u30a2\u590f\u6642\u9593", "NCST", - "\u30CB\u30E5\u30FC\u30AB\u30EC\u30C9\u30CB\u30A2\u6642\u9593", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"\u30d1\u30e9\u30aa\u6642\u9593", "PWT", - "\u30d1\u30e9\u30aa\u590f\u6642\u9593", "PWST", - "\u30D1\u30E9\u30AA\u6642\u9593", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u6642\u9593", "PGT", - "\u30d1\u30d7\u30a2\u30cb\u30e5\u30fc\u30ae\u30cb\u30a2\u590f\u6642\u9593", "PGST", - "\u30D1\u30D7\u30A2\u30CB\u30E5\u30FC\u30AE\u30CB\u30A2\u6642\u9593", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"\u30af\u30c3\u30af\u8af8\u5cf6\u6642\u9593", "CKT", - "\u30af\u30c3\u30af\u8af8\u5cf6\u590f\u6642\u9593", "CKHST", - "\u30AF\u30C3\u30AF\u8AF8\u5CF6\u6642\u9593", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"\u30bf\u30d2\u30c1\u6642\u9593", "TAHT", - "\u30bf\u30d2\u30c1\u590f\u6642\u9593", "TAHST", - "\u30BF\u30D2\u30C1\u6642\u9593", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"\u30ae\u30eb\u30d0\u30fc\u30c8\u8af8\u5cf6\u6642\u9593", "GILT", - "\u30ae\u30eb\u30d0\u30fc\u30c8\u8af8\u5cf6\u590f\u6642\u9593", "GILST", - "\u30AE\u30EB\u30D0\u30FC\u30C8\u8AF8\u5CF6\u6642\u9593", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"\u30c8\u30f3\u30ac\u6642\u9593", "TOT", - "\u30c8\u30f3\u30ac\u590f\u6642\u9593", "TOST", - "\u30C8\u30F3\u30AC\u6642\u9593", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"\u30a6\u30a7\u30fc\u30af\u6642\u9593", "WAKT", - "\u30a6\u30a7\u30fc\u30af\u590f\u6642\u9593", "WAKST", - "\u30A6\u30A7\u30FC\u30AF\u6642\u9593", "WAKT"}}, - {"Pacific/Wallis", new String[] {"\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u6642\u9593", "WFT", - "\u30ef\u30ea\u30b9\u53ca\u3073\u30d5\u30c4\u30ca\u590f\u6642\u9593", "WFST", - "\u30A6\u30A9\u30EA\u30B9\u30FB\u30D5\u30C4\u30CA\u6642\u9593", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java deleted file mode 100644 index e8e6d45e523..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_ko extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"\uc5d0\uc774\ucee4 \uc2dc\uac04", "ACT", - "\uc5d0\uc774\ucee4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ACST", - "\uc5d0\uc774\ucee4 \uc2dc\uac04", "ACT"}; - String ADELAIDE[] = new String[] {"\uC911\uBD80 \uD45C\uC900\uC2DC(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACST", - "\uC911\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACDT", - "\uC911\uBD80 \uD45C\uC900\uC2DC(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACT"}; - String AGT[] = new String[] {"\uc544\ub974\ud5e8\ud2f0\ub098 \uc2dc\uac04", "ART", - "\uc544\ub974\ud5e8\ud2f0\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ARST", - "\uC544\uB974\uD5E8\uD2F0\uB098 \uD45C\uC900\uC2DC", "ART"}; - String AKST[] = new String[] {"\uc54c\ub798\uc2a4\uce74 \ud45c\uc900\uc2dc", "AKST", - "\uc54c\ub798\uc2a4\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AKDT", - "\uC54C\uB798\uC2A4\uCE74 \uD45C\uC900\uC2DC", "AKT"}; - String AMT[] = new String[] {"\uc544\ub9c8\uc874 \uc2dc\uac04", "AMT", - "\uc544\ub9c8\uc874 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AMST", - "\uC544\uB9C8\uC874 \uD45C\uC900\uC2DC", "AMT"}; - String ARAST[] = new String[] {"\uc544\ub78d \ud45c\uc900\uc2dc", "AST", - "\uc544\ub78d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ADT", - "\uC544\uB77C\uBE44\uC544 \uD45C\uC900\uC2DC", "AT"}; - String ARMT[] = new String[] {"\uc544\ub974\uba54\ub2c8\uc544 \uc2dc\uac04", "AMT", - "\uc544\ub974\uba54\ub2c8\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AMST", - "\uC544\uB974\uBA54\uB2C8\uC544 \uD45C\uC900\uC2DC", "AMT"}; - String AST[] = new String[] {"\ub300\uc11c\uc591 \ud45c\uc900\uc2dc", "AST", - "\ub300\uc11c\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ADT", - "\uB300\uC11C\uC591 \uD45C\uC900\uC2DC", "AT"}; - String BDT[] = new String[] {"\ubc29\uae00\ub77c\ub370\uc2dc \uc2dc\uac04", "BDT", - "\ubc29\uae00\ub77c\ub370\uc2dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BDST", - "\uBC29\uAE00\uB77C\uB370\uC2DC \uD45C\uC900\uC2DC", "BDT"}; - String BRISBANE[] = new String[] {"\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uD038\uC990\uB79C\uB4DC)", "AEST", - "\uB3D9\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uD038\uC990\uB79C\uB4DC)", "AEDT", - "\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uD038\uC990\uB79C\uB4DC)", "AET"}; - String BROKEN_HILL[] = new String[] {"\uC911\uBD80 \uD45C\uC900\uC2DC(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544/\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "ACST", - "\uC911\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544/\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "ACDT", - "\uC911\uBD80 \uD45C\uC900\uC2DC(\uB0A8\uBD80 \uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544/\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "ACT"}; - String BRT[] = new String[] {"\ube0c\ub77c\uc9c8\ub9ac\uc544 \uc2dc\uac04", "BRT", - "\ube0c\ub77c\uc9c8\ub9ac\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BRST", - "\uBE0C\uB77C\uC9C8\uB9AC\uC544 \uD45C\uC900\uC2DC", "BRT"}; - String BTT[] = new String[] {"\ubd80\ud0c4 \uc2dc\uac04", "BTT", - "\ubd80\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BTST", - "\uBD80\uD0C4 \uD45C\uC900\uC2DC", "BTT"}; - String CAT[] = new String[] {"\uc911\uc559 \uc544\ud504\ub9ac\uce74 \uc2dc\uac04", "CAT", - "\uc911\uc559 \uc544\ud504\ub9ac\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CAST", - "\uC911\uC559 \uC544\uD504\uB9AC\uCE74 \uD45C\uC900\uC2DC", "CAT"}; - String CET[] = new String[] {"\uc911\uc559 \uc720\ub7fd \uc2dc\uac04", "CET", - "\uc911\uc559 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CEST", - "\uC911\uC559 \uC720\uB7FD \uD45C\uC900\uC2DC", "CET"}; - String CHAST[] = new String[] {"Chatham \ud45c\uc900\uc2dc", "CHAST", - "Chatham \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CHADT", - "\uCC44\uD140 \uD45C\uC900\uC2DC", "CHAT"}; - String CHUT[] = new String[] {"\uCD94\uD06C \uD45C\uC900\uC2DC", "CHUT", - "\uCD94\uD06C \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04", "CHUST", - "\uCD94\uD06C \uD45C\uC900\uC2DC", "CHUT"}; - String CIT[] = new String[] {"\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "WITA", - "\uc911\uc559 \uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CIST", - "\uC911\uBD80 \uC778\uB3C4\uB124\uC2DC\uC544 \uD45C\uC900\uC2DC", "WITA"}; - String CLT[] = new String[] {"\uce60\ub808 \uc2dc\uac04", "CLT", - "\uce60\ub808 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CLST", - "\uCE60\uB808 \uD45C\uC900\uC2DC", "CLT"}; - String CST[] = new String[] {"\uc911\ubd80 \ud45c\uc900\uc2dc", "CST", - "\uc911\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CDT", - "\uC911\uBD80 \uD45C\uC900\uC2DC", "CT"}; - String CTT[] = new String[] {"\uc911\uad6d \ud45c\uc900\uc2dc", "CST", - "\uc911\uad6d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CDT", - "\uC911\uAD6D \uD45C\uC900\uC2DC", "CT"}; - String CUBA[] = new String[] {"\ucfe0\ubc14 \ud45c\uc900\uc2dc", "CST", - "\ucfe0\ubc14 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CDT", - "\uCFE0\uBC14 \uD45C\uC900\uC2DC", "CT"}; - String DARWIN[] = new String[] {"\uC911\uBD80 \uD45C\uC900\uC2DC(\uBD81\uBD80 \uC9C0\uC5ED)", "ACST", - "\uC911\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uBD81\uBD80 \uC9C0\uC5ED)", "ACDT", - "\uC911\uBD80 \uD45C\uC900\uC2DC(\uBD81\uBD80 \uC9C0\uC5ED)", "ACT"}; - String DUBLIN[] = new String[] {"\uadf8\ub9ac\ub2c8\uce58 \ud45c\uc900\uc2dc", "GMT", - "\uc544\uc77c\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IST", - "\uC544\uC77C\uB79C\uB4DC \uD45C\uC900\uC2DC", "IT"}; - String EAT[] = new String[] {"\ub3d9\ubd80 \uc544\ud504\ub9ac\uce74 \uc2dc\uac04", "EAT", - "\ub3d9\ubd80 \uc544\ud504\ub9ac\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EAST", - "\uB3D9\uBD80 \uC544\uD504\uB9AC\uCE74 \uD45C\uC900\uC2DC", "EAT"}; - String EASTER[] = new String[] {"Easter Is. \uc2dc\uac04", "EAST", - "Easter Is. \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EASST", - "\uC774\uC2A4\uD130 \uC12C \uD45C\uC900\uC2DC", "EAST"}; - String EET[] = new String[] {"\ub3d9\uc720\ub7fd \uc2dc\uac04", "EET", - "\ub3d9\uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EEST", - "\ub3d9\ubd80 \uc720\ub7fd \ud45c\uc900\uc2dc", "EET"}; - String EGT[] = new String[] {"\ub3d9\ubd80 \uadf8\ub9b0\ub79c\ub4dc \uc2dc\uac04", "EGT", - "\ub3d9\ubd80 \uadf8\ub9b0\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EGST", - "\uB3D9\uBD80 \uADF8\uB9B0\uB780\uB4DC \uD45C\uC900\uC2DC", "EGT"}; - String EST[] = new String[] {"\ub3d9\ubd80 \ud45c\uc900\uc2dc", "EST", - "\ub3d9\ubd80 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EDT", - "\uB3D9\uBD80 \uD45C\uC900\uC2DC", "ET"}; - String EST_NSW[] = new String[] {"\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "AEST", - "\uB3D9\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "AEDT", - "\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uB274\uC0AC\uC6B0\uC2A4\uC6E8\uC77C\uC988)", "AET"}; - String FET[] = new String[] {"\uADF9\uB3D9 \uC720\uB7FD \uD45C\uC900\uC2DC", "FET", - "\uADF9\uB3D9 \uC720\uB7FD \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04", "FEST", - "\uADF9\uB3D9 \uC720\uB7FD \uD45C\uC900\uC2DC", "FET"}; - String GHMT[] = new String[] {"\uac00\ub098 \ud45c\uc900\uc2dc", "GMT", - "\uac00\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GHST", - "\uAC00\uB098 \uD45C\uC900\uC2DC", "GMT"}; - String GAMBIER[] = new String[] {"\uac10\ube44\uc544 \uc2dc\uac04", "GAMT", - "\uac10\ube44\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GAMST", - "\uC7A0\uBE44\uC544 \uD45C\uC900\uC2DC", "GAMT"}; - String GMT[] = new String[] {"\uadf8\ub9ac\ub2c8\uce58 \ud45c\uc900\uc2dc", "GMT", - "\uadf8\ub9ac\ub2c8\uce58 \ud45c\uc900\uc2dc", "GMT", - "\uADF8\uB9AC\uB2C8\uCE58 \uD45C\uC900\uC2DC", "GMT"}; - String GMTBST[] = new String[] {"\uadf8\ub9ac\ub2c8\uce58 \ud45c\uc900\uc2dc", "GMT", - "\uc601\uad6d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BST", - "\uC601\uAD6D \uD45C\uC900\uC2DC", "BT"}; - String GST[] = new String[] {"\uac78\ud504\ub9cc \ud45c\uc900\uc2dc", "GST", - "\uac78\ud504\ub9cc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GDT", - "\uAC78\uD504\uB9CC \uD45C\uC900\uC2DC", "GT"}; - String HKT[] = new String[] {"\ud64d\ucf69 \uc2dc\uac04", "HKT", - "\ud64d\ucf69 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "HKST", - "\uD64D\uCF69 \uD45C\uC900\uC2DC", "HKT"}; - String HST[] = new String[] {"\ud558\uc640\uc774 \ud45c\uc900\uc2dc", "HST", - "\ud558\uc640\uc774 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "HDT", - "\uD558\uC640\uC774 \uD45C\uC900\uC2DC", "HT"}; - String ICT[] = new String[] {"\uc778\ub3c4\ucc28\uc774\ub098 \ubc18\ub3c4 \uc2dc\uac04", "ICT", - "\uc778\ub3c4\ucc28\uc774\ub098 \ubc18\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ICST", - "\uC778\uB3C4\uCC28\uC774\uB098 \uBC18\uB3C4 \uD45C\uC900\uC2DC", "ICT"}; - String IRKT[] = new String[] {"\uc774\ub974\ucfe0\uce20\ud06c \uc2dc\uac04", "IRKT", - "\uc774\ub974\ucfe0\uce20\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IRKST", - "\uC774\uB974\uCFE0\uCE20\uD06C \uD45C\uC900\uC2DC", "IRKT"}; - String IRT[] = new String[] {"\uc774\ub780 \ud45c\uc900\uc2dc", "IRST", - "\uc774\ub780 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IRDT", - "\uC774\uB780 \uD45C\uC900\uC2DC", "IRT"}; - String ISRAEL[] = new String[] {"\uc774\uc2a4\ub77c\uc5d8 \ud45c\uc900\uc2dc", "IST", - "\uc774\uc2a4\ub77c\uc5d8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IDT", - "\uC544\uC2A4\uB77C\uC5D8 \uD45C\uC900\uC2DC", "IT"}; - String IST[] = new String[] {"\uc778\ub3c4 \ud45c\uc900\uc2dc", "IST", - "\uc778\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IDT", - "\uC778\uB3C4 \uD45C\uC900\uC2DC", "IT"}; - String JST[] = new String[] {"\uc77c\ubcf8 \ud45c\uc900\uc2dc", "JST", - "\uc77c\ubcf8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "JDT", - "\uC77C\uBCF8 \uD45C\uC900\uC2DC", "JT"}; - String KRAT[] = new String[] {"\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc2dc\uac04", "KRAT", - "\ud06c\ub77c\uc2a4\ub178\uc57c\ub974\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KRAST", - "\uD06C\uB77C\uC2A4\uB178\uC57C\uB974\uC2A4\uD06C \uD45C\uC900\uC2DC", "KRAT"}; - String KST[] = new String[] {"\ud55c\uad6d \ud45c\uc900\uc2dc", "KST", - "\ud55c\uad6d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KDT", - "\uB300\uD55C\uBBFC\uAD6D \uD45C\uC900\uC2DC", "KT"}; - String LORD_HOWE[] = new String[] {"\ub85c\ub4dc \ud558\uc6b0 \ud45c\uc900\uc2dc", "LHST", - "\ub85c\ub4dc \ud558\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "LHDT", - "\uB85C\uB4DC\uD558\uC6B0 \uD45C\uC900\uC2DC", "LHT"}; - String MHT[] = new String[] {"\ub9c8\uc15c\uc81c\ub3c4 \uc2dc\uac04", "MHT", - "\ub9c8\uc15c\uc81c\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MHST", - "\uB9C8\uC15C \uC81C\uB3C4 \uD45C\uC900\uC2DC", "MHT"}; - String MMT[] = new String[] {"\ubbf8\uc580\ub9c8 \uc2dc\uac04", "MMT", - "\ubbf8\uc580\ub9c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MMST", - "\uBBF8\uC580\uB9C8 \uD45C\uC900\uC2DC", "MMT"}; - String MSK[] = new String[] {"\ubaa8\uc2a4\ud06c\ubc14 \ud45c\uc900\uc2dc", "MSK", - "\ubaa8\uc2a4\ud06c\ubc14 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MSD", - "\uBAA8\uC2A4\uD06C\uBC14 \uD45C\uC900\uC2DC", "MT"}; - String MST[] = new String[] {"\uc0b0\uc9c0 \ud45c\uc900\uc2dc", "MST", - "\uc0b0\uc9c0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MDT", - "\uC0B0\uC9C0 \uD45C\uC900\uC2DC", "MT"}; - String MYT[] = new String[] {"\ub9d0\ub808\uc774\uc2dc\uc544 \uc2dc\uac04", "MYT", - "\ub9d0\ub808\uc774\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MYST", - "\uB9D0\uB808\uC774\uC2DC\uC544 \uD45C\uC900\uC2DC", "MYT"}; - String NORONHA[] = new String[] {"Fernando de Noronha \uc2dc\uac04", "FNT", - "Fernando de Noronha \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FNST", - "\uD398\uB974\uB09C\uB3C4 \uB4DC \uB178\uB85C\uD558 \uD45C\uC900\uC2DC", "FNT"}; - String NOVT[] = new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT", - "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST", - "\uB178\uBCF4\uC2DC\uBE44\uB974\uC2A4\uD06C \uD45C\uC900\uC2DC", "NOVT"}; - String NPT[] = new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT", - "\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST", - "\uB124\uD314 \uD45C\uC900\uC2DC", "NPT"}; - String NST[] = new String[] {"\ub274\ud380\ub4e4\ub79c\ub4dc \ud45c\uc900\uc2dc", "NST", - "\ub274\ud380\ub4e4\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NDT", - "\uB274\uD380\uB4E4\uB79C\uB4DC \uD45C\uC900\uC2DC", "NT"}; - String NZST[] = new String[] {"\ub274\uc9c8\ub79c\ub4dc \ud45c\uc900\uc2dc", "NZST", - "\ub274\uc9c8\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NZDT", - "\uB274\uC9C8\uB79C\uB4DC \uD45C\uC900\uC2DC", "NZT"}; - String PITCAIRN[] = new String[] {"Pitcairn \ud45c\uc900\uc2dc", "PST", - "Pitcairn \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT", - "\uD54F\uCF00\uC5B8 \uD45C\uC900\uC2DC", "PT"}; - String PKT[] = new String[] {"\ud30c\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "PKT", - "\ud30c\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PKST", - "\uD30C\uD0A4\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "PKT"}; - String PONT[] = new String[] {"\uD3F0\uD398\uC774 \uD45C\uC900\uC2DC", "PONT", - "\uD3F0\uD398\uC774 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04", "PONST", - "\uD3EC\uB098\uD398 \uD45C\uC900\uC2DC", "PONT"}; - String PST[] = new String[] {"\ud0dc\ud3c9\uc591 \ud45c\uc900\uc2dc", "PST", - "\ud0dc\ud3c9\uc591 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PDT", - "\uD0DC\uD3C9\uC591 \uD45C\uC900\uC2DC", "PT"}; - String SAST[] = new String[] {"\ub0a8\uc544\ud504\ub9ac\uce74 \ud45c\uc900\uc2dc", "SAST", - "\ub0a8\uc544\ud504\ub9ac\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SAST", - "\uB0A8\uC544\uD504\uB9AC\uCE74 \uD45C\uC900\uC2DC", "SAT"}; - String SBT[] = new String[] {"\uc194\ub85c\ubaac \uad70\ub3c4 \uc2dc\uac04", "SBT", - "\uc194\ub85c\ubaac \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SBST", - "\uC194\uB85C\uBAAC \uC81C\uB3C4 \uD45C\uC900\uC2DC", "SBT"}; - String SGT[] = new String[] {"\uc2f1\uac00\ud3ec\ub974 \uc2dc\uac04", "SGT", - "\uc2f1\uac00\ud3ec\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SGST", - "\uC2F1\uAC00\uD3EC\uB974 \uD45C\uC900\uC2DC", "SGT"}; - String TASMANIA[] = new String[] {"\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uD0DC\uC988\uBA54\uC774\uB2C8\uC544)", "AEST", - "\uB3D9\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uD0DC\uC988\uBA54\uC774\uB2C8\uC544)", "AEDT", - "\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uD0DC\uC988\uBA54\uC774\uB2C8\uC544)", "AET"}; - String TMT[] = new String[] {"\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc2dc\uac04", "TMT", - "\ud22c\ub974\ud06c\uba54\ub2c8\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TMST", - "\uD22C\uB974\uD06C\uBA54\uB2C8\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "TMT"}; - String ULAT[]= new String[] {"\uc6b8\ub780\ubc14\ud0c0\ub974 \uc2dc\uac04", "ULAT", - "\uc6b8\ub780\ubc14\ud0c0\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ULAST", - "\uC6B8\uB780\uBC14\uD1A0\uB974 \uD45C\uC900\uC2DC", "ULAT"}; - String WAT[] = new String[] {"\uc11c\ubd80 \uc544\ud504\ub9ac\uce74 \uc2dc\uac04", "WAT", - "\uc11c\ubd80 \uc544\ud504\ub9ac\uce74 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WAST", - "\uC11C\uBD80 \uC544\uD504\uB9AC\uCE74 \uD45C\uC900\uC2DC", "WAT"}; - String WET[] = new String[] {"\uc11c\uc720\ub7fd \uc2dc\uac04", "WET", - "\uc11c\uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WEST", - "\uC11C\uBD80 \uC720\uB7FD \uD45C\uC900\uC2DC", "WET"}; - String WGT[] = new String[] {"\uc11c\ubd80 \uadf8\ub9b0\ub79c\ub4dc \uc2dc\uac04", "WGT", - "\uc11c\ubd80 \uadf8\ub9b0\ub79c\ub4dc \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WGST", - "\uC11C\uBD80 \uADF8\uB9B0\uB780\uB4DC \uD45C\uC900\uC2DC", "WGT"}; - String WIT[] = new String[] {"\uc11c\uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "WIB", - "\uc11c\uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WIST", - "\uC11C\uBD80 \uC778\uB3C4\uB124\uC2DC\uC544 \uD45C\uC900\uC2DC", "WIB"}; - String WST_AUS[] = new String[] {"\uC11C\uBD80 \uD45C\uC900\uC2DC(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "AWST", - "\uC11C\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "AWDT", - "\uC11C\uBD80 \uD45C\uC900\uC2DC(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "AWT"}; - String SAMOA[] = new String[] {"\uc0ac\ubaa8\uc544 \ud45c\uc900\uc2dc", "SST", - "\uc0ac\ubaa8\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SDT", - "\uC0AC\uBAA8\uC544 \uD45C\uC900\uC2DC", "ST"}; - String WST_SAMOA[] = new String[] {"\uc11c\uc0ac\ubaa8\uc544 \uc2dc\uac04", "WSST", - "\uc11c\uc0ac\ubaa8\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WSDT", - "\uC11C\uC0AC\uBAA8\uC544 \uD45C\uC900\uC2DC", "WST"}; - String ChST[] = new String[] {"\ucc28\ubaa8\ub85c \ud45c\uc900\uc2dc", "ChST", - "\ucc28\ubaa8\ub85c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ChDT", - "\uCC28\uBAA8\uB974 \uD45C\uC900\uC2DC", "ChT"}; - String VICTORIA[] = new String[] {"\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uBE45\uD1A0\uB9AC\uC544)", "AEST", - "\uB3D9\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uBE45\uD1A0\uB9AC\uC544)", "AEDT", - "\uB3D9\uBD80 \uD45C\uC900\uC2DC(\uBE45\uD1A0\uB9AC\uC544)", "AET"}; - String UTC[] = new String[] {"\uc138\uacc4 \ud45c\uc900\uc2dc", "UTC", - "\uc138\uacc4 \ud45c\uc900\uc2dc", "UTC", - "\uC9C0\uC5ED \uD45C\uC900\uC2DC", "UTC"}; - String UZT[] = new String[] {"\uc6b0\uc988\ubca0\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "UZT", - "\uc6b0\uc988\ubca0\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "UZST", - "\uC6B0\uC988\uBCA0\uD0A4\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "UZT"}; - String XJT[] = new String[] {"\uc911\uad6d \ud45c\uc900\uc2dc", "XJT", - "\uc911\uad6d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "XJDT", - "\uC911\uAD6D \uD45C\uC900\uC2DC", "XJT"}; - String YAKT[] = new String[] {"\uc57c\uce20\ud06c \uc2dc\uac04", "YAKT", - "\uc57c\uce20\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "YAKST", - "\uC57C\uCFE0\uCE20\uD06C \uD45C\uC900\uC2DC", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"\ud30c\ub77c\uacfc\uc774 \uc2dc\uac04", "PYT", - "\ud30c\ub77c\uacfc\uc774 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PYST", - "\uD30C\uB77C\uACFC\uC774 \uD45C\uC900\uC2DC", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"\ucf5c\ub86c\ube44\uc544 \uc2dc\uac04", "COT", - "\ucf5c\ub86c\ube44\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "COST", - "\uCF5C\uB86C\uBE44\uC544 \uD45C\uC900\uC2DC", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\ubca0\ub124\uc218\uc5d8\ub77c \uc2dc\uac04", "VET", - "\ubca0\ub124\uc218\uc5d8\ub77c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VEST", - "\uBCA0\uB124\uC218\uC5D8\uB77C \uD45C\uC900\uC2DC", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"\ud504\ub791\uc2a4\ub839 \uae30\uc544\ub098 \uc2dc\uac04", "GFT", - "\ud504\ub791\uc2a4\ub839 \uae30\uc544\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GFST", - "\uD504\uB791\uC2A4\uB839 \uAE30\uC544\uB098 \uD45C\uC900\uC2DC", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"\uc5d0\ucfe0\uc544\ub3c4\ub974 \uc2dc\uac04", "ECT", - "\uc5d0\ucfe0\uc544\ub3c4\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ECST", - "\uC5D0\uCF70\uB3C4\uB974 \uD45C\uC900\uC2DC", "ECT"}}, - {"America/Guyana", new String[] {"\uac00\uc774\uc544\ub098 \uc2dc\uac04", "GYT", - "\uac00\uc774\uc544\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GYST", - "\uAC00\uC774\uC544\uB098 \uD45C\uC900\uC2DC", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"\ubcfc\ub9ac\ube44\uc544 \uc2dc\uac04", "BOT", - "\ubcfc\ub9ac\ube44\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BOST", - "\uBCFC\uB9AC\uBE44\uC544 \uD45C\uC900\uC2DC", "BOT"}}, - {"America/Lima", new String[] {"\ud398\ub8e8 \uc2dc\uac04", "PET", - "\ud398\ub8e8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PEST", - "\uD398\uB8E8 \uD45C\uC900\uC2DC", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"\ud53c\uc5d0\ub974 \ubbf8\ud06c\ub860 \ud45c\uc900\uc2dc", "PMST", - "\ud53c\uc5d0\ub974 \ubbf8\ud06c\ub860 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PMDT", - "\uD53C\uC5D0\uB974 \uBBF8\uD074\uB871 \uD45C\uC900\uC2DC", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"\uc6b0\ub8e8\uacfc\uc774 \uc2dc\uac04", "UYT", - "\uc6b0\ub8e8\uacfc\uc774 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "UYST", - "\uC6B0\uB8E8\uACFC\uC774 \uD45C\uC900\uC2DC", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"\uc218\ub9ac\ub0a8 \uc2dc\uac04", "SRT", - "\uc218\ub9ac\ub0a8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SRST", - "\uC218\uB9AC\uB0A8 \uD45C\uC900\uC2DC", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT", - "Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST", - "\uB370\uC774\uBE44\uC2A4 \uD45C\uC900\uC2DC", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT", - "\ub4a4\ubabd \ub4a4\ub974\ube4c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DDUST", - "\uB450\uBAAC\uD2B8\uC6B0\uB974\uBE4C \uD45C\uC900\uC2DC", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"\ubaa8\uc2a8 \uc2dc\uac04", "MAWT", - "\ubaa8\uc2a8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MAWST", - "\uB9C8\uC2A8 \uD45C\uC900\uC2DC", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"\ub85c\uc81c\ub77c \ud45c\uc900\uc2dc", "ROTT", - "\ub85c\uc81c\ub77c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ROTST", - "\uB85C\uB354\uB77C \uD45C\uC900\uC2DC", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Syowa \uc2dc\uac04", "SYOT", - "Syowa \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SYOST", - "\uC1FC\uC640 \uD45C\uC900\uC2DC", "SYOT"}}, - {"Antarctica/Troll", new String[] {"\uc138\uacc4 \ud45c\uc900\uc2dc", "UTC", - "\uc911\uc559 \uc720\ub7fd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Vostok \uc2dc\uac04", "VOST", - "Vostok \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VOSST", - "\uBCF4\uC2A4\uD1A1 \uD45C\uC900\uC2DC", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"\uc54c\ub9c8\uc544\ud0c0 \uc2dc\uac04", "ALMT", - "\uc54c\ub9c8\uc544\ud0c0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ALMST", - "\uC54C\uB9C8\uC544\uD0C0 \uD45C\uC900\uC2DC", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"\uc544\ub098\ub514\ub974 \uc2dc\uac04", "ANAT", - "\uc544\ub098\ub514\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ANAST", - "\uC544\uB098\uB514\uB9AC \uD45C\uC900\uC2DC", "ANAT"}}, - {"Asia/Aqtau", new String[] {"\uc545\ud0c0\uc6b0 \uc2dc\uac04", "AQTT", - "\uc545\ud0c0\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AQTST", - "\uC544\uD06C\uD0C0\uC6B0 \uD45C\uC900\uC2DC", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"\uc545\ud1a0\ube0c \uc2dc\uac04", "AQTT", - "\uc545\ud1a0\ube0c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AQTST", - "\uC544\uD06C\uD1A0\uBCA0 \uD45C\uC900\uC2DC", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"\uc544\uc81c\ub974\ubc14\uc774\uc794 \uc2dc\uac04", "AZT", - "\uc544\uc81c\ub974\ubc14\uc774\uc794 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AZST", - "\uC544\uC81C\uB974\uBC14\uC774\uC794 \uD45C\uC900\uC2DC", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"\ud0a4\ub974\ud0a4\uc988\uc2a4\ud0c4 \uc2dc\uac04", "KGT", - "\ud0a4\ub974\uae30\uc988\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KGST", - "\uD0A4\uB974\uAE30\uC2A4\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "KGT"}}, - {"Asia/Brunei", new String[] {"\ube0c\ub8e8\ub098\uc774 \uc2dc\uac04", "BNT", - "\ube0c\ub8e8\ub098\uc774 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "BNST", - "\uBE0C\uB8E8\uB098\uC774 \uD45C\uC900\uC2DC", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Choibalsan \uc2dc\uac04", "CHOT", - "Choibalsan \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CHOST", - "\uCD08\uC774\uBC1C\uC0B0 \uD45C\uC900\uC2DC", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"\ud2f0\ubaa8\ub974-\ub808\uc2a4\ud14c \uc2dc\uac04", "TLT", - "\ud2f0\ubaa8\ub974-\ub808\uc2a4\ud14c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TLST", - "\uB3D9\uD2F0\uBAA8\uB974 \uD45C\uC900\uC2DC", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"\ud0c0\uc9c0\ud0a4\uc2a4\ud0c4 \uc2dc\uac04", "TJT", - "\ud0c0\uc9c0\ud0a4\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TJST", - "\uD0C0\uC9C0\uD0A4\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Hovd \uc2dc\uac04", "HOVT", - "Hovd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "HOVST", - "\uD638\uBE0C\uB4DC \uD45C\uC900\uC2DC", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"\ub3d9\ubd80 \uc778\ub3c4\ub124\uc2dc\uc544 \uc2dc\uac04", "WIT", - "\ub3d9\ubd80 \uc778\ub3c4\ub124\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "EIST", - "\uB3D9\uBD80 \uC778\uB3C4\uB124\uC2DC\uC544 \uD45C\uC900\uC2DC", "WIT"}}, - {"Asia/Kabul", new String[] {"\uc544\ud504\uac00\ub2c8\uc2a4\ud0c4 \uc2dc\uac04", "AFT", - "\uc544\ud504\uac00\ub2c8\uc2a4\ud0c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AFST", - "\uC544\uD504\uAC00\uB2C8\uC2A4\uD0C4 \uD45C\uC900\uC2DC", "AFT"}}, - {"Asia/Kamchatka", new String[] {"\ud398\ud2b8\ub85c\ud30c\ube14\ub85c\ud504\uc2a4\ud06c-\uce84\ucc28\uce20\ud0a4 \uc2dc\uac04", "PETT", - "\ud398\ud2b8\ub85c\ud30c\ube14\ub85c\ud504\uc2a4\ud06c-\uce84\ucc28\uce20\ud0a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PETST", - "\uD398\uD2B8\uB85C\uD30C\uBE0C\uB85C\uD504\uC2A4\uD06C-\uCE84\uCC28\uCE20\uD0A4 \uD45C\uC900\uC2DC", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"\ub9c8\uac00\ub2e8 \uc2dc\uac04", "MAGT", - "\ub9c8\uac00\ub2e8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MAGST", - "\uB9C8\uAC00\uB2E8 \uD45C\uC900\uC2DC", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Oral \ud45c\uc900\uc2dc", "ORAT", - "Oral \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ORAST", - "\uC624\uB7F4 \uD45C\uC900\uC2DC", "ORAT"}}, - {"Asia/Omsk", new String[] {"Omsk \uc2dc\uac04", "OMST", - "Omsk \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "OMSST", - "\uC634\uC2A4\uD06C \uD45C\uC900\uC2DC", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Qyzylorda \ud45c\uc900\uc2dc", "QYZT", - "Qyzylorda \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "QYZST", - "\uD0A4\uC9C8\uB85C\uB974\uB2E4 \uD45C\uC900\uC2DC", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"\uc0ac\ud560\ub9b0 \uc2dc\uac04", "SAKT", - "\uc0ac\ud560\ub9b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SAKST", - "\uC0AC\uD560\uB9B0 \uD45C\uC900\uC2DC", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"\uadf8\ub8e8\uc9c0\uc57c \uc2dc\uac04", "GET", - "\uadf8\ub8e8\uc9c0\uc57c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GEST", - "\uADF8\uB8E8\uC9C0\uC57C \uD45C\uC900\uC2DC", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"\uC6B0\uC2A4\uD2F0\uB124\uB77C \uD45C\uC900\uC2DC", "VLAT", - "\uC6B0\uC2A4\uD2F0\uB124\uB77C \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04", "VLAST" , - "\uC6B0\uC2A4\uD2F0\uB124\uB77C \uD45C\uC900\uC2DC", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"\ube14\ub77c\ub514\ubcf4\uc2a4\ud1a1 \uc2dc\uac04", "VLAT", - "\ube14\ub77c\ub514\ubcf4\uc2a4\ud1a1 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VLAST", - "\uBE14\uB77C\uB514\uBCF4\uC2A4\uD1A1 \uD45C\uC900\uC2DC", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"\uc608\uce74\ud14c\ub9b0\ubc84\uadf8 \uc2dc\uac04", "YEKT", - "\uc608\uce74\ud14c\ub9b0\ubc84\uadf8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "YEKST", - "\uC608\uCE74\uD14C\uB9B0\uBD80\uB974\uD06C \uD45C\uC900\uC2DC", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"\uc544\uc870\ub808\uc2a4 \uc2dc\uac04", "AZOT", - "\uc544\uc870\ub808\uc2a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "AZOST", - "\uC544\uC870\uB808\uC2A4 \uD45C\uC900\uC2DC", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"\uae4c\ubf40\ubca0\ub974\ub370 \uc2dc\uac04", "CVT", - "\uae4c\ubf40\ubca0\ub974\ub370 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CVST", - "\uCF00\uC774\uD504\uBCA0\uB974\uB370 \uD45C\uC900\uC2DC", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"\uc0ac\uc6b0\uc2a4 \uc870\uc9c0\uc544 \ud45c\uc900\uc2dc", "GST", - "\uc0ac\uc6b0\uc2a4 \uc870\uc9c0\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GDT", - "\uC0AC\uC6B0\uC2A4\uC870\uC9C0\uC544 \uD45C\uC900\uC2DC", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"\ud3ec\ud074\ub79c\ub4dc \uad70\ub3c4 \uc2dc\uac04", "FKT", - "\ud3ec\ud074\ub79c\ub4dc \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FKST", - "\uD3EC\uD074\uB79C\uB4DC \uC81C\uB3C4 \uD45C\uC900\uC2DC", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"\uC911\uC559 \uC11C\uBD80 \uD45C\uC900\uC2DC(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACWST", - "\uC911\uC559 \uC11C\uBD80 \uC77C\uAD11 \uC808\uC57D \uC2DC\uAC04(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACWDT", - "\uC911\uC559 \uC11C\uBD80 \uD45C\uC900\uC2DC(\uC624\uC2A4\uD2B8\uB808\uC77C\uB9AC\uC544)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"\uc0ac\ub9c8\ub77c \uc2dc\uac04", "SAMT", - "\uc0ac\ub9c8\ub77c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SAMST", - "\uC0AC\uB9C8\uB77C \uD45C\uC900\uC2DC", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"\uc601\uc778\ub3c4 \uc81c\ub3c4 \uc2dc\uac04", "IOT", - "\uc601\uc778\ub3c4 \uc81c\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "IOST", - "\uC778\uB3C4\uC591 \uC2DD\uBBFC\uC9C0 \uD45C\uC900\uC2DC", "IOT"}}, - {"Indian/Christmas", new String[] {"\ud06c\ub9ac\uc2a4\ub9c8\uc2a4\uc12c \uc2dc\uac04", "CXT", - "\ud06c\ub9ac\uc2a4\ub9c8\uc2a4\uc12c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CXST", - "\uD06C\uB9AC\uC2A4\uB9C8\uC2A4 \uC12C \uD45C\uC900\uC2DC", "CIT"}}, - {"Indian/Cocos", new String[] {"\ucf54\ucf54\uc2a4 \uad70\ub3c4 \uc2dc\uac04", "CCT", - "\ucf54\ucf54\uc2a4 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CCST", - "\uCF54\uCF54\uC2A4 \uC81C\uB3C4 \uD45C\uC900\uC2DC", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"\ud504\ub791\uc2a4 \ub0a8\ubd80 \uc9c0\ubc29 \ubc0f \ub0a8\uadf9 \uc9c0\uc5ed \uc2dc\uac04", "TFT", - "\ud504\ub791\uc2a4 \ub0a8\ubd80 \uc9c0\ubc29 \ubc0f \ub0a8\uadf9 \uc9c0\uc5ed \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TFST", - "\uD504\uB791\uC2A4\uB839 \uB0A8\uBD80 \uBC0F \uB0A8\uADF9 \uB300\uB959 \uD45C\uC900\uC2DC", "TFT"}}, - {"Indian/Mahe", new String[] {"\uc138\uc774\uc140 \uc2dc\uac04", "SCT", - "\uc138\uc774\uc258 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "SCST", - "\uC138\uC774\uC178 \uD45C\uC900\uC2DC", "SCT"}}, - {"Indian/Maldives", new String[] {"\ubab0\ub514\ube0c \uc2dc\uac04", "MVT", - "\ubab0\ub514\ube0c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MVST", - "\uBAB0\uB514\uBE0C \uD45C\uC900\uC2DC", "MVT"}}, - {"Indian/Mauritius", new String[] {"\ubaa8\ub9ac\uc154\uc2a4 \uc2dc\uac04", "MUT", - "\ubaa8\ub9ac\uc154\uc2a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MUST", - "\uBAA8\uB9AC\uC154\uC2A4 \uD45C\uC900\uC2DC", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"\ub9ac\uc720\ub2c8\uc5b8 \uc2dc\uac04", "RET", - "\ub9ac\uc720\ub2c8\uc5b8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "REST", - "\uB808\uC704\uB2C8\uC639 \uD45C\uC900\uC2DC", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"\ube44\ub204\uc544\ud22c \uc2dc\uac04", "VUT", - "\ubc14\ub204\uc544\ud22c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VUST", - "\uBC14\uB204\uC544\uD22C \uD45C\uC900\uC2DC", "VUT"}}, - {"Pacific/Enderbury", new String[] {"\ud53c\ub2c9\uc2a4 \uad70\ub3c4 \uc2dc\uac04", "PHOT", - "\ud53c\ub2c9\uc2a4 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PHOST", - "\uD53C\uB2C9\uC2A4 \uC81C\uB3C4 \uD45C\uC900\uC2DC", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"\ud1a0\ucf08\ub77c\uc6b0 \uc2dc\uac04", "TKT", - "\ud1a0\ucf08\ub77c\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TKST", - "\uD1A0\uCF08\uB77C\uC6B0 \uD45C\uC900\uC2DC", "TKT"}}, - {"Pacific/Fiji", new String[] {"\ud53c\uc9c0 \uc2dc\uac04", "FJT", - "\ud53c\uc9c0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FJST", - "\uD53C\uC9C0 \uD45C\uC900\uC2DC", "FJT"}}, - {"Pacific/Funafuti", new String[] {"\ud22c\ubc1c\ub8e8 \uc2dc\uac04", "TVT", - "\ud22c\ubc1c\ub8e8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TVST", - "\uD22C\uBC1C\uB8E8 \uD45C\uC900\uC2DC", "TVT"}}, - {"Pacific/Galapagos", new String[] {"\uac08\ub77c\ud30c\uace0\uc2a4 \uc2dc\uac04", "GALT", - "\uac08\ub77c\ud30c\uace0\uc2a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GALST", - "\uAC08\uB77C\uD30C\uACE0\uC2A4 \uD45C\uC900\uC2DC", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"\ub77c\uc778 \uad70\ub3c4 \uc2dc\uac04", "LINT", - "\ub77c\uc778 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "LINST", - "\uB77C\uC778 \uC81C\uB3C4 \uD45C\uC900\uC2DC", "LINT"}}, - {"Pacific/Kosrae", new String[] {"\ucf54\uc2a4\ub798 \uc2dc\uac04", "KOST", - "\ucf54\uc2a4\ub798 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "KOSST", - "\uCF54\uC2A4\uB808 \uD45C\uC900\uC2DC", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"\ub9c8\ub974\ucf00\uc0ac\uc2a4 \uc2dc\uac04", "MART", - "\ub9c8\ub974\ucf00\uc0ac\uc2a4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MARST", - "\uB9C8\uD0A4\uC800\uC2A4 \uD45C\uC900\uC2DC", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"\ub098\uc6b0\ub8e8 \uc2dc\uac04", "NRT", - "\ub098\uc6b0\ub8e8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NRST", - "\uB098\uC6B0\uB8E8 \uD45C\uC900\uC2DC", "NRT"}}, - {"Pacific/Niue", new String[] {"\ub2c8\uc6b0\uc5d0 \uc2dc\uac04", "NUT", - "\ub2c8\uc6b0\uc5d0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NUST", - "\uB2C8\uC6B0\uC5D0 \uD45C\uC900\uC2DC", "NUT"}}, - {"Pacific/Norfolk", new String[] {"\ub178\ud37d \uc2dc\uac04", "NFT", - "\ub178\ud37d \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NFST", - "\uB178\uD37D \uD45C\uC900\uC2DC", "NFT"}}, - {"Pacific/Noumea", new String[] {"\ub274 \uce7c\ub808\ub3c4\ub2c8\uc544 \uc2dc\uac04", "NCT", - "\ub274 \uce7c\ub808\ub3c4\ub2c8\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NCST", - "\uB274 \uCE7C\uB808\uB3C4\uB2C8\uC544 \uD45C\uC900\uC2DC", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"\ud314\ub77c\uc6b0 \uc2dc\uac04", "PWT", - "\ud314\ub77c\uc6b0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PWST", - "\uD314\uB77C\uC6B0 \uD45C\uC900\uC2DC", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc2dc\uac04", "PGT", - "\ud30c\ud478\uc544\ub274\uae30\ub2c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PGST", - "\uD30C\uD478\uC544 \uB274\uAE30\uB2C8\uC544 \uD45C\uC900\uC2DC", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"\ucfe0\ud06c \uad70\ub3c4 \uc2dc\uac04", "CKT", - "\ucfe0\ud06c \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "CKHST", - "\uCFE1 \uC81C\uB3C4 \uD45C\uC900\uC2DC", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"\ud0c0\ud788\ud2f0 \uc2dc\uac04", "TAHT", - "\ud0c0\ud788\ud2f0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TAHST", - "\uD0C0\uD788\uD2F0 \uD45C\uC900\uC2DC", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"\uae38\ubc84\ud2b8 \uad70\ub3c4 \uc2dc\uac04", "GILT", - "\uae38\ubc84\ud2b8 \uad70\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GILST", - "\uAE38\uBC84\uD2B8 \uC81C\uB3C4 \uD45C\uC900\uC2DC", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"\ud1b5\uac00 \uc2dc\uac04", "TOT", - "\ud1b5\uac00 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "TOST", - "\uD1B5\uAC00 \uD45C\uC900\uC2DC", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"\uc6e8\uc774\ud06c \uc2dc\uac04", "WAKT", - "\uc6e8\uc774\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WAKST", - "\uC6E8\uC774\uD06C \uD45C\uC900\uC2DC", "WAKT"}}, - {"Pacific/Wallis", new String[] {"\uc6d4\ub9ac\uc2a4 \ud6c4\ud22c\ub098 \uc2dc\uac04", "WFT", - "\uc6d4\ub9ac\uc2a4 \ud6c4\ud2b8\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "WFST", - "\uC6D4\uB9AC\uC2A4 \uD478\uD22C\uB098 \uD45C\uC900\uC2DC", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java deleted file mode 100644 index 8f79d22ca4e..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Fuso hor\u00e1rio do Acre", "ACT", - "Fuso hor\u00e1rio de ver\u00e3o do Acre", "ACST", - "Fuso hor\u00e1rio do Acre", "ACT"}; - String ADELAIDE[] = new String[] {"Hor\u00E1rio-Padr\u00E3o Central (Austr\u00E1lia do Sul)", "ACST", - "Fuso Hor\u00E1rio de Ver\u00E3o Central (Austr\u00E1lia do Sul)", "ACDT", - "Hor\u00E1rio Central (Austr\u00E1lia do Sul)", "ACT"}; - String AGT[] = new String[] {"Fuso hor\u00e1rio da Argentina", "ART", - "Fuso hor\u00e1rio de ver\u00e3o da Argentina", "ARST", - "Hor\u00E1rio da Argentina", "ART"}; - String AKST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Alaska", "AKST", - "Hor\u00e1rio de luz natural do Alaska", "AKDT", - "Hor\u00E1rio do Alasca", "AKT"}; - String AMT[] = new String[] {"Fuso hor\u00e1rio do Amazonas", "AMT", - "Fuso hor\u00e1rio de ver\u00e3o do Amazonas", "AMST", - "Hor\u00E1rio do Amazonas", "AMT"}; - String ARAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ar\u00e1bia", "AST", - "Hor\u00e1rio de luz natural da Ar\u00e1bia", "ADT", - "Hor\u00E1rio da Ar\u00E1bia", "AT"}; - String ARMT[] = new String[] {"Fuso hor\u00e1rio da Arm\u00eania", "AMT", - "Fuso hor\u00e1rio de ver\u00e3o da Arm\u00eania", "AMST", - "Hor\u00E1rio da Arm\u00EAnia", "AMT"}; - String AST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Atl\u00e2ntico", "AST", - "Hor\u00e1rio de luz natural do Atl\u00e2ntico", "ADT", - "Hor\u00E1rio do Atl\u00E2ntico", "AT"}; - String BDT[] = new String[] {"Fuso hor\u00e1rio de Bangladesh", "BDT", - "Fuso hor\u00e1rio de ver\u00e3o de Bangladesh", "BDST", - "Hor\u00E1rio de Bangladesh", "BDT"}; - String BRISBANE[] = new String[] {"Hor\u00E1rio-Padr\u00E3o do Leste (Queensland)", "AEST", - "Fuso Hor\u00E1rio de Ver\u00E3o Oriental (Queensland)", "AEDT", - "Hor\u00E1rio do Leste (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Hor\u00E1rio-Padr\u00E3o Central (Austr\u00E1lia do Sul/Nova Gales do Sul)", "ACST", - "Fuso Hor\u00E1rio de Ver\u00E3o Central (Austr\u00E1lia do Sul/Nova Gales do Sul)", "ACDT", - "Hor\u00E1rio Central (Austr\u00E1lia do Sul/Nova Gales do Sul)", "ACT"}; - String BRT[] = new String[] {"Fuso hor\u00e1rio de Bras\u00edlia", "BRT", - "Fuso hor\u00e1rio de ver\u00e3o de Bras\u00edlia", "BRST", - "Hor\u00E1rio de Bras\u00EDlia", "BRT"}; - String BTT[] = new String[] {"Fuso hor\u00e1rio de But\u00e3o", "BTT", - "Fuso hor\u00e1rio de ver\u00e3o de But\u00e3o", "BTST", - "Hor\u00E1rio do But\u00E3o", "BTT"}; - String CAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Central", "CAT", - "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Central", "CAST", - "Hor\u00E1rio da \u00C1frica Central", "CAT"}; - String CET[] = new String[] {"Fuso hor\u00e1rio da Europa Central", "CET", - "Fuso hor\u00e1rio de ver\u00e3o da Europa Central", "CEST", - "Hor\u00E1rio da Europa Central", "CET"}; - String CHAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chatham", "CHAST", - "Hor\u00e1rio de luz natural de Chatham", "CHADT", - "Hor\u00E1rio de Chatham", "CHAT"}; - String CIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Central", "WITA", - "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Central", "CIST", - "Hor\u00E1rio da Indon\u00E9sia Central", "WITA"}; - String CLT[] = new String[] {"Fuso hor\u00e1rio do Chile", "CLT", - "Fuso hor\u00e1rio de ver\u00e3o do Chile", "CLST", - "Hor\u00E1rio do Chile", "CLT"}; - String CST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central", "CST", - "Hor\u00e1rio de luz natural central", "CDT", - "Hor\u00E1rio Central", "CT"}; - String CTT[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da China", "CST", - "Hor\u00e1rio de luz natural da China", "CDT", - "Hor\u00E1rio da China", "CT"}; - String CUBA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Cuba", "CST", - "Hor\u00e1rio de luz natural de Cuba", "CDT", - "Hor\u00E1rio de Cuba", "CT"}; - String DARWIN[] = new String[] {"Hor\u00E1rio-Padr\u00E3o Central (Territ\u00F3rio do Norte)", "ACST", - "Fuso Hor\u00E1rio de Ver\u00E3o Central (Territ\u00F3rio do Norte)", "ACDT", - "Hor\u00E1rio Central (Territ\u00F3rio do Norte)", "ACT"}; - String DUBLIN[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", - "Fuso hor\u00e1rio de ver\u00e3o da Irlanda", "IST", - "Hor\u00E1rio da Rep\u00FAblica da Irlanda", "IT"}; - String EAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Oriental", "EAT", - "Fuso hor\u00e1rio padr\u00e3o da \u00c1frica Oriental", "EAST", - "Hor\u00E1rio do Leste da \u00C1frica", "EAT"}; - String EASTER[] = new String[] {"Fuso hor\u00e1rio da Ilha de P\u00e1scoa", "EAST", - "Fuso hor\u00e1rio de ver\u00e3o da Ilha de P\u00e1scoa", "EASST", - "Hor\u00E1rio da Ilha de P\u00E1scoa", "EAST"}; - String EET[] = new String[] {"Fuso hor\u00e1rio da Europa Oriental", "EET", - "Fuso hor\u00e1rio de ver\u00e3o da Europa Oriental", "EEST", - "Hor\u00e1rio da Europa Oriental", "EET"}; - String EGT[] = new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Oriental", "EGT", - "Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Oriental", "EGST", - "Hor\u00E1rio da Groenl\u00E2ndia Oriental", "EGT"}; - String EST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental", "EST", - "Hor\u00e1rio de luz natural oriental", "EDT", - "Hor\u00E1rio do Leste", "ET"}; - String EST_NSW[] = new String[] {"Hor\u00E1rio-Padr\u00E3o Oriental (Nova Gales do Sul)", "AEST", - "Fuso Hor\u00E1rio de Ver\u00E3o Oriental (Nova Gales do Sul)", "AEDT", - "Hor\u00E1rio Oriental (Nova Gales do Sul)", "AET"}; - String FET[] = new String[] {"Hor\u00E1rio do Extremo Leste Europeu (FET)", "FET", - "Fuso Hor\u00E1rio de Ver\u00E3o do Extremo Leste Europeu", "FEST", - "Hor\u00E1rio do Extremo Leste Europeu (FET)", "FET"}; - String GHMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Gana", "GMT", - "Fuso hor\u00e1rio de ver\u00e3o de Gana", "GHST", - "Fuso Hor\u00E1rio do Meridiano de Gana", "GMT"}; - String GAMBIER[] = new String[] {"Fuso hor\u00e1rio de Gambier", "GAMT", - "Fuso hor\u00e1rio de ver\u00e3o de Gambier", "GAMST", - "Hor\u00E1rio de Gambier", "GAMT"}; - String GMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", - "Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", - "Hor\u00E1rio M\u00E9dio de Greenwich", "GMT"}; - String GMTBST[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", - "Fuso hor\u00e1rio de ver\u00e3o da Gr\u00e3-Bretanha", "BST", - "Hor\u00E1rio do Reino Unido", "BT"}; - String GST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do golfo", "GST", - "Hor\u00e1rio de luz natural do golfo", "GDT", - "Hor\u00E1rio do Golfo", "GT"}; - String HKT[] = new String[] {"Fuso hor\u00e1rio de Hong Kong", "HKT", - "Fuso hor\u00e1rio de ver\u00e3o de Hong Kong", "HKST", - "Hor\u00E1rio de Hong Kong", "HKT"}; - String HST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Hava\u00ed", "HST", - "Hor\u00e1rio de luz natural do Hava\u00ed", "HDT", - "Hor\u00E1rio do Hava\u00ED", "HT"}; - String ICT[] = new String[] {"Fuso hor\u00e1rio da Indochina", "ICT", - "Fuso hor\u00e1rio de ver\u00e3o da Indochina", "ICST", - "Hor\u00E1rio da Indochina", "ICT"}; - String IRKT[] = new String[] {"Fuso hor\u00e1rio de Irkutsk", "IRKT", - "Fuso hor\u00e1rio de ver\u00e3o de Irkutsk", "IRKST", - "Hor\u00E1rio de Irkutsk", "IRKT"}; - String IRT[] = new String[] {"Fuso hor\u00e1rio do Ir\u00e3", "IRST", - "Hor\u00e1rio de luz natural do Ir\u00e3", "IRDT", - "Hor\u00E1rio do Ir\u00E3", "IRT"}; - String ISRAEL[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Israel", "IST", - "Hor\u00e1rio de luz natural de Israel", "IDT", - "Hor\u00E1rio de Israel", "IT"}; - String IST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00cdndia", "IST", - "Hor\u00e1rio de luz natural da \u00cdndia", "IDT", - "Hor\u00E1rio da \u00CDndia", "IT"}; - String JST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Jap\u00e3o", "JST", - "Hor\u00e1rio de luz natural do Jap\u00e3o", "JDT", - "Hor\u00E1rio do Jap\u00E3o", "JT"}; - String KRAT[] = new String[] {"Fuso hor\u00e1rio de Krasnoyarsk", "KRAT", - "Fuso hor\u00e1rio de ver\u00e3o de Krasnoyarsk", "KRAST", - "Hor\u00E1rio de Krasnoyarsk", "KRAT"}; - String KST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Coreia", "KST", - "Hor\u00e1rio de luz natural da Coreia", "KDT", - "Hor\u00E1rio da Coreia", "KT"}; - String LORD_HOWE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Lord Howe", "LHST", - "Fuso hor\u00e1rio de ver\u00e3o de Lord Howe", "LHDT", - "Hor\u00E1rio de Lord Howe", "LHT"}; - String MHT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Marshall", "MHT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marshall", "MHST", - "Hor\u00E1rio das Ilhas Marshall", "MHT"}; - String MSK[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Moscou", "MSK", - "Hor\u00e1rio de luz natural de Moscou", "MSD", - "Hor\u00E1rio de Moscou", "MT"}; - String MMT[] = new String[] {"Fuso hor\u00e1rio de Mianmar", "MMT", - "Fuso hor\u00e1rio de ver\u00e3o de Mianmar", "MMST", - "Hor\u00E1rio de Mianmar", "MMT"}; - String MST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o das montanhas", "MST", - "Hor\u00e1rio de luz natural das montanhas", "MDT", - "Hor\u00E1rio das Montanhas Rochosas", "MT"}; - String MYT[] = new String[] {"Fuso hor\u00e1rio da Mal\u00e1sia", "MYT", - "Fuso hor\u00e1rio de ver\u00e3o da Mal\u00e1sia", "MYST", - "Hor\u00E1rio da Mal\u00E1sia", "MYT"}; - String NORONHA[] = new String[] {"Fuso hor\u00e1rio de Fernando de Noronha", "FNT", - "Fuso hor\u00e1rio de ver\u00e3o de Fernando de Noronha", "FNST", - "Hor\u00E1rio de Fernando de Noronha", "FNT"}; - String NOVT[] = new String[] {"Fuso hor\u00e1rio de Novosibirsk", "NOVT", - "Fuso hor\u00e1rio de ver\u00e3o de Novosibirsk", "NOVST", - "Hor\u00E1rio de Novosibirsk", "NOVT"}; - String NPT[] = new String[] {"Fuso hor\u00e1rio do Nepal", "NPT", - "Fuso hor\u00e1rio de ver\u00e3o do Nepal", "NPST", - "Hor\u00E1rio do Nepal", "NPT"}; - String NST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Terra Nova", "NST", - "Hor\u00e1rio de luz natural de Terra Nova", "NDT", - "Hor\u00E1rio de Terra Nova", "NT"}; - String NZST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Nova Zel\u00e2ndia", "NZST", - "Hor\u00e1rio de luz natural da Nova Zel\u00e2ndia", "NZDT", - "Hor\u00E1rio da Nova Zel\u00E2ndia", "NZT"}; - String PITCAIRN[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Pitcairn", "PST", - "Hor\u00e1rio de luz natural de Pitcairn", "PDT", - "Hor\u00E1rio de Pitcairn", "PT"}; - String PKT[] = new String[] {"Fuso hor\u00e1rio do Paquist\u00e3o", "PKT", - "Fuso hor\u00e1rio de ver\u00e3o do Paquist\u00e3o", "PKST", - "Hor\u00E1rio do Paquist\u00E3o", "PKT"}; - String PONT[] = new String[] {"Fuso Hor\u00E1rio de Pohnpei", "PONT", - "Fuso Hor\u00E1rio de Ver\u00E3o de Pohnpei", "PONST", - "Hor\u00E1rio de Ponape", "PONT"}; - String PST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Pac\u00edfico", "PST", - "Hor\u00e1rio de luz natural do Pac\u00edfico", "PDT", - "Hor\u00E1rio do Pac\u00EDfico", "PT"}; - String SAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00c1frica do Sul", "SAST", - "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica do Sul", "SAST", - "Hor\u00E1rio da \u00C1frica do Sul", "SAT"}; - String SBT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Salom\u00e3o", "SBT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Salom\u00e3o", "SBST", - "Hor\u00E1rio das Ilhas Salom\u00E3o", "SBT"}; - String SGT[] = new String[] {"Fuso hor\u00e1rio de Cingapura", "SGT", - "Fuso hor\u00e1rio de ver\u00e1 de Cingapura", "SGST", - "Hor\u00E1rio de Cingapura", "SGT"}; - String TASMANIA[] = new String[] {"Hor\u00E1rio-Padr\u00E3o do Leste (Tasm\u00E2nia)", "AEST", - "Fuso Hor\u00E1rio de Ver\u00E3o Oriental (Tasm\u00E2nia)", "AEDT", - "Hor\u00E1rio do Leste (Tasm\u00E2nia)", "AET"}; - String TMT[] = new String[] {"Fuso hor\u00e1rio do Turcomenist\u00e3o", "TMT", - "Fuso hor\u00e1rio de ver\u00e3o do Turcomenist\u00e3o", "TMST", - "Hor\u00E1rio do Turcomenist\u00E3o", "TMT"}; - String TRUT[] = new String[] {"Fuso Hor\u00E1rio de Chuuk", "CHUT", - "Fuso Hor\u00E1rio de Ver\u00E3o de Chuuk", "CHUST", - "Fuso Hor\u00E1rio de Chuuk", "CHUT"}; - String ULAT[]= new String[] {"Fuso hor\u00e1rio de Ulan Bator", "ULAT", - "Fuso hor\u00e1rio de ver\u00e3o de Ulan Bator", "ULAST", - "Hor\u00E1rio de Ulaanbaatar", "ULAT"}; - String WAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Ocidental", "WAT", - "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Ocidental", "WAST", - "Hor\u00E1rio da \u00C1frica Ocidental", "WAT"}; - String WET[] = new String[] {"Fuso hor\u00e1rio da Europa Ocidental", "WET", - "Fuso hor\u00e1rio de ver\u00e3o da Europa Ocidental", "WEST", - "Hor\u00E1rio da Europa Ocidental", "WET"}; - String WGT[] = new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Ocidental", "WGT", - "Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Ocidental", "WGST", - "Hor\u00E1rio da Groenl\u00E2ndia Ocidental", "WGT"}; - String WIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Ocidental", "WIB", - "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Ocidental", "WIST", - "Hor\u00E1rio da Indon\u00E9sia Ocidental", "WIB"}; - String WST_AUS[] = new String[] {"Hor\u00E1rio-Padr\u00E3o Ocidental (Austr\u00E1lia)", "AWST", - "Fuso Hor\u00E1rio de Ver\u00E3o Ocidental (Austr\u00E1lia)", "AWDT", - "Hor\u00E1rio Ocidental (Austr\u00E1lia)", "AWT"}; - String SAMOA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Samoa", "SST", - "Hor\u00e1rio de luz natural de Samoa", "SDT", - "Hor\u00E1rio da Samoa", "ST"}; - String WST_SAMOA[] = new String[] {"Fuso hor\u00e1rio de Samoa Ocidental", "WSST", - "Fuso hor\u00e1rio de ver\u00e3o de Samoa Ocidental", "WSDT", - "Fuso Hor\u00E1rio de Samoa Ocidental", "WST"}; - String ChST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chamorro", "ChST", - "Hor\u00e1rio de luz natural de Chamorro", "ChDT", - "Hor\u00E1rio de Chamorro", "ChT"}; - String VICTORIA[] = new String[] {"Hor\u00E1rio-Padr\u00E3o do Leste (Victoria)", "AEST", - "Fuso Hor\u00E1rio de Ver\u00E3o Oriental (Victoria)", "AEDT", - "Hor\u00E1rio do Leste (Victoria)", "AET"}; - String UTC[] = new String[] {"Tempo universal coordenado", "UTC", - "Tempo universal coordenado", "UTC", - "Hor\u00E1rio Universal Coordenado", "UTC"}; - String UZT[] = new String[] {"Fuso hor\u00e1rio do Uzbequist\u00e3o", "UZT", - "Fuso hor\u00e1rio de ver\u00e3o do Uzbequist\u00e3o", "UZST", - "Hor\u00E1rio do Uzbequist\u00E3o", "UZT"}; - String XJT[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da China", "XJT", - "Hor\u00e1rio de luz natural da China", "XJDT", - "Hor\u00E1rio da China", "XJT"}; - String YAKT[] = new String[] {"Fuso hor\u00e1rio de Yakutsk", "YAKT", - "Fuso hor\u00e1rio de ver\u00e3o de Yakutsk", "YAKST", - "Hor\u00E1rio de Yakutsk", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Fuso hor\u00e1rio do Paraguai", "PYT", - "Fuso hor\u00e1rio de ver\u00e3o do Paraguai", "PYST", - "Hor\u00E1rio do Paraguai", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Fuso hor\u00e1rio da Col\u00f4mbia", "COT", - "Fuso hor\u00e1rio de ver\u00e3o da Col\u00f4mbia", "COST", - "Hor\u00E1rio da Col\u00F4mbia", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Fuso hor\u00e1rio da Venezuela", "VET", - "Fuso hor\u00e1rio de ver\u00e3o da Venezuela", "VEST", - "Hor\u00E1rio da Venezuela", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Fuso hor\u00e1rio da Guiana Francesa", "GFT", - "Fuso hor\u00e1rio de ver\u00e3o da Guiana Francesa", "GFST", - "Hor\u00E1rio da Guiana Francesa", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Fuso hor\u00e1rio do Equador", "ECT", - "Fuso hor\u00e1rio de ver\u00e3o do Equador", "ECST", - "Hor\u00E1rio do Equador", "ECT"}}, - {"America/Guyana", new String[] {"Fuso hor\u00e1rio da Guiana", "GYT", - "Fuso hor\u00e1rio de ver\u00e3o da Guiana", "GYST", - "Hor\u00E1rios da Guiana", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Fuso hor\u00e1rio da Bol\u00edvia", "BOT", - "Fuso hor\u00e1rio de ver\u00e3o da Bol\u00edvia", "BOST", - "Hor\u00E1rio da Bol\u00EDvia", "BOT"}}, - {"America/Lima", new String[] {"Fuso hor\u00e1rio do Peru", "PET", - "Fuso hor\u00e1rio de ver\u00e3o do Peru", "PEST", - "Hor\u00E1rio do Peru", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Fuso hor\u00e1rio padr\u00e3o de S\u00e3o Pedro e Miquelon", "PMST", - "Hor\u00e1rio de luz natural de S\u00e3o Pedro e Miquelon", "PMDT", - "Hor\u00E1rio de Saint Pierre e Miquelon", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Fuso hor\u00e1rio do Uruguai", "UYT", - "Fuso hor\u00e1rio de ver\u00e3o do Uruguai", "UYST", - "Hor\u00E1rio do Uruguai", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Fuso hor\u00e1rio do Suriname", "SRT", - "Fuso hor\u00e1rio de ver\u00e3o do Suriname", "SRST", - "Hor\u00E1rio do Suriname", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Fuso hor\u00e1rio de Davis", "DAVT", - "Fuso hor\u00e1rio de ver\u00e3o de Davis", "DAVST", - "Hor\u00E1rio de Davis", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Fuso hor\u00e1rio de Dumont-d'Urville", "DDUT", - "Fuso hor\u00e1rio de ver\u00e3o de Dumont-d'Urville", "DDUST", - "Fuso Hor\u00E1rio de Dumont-d'Urville", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Fuso hor\u00e1rio de Mawson", "MAWT", - "Fuso hor\u00e1rio de ver\u00e3o de Mawson", "MAWST", - "Hor\u00E1rio de Mawson", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Fuso hor\u00e1rio de Rothera", "ROTT", - "Fuso hor\u00e1rio de ver\u00e3o de Rothera", "ROTST", - "Hor\u00E1rio de Rothera", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Fuso hor\u00e1rio de Syowa", "SYOT", - "Fuso hor\u00e1rio de ver\u00e3o de Syowa", "SYOST", - "Hor\u00E1rio de Syowa", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Tempo universal coordenado", "UTC", - "Fuso hor\u00e1rio de ver\u00e3o da Europa Central", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Fuso hor\u00e1rio de Vostok", "VOST", - "Fuso hor\u00e1rio de ver\u00e3o de Vostok", "VOSST", - "Hor\u00E1rio de Vostok", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Fuso hor\u00e1rio de Alma-Ata", "ALMT", - "Fuso hor\u00e1rio de ver\u00e3o de Alma-Ata", "ALMST", - "Hor\u00E1rio de Alma-Ata", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Fuso hor\u00e1rio de Anadyr", "ANAT", - "Fuso hor\u00e1rio de ver\u00e3o de Anadyr", "ANAST", - "Hor\u00E1rio de Anadyr", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Fuso hor\u00e1rio de Aqtau", "AQTT", - "Fuso hor\u00e1rio de ver\u00e3o de Aqtau", "AQTST", - "Hor\u00E1rio de Aqtau", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Fuso hor\u00e1rio de Aqtobe", "AQTT", - "Fuso hor\u00e1rio de ver\u00e3o de Aqtobe", "AQTST", - "Hor\u00E1rio de Aqtobe", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Fuso hor\u00e1rio do Azerbaij\u00e3o", "AZT", - "Fuso hor\u00e1rio de ver\u00e3o do Azerbaij\u00e3o", "AZST", - "Hor\u00E1rio do Azerbaij\u00E3o", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Fuso hor\u00e1rio do Quirguist\u00e3o", "KGT", - "Fuso hor\u00e1rio de ver\u00e3o do Quirguist\u00e3o", "KGST", - "Hor\u00E1rio do Quirguist\u00E3o", "KGT"}}, - {"Asia/Brunei", new String[] {"Fuso hor\u00e1rio de Brunei", "BNT", - "Fuso hor\u00e1rio de ver\u00e3o de Brunei", "BNST", - "Hor\u00E1rio de Brunei", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Fuso hor\u00e1rio de Choibalsan", "CHOT", - "Fuso hor\u00e1rio de ver\u00e3o de Choibalsan", "CHOST", - "Hor\u00E1rio de Choibalsan", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Fuso hor\u00e1rio do Timor-Leste", "TLT", - "Fuso hor\u00e1rio de ver\u00e3o do Timor-Leste", "TLST", - "Hor\u00E1rio do Timor-Leste", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Fuso hor\u00e1rio do Tadjiquist\u00e3o", "TJT", - "Fuso hor\u00e1rio de ver\u00e3o do Tadjiquist\u00e3o", "TJST", - "Hor\u00E1rio do Tadjiquist\u00E3o", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Fuso hor\u00e1rio de Hovd", "HOVT", - "Fuso hor\u00e1rio de ver\u00e3o de Hovd", "HOVST", - "Hor\u00E1rio de Hovd", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Oriental", "WIT", - "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Oriental", "EIST", - "Hor\u00E1rio da Indon\u00E9sia Oriental", "WIT"}}, - {"Asia/Kabul", new String[] {"Fuso hor\u00e1rio do Afeganist\u00e3o", "AFT", - "Fuso hor\u00e1rio de ver\u00e3o do Afeganist\u00e3o", "AFST", - "Hor\u00E1rio do Afeganist\u00E3o", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Fuso hor\u00e1rio de Petropavlovsk-Kamchatski", "PETT", - "Fuso hor\u00e1rio de ver\u00e3o de Petropavlovsk-Kamchatski", "PETST", - "Hor\u00E1rio de Petropavlovsk-Kamchatski", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Fuso hor\u00e1rio de Magadan", "MAGT", - "Fuso hor\u00e1rio de ver\u00e3o de Magadan", "MAGST", - "Hor\u00E1rio de Magadan", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Fuso hor\u00e1rio de Uralsk", "ORAT", - "Fuso hor\u00e1rio de ver\u00e3o de Uralsk", "ORAST", - "Hor\u00E1rio de Uralsk", "ORAT"}}, - {"Asia/Omsk", new String[] {"Fuso hor\u00e1rio de Omsk", "OMST", - "Fuso hor\u00e1rio de ver\u00e3o de Omsk", "OMSST", - "Hor\u00E1rio de Omsk", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Fuso hor\u00e1rio de Kizil-Orda", "QYZT", - "Fuso hor\u00e1rio de ver\u00e3o de Kizil-Orda", "QYZST", - "Hor\u00E1rio de Qyzylorda", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Fuso hor\u00e1rio de Sakhalina", "SAKT", - "Fuso hor\u00e1rio de ver\u00e3o de Sakhalina", "SAKST", - "Hor\u00E1rio de Sakhalin", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Fuso hor\u00e1rio da Ge\u00f3rgia", "GET", - "Fuso hor\u00e1rio de ver\u00e3o da Ge\u00f3rgia", "GEST", - "Hor\u00E1rio da Ge\u00F3rgia", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Hor\u00E1rio de Ust-Nera", "VLAT", - "Hor\u00E1rio de Ver\u00E3o de Ust-Nera", "VLAST", - "Hor\u00E1rio de Ust-Nera", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Fuso hor\u00e1rio de Vladivostok", "VLAT", - "Fuso hor\u00e1rio de ver\u00e3o de Vladivostok", "VLAST", - "Hor\u00E1rio de Vladivostok", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Fuso hor\u00e1rio de Yekaterinburgo", "YEKT", - "Fuso hor\u00e1rio de ver\u00e3o de Yekaterinburgo", "YEKST", - "Hor\u00E1rio de Yekaterinburg", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Fuso hor\u00e1rio das A\u00e7ores", "AZOT", - "Fuso hor\u00e1rio de ver\u00e3o das A\u00e7ores", "AZOST", - "Hor\u00E1rio de A\u00E7ores", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Fuso hor\u00e1rio de Cabo Verde", "CVT", - "Fuso hor\u00e1rio de ver\u00e3o de Cabo Verde", "CVST", - "Hor\u00E1rio de Cabo Verde", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ge\u00f3rgia do Sul", "GST", - "Hor\u00e1rio de luz natural da Ge\u00f3rgia do Sul", "GDT", - "Hor\u00E1rio da Ge\u00F3rgia do Sul", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Fuso hor\u00e1rio das Ilhas Falkland", "FKT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Falkland", "FKST", - "Hor\u00E1rio das Ilhas Malvinas", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Fuso Hor\u00E1rio Ocidental Central (Austr\u00E1lia)", "ACWST", - "Fuso Hor\u00E1rio de Ver\u00E3o Ocidental Central (Austr\u00E1lia)", "ACWDT", - "Hor\u00E1rio Ocidental Central (Austr\u00E1lia)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Fuso hor\u00e1rio de Samara", "SAMT", - "Fuso hor\u00e1rio de ver\u00e3o de Samara", "SAMST", - "Hor\u00E1rio de Samara", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Fuso hor\u00e1rio dos territ\u00f3rios do Oceano \u00cdndico", "IOT", - "Fuso hor\u00e1rio de ver\u00e3o dos territ\u00f3rios do Oceano \u00cdndico", "IOST", - "Hor\u00E1rio do Territ\u00F3rio do Oceano \u00CDndico", "IOT"}}, - {"Indian/Christmas", new String[] {"Fuso hor\u00e1rio das Ilhas Christmas", "CXT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Christmas", "CXST", - "Hor\u00E1rio da Ilha Christmas", "CIT"}}, - {"Indian/Cocos", new String[] {"Fuso hor\u00e1rio das Ilhas Cocos", "CCT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cocos", "CCST", - "Hor\u00E1rio das Ilhas Cocos", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Fuso hor\u00e1rio das Terras Austrais e Ant\u00e1rticas Francesas", "TFT", - "Fuso hor\u00e1rio de ver\u00e3o das Terras Austrais e Ant\u00e1rticas Francesas", "TFST", - "Hor\u00E1rio do Territ\u00F3rio Franc\u00EAs no Sul da Ant\u00E1rtica", "TFT"}}, - {"Indian/Mahe", new String[] {"Fuso hor\u00e1rio das Seychelles", "SCT", - "Fuso hor\u00e1rio de ver\u00e3o das Seychelles", "SCST", - "Hor\u00E1rio de Seychelles", "SCT"}}, - {"Indian/Maldives", new String[] {"Fuso hor\u00e1rio das Maldivas", "MVT", - "Fuso hor\u00e1rio de ver\u00e3o das Maldivas", "MVST", - "Hor\u00E1rio das Maldivas", "MVT"}}, - {"Indian/Mauritius", new String[] {"Fuso hor\u00e1rio das Ilhas Maur\u00edcio", "MUT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Maur\u00edcio", "MUST", - "Hor\u00E1rio de Maur\u00EDcio", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Fuso hor\u00e1rio de Reuni\u00e3o", "RET", - "Fuso hor\u00e1rio de ver\u00e3o de Reuni\u00e3o", "REST", - "Hor\u00E1rio das Ilhas Reuni\u00E3o", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", TRUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Fuso hor\u00e1rio de Vanuatu", "VUT", - "Fuso hor\u00e1rio de ver\u00e3o de Vanuatu", "VUST", - "Hor\u00E1rio de Vanuatu", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Fuso hor\u00e1rio das Ilhas F\u00e9nix", "PHOT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas F\u00e9nix", "PHOST", - "Hor\u00E1rio da Ilha Phoenix", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Fuso hor\u00e1rio de Tokelau", "TKT", - "Fuso hor\u00e1rio de ver\u00e3o de Tokelau", "TKST", - "Hor\u00E1rio de Toquelau", "TKT"}}, - {"Pacific/Fiji", new String[] {"Fuso hor\u00e1rio de Fiji", "FJT", - "Fuso hor\u00e1rio de ver\u00e3o de Fiji", "FJST", - "Hor\u00E1rio de Fiji", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Fuso hor\u00e1rio de Tuvalu", "TVT", - "Fuso hor\u00e1rio de ver\u00e3o de Tuvalu", "TVST", - "Hor\u00E1rio de Tuvalu", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Fuso hor\u00e1rio das Ilhas Gal\u00e1pagos", "GALT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gal\u00e1pagos", "GALST", - "Hor\u00E1rio de Gal\u00E1pagos", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Fuso hor\u00e1rio das Esp\u00f3rades Equatoriais", "LINT", - "Fuso hor\u00e1rio de ver\u00e3o das Esp\u00f3rades Equatoriais", "LINST", - "Hor\u00E1rio das Ilhas Line", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Fuso hor\u00e1rio de Kosrae", "KOST", - "Fuso hor\u00e1rio de ver\u00e3o de Kosrae", "KOSST", - "Hor\u00E1rio de Kosrae", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Fuso hor\u00e1rio das Ilhas Marquesas", "MART", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marquesas", "MARST", - "Hor\u00E1rio das Ilhas Marquesas", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Fuso hor\u00e1rio de Nauru", "NRT", - "Fuso hor\u00e1rio de ver\u00e3o de Nauru", "NRST", - "Hor\u00E1rio de Nauru", "NRT"}}, - {"Pacific/Niue", new String[] {"Fuso hor\u00e1rio de Niue", "NUT", - "Fuso hor\u00e1rio de ver\u00e3o de Niue", "NUST", - "Hor\u00E1rio de Niue", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Fuso hor\u00e1rio da Ilha de Norfolk", "NFT", - "Fuso hor\u00e1rio de ver\u00e3o da Ilha de Norfolk", "NFST", - "Hor\u00E1rio de Norfolk", "NFT"}}, - {"Pacific/Noumea", new String[] {"Fuso hor\u00e1rio da Nova Caled\u00f4nia", "NCT", - "Fuso hor\u00e1rio de ver\u00e3o da Nova Caled\u00f4nia", "NCST", - "Hor\u00E1rio da Nova Caled\u00F4nia", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Fuso hor\u00e1rio de Palau", "PWT", - "Fuso hor\u00e1rio de ver\u00e3o de Palau", "PWST", - "Hor\u00E1rio de Palau", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Fuso hor\u00e1rio de Papua-Nova Guin\u00e9", "PGT", - "Fuso hor\u00e1rio de ver\u00e3o de Papua-Nova Guin\u00e9", "PGST", - "Hor\u00E1rio de Papua-Nova Guin\u00E9", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Fuso hor\u00e1rio das Ilhas Cook", "CKT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cook", "CKHST", - "Hor\u00E1rio das Ilhas Cook", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Fuso hor\u00e1rio do Taiti", "TAHT", - "Fuso hor\u00e1rio de ver\u00e3o do Taiti", "TAHST", - "Hor\u00E1rio do Tahiti", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Fuso hor\u00e1rio das Ilhas Gilbert", "GILT", - "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gilbert", "GILST", - "Hor\u00E1rio das Ilhas Gilbert", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Fuso hor\u00e1rio de Tonga", "TOT", - "Fuso hor\u00e1rio de ver\u00e3o de Tonga", "TOST", - "Hor\u00E1rio de Tonga", "TOT"}}, - {"Pacific/Truk", TRUT}, - {"Pacific/Wake", new String[] {"Fuso hor\u00e1rio de Wake", "WAKT", - "Fuso hor\u00e1rio de ver\u00e3o de Wake", "WAKST", - "Hor\u00E1rio de Wake", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Fuso hor\u00e1rio de Wallis e Futuna", "WFT", - "Fuso hor\u00e1rio de ver\u00e3o de Wallis e Futuna", "WFST", - "Hor\u00E1rio das Ilhas Wallis e Futuna", "WFT"}}, - {"Pacific/Yap", TRUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java deleted file mode 100644 index 6b0e1dd7266..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_sv extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Acre, normaltid", "ACT", - "Acre, sommartid", "ACST", - "Acre, normaltid", "ACT"}; - String ADELAIDE[] = new String[] {"Central standardtid (Sydaustralien)", "ACST", - "Central sommartid (South Australia)", "ACDT", - "Central tid (Sydaustralien)", "ACT"}; - String AGT[] = new String[] {"Argentina, normaltid", "ART", - "Argentina, sommartid", "ARST", - "Argentinsk tid", "ART"}; - String AKST[] = new String[] {"Alaska, normaltid", "AKST", - "Alaska, sommartid", "AKDT", - "Alaskisk tid", "AKT"}; - String AMT[] = new String[] {"Amazonas, normaltid", "AMT", - "Amazonas, sommartid", "AMST", - "Amazonas-tid", "AMT"}; - String ARAST[] = new String[] {"Arabisk normaltid", "AST", - "Arabisk sommartid", "ADT", - "Arabisk tid", "AT"}; - String ARMT[] = new String[] {"Armenien, normaltid", "AMT", - "Armenien, sommartid", "AMST", - "Armenisk tid", "AMT"}; - String AST[] = new String[] {"Atlantisk normaltid", "AST", - "Atlantisk sommartid", "ADT", - "Atlantisk tid", "AT"}; - String BDT[] = new String[] {"Bangladesh, normaltid", "BDT", - "Bangladesh, sommartid", "BDST", - "Bangladeshisk tid", "BDT"}; - String BRISBANE[] = new String[] {"\u00D6stlig standardtid (Queensland)", "AEST", - "\u00D6stlig sommartid (Queensland)", "AEDT", - "\u00D6stlig tid (Queensland)", "AET"}; - String BROKEN_HILL[] = new String[] {"Central standardtid (Sydaustralien/New South Wales)", "ACST", - "Central sommartid (South Australia/New South Wales)", "ACDT", - "Central tid (Sydaustralien/New South Wales)", "ACT"}; - String BRT[] = new String[] {"Brasilien, normaltid", "BRT", - "Brasilien, sommartid", "BRST", - "Brasiliansk tid", "BRT"}; - String BTT[] = new String[] {"Bhutan, normaltid", "BTT", - "Bhutan, sommartid", "BTST", - "Bhutanesisk tid", "BTT"}; - String CAT[] = new String[] {"Centralafrikansk tid", "CAT", - "Centralafrikansk sommartid", "CAST", - "Centralafrikansk tid", "CAT"}; - String CET[] = new String[] {"Centraleuropeisk tid", "CET", - "Centraleuropeisk sommartid", "CEST", - "Centraleuropeisk tid", "CET"}; - String CHAST[] = new String[] {"Chatham, normaltid", "CHAST", - "Chatham, sommartid", "CHADT", - "Chathams tid", "CHAT"}; - String CHUT[] = new String[] {"Chuuk, normaltid", "CHUT", - "Chuuk, sommartid", "CHUST", - "Chuuk, normaltid", "CHUT"}; - String CIT[] = new String[] {"Centralindonesisk tid", "WITA", - "Centralindonesisk sommartid", "CIST", - "Centralindonesisk tid", "WITA"}; - String CLT[] = new String[] {"Chile, normaltid", "CLT", - "Chile, sommartid", "CLST", - "Chilensk tid", "CLT"}; - String CST[] = new String[] {"Central normaltid", "CST", - "Central sommartid", "CDT", - "Central tid", "CT"}; - String CTT[] = new String[] {"Kina, normaltid", "CST", - "Kina, sommartid", "CDT", - "Kinesisk tid", "CT"}; - String CUBA[] = new String[] {"Kuba, normaltid", "CST", - "Kuba, sommartid", "CDT", - "Kubansk tid", "CT"}; - String DARWIN[] = new String[] {"Central standardtid (Nordterritoriet)", "ACST", - "Central sommartid (Nordterritoriet)", "ACDT", - "Central tid (Nordterritoriet)", "ACT"}; - String DUBLIN[] = new String[] {"Greenwichtid", "GMT", - "Irland, sommartid", "IST", - "Irl\u00E4ndsk tid", "IT"}; - String EAT[] = new String[] {"\u00d6stafrikansk tid", "EAT", - "\u00d6stafrikansk sommartid", "EAST", - "\u00D6stafrikansk tid", "EAT"}; - String EASTER[] = new String[] {"P\u00e5sk\u00f6n, normaltid", "EAST", - "P\u00e5sk\u00f6n, sommartid", "EASST", - "P\u00E5sk\u00F6n-tid", "EAST"}; - String EET[] = new String[] {"\u00d6steuropeisk tid", "EET", - "\u00d6steuropeisk sommartid", "EEST", - "\u00d6steuropeisk tid", "EET"}; - String EGT[] = new String[] {"\u00d6stgr\u00f6nl\u00e4ndsk tid", "EGT", - "\u00d6stgr\u00f6nl\u00e4ndsk sommartid", "EGST", - "\u00D6stgr\u00F6nl\u00E4ndsk tid", "EGT"}; - String EST[] = new String[] {"Eastern, normaltid", "EST", - "Eastern, sommartid", "EDT", - "\u00D6stlig tid", "ET"}; - String EST_NSW[] = new String[] {"\u00D6stlig standardtid (New South Wales)", "AEST", - "\u00D6stlig sommartid (New South Wales)", "AEDT", - "\u00D6stlig tid (New South Wales)", "AET"}; - String FET[] = new String[] {"Kaliningradtid", "FET", - "\u00D6steuropeisk sommartid", "FEST", - "Kaliningradtid", "FET"}; - String GHMT[] = new String[] {"Ghana, normaltid", "GMT", - "Ghana, sommartid", "GHST", - "Ghana, normaltid", "GMT"}; - String GAMBIER[] = new String[] {"Gambier, normaltid", "GAMT", - "Gambier, sommartid", "GAMST", - "Gambier\u00F6arna-tid", "GAMT"}; - String GMT[] = new String[] {"Greenwichtid", "GMT", - "Greenwichtid", "GMT", - "Greenwichtid", "GMT"}; - String GMTBST[] = new String[] {"Greenwichtid", "GMT", - "Brittisk sommartid", "BST", - "Brittisk tid", "BT"}; - String GST[] = new String[] {"Gulf-normaltid", "GST", - "Gulf-sommartid", "GDT", - "Golfens tid", "GT"}; - String HKT[] = new String[] {"Hong Kong, normaltid", "HKT", - "Hong Kong, sommartid", "HKST", - "Hongkong-tid", "HKT"}; - String HST[] = new String[] {"Hawaii, normaltid", "HST", - "Hawaii, sommartid", "HDT", - "Hawaiiansk tid", "HT"}; - String ICT[] = new String[] {"Indokinesisk tid", "ICT", - "Indokinesisk sommartid", "ICST", - "Indokinesisk tid", "ICT"}; - String IRKT[] = new String[] {"Irkutsk, normaltid", "IRKT", - "Irkutsk, sommartid", "IRKST", - "Irkutsk-tid", "IRKT"}; - String IRT[] = new String[] {"Iran, normaltid", "IRST", - "Iran, sommartid", "IRDT", - "Iransk tid", "IRT"}; - String ISRAEL[] = new String[] {"Israel, normaltid", "IST", - "Israel, sommartid", "IDT", - "Israelisk tid", "IT"}; - String IST[] = new String[] {"Indien, normaltid", "IST", - "Indien, sommartid", "IDT", - "Indisk tid", "IT"}; - String JST[] = new String[] {"Japan, normaltid", "JST", - "Japan, sommartid", "JDT", - "Japansk tid", "JT"}; - String KRAT[] = new String[] {"Krasnojarsk, normaltid", "KRAT", - "Krasnojarsk, sommartid", "KRAST", - "Krasnojarsk-tid", "KRAT"}; - String KST[] = new String[] {"Korea, normaltid", "KST", - "Korea, sommartid", "KDT", - "Koreansk tid", "KT"}; - String LORD_HOWE[] = new String[] {"Lord Howe, normaltid", "LHST", - "Lord Howe, sommartid", "LHDT", - "Lord Howe-tid", "LHT"}; - String MHT[] = new String[] {"Marshall\u00f6arna, normaltid", "MHT", - "Marshall\u00f6arna, sommartid", "MHST", - "Marshall\u00F6arna-tid", "MHT"}; - String MMT[] = new String[] {"Myanmar, normaltid", "MMT", - "Myanmar, sommartid", "MMST", - "Myanmar-tid", "MMT"}; - String MSK[] = new String[] {"Moskva, normaltid", "MSK", - "Moskva, sommartid", "MSD", - "Moskvas tid", "MT"}; - String MST[] = new String[] {"Mountain, normaltid", "MST", - "Mountain, sommartid", "MDT", - "Mountain-tid", "MT"}; - String MYT[] = new String[] {"Malaysia, normaltid", "MYT", - "Malaysia, sommartid", "MYST", - "Malaysisk tid", "MYT"}; - String NORONHA[] = new String[] {"Fernando de Noronha, normaltid", "FNT", - "Fernando de Noronha, sommartid", "FNST", - "Fernando de Noronha-tid", "FNT"}; - String NOVT[] = new String[] {"Novosibirsk, normaltid", "NOVT", - "Novosibirsk, sommartid", "NOVST", - "Sibirisk tid", "NOVT"}; - String NPT[] = new String[] {"Nepal, normaltid", "NPT", - "Nepal, sommartid", "NPST", - "Nepalesisk tid", "NPT"}; - String NST[] = new String[] {"Newfoundland, normaltid", "NST", - "Newfoundland, sommartid", "NDT", - "Newfoundl\u00E4ndsk tid", "NT"}; - String NZST[] = new String[] {"Nya Zeeland, normaltid", "NZST", - "Nya Zeeland, sommartid", "NZDT", - "Nyzeel\u00E4ndsk tid", "NZT"}; - String PITCAIRN[] = new String[] {"Pitcairn, normaltid", "PST", - "Pitcairn, sommartid", "PDT", - "Pitcairn-tid", "PT"}; - String PKT[] = new String[] {"Pakistan, normaltid", "PKT", - "Pakistan, sommartid", "PKST", - "Pakistansk tid", "PKT"}; - String PONT[] = new String[] {"Pohnpei, normaltid", "PONT", - "Pohnpei, sommartid", "PONST", - "Ponape-tid", "PONT"}; - String PST[] = new String[] {"Stilla havet, normaltid", "PST", - "Stilla havet, sommartid", "PDT", - "Stillahavet", "PT"}; - String SAST[] = new String[] {"Sydafrika, normaltid", "SAST", - "Sydafrika, sommartid", "SAST", - "Sydafrikansk tid", "SAT"}; - String SBT[] = new String[] {"Salomon\u00f6arna, normaltid", "SBT", - "Salomon\u00f6arna, sommartid", "SBST", - "Salomon\u00F6arna-tid", "SBT"}; - String SGT[] = new String[] {"Singapore, normaltid", "SGT", - "Singapore, sommartid", "SGST", - "Singapore-tid", "SGT"}; - String TASMANIA[] = new String[] {"\u00D6stlig standardtid (Tasmania)", "AEST", - "\u00D6stlig sommartid (Tasmanien)", "AEDT", - "\u00D6stlig tid (Tasmania)", "AET"}; - String TMT[] = new String[] {"Turkmenistan, normaltid", "TMT", - "Turkmenistan, sommartid", "TMST", - "Turkmensk tid", "TMT"}; - String ULAT[]= new String[] {"Ulaanbaatar, normaltid", "ULAT", - "Ulaanbaatar, sommartid", "ULAST", - "Ulaanbaatar-tid", "ULAT"}; - String WAT[] = new String[] {"V\u00e4stafrikansk tid", "WAT", - "V\u00e4stafrikansk sommartid", "WAST", - "V\u00E4stafrikansk tid", "WAT"}; - String WET[] = new String[] {"V\u00e4steuropeisk tid", "WET", - "V\u00e4steuropeisk sommartid", "WEST", - "V\u00E4steuropeisk tid", "WET"}; - String WGT[] = new String[] {"V\u00e4stra Gr\u00f6nland, normaltid", "WGT", - "V\u00e4stra Gr\u00f6nland, sommartid", "WGST", - "V\u00E4stgr\u00F6nl\u00E4ndsk tid", "WGT"}; - String WIT[] = new String[] {"V\u00e4stindonesisk tid", "WIB", - "V\u00e4stindonesisk sommartid", "WIST", - "V\u00E4stindonesisk tid", "WIB"}; - String WST_AUS[] = new String[] {"Western Standard Time (Australien)", "AWST", - "V\u00E4stlig sommartid (Australien)", "AWDT", - "V\u00E4stlig tid (Australien)", "AWT"}; - String SAMOA[] = new String[] {"Samoa, normaltid", "SST", - "Samoa, sommartid", "SDT", - "Samoansk tid", "ST"}; - String WST_SAMOA[] = new String[] {"V\u00e4stsamoansk tid", "WSST", - "V\u00e4stsamoansk sommartid", "WSDT", - "V\u00E4stsamoansk tid", "WST"}; - String ChST[] = new String[] {"Chamorro, normaltid", "ChST", - "Chamorro, sommartid", "ChDT", - "Chamorros tid", "ChT"}; - String VICTORIA[] = new String[] {"\u00D6stlig standardtid (Victoria)", "AEST", - "\u00D6stlig sommartid (Victoria)", "AEDT", - "\u00D6stlig tid (Victoria)", "AET"}; - String UTC[] = new String[] {"Koordinerad universell tid", "UTC", - "Koordinerad universell tid", "UTC", - "UTC (koordinerad v\u00E4rldstid)", "UTC"}; - String UZT[] = new String[] {"Uzbekistan, normaltid", "UZT", - "Uzbekistan, sommartid", "UZST", - "Uzbekisk tid", "UZT"}; - String XJT[] = new String[] {"Kina, normaltid", "XJT", - "Kina, sommartid", "XJDT", - "Kinesisk tid", "XJT"}; - String YAKT[] = new String[] {"Jakutsk, normaltid", "YAKT", - "Jakutsk, sommartid", "YAKST", - "Jakutsk-tid", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"Paraguay, normaltid", "PYT", - "Paraguay, sommartid", "PYST", - "Paraguayansk tid", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"Colombia, normaltid", "COT", - "Colombia, sommartid", "COST", - "Kolombiansk tid", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Venezuela, normaltid", "VET", - "Venezuela, sommartid", "VEST", - "Venezuelansk tid", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"Franska Guyana, normaltid", "GFT", - "Franska Guyana, sommartid", "GFST", - "Franska Guyana-tid", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"Ecuador, normaltid", "ECT", - "Ecuador, sommartid", "ECST", - "Ecuadoriansk tid", "ECT"}}, - {"America/Guyana", new String[] {"Guyana, normaltid", "GYT", - "Guyana, sommartid", "GYST", - "Guyansk tid", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"Bolivia, normaltid", "BOT", - "Bolivia, sommartid", "BOST", - "Boliviansk tid", "BOT"}}, - {"America/Lima", new String[] {"Peru, normaltid", "PET", - "Peru, sommartid", "PEST", - "Peruansk tid", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"Saint-Pierre-et-Miquelon, normaltid", "PMST", - "Saint-Pierre-et-Miquelon, sommartid", "PMDT", - "Saint-Pierre och Miquelons tid", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"Uruguay, normaltid", "UYT", - "Uruguay, sommartid", "UYST", - "Uruguayansk tid", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"Surinam, normaltid", "SRT", - "Surinam, sommartid", "SRST", - "Surinamsk tid", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT", - "Davis, sommartid", "DAVST", - "Davis-tid", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT", - "Dumont-d'Urville, sommartid", "DDUST", - "Dumont-d'Urville-tid", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"Mawson, normaltid", "MAWT", - "Mawson, sommartid", "MAWST", - "Mawson-tid", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"Rothera, normaltid", "ROTT", - "Rothera, sommartid", "ROTST", - "Rothera-tid", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Syowa, normaltid", "SYOT", - "Syowa, sommartid", "SYOST", - "Syowa-tid", "SYOT"}}, - {"Antarctica/Troll", new String[] {"Koordinerad universell tid", "UTC", - "Centraleuropeisk sommartid", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"Vostok, normaltid", "VOST", - "Vostok, sommartid", "VOSST", - "Vostok-tid", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Alma-Ata, normaltid", "ALMT", - "Alma-Ata, sommartid", "ALMST", - "Alma-Ata-tid", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"Anadyr, normaltid", "ANAT", - "Anadyr, sommartid", "ANAST", - "Anadyr-tid", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Aqtau, normaltid", "AQTT", - "Aqtau, sommartid", "AQTST", - "Aqtau-tid", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Aqtobe, normaltid", "AQTT", - "Aqtobe, sommartid", "AQTST", - "Aqtobe-tid", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"Azerbajdzjan, normaltid", "AZT", - "Azerbajdzjan, sommartid", "AZST", - "Azerbajdzjansk tid", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Kirgizstan, normaltid", "KGT", - "Kirgizstan, sommartid", "KGST", - "Kirgizisk tid", "KGT"}}, - {"Asia/Brunei", new String[] {"Brunei, normaltid", "BNT", - "Brunei, sommartid", "BNST", - "Bruneisk tid", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Choibalsan", new String[] {"Choibalsan, normaltid", "CHOT", - "Choibalsan, sommartid", "CHOST", - "Choibalsan-tid", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Chita", YAKT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"Timor-Leste, normaltid", "TLT", - "Timor-Leste, sommartid", "TLST", - "\u00D6sttimor, normaltid", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"Tadzjikistan, normaltid", "TJT", - "Tadzjikistan, sommartid", "TJST", - "Tadzjikisk tid", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"Hovd, normaltid", "HOVT", - "Hovd, sommartid", "HOVST", - "Hovd-tid", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"\u00d6stindonesisk tid", "WIT", - "\u00d6stindonesisk sommartid", "EIST", - "\u00D6stindonesisk tid", "WIT"}}, - {"Asia/Kabul", new String[] {"Afghanistan, normaltid", "AFT", - "Afghanistan, sommartid", "AFST", - "Afghansk tid", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Petropavlovsk-Kamtjatka, normaltid", "PETT", - "Petropavlovsk-Kamtjatka, sommartid", "PETST", - "Petropavlovsk-Kamtjatskij-tid", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Magadan, normaltid", "MAGT", - "Magadan, sommartid", "MAGST", - "Magadan-tid", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Oral, normaltid", "ORAT", - "Oral, sommartid", "ORAST", - "Oral-tid", "ORAT"}}, - {"Asia/Omsk", new String[] {"Omsk, normaltid", "OMST", - "Omsk, sommartid", "OMSST", - "Omsk-tid", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Qyzylorda, normaltid", "QYZT", - "Qyzylorda, sommartid", "QYZST", - "Qyzylorda-tid", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"Sakhalin, normaltid", "SAKT", - "Sakhalin, sommartid", "SAKST", - "Sakhalin-tid", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"Georgien, normaltid", "GET", - "Georgien, sommartid", "GEST", - "Georgisk tid", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"Ust-Nera, normaltid", "VLAT", - "Ust-Nera, sommartid", "VLAST", - "Ust-Nera, normaltid", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"Vladivostok, normaltid", "VLAT", - "Vladivostok, sommartid", "VLAST", - "Vladivostok-tid", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Jekaterinburg, normaltid", "YEKT", - "Jekaterinburg, sommartid", "YEKST", - "Jekaterinburg-tid", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"Azorerna, normaltid", "AZOT", - "Azorerna, sommartid", "AZOST", - "Azorerna-tid", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"Kap Verde, normaltid", "CVT", - "Kap Verde, sommartid", "CVST", - "Kap Verde-tid", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"Sydgeorgien, normaltid", "GST", - "Sydgeorgien, sommartid", "GDT", - "Sydgeorgisk tid", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"Falklands\u00f6arna, normaltid", "FKT", - "Falklands\u00f6arna, sommartid", "FKST", - "Falklands\u00F6arna-tid", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"Central v\u00E4stlig normaltid (Australien)", "ACWST", - "Central v\u00E4stlig sommartid (Australien)", "ACWDT", - "Central v\u00E4stlig tid (Australien)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"Samara, normaltid", "SAMT", - "Samara, sommartid", "SAMST", - "Samara-tid", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"Indiska oceanen, normaltid", "IOT", - "Indiska oceanen, sommartid", "IOST", - "Indiska Ocean\u00F6arna-tid", "IOT"}}, - {"Indian/Christmas", new String[] {"Jul\u00f6n, normaltid", "CXT", - "Jul\u00f6n, sommartid", "CXST", - "Jul\u00F6n-tid", "CIT"}}, - {"Indian/Cocos", new String[] {"Cocos-Keeling\u00f6arna, normaltid", "CCT", - "Cocos-Keeling\u00f6arna, sommartid", "CCST", - "Kokos\u00F6arna-tid", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"Franska s\u00f6dra och antarktiska omr\u00e5dena, normaltid", "TFT", - "Franska s\u00f6dra och antarktiska omr\u00e5dena, sommartid", "TFST", - "Franska s\u00F6dra och antarktiska \u00F6arna-tid", "TFT"}}, - {"Indian/Mahe", new String[] {"Seychellerna, normaltid", "SCT", - "Seychellerna, sommartid", "SCST", - "Seychellisk tid", "SCT"}}, - {"Indian/Maldives", new String[] {"Maldiverna, normaltid", "MVT", - "Maldiverna, sommartid", "MVST", - "Maldivisk tid", "MVT"}}, - {"Indian/Mauritius", new String[] {"Mauritius, normaltid", "MUT", - "Mauritius, sommartid", "MUST", - "Mauritiansk tid", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"Reunion, normaltid", "RET", - "Reunion, sommartid", "REST", - "Reunion-tid", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"Vanuatu, normaltid", "VUT", - "Vanuatu, sommartid", "VUST", - "Vanuatu-tid", "VUT"}}, - {"Pacific/Enderbury", new String[] {"Phoenix-\u00f6arna, normaltid", "PHOT", - "Phoenix-\u00f6arna, sommartid", "PHOST", - "Phoenix\u00F6arna-tid", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"Tokelau, normaltid", "TKT", - "Tokelau, sommartid", "TKST", - "Tokelau-tid", "TKT"}}, - {"Pacific/Fiji", new String[] {"Fiji, normaltid", "FJT", - "Fiji, sommartid", "FJST", - "Fijiansk tid", "FJT"}}, - {"Pacific/Funafuti", new String[] {"Tuvalu, normaltid", "TVT", - "Tuvalu, sommartid", "TVST", - "Tuvalu-tid", "TVT"}}, - {"Pacific/Galapagos", new String[] {"Galapagos, normaltid", "GALT", - "Galapagos, sommartid", "GALST", - "Galapagos-tid", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Line-\u00f6arna, normaltid", "LINT", - "Line-\u00f6arna, sommartid", "LINST", - "Line Islands-tid", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Kosrae, normaltid", "KOST", - "Kosrae, sommartid", "KOSST", - "Kosrae-tid", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"Marquesas, normaltid", "MART", - "Marquesas, sommartid", "MARST", - "Marquesas\u00F6arna-tid", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"Nauru, normaltid", "NRT", - "Nauru, sommartid", "NRST", - "Nauruansk tid", "NRT"}}, - {"Pacific/Niue", new String[] {"Niue, normaltid", "NUT", - "Niue, sommartid", "NUST", - "Niue-tid", "NUT"}}, - {"Pacific/Norfolk", new String[] {"Norfolk, normaltid", "NFT", - "Norfolk, sommartid", "NFST", - "Norfolk-tid", "NFT"}}, - {"Pacific/Noumea", new String[] {"Nya Caledonien, normaltid", "NCT", - "Nya Caledonien, sommartid", "NCST", - "Nya Kaledonien-tid", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"Palau, normaltid", "PWT", - "Palau, sommartid", "PWST", - "Palau-tid", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"Papua Nya Guinea, normaltid", "PGT", - "Papua Nya Guinea, sommartid", "PGST", - "Papua Nya Guinea-tid", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"Cook\u00f6arna, normaltid", "CKT", - "Cook\u00f6arna, sommartid", "CKHST", - "Cook\u00F6arna-tid", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"Tahiti, normaltid", "TAHT", - "Tahiti, sommartid", "TAHST", - "Tahiti-tid", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"Gilbert\u00f6arna, normaltid", "GILT", - "Gilbert\u00f6arna, sommartid", "GILST", - "Gilbert\u00F6arna-tid", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"Tonga, normaltid", "TOT", - "Tonga, sommartid", "TOST", - "Tonga-tid", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"Wake, normaltid", "WAKT", - "Wake, sommartid", "WAKST", - "Wake-tid", "WAKT"}}, - {"Pacific/Wallis", new String[] {"Wallis & Futuna, normaltid", "WFT", - "Wallis & Futuna, sommartid", "WFST", - "Wallis- och Futuna\u00F6arna-tid", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java deleted file mode 100644 index 4d493df7254..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Acre \u65f6\u95f4", "ACT", - "Acre \u590f\u4ee4\u65f6", "ACST", - "Acre \u65f6\u95f4", "ACT"}; - String ADELAIDE[] = new String[] {"\u4E2D\u592E\u6807\u51C6\u65F6\u95F4 (\u5357\u6FB3\u5927\u5229\u4E9A)", "ACST", - "\u4E2D\u592E\u590F\u4EE4\u65F6 (\u5357\u6FB3\u5927\u5229\u4E9A)", "ACDT", - "\u4E2D\u90E8\u65F6\u95F4 (\u5357\u6FB3\u5927\u5229\u4E9A)", "ACT"}; - String AGT[] = new String[] {"\u963f\u6839\u5ef7\u65f6\u95f4", "ART", - "\u963f\u6839\u5ef7\u590f\u4ee4\u65f6", "ARST", - "\u963F\u6839\u5EF7\u65F6\u95F4", "ART"}; - String AKST[] = new String[] {"\u963f\u62c9\u65af\u52a0\u6807\u51c6\u65f6\u95f4", "AKST", - "\u963f\u62c9\u65af\u52a0\u590f\u4ee4\u65f6", "AKDT", - "\u963F\u62C9\u65AF\u52A0\u65F6\u95F4", "AKT"}; - String AMT[] = new String[] {"\u4e9a\u9a6c\u900a\u65f6\u95f4", "AMT", - "\u4e9a\u9a6c\u900a\u590f\u4ee4\u65f6", "AMST", - "\u4E9A\u9A6C\u900A\u65F6\u95F4", "AMT"}; - String ARAST[] = new String[] {"\u963f\u62c9\u4f2f\u6807\u51c6\u65f6\u95f4", "AST", - "\u963f\u62c9\u4f2f\u590f\u4ee4\u65f6", "ADT", - "\u963F\u62C9\u4F2F\u534A\u5C9B\u65F6\u95F4", "AT"}; - String ARMT[] = new String[] {"\u4e9a\u7f8e\u5c3c\u4e9a\u65f6\u95f4", "AMT", - "\u4e9a\u7f8e\u5c3c\u4e9a\u590f\u4ee4\u65f6", "AMST", - "\u4E9A\u7F8E\u5C3C\u4E9A\u65F6\u95F4", "AMT"}; - String AST[] = new String[] {"\u5927\u897f\u6d0b\u6807\u51c6\u65f6\u95f4", "AST", - "\u5927\u897f\u6d0b\u590f\u4ee4\u65f6", "ADT", - "\u5927\u897F\u6D0B\u65F6\u95F4", "AT"}; - String BDT[] = new String[] {"\u5b5f\u52a0\u62c9\u65f6\u95f4", "BDT", - "\u5b5f\u52a0\u62c9\u590f\u4ee4\u65f6", "BDST", - "\u5B5F\u52A0\u62C9\u65F6\u95F4", "BDT"}; - String BRISBANE[] = new String[] {"\u4E1C\u90E8\u6807\u51C6\u65F6\u95F4 (\u6606\u58EB\u5170)", "AEST", - "\u4E1C\u90E8\u590F\u4EE4\u65F6 (\u6606\u58EB\u5170)", "AEDT", - "\u4E1C\u90E8\u65F6\u95F4 (\u6606\u58EB\u5170)", "AET"}; - String BROKEN_HILL[] = new String[] {"\u4E2D\u592E\u6807\u51C6\u65F6\u95F4 (\u5357\u6FB3\u5927\u5229\u4E9A/\u65B0\u5357\u5A01\u5C14\u65AF)", "ACST", - "\u4E2D\u592E\u590F\u4EE4\u65F6 (\u5357\u6FB3\u5927\u5229\u4E9A/\u65B0\u5357\u5A01\u5C14\u65AF)", "ACDT", - "\u4E2D\u90E8\u65F6\u95F4 (\u5357\u6FB3\u5927\u5229\u4E9A/\u65B0\u5357\u5A01\u5C14\u65AF)", "ACT"}; - String BRT[] = new String[] {"\u5df4\u897f\u5229\u4e9a\u65f6\u95f4", "BRT", - "\u5df4\u897f\u5229\u4e9a\u590f\u4ee4\u65f6", "BRST", - "\u5DF4\u897F\u5229\u4E9A\u65F6\u95F4", "BRT"}; - String BTT[] = new String[] {"\u4e0d\u4e39\u65f6\u95f4", "BTT", - "\u4e0d\u4e39\u590f\u4ee4\u65f6", "BTST", - "\u4E0D\u4E39\u65F6\u95F4", "BTT"}; - String CAT[] = new String[] {"\u4e2d\u975e\u65f6\u95f4", "CAT", - "\u4e2d\u975e\u590f\u4ee4\u65f6", "CAST", - "\u4E2D\u975E\u65F6\u95F4", "CAT"}; - String CET[] = new String[] {"\u4e2d\u6b27\u65f6\u95f4", "CET", - "\u4e2d\u6b27\u590f\u4ee4\u65f6", "CEST", - "\u4E2D\u6B27\u65F6\u95F4", "CET"}; - String CHAST[] = new String[] {"\u67e5\u8428\u59c6\u6807\u51c6\u65f6\u95f4", "CHAST", - "\u67e5\u8428\u59c6\u590f\u4ee4\u65f6", "CHADT", - "\u67E5\u5854\u59C6\u65F6\u95F4", "CHAT"}; - String CHUT[] = new String[] {"\u4E18\u514B\u65F6\u95F4", "CHUT", - "\u4E18\u514B\u590F\u4EE4\u65F6", "CHUST", - "\u4E18\u514B\u65F6\u95F4", "CHUT"}; - String CIT[] = new String[] {"\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "WITA", - "\u4e2d\u90e8\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "CIST", - "\u4E2D\u90E8\u5370\u5EA6\u5C3C\u897F\u4E9A\u65F6\u95F4", "WITA"}; - String CLT[] = new String[] {"\u667a\u5229\u65f6\u95f4", "CLT", - "\u667a\u5229\u590f\u4ee4\u65f6", "CLST", - "\u667A\u5229\u65F6\u95F4", "CLT"}; - String CST[] = new String[] {"\u4e2d\u592e\u6807\u51c6\u65f6\u95f4", "CST", - "\u4e2d\u592e\u590f\u4ee4\u65f6", "CDT", - "\u4E2D\u90E8\u65F6\u95F4", "CT"}; - String CTT[] = new String[] {"\u4e2d\u56fd\u6807\u51c6\u65f6\u95f4", "CST", - "\u4e2d\u56fd\u590f\u4ee4\u65f6", "CDT", - "\u4E2D\u56FD\u65F6\u95F4", "CT"}; - String CUBA[] = new String[] {"\u53e4\u5df4\u6807\u51c6\u65f6\u95f4", "CST", - "\u53e4\u5df4\u590f\u4ee4\u65f6", "CDT", - "\u53E4\u5DF4\u65F6\u95F4", "CT"}; - String DARWIN[] = new String[] {"\u4E2D\u592E\u6807\u51C6\u65F6\u95F4 (\u5317\u9886\u5730)", "ACST", - "\u4E2D\u592E\u590F\u4EE4\u65F6 (\u5317\u9886\u5730)", "ACDT", - "\u4E2D\u90E8\u65F6\u95F4 (\u5317\u90E8\u5730\u533A)", "ACT"}; - String DUBLIN[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u65f6\u95f4", "GMT", - "\u7231\u5c14\u5170\u590f\u4ee4\u65f6", "IST", - "\u7231\u5C14\u5170\u65F6\u95F4", "IT"}; - String EAT[] = new String[] {"\u4e1c\u975e\u65f6\u95f4", "EAT", - "\u4e1c\u975e\u590f\u4ee4\u65f6", "EAST", - "\u4E1C\u975E\u65F6\u95F4", "EAT"}; - String EASTER[] = new String[] {"\u590d\u6d3b\u5c9b\u65f6\u95f4", "EAST", - "\u590d\u6d3b\u5c9b\u590f\u4ee4\u65f6", "EASST", - "\u590D\u6D3B\u5C9B\u65F6\u95F4", "EAST"}; - String EET[] = new String[] {"\u4e1c\u6b27\u65f6\u95f4", "EET", - "\u4e1c\u6b27\u590f\u4ee4\u65f6", "EEST", - "\u4e1c\u6b27\u65f6\u95f4", "EET"}; - String EGT[] = new String[] {"\u4e1c\u683c\u6797\u5c9b\u65f6\u95f4", "EGT", - "\u4e1c\u683c\u6797\u5c9b\u590f\u4ee4\u65f6", "EGST", - "\u4E1C\u683C\u6797\u5C9B\u65F6\u95F4", "EGT"}; - String EST[] = new String[] {"\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "EST", - "\u4e1c\u90e8\u590f\u4ee4\u65f6", "EDT", - "\u4E1C\u90E8\u65F6\u95F4", "ET"}; - String EST_NSW[] = new String[] {"\u4E1C\u90E8\u6807\u51C6\u65F6\u95F4 (\u65B0\u5357\u5A01\u5C14\u65AF)", "AEST", - "\u4E1C\u90E8\u590F\u4EE4\u65F6 (\u65B0\u5357\u5A01\u5C14\u65AF)", "AEDT", - "\u4E1C\u90E8\u65F6\u95F4 (\u65B0\u5357\u5A01\u5C14\u65AF)", "AET"}; - String FET[] = new String[] {"\u8FDC\u4E1C\u6B27\u65F6\u95F4", "FET", - "\u8FDC\u4E1C\u6B27\u590F\u4EE4\u65F6", "FEST", - "\u8FDC\u4E1C\u6B27\u65F6\u95F4", "FET"}; - String GHMT[] = new String[] {"\u52a0\u7eb3\u65f6\u95f4", "GMT", - "\u52a0\u7eb3\u590f\u4ee4\u65f6", "GHST", - "\u52A0\u7EB3\u65F6\u95F4", "GMT"}; - String GAMBIER[] = new String[] {"\u5188\u6bd4\u4e9a\u65f6\u95f4", "GAMT", - "\u5188\u6bd4\u4e9a\u590f\u4ee4\u65f6", "GAMST", - "\u5188\u6BD4\u4E9A\u65F6\u95F4", "GAMT"}; - String GMT[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u65f6\u95f4", "GMT", - "\u683c\u6797\u5a01\u6cbb\u65f6\u95f4", "GMT", - "\u683C\u6797\u5A01\u6CBB\u65F6\u95F4", "GMT"}; - String GMTBST[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u65f6\u95f4", "GMT", - "\u82f1\u56fd\u590f\u4ee4\u65f6", "BST", - "\u82F1\u56FD\u65F6\u95F4", "BT"}; - String GST[] = new String[] {"\u6ce2\u65af\u6e7e\u6807\u51c6\u65f6\u95f4", "GST", - "\u6ce2\u65af\u6e7e\u590f\u4ee4\u65f6", "GDT", - "\u6D77\u6E7E\u65F6\u95F4", "GT"}; - String HKT[] = new String[] {"\u9999\u6e2f\u65f6\u95f4", "HKT", - "\u9999\u6e2f\u590f\u4ee4\u65f6", "HKST", - "\u9999\u6E2F\u65F6\u95F4", "HKT"}; - String HST[] = new String[] {"\u590f\u5a01\u5937\u6807\u51c6\u65f6\u95f4", "HST", - "\u590f\u5a01\u5937\u590f\u4ee4\u65f6", "HDT", - "\u590F\u5A01\u5937\u65F6\u95F4", "HT"}; - String ICT[] = new String[] {"\u5370\u5ea6\u652f\u90a3\u65f6\u95f4", "ICT", - "\u5370\u5ea6\u652f\u90a3\u590f\u4ee4\u65f6", "ICST", - "\u5370\u5EA6\u652F\u90A3\u65F6\u95F4", "ICT"}; - String IRKT[] = new String[] {"\u4f0a\u5c14\u5e93\u6b21\u514b\u65f6\u95f4", "IRKT", - "\u4f0a\u5c14\u5e93\u6b21\u514b\u590f\u4ee4\u65f6", "IRKST", - "\u4F0A\u5C14\u5E93\u6B21\u514B\u65F6\u95F4", "IRKT"}; - String IRT[] = new String[] {"\u4f0a\u6717\u6807\u51c6\u65f6\u95f4", "IRST", - "\u4f0a\u6717\u590f\u4ee4\u65f6", "IRDT", - "\u4F0A\u6717\u65F6\u95F4", "IRT"}; - String ISRAEL[] = new String[] {"\u4ee5\u8272\u5217\u6807\u51c6\u65f6\u95f4", "IST", - "\u4ee5\u8272\u5217\u590f\u4ee4\u65f6", "IDT", - "\u4EE5\u8272\u5217\u65F6\u95F4", "IT"}; - String IST[] = new String[] {"\u5370\u5ea6\u6807\u51c6\u65f6\u95f4", "IST", - "\u5370\u5ea6\u590f\u4ee4\u65f6", "IDT", - "\u5370\u5EA6\u65F6\u95F4", "IT"}; - String JST[] = new String[] {"\u65e5\u672c\u6807\u51c6\u65f6\u95f4", "JST", - "\u65e5\u672c\u590f\u4ee4\u65f6", "JDT", - "\u65E5\u672C\u65F6\u95F4", "JT"}; - String KRAT[] = new String[] {"\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u65f6\u95f4", "KRAT", - "\u514b\u62c9\u65af\u8bfa\u4e9a\u5c14\u65af\u514b\u590f\u4ee4\u65f6", "KRAST", - "\u514B\u62C9\u65AF\u8BFA\u4E9A\u5C14\u65AF\u514B\u65F6\u95F4", "KRAT"}; - String KST[] = new String[] {"\u97e9\u56fd\u6807\u51c6\u65f6\u95f4", "KST", - "\u97e9\u56fd\u590f\u4ee4\u65f6", "KDT", - "\u97E9\u56FD\u65F6\u95F4", "KT"}; - String LORD_HOWE[] = new String[] {"\u8c6a\u516c\u6807\u51c6\u65f6\u95f4", "LHST", - "\u8c6a\u516c\u590f\u4ee4\u65f6", "LHDT", - "\u8C6A\u516C\u65F6\u95F4", "LHT"}; - String MHT[] = new String[] {"\u9a6c\u7ecd\u5c14\u7fa4\u5c9b\u65f6\u95f4", "MHT", - "\u9a6c\u7ecd\u5c14\u7fa4\u5c9b\u590f\u4ee4\u65f6", "MHST", - "\u9A6C\u7ECD\u5C14\u7FA4\u5C9B\u65F6\u95F4", "MHT"}; - String MMT[] = new String[] {"\u7f05\u7538\u65f6\u95f4", "MMT", - "\u7f05\u7538\u590f\u4ee4\u65f6", "MMST", - "\u7F05\u7538\u65F6\u95F4", "MMT"}; - String MSK[] = new String[] {"\u83ab\u65af\u79d1\u6807\u51c6\u65f6\u95f4", "MSK", - "\u83ab\u65af\u79d1\u590f\u4ee4\u65f6", "MSD", - "\u83AB\u65AF\u79D1\u65F6\u95F4", "MT"}; - String MST[] = new String[] {"Mountain \u6807\u51c6\u65f6\u95f4", "MST", - "Mountain \u590f\u4ee4\u65f6", "MDT", - "\u5C71\u5730\u65F6\u95F4", "MT"}; - String MYT[] = new String[] {"\u9a6c\u6765\u897f\u4e9a\u65f6\u95f4", "MYT", - "\u9a6c\u6765\u897f\u4e9a\u590f\u4ee4\u65f6", "MYST", - "\u9A6C\u6765\u897F\u4E9A\u65F6\u95F4", "MYT"}; - String NORONHA[] = new String[] {"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u65f6\u95f4", "FNT", - "\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u590f\u4ee4\u65f6", "FNST", - "\u8D39\u5C14\u5357\u591A\u5FB7\u8BFA\u7F57\u5C3C\u4E9A\u65F6\u95F4", "FNT"}; - String NOVT[] = new String[] {"Novosibirsk \u65f6\u95f4", "NOVT", - "Novosibirsk \u590f\u4ee4\u65f6", "NOVST", - "Novosibirsk \u65F6\u95F4", "NOVT"}; - String NPT[] = new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT", - "\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST", - "\u5C3C\u6CCA\u5C14\u65F6\u95F4", "NPT"}; - String NST[] = new String[] {"\u7ebd\u82ac\u5170\u6807\u51c6\u65f6\u95f4", "NST", - "\u7ebd\u82ac\u5170\u590f\u4ee4\u65f6", "NDT", - "\u7EBD\u82AC\u5170\u65F6\u95F4", "NT"}; - String NZST[] = new String[] {"\u65b0\u897f\u5170\u6807\u51c6\u65f6\u95f4", "NZST", - "\u65b0\u897f\u5170\u590f\u4ee4\u65f6", "NZDT", - "\u65B0\u897F\u5170\u65F6\u95F4", "NZT"}; - String PITCAIRN[] = new String[] {"\u76ae\u7279\u5eb7\u5c9b\u6807\u51c6\u65f6\u95f4", "PST", - "\u76ae\u7279\u5eb7\u5c9b\u590f\u4ee4\u65f6", "PDT", - "\u76AE\u7279\u51EF\u6069\u65F6\u95F4", "PT"}; - String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u65f6\u95f4", "PKT", - "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u65f6", "PKST", - "\u5DF4\u57FA\u65AF\u5766\u65F6\u95F4", "PKT"}; - String PONT[] = new String[] {"\u6CE2\u7EB3\u4F69\u65F6\u95F4", "PONT", - "\u6CE2\u7EB3\u4F69\u590F\u4EE4\u65F6", "PONST", - "\u6CE2\u7EB3\u4F69\u65F6\u95F4", "PONT"}; - String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "PST", - "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6", "PDT", - "\u592A\u5E73\u6D0B\u65F6\u95F4", "PT"}; - String SAST[] = new String[] {"\u5357\u975e\u6807\u51c6\u65f6\u95f4", "SAST", - "\u5357\u975e\u590f\u4ee4\u65f6", "SAST", - "\u5357\u975E\u65F6\u95F4", "SAT"}; - String SBT[] = new String[] {"\u6240\u7f57\u95e8\u7fa4\u5c9b\u65f6\u95f4", "SBT", - "\u6240\u7f57\u95e8\u7fa4\u5c9b\u590f\u4ee4\u65f6", "SBST", - "\u6240\u7F57\u95E8\u7FA4\u5C9B\u65F6\u95F4", "SBT"}; - String SGT[] = new String[] {"\u65b0\u52a0\u5761\u65f6\u95f4", "SGT", - "\u65b0\u52a0\u5761\u590f\u4ee4\u65f6", "SGST", - "\u65B0\u52A0\u5761\u65F6\u95F4", "SGT"}; - String TASMANIA[] = new String[] {"\u4E1C\u90E8\u6807\u51C6\u65F6\u95F4 (\u5854\u65AF\u9A6C\u5C3C\u4E9A)", "AEST", - "\u4E1C\u90E8\u590F\u4EE4\u65F6 (\u5854\u65AF\u9A6C\u5C3C\u4E9A)", "AEDT", - "\u4E1C\u90E8\u65F6\u95F4 (\u5854\u65AF\u9A6C\u5C3C\u4E9A)", "AET"}; - String TMT[] = new String[] {"\u571f\u5e93\u66fc\u65f6\u95f4", "TMT", - "\u571f\u5e93\u66fc\u590f\u4ee4\u65f6", "TMST", - "\u571F\u5E93\u66FC\u65F6\u95F4", "TMT"}; - String ULAT[]= new String[] {"\u5e93\u4f26\u65f6\u95f4", "ULAT", - "\u5e93\u4f26\u590f\u4ee4\u65f6", "ULAST", - "\u5E93\u4F26\u65F6\u95F4", "ULAT"}; - String WAT[] = new String[] {"\u897f\u975e\u65f6\u95f4", "WAT", - "\u897f\u975e\u590f\u4ee4\u65f6", "WAST", - "\u897F\u975E\u65F6\u95F4", "WAT"}; - String WET[] = new String[] {"\u897f\u6b27\u65f6\u95f4", "WET", - "\u897f\u6b27\u590f\u4ee4\u65f6", "WEST", - "\u897F\u6B27\u65F6\u95F4", "WET"}; - String WGT[] = new String[] {"\u897f\u683c\u6797\u5170\u5c9b\u65f6\u95f4", "WGT", - "\u897f\u683c\u6797\u5170\u5c9b\u590f\u4ee4\u65f6", "WGST", - "\u897F\u683C\u6797\u5170\u5C9B\u65F6\u95F4", "WGT"}; - String WIT[] = new String[] {"\u897f\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "WIB", - "\u897f\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "WIST", - "\u897F\u5370\u5EA6\u5C3C\u897F\u4E9A\u65F6\u95F4", "WIB"}; - String WST_AUS[] = new String[] {"\u897F\u90E8\u6807\u51C6\u65F6\u95F4 (\u6FB3\u5927\u5229\u4E9A)", "AWST", - "\u897F\u90E8\u590F\u4EE4\u65F6 (\u6FB3\u5927\u5229\u4E9A)", "AWDT", - "\u897F\u90E8\u65F6\u95F4 (\u6FB3\u5927\u5229\u4E9A)", "AWT"}; - String SAMOA[] = new String[] {"\u8428\u6469\u4e9a\u7fa4\u5c9b\u6807\u51c6\u65f6\u95f4", "SST", - "\u8428\u6469\u4e9a\u7fa4\u5c9b\u590f\u4ee4\u65f6", "SDT", - "\u8428\u6469\u4E9A\u65F6\u95F4", "ST"}; - String WST_SAMOA[] = new String[] {"\u897f\u8428\u6469\u4e9a\u65f6\u95f4", "WSST", - "\u897f\u8428\u6469\u4e9a\u590f\u4ee4\u65f6", "WSDT", - "\u897F\u8428\u6469\u4E9A\u65F6\u95F4", "WST"}; - String ChST[] = new String[] {"Chamorro \u6807\u51c6\u65f6\u95f4", "ChST", - "Chamorro \u590f\u4ee4\u65f6", "ChDT", - "\u67E5\u6469\u6D1B\u65F6\u95F4", "ChT"}; - String VICTORIA[] = new String[] {"\u4E1C\u90E8\u6807\u51C6\u65F6\u95F4 (\u7EF4\u591A\u5229\u4E9A)", "AEST", - "\u4E1C\u90E8\u590F\u4EE4\u65F6 (\u7EF4\u591A\u5229\u4E9A)", "AEDT", - "\u4E1C\u90E8\u65F6\u95F4 (\u7EF4\u591A\u5229\u4E9A)", "AET"}; - String UTC[] = new String[] {"\u534f\u8c03\u4e16\u754c\u65f6\u95f4", "UTC", - "\u534f\u8c03\u4e16\u754c\u65f6\u95f4", "UTC", - "\u534F\u8C03\u4E16\u754C\u65F6\u95F4", "UTC"}; - String UZT[] = new String[] {"\u4e4c\u5179\u522b\u514b\u65af\u5766\u65f6\u95f4", "UZT", - "\u4e4c\u5179\u522b\u514b\u65af\u5766\u590f\u4ee4\u65f6", "UZST", - "\u4E4C\u5179\u522B\u514B\u65AF\u5766\u65F6\u95F4", "UZT"}; - String XJT[] = new String[] {"\u4e2d\u56fd\u6807\u51c6\u65f6\u95f4", "XJT", - "\u4e2d\u56fd\u590f\u4ee4\u65f6", "XJDT", - "\u4E2D\u56FD\u65F6\u95F4", "XJT"}; - String YAKT[] = new String[] {"\u4e9a\u5e93\u6b21\u514b\u65f6\u95f4", "YAKT", - "\u4e9a\u5e93\u6b21\u514b\u590f\u4ee4\u65f6", "YAKST", - "\u4E9A\u5E93\u6B21\u514B\u65F6\u95F4", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"\u5df4\u62c9\u572d\u65f6\u95f4", "PYT", - "\u5df4\u62c9\u572d\u590f\u4ee4\u65f6", "PYST", - "\u5DF4\u62C9\u572D\u65F6\u95F4", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"\u54e5\u4f26\u6bd4\u4e9a\u65f6\u95f4", "COT", - "\u54e5\u4f26\u6bd4\u4e9a\u590f\u4ee4\u65f6", "COST", - "\u54E5\u4F26\u6BD4\u4E9A\u65F6\u95F4", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u59d4\u5185\u745e\u62c9\u65f6\u95f4", "VET", - "\u59d4\u5185\u745e\u62c9\u590f\u4ee4\u65f6", "VEST", - "\u59D4\u5185\u745E\u62C9\u65F6\u95F4", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"\u6cd5\u5c5e\u572d\u4e9a\u90a3\u65f6\u95f4", "GFT", - "\u6cd5\u5c5e\u572d\u4e9a\u90a3\u590f\u4ee4\u65f6", "GFST", - "\u6CD5\u5C5E\u572D\u4E9A\u90A3\u65F6\u95F4", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"\u5384\u74dc\u591a\u5c14\u65f6\u95f4", "ECT", - "\u5384\u74dc\u591a\u5c14\u590f\u4ee4\u65f6", "ECST", - "\u5384\u74DC\u591A\u5C14\u65F6\u95F4", "ECT"}}, - {"America/Guyana", new String[] {"\u572d\u4e9a\u90a3\u65f6\u95f4", "GYT", - "\u572d\u4e9a\u90a3\u590f\u4ee4\u65f6", "GYST", - "\u572D\u4E9A\u90A3\u65F6\u95F4", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"\u73bb\u5229\u7ef4\u4e9a\u65f6\u95f4", "BOT", - "\u73bb\u5229\u7ef4\u4e9a\u590f\u4ee4\u65f6", "BOST", - "\u73BB\u5229\u7EF4\u4E9A\u65F6\u95F4", "BOT"}}, - {"America/Lima", new String[] {"\u79d8\u9c81\u65f6\u95f4", "PET", - "\u79d8\u9c81\u590f\u4ee4\u65f6", "PEST", - "\u79D8\u9C81\u65F6\u95F4", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"\u76ae\u57c3\u5c14\u5c9b\u53ca\u5bc6\u514b\u9686\u5c9b\u6807\u51c6\u65f6\u95f4", "PMST", - "\u76ae\u57c3\u5c14\u5c9b\u53ca\u5bc6\u514b\u9686\u5c9b\u590f\u4ee4\u65f6", "PMDT", - "\u76AE\u57C3\u5C14\u548C\u5BC6\u514B\u9686\u5C9B\u65F6\u95F4", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"\u4e4c\u62c9\u572d\u65f6\u95f4", "UYT", - "\u4e4c\u62c9\u572d\u590f\u4ee4\u65f6", "UYST", - "\u4E4C\u62C9\u572D\u65F6\u95F4", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"\u82cf\u5229\u5357\u65f6\u95f4", "SRT", - "\u82cf\u5229\u5357\u590f\u4ee4\u65f6", "SRST", - "\u82CF\u5229\u5357\u65F6\u95F4", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT", - "\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST", - "\u6234\u7EF4\u65AF\u65F6\u95F4", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT", - "Dumont-d'Urville \u590f\u4ee4\u65f6", "DDUST", - "Dumont-d'Urville \u65F6\u95F4", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u65f6\u95f4", "MAWT", - "\u83ab\u68ee\u590f\u4ee4\u65f6", "MAWST", - "\u83AB\u68EE\u65F6\u95F4", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"\u7f57\u745f\u62c9\u65f6\u95f4", "ROTT", - "\u7f57\u745f\u62c9\u590f\u4ee4\u65f6", "ROTST", - "\u7F57\u745F\u62C9\u65F6\u95F4", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"Syowa \u65f6\u95f4", "SYOT", - "Syowa \u590f\u4ee4\u65f6", "SYOST", - "Syowa \u65F6\u95F4", "SYOT"}}, - {"Antarctica/Troll", new String[] {"\u534f\u8c03\u4e16\u754c\u65f6\u95f4", "UTC", - "\u4e2d\u6b27\u590f\u4ee4\u65f6", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"\u83ab\u65af\u6258\u514b\u65f6\u95f4", "VOST", - "\u83ab\u65af\u6258\u514b\u590f\u4ee4\u65f6", "VOSST", - "\u83AB\u65AF\u6258\u514B\u65F6\u95F4", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Alma-Ata \u65f6\u95f4", "ALMT", - "Alma-Ata \u590f\u4ee4\u65f6", "ALMST", - "Alma-Ata \u65F6\u95F4", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"\u963f\u90a3\u5e95\u6cb3\u65f6\u95f4", "ANAT", - "\u963f\u90a3\u5e95\u6cb3\u590f\u4ee4\u65f6", "ANAST", - "\u963F\u90A3\u5E95\u6CB3\u65F6\u95F4", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Aqtau \u65f6\u95f4", "AQTT", - "Aqtau \u590f\u4ee4\u65f6", "AQTST", - "Aqtau \u65F6\u95F4", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Aqtobe \u65f6\u95f4", "AQTT", - "Aqtobe \u590f\u4ee4\u65f6", "AQTST", - "Aqtobe \u65F6\u95F4", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"\u4e9a\u585e\u62dc\u7136\u65f6\u95f4", "AZT", - "\u4e9a\u585e\u62dc\u7136\u590f\u4ee4\u65f6", "AZST", - "\u4E9A\u585E\u62DC\u7136\u65F6\u95F4", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"\u5409\u5c14\u5409\u65af\u65af\u5766\u65f6\u95f4", "KGT", - "\u5409\u5c14\u5409\u65af\u65af\u5766\u590f\u4ee4\u65f6", "KGST", - "\u5409\u5C14\u5409\u65AF\u65AF\u5766\u65F6\u95F4", "KGT"}}, - {"Asia/Brunei", new String[] {"\u6587\u83b1\u65f6\u95f4", "BNT", - "\u6587\u83b1\u590f\u4ee4\u65f6", "BNST", - "\u6587\u83B1\u65F6\u95F4", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"Choibalsan \u65f6\u95f4", "CHOT", - "Choibalsan \u590f\u4ee4\u65f6", "CHOST", - "Choibalsan \u65F6\u95F4", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"\u4e1c\u5e1d\u6c76\u65f6\u95f4", "TLT", - "\u4e1c\u5e1d\u6c76\u590f\u4ee4\u65f6", "TLST", - "\u4E1C\u5E1D\u6C76\u65F6\u95F4", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"\u5854\u5409\u514b\u65af\u5766\u65f6\u95f4", "TJT", - "\u5854\u5409\u514b\u65af\u5766\u590f\u4ee4\u65f6", "TJST", - "\u5854\u5409\u514B\u65AF\u5766\u65F6\u95F4", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"\u79d1\u5e03\u591a\u65f6\u95f4", "HOVT", - "\u79d1\u5e03\u591a\u590f\u4ee4\u65f6", "HOVST", - "\u79D1\u5E03\u591A\u65F6\u95F4", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"\u4e1c\u5370\u5ea6\u5c3c\u897f\u4e9a\u65f6\u95f4", "WIT", - "\u4e1c\u5370\u5ea6\u5c3c\u897f\u4e9a\u590f\u4ee4\u65f6", "EIST", - "\u4E1C\u5370\u5EA6\u5C3C\u897F\u4E9A\u65F6\u95F4", "WIT"}}, - {"Asia/Kabul", new String[] {"\u963f\u5bcc\u6c57\u65f6\u95f4", "AFT", - "\u963f\u5bcc\u6c57\u590f\u4ee4\u65f6", "AFST", - "\u963F\u5BCC\u6C57\u65F6\u95F4", "AFT"}}, - {"Asia/Kamchatka", new String[] {"\u5f7c\u5f97\u7f57\u5df4\u752b\u6d1b\u592b\u65af\u514b\u65f6\u95f4", "PETT", - "\u5f7c\u5f97\u7f57\u5df4\u752b\u6d1b\u592b\u65af\u514b\u590f\u4ee4\u65f6", "PETST", - "\u5F7C\u5F97\u7F57\u5DF4\u752B\u6D1B\u592B\u65AF\u514B\u65F6\u95F4", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Magadan \u65f6\u95f4", "MAGT", - "Magadan \u590f\u4ee4\u65f6", "MAGST", - "Magadan \u65F6\u95F4", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"Oral \u65f6\u95f4", "ORAT", - "Oral \u590f\u4ee4\u65f6", "ORAST", - "Oral \u65F6\u95F4", "ORAT"}}, - {"Asia/Omsk", new String[] {"\u9102\u6728\u65af\u514b\u65f6\u95f4", "OMST", - "\u9102\u6728\u65af\u514b\u590f\u4ee4\u65f6", "OMSST", - "\u9102\u6728\u65AF\u514B\u65F6\u95F4", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Qyzylorda \u65f6\u95f4", "QYZT", - "Qyzylorda \u590f\u4ee4\u65f6", "QYZST", - "Qyzylorda \u65F6\u95F4", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"\u5e93\u9875\u5c9b\u65f6\u95f4", "SAKT", - "\u5e93\u9875\u5c9b\u590f\u4ee4\u65f6", "SAKST", - "\u5E93\u9875\u5C9B\u65F6\u95F4", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", CTT}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"\u4e54\u6cbb\u4e9a\u65f6\u95f4", "GET", - "\u4e54\u6cbb\u4e9a\u590f\u4ee4\u65f6", "GEST", - "\u4E54\u6CBB\u4E9A\u65F6\u95F4", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"\u4E4C\u65AF\u5B63\u6D85\u62C9\u65F6\u95F4", "VLAT", - "\u4E4C\u65AF\u5B63\u6D85\u62C9\u590F\u4EE4\u65F6", "VLAST", - "\u4E4C\u65AF\u5B63\u6D85\u62C9\u65F6\u95F4", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"\u6d77\u53c2\u5d34\u65f6\u95f4", "VLAT", - "\u6d77\u53c2\u5d34\u590f\u4ee4\u65f6", "VLAST", - "\u6D77\u53C2\u5D34\u65F6\u95F4", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Yekaterinburg \u65f6\u95f4", "YEKT", - "Yekaterinburg \u590f\u4ee4\u65f6", "YEKST", - "Yekaterinburg \u65F6\u95F4", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"\u4e9a\u901f\u5c14\u7fa4\u5c9b\u65f6\u95f4", "AZOT", - "\u4e9a\u901f\u5c14\u7fa4\u5c9b\u590f\u4ee4\u65f6", "AZOST", - "\u4E9A\u901F\u5C14\u7FA4\u5C9B\u65F6\u95F4", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"\u4f5b\u5fb7\u89d2\u65f6\u95f4", "CVT", - "\u4f5b\u5fb7\u89d2\u590f\u4ee4\u65f6", "CVST", - "\u4F5B\u5FB7\u89D2\u65F6\u95F4", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"\u5357\u4e54\u6cbb\u4e9a\u6807\u51c6\u65f6\u95f4", "GST", - "\u5357\u4e54\u6cbb\u4e9a\u590f\u4ee4\u65f6", "GDT", - "\u5357\u4E54\u6CBB\u4E9A\u5C9B\u65F6\u95F4", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"\u798f\u514b\u5170\u7fa4\u5c9b\u65f6\u95f4", "FKT", - "\u798f\u514b\u5170\u7fa4\u5c9b\u590f\u4ee4\u65f6", "FKST", - "\u798F\u514B\u5170\u7FA4\u5C9B\u65F6\u95F4", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"\u4E2D\u897F\u90E8\u6807\u51C6\u65F6\u95F4 (\u6FB3\u5927\u5229\u4E9A)", "ACWST", - "\u4E2D\u897F\u90E8\u590F\u4EE4\u65F6 (\u6FB3\u5927\u5229\u4E9A)", "ACWDT", - "\u4E2D\u897F\u90E8\u65F6\u95F4 (\u6FB3\u5927\u5229\u4E9A)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"\u6c99\u9a6c\u62c9\u65f6\u95f4", "SAMT", - "\u6c99\u9a6c\u62c9\u590f\u4ee4\u65f6", "SAMST", - "\u6C99\u9A6C\u62C9\u65F6\u95F4", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"\u5370\u5ea6\u6d0b\u5730\u5e26\u65f6\u95f4", "IOT", - "\u5370\u5ea6\u6d0b\u5730\u5e26\u590f\u4ee4\u65f6", "IOST", - "\u5370\u5EA6\u6D0B\u5730\u5E26\u65F6\u95F4", "IOT"}}, - {"Indian/Christmas", new String[] {"\u5723\u8bde\u5c9b\u65f6\u95f4", "CXT", - "\u5723\u8bde\u5c9b\u590f\u4ee4\u65f6", "CXST", - "\u5723\u8BDE\u5C9B\u65F6\u95F4", "CIT"}}, - {"Indian/Cocos", new String[] {"\u53ef\u53ef\u65af\u7fa4\u5c9b\u65f6\u95f4", "CCT", - "\u53ef\u53ef\u65af\u7fa4\u5c9b\u590f\u4ee4\u65f6", "CCST", - "\u53EF\u53EF\u65AF\u7FA4\u5C9B\u65F6\u95F4", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"\u6cd5\u5c5e\u5357\u6781\u65f6\u95f4", "TFT", - "\u6cd5\u5c5e\u5357\u6781\u590f\u4ee4\u65f6", "TFST", - "\u6CD5\u5C5E\u5357\u6781\u65F6\u95F4", "TFT"}}, - {"Indian/Mahe", new String[] {"\u585e\u5e2d\u5c14\u7fa4\u5c9b\u65f6\u95f4", "SCT", - "\u585e\u5e2d\u5c14\u7fa4\u5c9b\u590f\u4ee4\u65f6", "SCST", - "\u585E\u5E2D\u5C14\u7FA4\u5C9B\u65F6\u95F4", "SCT"}}, - {"Indian/Maldives", new String[] {"\u9a6c\u5c14\u4ee3\u592b\u65f6\u95f4", "MVT", - "\u9a6c\u5c14\u4ee3\u592b\u590f\u4ee4\u65f6", "MVST", - "\u9A6C\u5C14\u4EE3\u592B\u65F6\u95F4", "MVT"}}, - {"Indian/Mauritius", new String[] {"\u6469\u91cc\u897f\u65af\u65f6\u95f4", "MUT", - "\u6469\u91cc\u897f\u65af\u590f\u4ee4\u65f6", "MUST", - "\u6469\u91CC\u897F\u65AF\u65F6\u95F4", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"\u7559\u5c3c\u65fa\u5c9b\u65f6\u95f4", "RET", - "\u7559\u5c3c\u65fa\u5c9b\u590f\u4ee4\u65f6", "REST", - "\u7559\u5C3C\u65FA\u5C9B\u65F6\u95F4", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u56fe\u65f6\u95f4", "VUT", - "\u74e6\u5974\u963f\u56fe\u590f\u4ee4\u65f6", "VUST", - "\u74E6\u5974\u963F\u56FE\u65F6\u95F4", "VUT"}}, - {"Pacific/Enderbury", new String[] {"\u83f2\u5c3c\u514b\u65af\u7fa4\u5c9b\u65f6\u95f4", "PHOT", - "\u83f2\u5c3c\u514b\u65af\u7fa4\u5c9b\u590f\u4ee4\u65f6", "PHOST", - "\u83F2\u5C3C\u514B\u65AF\u7FA4\u5C9B\u65F6\u95F4", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"\u6258\u514b\u52b3\u7fa4\u5c9b\u65f6\u95f4", "TKT", - "\u6258\u514b\u52b3\u7fa4\u5c9b\u590f\u4ee4\u65f6", "TKST", - "\u6258\u514B\u52B3\u7FA4\u5C9B\u65F6\u95F4", "TKT"}}, - {"Pacific/Fiji", new String[] {"\u6590\u6d4e\u65f6\u95f4", "FJT", - "\u6590\u6d4e\u590f\u4ee4\u65f6", "FJST", - "\u6590\u6D4E\u65F6\u95F4", "FJT"}}, - {"Pacific/Funafuti", new String[] {"\u5410\u9c81\u74e6\u65f6\u95f4", "TVT", - "\u5410\u9c81\u74e6\u590f\u4ee4\u65f6", "TVST", - "\u5410\u9C81\u74E6\u65F6\u95F4", "TVT"}}, - {"Pacific/Galapagos", new String[] {"\u52a0\u62c9\u5df4\u54e5\u65f6\u95f4", "GALT", - "\u52a0\u62c9\u5df4\u54e5\u590f\u4ee4\u65f6", "GALST", - "\u52A0\u62C9\u5DF4\u54E5\u65F6\u95F4", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Line \u5c9b\u65f6\u95f4", "LINT", - "Line \u5c9b\u590f\u4ee4\u65f6", "LINST", - "Line \u5C9B\u65F6\u95F4", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Kosrae \u65f6\u95f4", "KOST", - "Kosrae \u590f\u4ee4\u65f6", "KOSST", - "Kosrae \u65F6\u95F4", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"\u9a6c\u514b\u8428\u65af\u65f6\u95f4", "MART", - "\u9a6c\u514b\u8428\u65af\u590f\u4ee4\u65f6", "MARST", - "\u9A6C\u514B\u8428\u65AF\u65F6\u95F4", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"\u8bfa\u9c81\u65f6\u95f4", "NRT", - "\u8bfa\u9c81\u590f\u4ee4\u65f6", "NRST", - "\u8BFA\u9C81\u65F6\u95F4", "NRT"}}, - {"Pacific/Niue", new String[] {"\u7ebd\u5a01\u5c9b\u65f6\u95f4", "NUT", - "\u7ebd\u5a01\u5c9b\u590f\u4ee4\u65f6", "NUST", - "\u7EBD\u5A01\u5C9B\u65F6\u95F4", "NUT"}}, - {"Pacific/Norfolk", new String[] {"\u8bfa\u798f\u514b\u65f6\u95f4", "NFT", - "\u8bfa\u798f\u514b\u590f\u4ee4\u65f6", "NFST", - "\u8BFA\u798F\u514B\u65F6\u95F4", "NFT"}}, - {"Pacific/Noumea", new String[] {"\u65b0\u52a0\u52d2\u591a\u5c3c\u4e9a\u65f6\u95f4", "NCT", - "\u65b0\u52a0\u52d2\u591a\u5c3c\u4e9a\u590f\u4ee4\u65f6", "NCST", - "\u65B0\u52A0\u52D2\u591A\u5C3C\u4E9A\u65F6\u95F4", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"\u5e1b\u7409\u65f6\u95f4", "PWT", - "\u5e1b\u7409\u590f\u4ee4\u65f6", "PWST", - "\u5E1B\u7409\u65F6\u95F4", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u65f6\u95f4", "PGT", - "\u5df4\u5e03\u4e9a\u65b0\u51e0\u5185\u4e9a\u590f\u4ee4\u65f6", "PGST", - "\u5DF4\u5E03\u4E9A\u65B0\u51E0\u5185\u4E9A\u65F6\u95F4", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"\u5e93\u514b\u7fa4\u5c9b\u65f6\u95f4", "CKT", - "\u5e93\u514b\u7fa4\u5c9b\u590f\u4ee4\u65f6", "CKHST", - "\u5E93\u514B\u7FA4\u5C9B\u65F6\u95F4", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"\u5927\u6eaa\u5730\u5c9b\u65f6\u95f4", "TAHT", - "\u5927\u6eaa\u5730\u5c9b\u590f\u4ee4\u65f6", "TAHST", - "\u5927\u6EAA\u5730\u5C9B\u65F6\u95F4", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"\u5409\u4f2f\u7279\u7fa4\u5c9b\u65f6\u95f4", "GILT", - "\u5409\u4f2f\u7279\u7fa4\u5c9b\u590f\u4ee4\u65f6", "GILST", - "\u5409\u4F2F\u7279\u7FA4\u5C9B\u65F6\u95F4", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"\u4e1c\u52a0\u65f6\u95f4", "TOT", - "\u4e1c\u52a0\u590f\u4ee4\u65f6", "TOST", - "\u4E1C\u52A0\u65F6\u95F4", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"\u5a01\u514b\u65f6\u95f4", "WAKT", - "\u5a01\u514b\u590f\u4ee4\u65f6", "WAKST", - "\u5A01\u514B\u65F6\u95F4", "WAKT"}}, - {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u65f6\u95f4", "WFT", - "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7eb3\u7fa4\u5c9b\u590f\u4ee4\u65f6", "WFST", - "\u74E6\u5229\u65AF\u53CA\u798F\u675C\u7EB3\u7FA4\u5C9B\u65F6\u95F4", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_HK.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_HK.java deleted file mode 100644 index 9733c12e96c..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_HK.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - All Rights Reserved - * - * The original version of this source code and documentation is copyrighted - * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These - * materials are provided under terms of a License Agreement between Taligent - * and Sun. This technology is protected by multiple US and International - * patents. This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import java.util.Locale; -import java.util.ResourceBundle; -import sun.util.locale.provider.LocaleProviderAdapter; -import sun.util.locale.provider.ResourceBundleBasedAdapter; -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_zh_HK extends TimeZoneNamesBundle { - - // reparent to zh_TW for traditional Chinese names - public TimeZoneNames_zh_HK() { - ResourceBundle bundle = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forJRE()).getLocaleData().getTimeZoneNames(Locale.TAIWAN); - setParent(bundle); - } - - @Override - protected Object[][] getContents() { - return new Object[][] {}; - } -} diff --git a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java b/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java deleted file mode 100644 index f2ddb6c407b..00000000000 --- a/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java +++ /dev/null @@ -1,1048 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved - * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved - * - * The original version of this source code and documentation - * is copyrighted and owned by Taligent, Inc., a wholly-owned - * subsidiary of IBM. These materials are provided under terms - * of a License Agreement between Taligent and Sun. This technology - * is protected by multiple US and International patents. - * - * This notice and attribution to Taligent may not be removed. - * Taligent is a registered trademark of Taligent, Inc. - * - */ - -package sun.util.resources.ext; - -import sun.util.resources.TimeZoneNamesBundle; - -public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { - - protected final Object[][] getContents() { - String ACT[] = new String[] {"Acre \u6642\u9593", "ACT", - "Acre \u590f\u4ee4\u6642\u9593", "ACST", - "Acre \u6642\u9593", "ACT"}; - String ADELAIDE[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u90E8)", "ACST", - "\u4E2D\u90E8\u590F\u4EE4\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u5340)", "ACDT", - "\u4E2D\u90E8\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u90E8)", "ACT"}; - String AGT[] = new String[] {"\u963f\u6839\u5ef7\u6642\u9593", "ART", - "\u963f\u6839\u5ef7\u590f\u4ee4\u6642\u9593", "ARST", - "\u963F\u6839\u5EF7\u6642\u9593", "ART"}; - String AKST[] = new String[] {"\u963f\u62c9\u65af\u52a0\u6a19\u6e96\u6642\u9593", "AKST", - "\u963f\u62c9\u65af\u52a0\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "AKDT", - "\u963F\u62C9\u65AF\u52A0\u6642\u9593", "AKT"}; - String AMT[] = new String[] {"\u4e9e\u99ac\u905c\u6642\u9593", "AMT", - "\u4e9e\u99ac\u905c\u590f\u4ee4\u6642\u9593", "AMST", - "\u4E9E\u99AC\u905C\u6642\u9593", "AMT"}; - String ARAST[] = new String[] {"\u963f\u62c9\u4f2f\u6a19\u6e96\u6642\u9593", "AST", - "\u963f\u62c9\u4f2f\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "ADT", - "\u963F\u62C9\u4F2F\u6642\u9593", "AT"}; - String ARMT[] = new String[] {"\u4e9e\u7f8e\u5c3c\u4e9e\u6642\u9593", "AMT", - "\u4e9e\u7f8e\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "AMST", - "\u4E9E\u7F8E\u5C3C\u4E9E\u6642\u9593", "AMT"}; - String AST[] = new String[] {"\u5927\u897f\u6d0b\u6a19\u6e96\u6642\u9593", "AST", - "\u5927\u897f\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "ADT", - "\u5927\u897F\u6D0B\u6642\u9593", "AT"}; - String BDT[] = new String[] {"\u5b5f\u52a0\u62c9\u6642\u9593", "BDT", - "\u5b5f\u52a0\u62c9\u590f\u4ee4\u6642\u9593", "BDST", - "\u5B5F\u52A0\u62C9\u6642\u9593", "BDT"}; - String BRISBANE[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642\u9593 (\u6606\u58EB\u862D)", "AEST", - "\u6771\u90E8\u590F\u4EE4\u6642\u9593 (\u6606\u58EB\u862D)", "AEDT", - "\u6771\u90E8\u6642\u9593 (\u6606\u58EB\u862D)", "AET"}; - String BROKEN_HILL[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u5340/\u65B0\u5357\u5A01\u723E\u65AF)", "ACST", - "\u4E2D\u90E8\u590F\u4EE4\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u5340/\u65B0\u5357\u5A01\u723E\u65AF)", "ACDT", - "\u4E2D\u90E8\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E\u5357\u90E8/\u65B0\u5357\u5A01\u723E\u65AF)", "ACT"}; - String BRT[] = new String[] {"\u5df4\u897f\u5229\u4e9e\u6642\u9593", "BRT", - "\u5df4\u897f\u5229\u4e9e\u590f\u4ee4\u6642\u9593", "BRST", - "\u5DF4\u897F\u5229\u4E9E\u6642\u9593", "BRT"}; - String BTT[] = new String[] {"\u4e0d\u4e39\u6642\u9593", "BTT", - "\u4e0d\u4e39\u590f\u4ee4\u6642\u9593", "BTST", - "\u4E0D\u4E39\u6642\u9593", "BTT"}; - String CAT[] = new String[] {"\u4e2d\u975e\u6642\u9593", "CAT", - "\u4e2d\u975e\u590f\u4ee4\u6642\u9593", "CAST", - "\u4E2D\u975E\u6642\u9593", "CAT"}; - String CET[] = new String[] {"\u4e2d\u6b50\u6642\u9593", "CET", - "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "CEST", - "\u4E2D\u6B50\u6642\u9593", "CET"}; - String CHAST[] = new String[] {"\u67e5\u5766\u6a19\u6e96\u6642\u9593", "CHAST", - "\u67e5\u5766\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CHADT", - "\u67E5\u5766\u6642\u9593", "CHAT"}; - String CHUT[] = new String[] {"\u695A\u514B\u6642\u9593", "CHUT", - "\u695A\u514B\u590F\u4EE4\u6642\u9593", "CHUST", - "\u695A\u514B\u6642\u9593", "CHUT"}; - String CIT[] = new String[] {"\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u6642\u9593", "WITA", - "\u4e2d\u5370\u5ea6\u5c3c\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "CIST", - "\u4E2D\u5370\u5EA6\u5C3C\u897F\u4E9E\u6642\u9593", "WITA"}; - String CLT[] = new String[] {"\u667a\u5229\u6642\u9593", "CLT", - "\u667a\u5229\u590f\u4ee4\u6642\u9593", "CLST", - "\u667A\u5229\u6642\u9593", "CLT"}; - String CST[] = new String[] {"\u4e2d\u592e\u6a19\u6e96\u6642\u9593", "CST", - "\u4e2d\u592e\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CDT", - "\u7F8E\u570B\u4E2D\u90E8\u6642\u9593", "CT"}; - String CTT[] = new String[] {"\u4e2d\u570b\u6a19\u6e96\u6642\u9593", "CST", - "\u4e2d\u570b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CDT", - "\u4E2D\u570B\u6642\u9593", "CT"}; - String CUBA[] = new String[] {"\u53e4\u5df4\u6a19\u6e96\u6642\u9593", "CST", - "\u53e4\u5df4\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "CDT", - "\u53E4\u5DF4\u6642\u9593", "CT"}; - String DARWIN[] = new String[] {"\u4E2D\u90E8\u6A19\u6E96\u6642\u9593 (\u5317\u90E8\u5404\u5730\u5340)", "ACST", - "\u4E2D\u90E8\u590F\u4EE4\u6642\u9593 (\u5317\u90E8\u5404\u5730\u5340)", "ACDT", - "\u6FB3\u5927\u5229\u4E9E\u4E2D\u90E8\u6642\u9593 (\u5317\u65B9\u5340\u57DF)", "ACT"}; - String DUBLIN[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u5e73\u5747\u6642\u9593", "GMT", - "\u611b\u723e\u862d\u590f\u4ee4\u6642\u9593", "IST", - "\u611B\u723E\u862D\u6587\u6642\u9593", "IT"}; - String EAT[] = new String[] {"\u6771\u975e\u6642\u9593", "EAT", - "\u6771\u975e\u590f\u4ee4\u6642\u9593", "EAST", - "\u6771\u975E\u6642\u9593", "EAT"}; - String EASTER[] = new String[] {"\u5fa9\u6d3b\u5cf6\u6642\u9593", "EAST", - "\u5fa9\u6d3b\u5cf6\u590f\u4ee4\u6642\u9593", "EASST", - "\u5FA9\u6D3B\u5CF6\u6642\u9593", "EAST"}; - String EET[] = new String[] {"\u6771\u6b50\u6642\u9593", "EET", - "\u6771\u6b50\u590f\u4ee4\u6642\u9593", "EEST", - "\u6771\u6b50\u6642\u9593", "EET"}; - String EGT[] = new String[] {"\u6771\u683c\u6797\u5cf6\u6642\u9593", "EGT", - "\u6771\u683c\u6797\u5cf6\u590f\u4ee4\u6642\u9593", "EGST", - "\u6771\u683C\u9675\u862D\u6642\u9593", "EGT"}; - String EST[] = new String[] {"\u6771\u65b9\u6a19\u6e96\u6642\u9593", "EST", - "\u6771\u65b9\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "EDT", - "\u7F8E\u570B\u6771\u90E8\u6642\u9593", "ET"}; - String EST_NSW[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642\u9593 (\u65B0\u5357\u5A01\u723E\u65AF)", "AEST", - "\u6771\u90E8\u590F\u4EE4\u6642\u9593 (\u65B0\u5357\u5A01\u723E\u65AF)", "AEDT", - "\u6771\u90E8\u6642\u9593 (\u65B0\u5357\u5A01\u723E\u65AF)", "AET"}; - String FET[] = new String[] {"\u6771\u6B50\u5167\u9678\u6642\u9593", "FET", - "\u6771\u6B50\u5167\u9678\u590F\u4EE4\u6642\u9593", "FEST", - "\u6771\u6B50\u5167\u9678\u6642\u9593", "FET"}; - String GHMT[] = new String[] {"\u8fe6\u7d0d\u5e73\u5747\u6642\u9593", "GMT", - "\u8fe6\u7d0d\u590f\u4ee4\u6642\u9593", "GHST", - "\u8FE6\u7D0D\u6642\u9593", "GMT"}; - String GAMBIER[] = new String[] {"\u7518\u6bd4\u723e\u6642\u9593", "GAMT", - "\u7518\u6bd4\u723e\u590f\u4ee4\u6642\u9593", "GAMST", - "\u7518\u6BD4\u723E\u6642\u9593", "GAMT"}; - String GMT[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u6642\u9593", "GMT", - "\u683c\u6797\u5a01\u6cbb\u6642\u9593", "GMT", - "\u683C\u6797\u5A01\u6CBB\u6642\u9593", "GMT"}; - String GMTBST[] = new String[] {"\u683c\u6797\u5a01\u6cbb\u5e73\u5747\u6642\u9593", "GMT", - "\u82f1\u570b\u590f\u4ee4\u6642\u9593", "BST", - "\u82F1\u570B\u6642\u9593", "BT"}; - String GST[] = new String[] {"\u6ce2\u65af\u7063\u6a19\u6e96\u6642\u9593", "GST", - "\u6ce2\u65af\u7063\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "GDT", - "\u6CE2\u65AF\u7063\u6642\u9593", "GT"}; - String HKT[] = new String[] {"\u9999\u6e2f\u6642\u9593", "HKT", - "\u9999\u6e2f\u590f\u4ee4\u6642\u9593", "HKST", - "\u9999\u6E2F\u6642\u9593", "HKT"}; - String HST[] = new String[] {"\u590f\u5a01\u5937\u6a19\u6e96\u6642\u9593", "HST", - "\u590f\u5a01\u5937\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "HDT", - "\u590F\u5A01\u5937\u6642\u9593", "HT"}; - String ICT[] = new String[] {"\u5370\u5ea6\u652f\u90a3\u6642\u9593", "ICT", - "\u5370\u5ea6\u652f\u90a3\u590f\u4ee4\u6642\u9593", "ICST", - "\u5370\u5EA6\u652F\u90A3\u6642\u9593", "ICT"}; - String IRKT[] = new String[] {"Irkutsk \u6642\u9593", "IRKT", - "Irkutsk \u590f\u4ee4\u6642\u9593", "IRKST", - "\u4F0A\u723E\u5EAB\u6B21\u514B\u6642\u9593", "IRKT"}; - String IRT[] = new String[] {"\u4f0a\u6717\u6a19\u6e96\u6642\u9593", "IRST", - "\u4f0a\u6717\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "IRDT", - "\u4F0A\u6717\u6642\u9593", "IRT"}; - String ISRAEL[] = new String[] {"\u4ee5\u8272\u5217\u6a19\u6e96\u6642\u9593", "IST", - "\u4ee5\u8272\u5217\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "IDT", - "\u4EE5\u8272\u5217\u6642\u9593", "IT"}; - String IST[] = new String[] {"\u5370\u5ea6\u6a19\u6e96\u6642\u9593", "IST", - "\u5370\u5ea6\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "IDT", - "\u5370\u5EA6\u6642\u9593", "IT"}; - String JST[] = new String[] {"\u65e5\u672c\u6a19\u6e96\u6642\u9593", "JST", - "\u65e5\u672c\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "JDT", - "\u65E5\u672C\u6642\u9593", "JT"}; - String KRAT[] = new String[] {"\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u6642\u9593", "KRAT", - "\u514b\u62c9\u65af\u8afe\u4e9e\u723e\u65af\u514b\u590f\u4ee4\u6642\u9593", "KRAST", - "\u514B\u62C9\u65AF\u8AFE\u4E9E\u723E\u65AF\u514B\u6642\u9593", "KRAT"}; - String KST[] = new String[] {"\u97d3\u570b\u6a19\u6e96\u6642\u9593", "KST", - "\u97d3\u570b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "KDT", - "\u97D3\u570B\u6642\u9593", "KT"}; - String LORD_HOWE[] = new String[] {"\u8c6a\u52f3\u7235\u5cf6\u6a19\u6e96\u6642\u9593", "LHST", - "\u8c6a\u52f3\u7235\u5cf6\u590f\u4ee4\u6642\u9593", "LHDT", - "\u8C6A\u52F3\u7235\u5CF6\u6642\u9593", "LHT"}; - String MHT[] = new String[] {"\u99ac\u7d39\u723e\u7fa4\u5cf6\u6642\u9593", "MHT", - "\u99ac\u7d39\u723e\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "MHST", - "\u99AC\u7D39\u723E\u7FA4\u5CF6\u6642\u9593", "MHT"}; - String MMT[] = new String[] {"\u7dec\u7538\u6642\u9593", "MMT", - "\u7dec\u7538\u590f\u4ee4\u6642\u9593", "MMST", - "\u7DEC\u7538\u6642\u9593", "MMT"}; - String MSK[] = new String[] {"\u83ab\u65af\u79d1\u6a19\u6e96\u6642\u9593", "MSK", - "\u83ab\u65af\u79d1\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "MSD", - "\u83AB\u65AF\u79D1\u6642\u9593", "MT"}; - String MST[] = new String[] {"\u5c71\u5340\u6a19\u6e96\u6642\u9593", "MST", - "\u5c71\u5340\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "MDT", - "\u7F8E\u570B\u5C71\u5340\u6642\u9593", "MT"}; - String MYT[] = new String[] {"\u99ac\u4f86\u897f\u4e9e\u6642\u9593", "MYT", - "\u99ac\u4f86\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "MYST", - "\u99AC\u4F86\u897F\u4E9E\u6642\u9593", "MYT"}; - String NORONHA[] = new String[] {"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u6642\u9593", "FNT", - "\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "FNST", - "\u8CBB\u723E\u5357\u591A-\u8FEA\u8AFE\u7F85\u5C3C\u4E9E\u6642\u9593", "FNT"}; - String NOVT[] = new String[] {"Novosibirsk \u6642\u9593", "NOVT", - "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST", - "\u65B0\u897F\u4F2F\u5229\u4E9E\u6642\u9593", "NOVT"}; - String NPT[] = new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT", - "\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST", - "\u5C3C\u6CCA\u723E\u6642\u9593", "NPT"}; - String NST[] = new String[] {"\u7d10\u82ac\u862d\u6a19\u6e96\u6642\u9593", "NST", - "\u7d10\u82ac\u862d\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "NDT", - "\u7D10\u82AC\u862D\u6642\u9593", "NT"}; - String NZST[] = new String[] {"\u7d10\u897f\u862d\u6a19\u6e96\u6642\u9593", "NZST", - "\u7d10\u897f\u862d\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "NZDT", - "\u7D10\u897F\u862D\u6642\u9593", "NZT"}; - String PITCAIRN[] = new String[] {"\u76ae\u7279\u5eb7\u6a19\u6e96\u6642\u9593", "PST", - "\u76ae\u7279\u5eb7\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT", - "\u76AE\u7279\u5EB7\u6642\u9593", "PT"}; - String PKT[] = new String[] {"\u5df4\u57fa\u65af\u5766\u6642\u9593", "PKT", - "\u5df4\u57fa\u65af\u5766\u590f\u4ee4\u6642\u9593", "PKST", - "\u5DF4\u57FA\u65AF\u5766\u6642\u9593", "PKT"}; - String PONT[] = new String[] {"\u6CE2\u7D0D\u4F69\u6642\u9593", "PONT", - "\u6CE2\u7D0D\u4F69\u590F\u4EE4\u6642\u9593", "PONST", - "\u6CE2\u7D0D\u4F69\u5CF6\u6642\u9593", "PONT"}; - String PST[] = new String[] {"\u592a\u5e73\u6d0b\u6a19\u6e96\u6642\u9593", "PST", - "\u592a\u5e73\u6d0b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PDT", - "\u592A\u5E73\u6D0B\u6642\u9593", "PT"}; - String SAST[] = new String[] {"\u5357\u975e\u6a19\u6e96\u6642\u9593", "SAST", - "\u5357\u975e\u590f\u4ee4\u6642\u9593", "SAST", - "\u5357\u975E\u6642\u9593", "SAT"}; - String SBT[] = new String[] {"\u6240\u7f85\u9580\u7fa4\u5cf6\u6642\u9593", "SBT", - "\u6240\u7f85\u9580\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "SBST", - "\u6240\u7F85\u9580\u7FA4\u5CF6\u6642\u9593", "SBT"}; - String SGT[] = new String[] {"\u65b0\u52a0\u5761\u6642\u9593", "SGT", - "\u65b0\u52a0\u5761\u590f\u4ee4\u6642\u9593", "SGST", - "\u65B0\u52A0\u5761\u6642\u9593", "SGT"}; - String TASMANIA[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642\u9593 (\u5854\u65AF\u6885\u5C3C\u4E9E\u5CF6)", "AEST", - "\u6771\u90E8\u590F\u4EE4\u6642\u9593 (\u5854\u65AF\u6885\u5C3C\u4E9E\u5CF6)", "AEDT", - "\u6FB3\u5927\u5229\u4E9E\u6771\u90E8\u6642\u9593 (\u5854\u65AF\u99AC\u5C3C\u4E9E\u5CF6)", "AET"}; - String TMT[] = new String[] {"\u571f\u5eab\u66fc\u6642\u9593", "TMT", - "\u571f\u5eab\u66fc\u590f\u4ee4\u6642\u9593", "TMST", - "\u571F\u5EAB\u66FC\u6642\u9593", "TMT"}; - String ULAT[]= new String[] {"\u5eab\u502b\u6642\u9593", "ULAT", - "\u5eab\u502b\u590f\u4ee4\u6642\u9593", "ULAST", - "\u5EAB\u502B\u6642\u9593", "ULAT"}; - String WAT[] = new String[] {"\u897f\u975e\u6642\u9593", "WAT", - "\u897f\u975e\u590f\u4ee4\u6642\u9593", "WAST", - "\u897F\u975E\u6642\u9593", "WAT"}; - String WET[] = new String[] {"\u897f\u6b50\u6642\u9593", "WET", - "\u897f\u6b50\u590f\u4ee4\u6642\u9593", "WEST", - "\u897F\u6B50\u6642\u9593", "WET"}; - String WGT[] = new String[] {"\u897f\u683c\u6797\u862d\u5cf6\u6642\u9593", "WGT", - "\u897f\u683c\u6797\u862d\u5cf6\u590f\u4ee4\u6642\u9593", "WGST", - "\u897F\u683C\u9675\u862D\u6642\u9593", "WGT"}; - String WIT[] = new String[] {"\u897f\u5370\u5c3c\u6642\u9593", "WIB", - "\u897f\u5370\u5c3c\u590f\u4ee4\u6642\u9593", "WIST", - "\u897F\u5370\u5C3C\u6642\u9593", "WIB"}; - String WST_AUS[] = new String[] {"\u897F\u90E8\u6A19\u6E96\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "AWST", - "\u897F\u90E8\u590F\u4EE4\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "AWDT", - "\u897F\u90E8\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "AWT"}; - String SAMOA[] = new String[] {"\u85a9\u6469\u4e9e\u6a19\u6e96\u6642\u9593", "SST", - "\u85a9\u6469\u4e9e\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "SDT", - "\u85A9\u6469\u4E9E\u6642\u9593", "ST"}; - String WST_SAMOA[] = new String[] {"\u897f\u85a9\u6469\u4e9e\u6642\u9593", "WSST", - "\u897f\u85a9\u6469\u4e9e\u590f\u4ee4\u6642\u9593", "WSDT", - "\u897F\u85A9\u6469\u4E9E\u6642\u9593", "WST"}; - String ChST[] = new String[] {"\u67e5\u83ab\u6d1b\u6a19\u6e96\u6642\u9593", "ChST", - "\u67e5\u83ab\u6d1b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "ChDT", - "\u67E5\u83AB\u7F85\u6642\u9593", "ChT"}; - String VICTORIA[] = new String[] {"\u6771\u90E8\u6A19\u6E96\u6642\u9593 (\u7DAD\u591A\u5229\u4E9E\u90A6)", "AEST", - "\u6771\u90E8\u590F\u4EE4\u6642\u9593 (\u7DAD\u591A\u5229\u4E9E\u90A6)", "AEDT", - "\u6771\u90E8\u6642\u9593 (\u7DAD\u591A\u5229\u4E9E)", "AET"}; - String UTC[] = new String[] {"\u5354\u8abf\u4e16\u754c\u6642\u9593", "UTC", - "\u5354\u8abf\u4e16\u754c\u6642\u9593", "UTC", - "\u5354\u8ABF\u4E16\u754C\u6642\u9593", "UTC"}; - String UZT[] = new String[] {"\u70cf\u8332\u5225\u514b\u65af\u5766\u6642\u9593", "UZT", - "\u70cf\u8332\u5225\u514b\u65af\u5766\u590f\u4ee4\u6642\u9593", "UZST", - "\u70CF\u8332\u5225\u514B\u65AF\u5766\u6642\u9593", "UZT"}; - String XJT[] = new String[] {"\u4e2d\u570b\u6a19\u6e96\u6642\u9593", "XJT", - "\u4e2d\u570b\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "XJDT", - "\u4E2D\u570B\u6642\u9593", "XJT"}; - String YAKT[] = new String[] {"\u4e9e\u5eab\u6b21\u514b\u6642\u9593", "YAKT", - "\u4e9e\u5eab\u6b21\u514b\u590f\u4ee4\u6642\u9593", "YAKST", - "\u4E9E\u5EAB\u6B21\u514B\u6642\u9593", "YAKT"}; - - return new Object[][] { - {"America/Los_Angeles", PST}, - {"PST", PST}, - {"America/Denver", MST}, - {"MST", MST}, - {"America/Phoenix", MST}, - {"PNT", MST}, - {"America/Chicago", CST}, - {"CST", CST}, - {"America/New_York", EST}, - {"EST", EST}, - {"America/Indianapolis", EST}, - {"IET", EST}, - {"Pacific/Honolulu", HST}, - {"HST", HST}, - {"America/Anchorage", AKST}, - {"AST", AKST}, - {"America/Halifax", AST}, - {"America/Sitka", AKST}, - {"America/St_Johns", NST}, - {"CNT", NST}, - {"Europe/Paris", CET}, - {"ECT", CET}, - {"GMT", GMT}, - {"Africa/Casablanca", WET}, - {"Asia/Jerusalem", ISRAEL}, - {"Asia/Tokyo", JST}, - {"JST", JST}, - {"Europe/Bucharest", EET}, - {"Asia/Shanghai", CTT}, - {"CTT", CTT}, - {"UTC", UTC}, - /* Don't change the order of the above zones - * to keep compatibility with the previous version. - */ - - {"ACT", DARWIN}, - {"AET", EST_NSW}, - {"AGT", AGT}, - {"ART", EET}, - {"Africa/Abidjan", GMT}, - {"Africa/Accra", GHMT}, - {"Africa/Addis_Ababa", EAT}, - {"Africa/Algiers", CET}, - {"Africa/Asmara", EAT}, - {"Africa/Asmera", EAT}, - {"Africa/Bamako", GMT}, - {"Africa/Bangui", WAT}, - {"Africa/Banjul", GMT}, - {"Africa/Bissau", GMT}, - {"Africa/Blantyre", CAT}, - {"Africa/Brazzaville", WAT}, - {"Africa/Bujumbura", CAT}, - {"Africa/Cairo", EET}, - {"Africa/Ceuta", CET}, - {"Africa/Conakry", GMT}, - {"Africa/Dakar", GMT}, - {"Africa/Dar_es_Salaam", EAT}, - {"Africa/Djibouti", EAT}, - {"Africa/Douala", WAT}, - {"Africa/El_Aaiun", WET}, - {"Africa/Freetown", GMT}, - {"Africa/Gaborone", CAT}, - {"Africa/Harare", CAT}, - {"Africa/Johannesburg", SAST}, - {"Africa/Juba", CAT}, - {"Africa/Kampala", EAT}, - {"Africa/Khartoum", CAT}, - {"Africa/Kigali", CAT}, - {"Africa/Kinshasa", WAT}, - {"Africa/Lagos", WAT}, - {"Africa/Libreville", WAT}, - {"Africa/Lome", GMT}, - {"Africa/Luanda", WAT}, - {"Africa/Lubumbashi", CAT}, - {"Africa/Lusaka", CAT}, - {"Africa/Malabo", WAT}, - {"Africa/Maputo", CAT}, - {"Africa/Maseru", SAST}, - {"Africa/Mbabane", SAST}, - {"Africa/Mogadishu", EAT}, - {"Africa/Monrovia", GMT}, - {"Africa/Nairobi", EAT}, - {"Africa/Ndjamena", WAT}, - {"Africa/Niamey", WAT}, - {"Africa/Nouakchott", GMT}, - {"Africa/Ouagadougou", GMT}, - {"Africa/Porto-Novo", WAT}, - {"Africa/Sao_Tome", GMT}, - {"Africa/Timbuktu", GMT}, - {"Africa/Tripoli", EET}, - {"Africa/Tunis", CET}, - {"Africa/Windhoek", new String[] {"Central African Time", "CAT", - "Western African Time", "WAT", - "Central African Time", "CAT"}}, - {"America/Adak", HST}, - {"America/Anguilla", AST}, - {"America/Antigua", AST}, - {"America/Araguaina", BRT}, - {"America/Argentina/Buenos_Aires", AGT}, - {"America/Argentina/Catamarca", AGT}, - {"America/Argentina/ComodRivadavia", AGT}, - {"America/Argentina/Cordoba", AGT}, - {"America/Argentina/Jujuy", AGT}, - {"America/Argentina/La_Rioja", AGT}, - {"America/Argentina/Mendoza", AGT}, - {"America/Argentina/Rio_Gallegos", AGT}, - {"America/Argentina/Salta", AGT}, - {"America/Argentina/San_Juan", AGT}, - {"America/Argentina/San_Luis", AGT}, - {"America/Argentina/Tucuman", AGT}, - {"America/Argentina/Ushuaia", AGT}, - {"America/Aruba", AST}, - {"America/Asuncion", new String[] {"\u5df4\u62c9\u572d\u6642\u9593", "PYT", - "\u5df4\u62c9\u572d\u590f\u4ee4\u6642\u9593", "PYST", - "\u5DF4\u62C9\u572D\u6642\u9593", "PYT"}}, - {"America/Atikokan", EST}, - {"America/Atka", HST}, - {"America/Bahia", BRT}, - {"America/Bahia_Banderas", CST}, - {"America/Barbados", AST}, - {"America/Belem", BRT}, - {"America/Belize", CST}, - {"America/Blanc-Sablon", AST}, - {"America/Boa_Vista", AMT}, - {"America/Bogota", new String[] {"\u54e5\u502b\u6bd4\u4e9e\u6642\u9593", "COT", - "\u54e5\u502b\u6bd4\u4e9e\u590f\u4ee4\u6642\u9593", "COST", - "\u54E5\u502B\u6BD4\u4E9E\u6642\u9593", "COT"}}, - {"America/Boise", MST}, - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, - {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u59d4\u5167\u745e\u62c9\u6642\u9593", "VET", - "\u59d4\u5167\u745e\u62c9\u590f\u4ee4\u6642\u9593", "VEST", - "\u59D4\u5167\u745E\u62C9\u6642\u9593", "VET"}}, - {"America/Catamarca", AGT}, - {"America/Cayenne", new String[] {"\u6cd5\u5c6c\u572d\u4e9e\u90a3\u6642\u9593", "GFT", - "\u6cd5\u5c6c\u572d\u4e9e\u90a3\u590f\u4ee4\u6642\u9593", "GFST", - "\u6CD5\u5C6C\u572D\u4E9E\u90A3\u6642\u9593", "GFT"}}, - {"America/Cayman", EST}, - {"America/Chihuahua", CST}, - {"America/Ciudad_Juarez", MST}, - {"America/Creston", MST}, - {"America/Coral_Harbour", EST}, - {"America/Cordoba", AGT}, - {"America/Costa_Rica", CST}, - {"America/Cuiaba", AMT}, - {"America/Curacao", AST}, - {"America/Danmarkshavn", GMT}, - {"America/Dawson", MST}, - {"America/Dawson_Creek", MST}, - {"America/Detroit", EST}, - {"America/Dominica", AST}, - {"America/Edmonton", MST}, - {"America/Eirunepe", ACT}, - {"America/El_Salvador", CST}, - {"America/Ensenada", PST}, - {"America/Fort_Nelson", MST}, - {"America/Fort_Wayne", EST}, - {"America/Fortaleza", BRT}, - {"America/Glace_Bay", AST}, - {"America/Godthab", WGT}, - {"America/Goose_Bay", AST}, - {"America/Grand_Turk", EST}, - {"America/Grenada", AST}, - {"America/Guadeloupe", AST}, - {"America/Guatemala", CST}, - {"America/Guayaquil", new String[] {"\u5384\u74dc\u591a\u723e\u6642\u9593", "ECT", - "\u5384\u74dc\u591a\u723e\u590f\u4ee4\u6642\u9593", "ECST", - "\u5384\u74DC\u591A\u723E\u6642\u9593", "ECT"}}, - {"America/Guyana", new String[] {"\u84cb\u4e9e\u90a3\u6642\u9593", "GYT", - "\u84cb\u4e9e\u90a3\u590f\u4ee4\u6642\u9593", "GYST", - "\u84CB\u4E9E\u90A3\u6642\u9593", "GYT"}}, - {"America/Havana", CUBA}, - {"America/Hermosillo", MST}, - {"America/Indiana/Indianapolis", EST}, - {"America/Indiana/Knox", CST}, - {"America/Indiana/Marengo", EST}, - {"America/Indiana/Petersburg", EST}, - {"America/Indiana/Tell_City", CST}, - {"America/Indiana/Vevay", EST}, - {"America/Indiana/Vincennes", EST}, - {"America/Indiana/Winamac", EST}, - {"America/Inuvik", MST}, - {"America/Iqaluit", EST}, - {"America/Jamaica", EST}, - {"America/Jujuy", AGT}, - {"America/Juneau", AKST}, - {"America/Kentucky/Louisville", EST}, - {"America/Kentucky/Monticello", EST}, - {"America/Knox_IN", CST}, - {"America/Kralendijk", AST}, - {"America/La_Paz", new String[] {"\u73bb\u5229\u7dad\u4e9e\u6642\u9593", "BOT", - "\u73bb\u5229\u7dad\u4e9e\u590f\u4ee4\u6642\u9593", "BOST", - "\u73BB\u5229\u7DAD\u4E9E\u6642\u9593", "BOT"}}, - {"America/Lima", new String[] {"\u7955\u9b6f\u6642\u9593", "PET", - "\u7955\u9b6f\u590f\u4ee4\u6642\u9593", "PEST", - "\u7955\u9B6F\u6642\u9593", "PET"}}, - {"America/Louisville", EST}, - {"America/Lower_Princes", AST}, - {"America/Maceio", BRT}, - {"America/Managua", CST}, - {"America/Manaus", AMT}, - {"America/Marigot", AST}, - {"America/Martinique", AST}, - {"America/Matamoros", CST}, - {"America/Mazatlan", MST}, - {"America/Mendoza", AGT}, - {"America/Menominee", CST}, - {"America/Merida", CST}, - {"America/Metlakatla", AKST}, - {"America/Mexico_City", CST}, - {"America/Miquelon", new String[] {"\u76ae\u57c3\u723e\u5cf6\u53ca\u5bc6\u514b\u9686\u5cf6\u6a19\u6e96\u6642\u9593", "PMST", - "\u76ae\u57c3\u723e\u5cf6\u53ca\u5bc6\u514b\u9686\u5cf6\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "PMDT", - "\u8056\u5F7C\u5FB7\u8207\u5BC6\u555F\u5D19\u6642\u9593", "PMT"}}, - {"America/Moncton", AST}, - {"America/Montevideo", new String[] {"\u70cf\u62c9\u572d\u6642\u9593", "UYT", - "\u70cf\u62c9\u572d\u590f\u4ee4\u6642\u9593", "UYST", - "\u70CF\u62C9\u572D\u6642\u9593", "UYT"}}, - {"America/Monterrey", CST}, - {"America/Montreal", EST}, - {"America/Montserrat", AST}, - {"America/Nassau", EST}, - {"America/Nipigon", EST}, - {"America/Nome", AKST}, - {"America/Noronha", NORONHA}, - {"America/North_Dakota/Beulah", CST}, - {"America/North_Dakota/Center", CST}, - {"America/North_Dakota/New_Salem", CST}, - {"America/Nuuk", WGT}, - {"America/Ojinaga", CST}, - {"America/Panama", EST}, - {"America/Pangnirtung", EST}, - {"America/Paramaribo", new String[] {"\u8607\u5229\u5357\u6642\u9593", "SRT", - "\u8607\u5229\u5357\u590f\u4ee4\u6642\u9593", "SRST", - "\u8607\u5229\u5357\u6642\u9593", "SRT"}}, - {"America/Port-au-Prince", EST}, - {"America/Port_of_Spain", AST}, - {"America/Porto_Acre", ACT}, - {"America/Porto_Velho", AMT}, - {"America/Puerto_Rico", AST}, - {"America/Rainy_River", CST}, - {"America/Rankin_Inlet", CST}, - {"America/Recife", BRT}, - {"America/Regina", CST}, - {"America/Resolute", CST}, - {"America/Rio_Branco", ACT}, - {"America/Rosario", AGT}, - {"America/Santa_Isabel", PST}, - {"America/Santarem", BRT}, - {"America/Santiago", CLT}, - {"America/Santo_Domingo", AST}, - {"America/Sao_Paulo", BRT}, - {"America/Scoresbysund", EGT}, - {"America/Shiprock", MST}, - {"America/St_Barthelemy", AST}, - {"America/St_Kitts", AST}, - {"America/St_Lucia", AST}, - {"America/St_Thomas", AST}, - {"America/St_Vincent", AST}, - {"America/Swift_Current", CST}, - {"America/Tegucigalpa", CST}, - {"America/Thule", AST}, - {"America/Thunder_Bay", EST}, - {"America/Tijuana", PST}, - {"America/Toronto", EST}, - {"America/Tortola", AST}, - {"America/Vancouver", PST}, - {"America/Virgin", AST}, - {"America/Whitehorse", MST}, - {"America/Winnipeg", CST}, - {"America/Yakutat", AKST}, - {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, - {"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT", - "\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST", - "\u81FA\u7DAD\u65AF\u6642\u9593", "DAVT"}}, - {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT", - "Dumont-d'Urville \u590f\u4ee4\u6642\u9593", "DDUST", - "Dumont-d'Urville \u6642\u9593", "DDUT"}}, - {"Antarctica/Macquarie", new String[] {"Australian Eastern Standard Time (Macquarie)", "AEST", - "Australian Eastern Daylight Time (Macquarie)", "AEDT", - "Australian Eastern Time (Macquarie)", "AET"}}, - {"Antarctica/Mawson", new String[] {"\u83ab\u68ee\u6642\u9593", "MAWT", - "\u83ab\u68ee\u590f\u4ee4\u6642\u9593", "MAWST", - "\u83AB\u68EE\u6642\u9593", "MAWT"}}, - {"Antarctica/McMurdo", NZST}, - {"Antarctica/Palmer", CLT}, - {"Antarctica/Rothera", new String[] {"\u7f85\u897f\u62c9\u6642\u9593", "ROTT", - "\u7f85\u897f\u62c9\u590f\u4ee4\u6642\u9593", "ROTST", - "\u7F85\u897F\u62C9\u6642\u9593", "ROTT"}}, - {"Antarctica/South_Pole", NZST}, - {"Antarctica/Syowa", new String[] {"\u5915\u6b50\u74e6 (Syowa) \u6642\u9593", "SYOT", - "\u5915\u6b50\u74e6 (Syowa) \u590f\u4ee4\u6642\u9593", "SYOST", - "\u5915\u6B50\u74E6 (Syowa) \u6642\u9593", "SYOT"}}, - {"Antarctica/Troll", new String[] {"\u5354\u8abf\u4e16\u754c\u6642\u9593", "UTC", - "\u4e2d\u6b50\u590f\u4ee4\u6642\u9593", "CEST", - "Troll Time", "ATT"}}, - {"Antarctica/Vostok", new String[] {"\u4f5b\u65af\u6258 (Vostok) \u6642\u9593", "VOST", - "\u4f5b\u65af\u6258 (Vostok) \u590f\u4ee4\u6642\u9593", "VOSST", - "\u4F5B\u65AF\u6258 (Vostok) \u6642\u9593", "VOST"}}, - {"Arctic/Longyearbyen", CET}, - {"Asia/Aden", ARAST}, - {"Asia/Almaty", new String[] {"Alma-Ata \u6642\u9593", "ALMT", - "Alma-Ata \u590f\u4ee4\u6642\u9593", "ALMST", - "\u963F\u62C9\u6728\u5716\u6642\u9593", "ALMT"}}, - {"Asia/Amman", EET}, - {"Asia/Anadyr", new String[] {"\u963f\u90a3\u5e95\u6cb3\u6642\u9593", "ANAT", - "\u963f\u90a3\u5e95\u6cb3\u590f\u4ee4\u6642\u9593", "ANAST", - "\u963F\u90A3\u5E95\u6CB3\u6642\u9593", "ANAT"}}, - {"Asia/Aqtau", new String[] {"Aqtau \u6642\u9593", "AQTT", - "Aqtau \u590f\u4ee4\u6642\u9593", "AQTST", - "\u963F\u514B\u5957\u6642\u9593", "AQTT"}}, - {"Asia/Aqtobe", new String[] {"Aqtobe \u6642\u9593", "AQTT", - "Aqtobe \u590f\u4ee4\u6642\u9593", "AQTST", - "\u963F\u514B\u6258\u5225\u6642\u9593", "AQTT"}}, - {"Asia/Ashgabat", TMT}, - {"Asia/Ashkhabad", TMT}, - {"Asia/Baghdad", ARAST}, - {"Asia/Bahrain", ARAST}, - {"Asia/Baku", new String[] {"\u4e9e\u585e\u62dc\u7136\u6642\u9593", "AZT", - "\u4e9e\u585e\u62dc\u7136\u590f\u4ee4\u6642\u9593", "AZST", - "\u4E9E\u585E\u62DC\u7136\u6642\u9593", "AZT"}}, - {"Asia/Bangkok", ICT}, - {"Asia/Beirut", EET}, - {"Asia/Bishkek", new String[] {"Kirgizstan \u6642\u9593", "KGT", - "Kirgizstan \u590f\u4ee4\u6642\u9593", "KGST", - "\u5409\u723E\u5409\u65AF\u6642\u9593", "KGT"}}, - {"Asia/Brunei", new String[] {"\u6c76\u840a\u6642\u9593", "BNT", - "\u6c76\u840a\u590f\u4ee4\u6642\u9593", "BNST", - "\u6C76\u840A\u6642\u9593", "BNT"}}, - {"Asia/Calcutta", IST}, - {"Asia/Chita", YAKT}, - {"Asia/Choibalsan", new String[] {"\u5de7\u5df4\u5c71 (Choibalsan) \u6642\u9593", "CHOT", - "\u5de7\u5df4\u5c71 (Choibalsan) \u590f\u4ee4\u6642\u9593", "CHOST", - "\u5DE7\u5DF4\u5C71 (Choibalsan) \u6642\u9593", "CHOT"}}, - {"Asia/Chongqing", CTT}, - {"Asia/Chungking", CTT}, - {"Asia/Colombo", IST}, - {"Asia/Dacca", BDT}, - {"Asia/Dhaka", BDT}, - {"Asia/Dili", new String[] {"\u6771\u5e1d\u6c76\u6642\u9593", "TLT", - "\u6771\u5e1d\u6c76\u590f\u4ee4\u6642\u9593", "TLST", - "\u6771\u5E1D\u6C76\u6642\u9593", "TLT"}}, - {"Asia/Damascus", EET}, - {"Asia/Dubai", GST}, - {"Asia/Dushanbe", new String[] {"\u5854\u5409\u514b\u6642\u9593", "TJT", - "\u5854\u5409\u514b\u590f\u4ee4\u6642\u9593", "TJST", - "\u5854\u5409\u514B\u6642\u9593", "TJT"}}, - {"Asia/Gaza", EET}, - {"Asia/Harbin", CTT}, - {"Asia/Hebron", EET}, - {"Asia/Ho_Chi_Minh", ICT}, - {"Asia/Hong_Kong", HKT}, - {"Asia/Hovd", new String[] {"\u4faf\u5fb7 (Hovd) \u6642\u9593", "HOVT", - "\u4faf\u5fb7 (Hovd) \u590f\u4ee4\u6642\u9593", "HOVST", - "\u4FAF\u5FB7 (Hovd) \u6642\u9593", "HOVT"}}, - {"Asia/Irkutsk", IRKT}, - {"Asia/Istanbul", EET}, - {"Asia/Jakarta", WIT}, - {"Asia/Jayapura", new String[] {"\u6771\u5370\u5ea6\u5c3c\u897f\u4e9e\u6642\u9593", "WIT", - "\u6771\u5370\u5ea6\u5c3c\u897f\u4e9e\u590f\u65e5\u6642\u9593", "EIST", - "\u6771\u5370\u5EA6\u5C3C\u897F\u4E9E\u6642\u9593", "WIT"}}, - {"Asia/Kabul", new String[] {"\u963f\u5bcc\u6c57\u6642\u9593", "AFT", - "\u963f\u5bcc\u6c57\u590f\u4ee4\u6642\u9593", "AFST", - "\u963F\u5BCC\u6C57\u6642\u9593", "AFT"}}, - {"Asia/Kamchatka", new String[] {"Petropavlovsk-Kamchatski \u6642\u9593", "PETT", - "Petropavlovsk-Kamchatski \u590f\u4ee4\u6642\u9593", "PETST", - "Petropavlovsk-Kamchatski \u6642\u9593", "PETT"}}, - {"Asia/Karachi", PKT}, - {"Asia/Kashgar", XJT}, - {"Asia/Kathmandu", NPT}, - {"Asia/Katmandu", NPT}, - {"Asia/Khandyga", YAKT}, - {"Asia/Kolkata", IST}, - {"Asia/Krasnoyarsk", KRAT}, - {"Asia/Kuala_Lumpur", MYT}, - {"Asia/Kuching", MYT}, - {"Asia/Kuwait", ARAST}, - {"Asia/Macao", CTT}, - {"Asia/Macau", CTT}, - {"Asia/Magadan", new String[] {"Magadan \u6642\u9593", "MAGT", - "Magadan \u590f\u4ee4\u6642\u9593", "MAGST", - "\u99AC\u52A0\u4E39\u6642\u9593", "MAGT"}}, - {"Asia/Makassar", CIT}, - {"Asia/Manila", new String[] {"Philippines Standard Time", "PST", - "Philippines Daylight Time", "PDT", - "Philippines Time", "PT"}}, - {"Asia/Muscat", GST}, - {"Asia/Nicosia", EET}, - {"Asia/Novokuznetsk", KRAT}, - {"Asia/Novosibirsk", NOVT}, - {"Asia/Oral", new String[] {"\u6b50\u4f5b\u6642\u9593", "ORAT", - "\u6b50\u4f5b\u590f\u4ee4\u6642\u9593", "ORAST", - "\u6B50\u4F5B\u6642\u9593", "ORAT"}}, - {"Asia/Omsk", new String[] {"\u6b50\u59c6\u65af\u514b (Omsk) \u6642\u9593", "OMST", - "\u6b50\u59c6\u65af\u514b (Omsk) \u590f\u4ee4\u6642\u9593", "OMSST", - "\u6B50\u59C6\u65AF\u514B (Omsk) \u6642\u9593", "OMST"}}, - {"Asia/Phnom_Penh", ICT}, - {"Asia/Pontianak", WIT}, - {"Asia/Pyongyang", KST}, - {"Asia/Qatar", ARAST}, - {"Asia/Qyzylorda", new String[] {"Qyzylorda \u6642\u9593", "QYZT", - "Qyzylorda \u590f\u4ee4\u6642\u9593", "QYZST", - "\u514B\u5B5C\u6D1B\u723E\u9054\u6642\u9593", "QYZT"}}, - {"Asia/Rangoon", MMT}, - {"Asia/Riyadh", ARAST}, - {"Asia/Saigon", ICT}, - {"Asia/Sakhalin", new String[] {"\u5eab\u9801\u5cf6\u6642\u9593", "SAKT", - "\u5eab\u9801\u5cf6\u590f\u4ee4\u6642\u9593", "SAKST", - "\u5EAB\u9801\u5CF6\u6642\u9593", "SAKT"}}, - {"Asia/Samarkand", UZT}, - {"Asia/Seoul", KST}, - {"Asia/Singapore", SGT}, - {"Asia/Srednekolymsk", new String[] {"Srednekolymsk Time", "SRET", - "Srednekolymsk Daylight Time", "SREDT", - "Srednekolymsk Time", "SRET"}}, - {"Asia/Taipei", new String[] {"\u53f0\u7063\u6a19\u6e96\u6642\u9593", "TST", - "\u53f0\u7063\u590f\u4ee4\u6642\u9593", "TDT", - "\u53f0\u7063\u6642\u9593", "TT"}}, - {"Asia/Tel_Aviv", ISRAEL}, - {"Asia/Tashkent", UZT}, - {"Asia/Tbilisi", new String[] {"\u55ac\u6cbb\u4e9e\u6642\u9593", "GET", - "\u55ac\u6cbb\u4e9e\u590f\u4ee4\u6642\u9593", "GEST", - "\u55AC\u6CBB\u4E9E\u6642\u9593", "GET"}}, - {"Asia/Tehran", IRT}, - {"Asia/Thimbu", BTT}, - {"Asia/Thimphu", BTT}, - {"Asia/Ujung_Pandang", CIT}, - {"Asia/Ulaanbaatar", ULAT}, - {"Asia/Ulan_Bator", ULAT}, - {"Asia/Urumqi", XJT}, - {"Asia/Ust-Nera", new String[] {"\u70CF\u65AF\u5167\u62C9 (Ust-Nera) \u6642\u9593", "VLAT", - "\u70CF\u65AF\u5167\u62C9 (Ust-Nera) \u590F\u4EE4\u6642\u9593", "VLAST", - "\u70CF\u65AF\u5167\u62C9 (Ust-Nera) \u6642\u9593", "VLAT"}}, - {"Asia/Vientiane", ICT}, - {"Asia/Vladivostok", new String[] {"\u6d77\u53c3\u5d34\u6642\u9593", "VLAT", - "\u6d77\u53c3\u5d34\u590f\u4ee4\u6642\u9593", "VLAST", - "\u6D77\u53C3\u5D34\u6642\u9593", "VLAT"}}, - {"Asia/Yakutsk", YAKT}, - {"Asia/Yangon", MMT}, - {"Asia/Yekaterinburg", new String[] {"Yekaterinburg \u6642\u9593", "YEKT", - "Yekaterinburg \u590f\u4ee4\u6642\u9593", "YEKST", - "\u8449\u5361\u6377\u7433\u5821\u6642\u9593", "YEKT"}}, - {"Asia/Yerevan", ARMT}, - {"Atlantic/Azores", new String[] {"\u4e9e\u901f\u723e\u7fa4\u5cf6\u6642\u9593", "AZOT", - "\u4e9e\u901f\u723e\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "AZOST", - "\u4E9E\u901F\u723E\u7FA4\u5CF6\u6642\u9593", "AZOT"}}, - {"Atlantic/Bermuda", AST}, - {"Atlantic/Canary", WET}, - {"Atlantic/Cape_Verde", new String[] {"\u4f5b\u5fb7\u89d2\u6642\u9593", "CVT", - "\u4f5b\u5fb7\u89d2\u590f\u4ee4\u6642\u9593", "CVST", - "\u4F5B\u5FB7\u89D2\u6642\u9593", "CVT"}}, - {"Atlantic/Faeroe", WET}, - {"Atlantic/Faroe", WET}, - {"Atlantic/Jan_Mayen", CET}, - {"Atlantic/Madeira", WET}, - {"Atlantic/Reykjavik", GMT}, - {"Atlantic/South_Georgia", new String[] {"\u5357\u55ac\u6cbb\u4e9e\u6a19\u6e96\u6642\u9593", "GST", - "\u5357\u55ac\u6cbb\u4e9e\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "GDT", - "\u5357\u55AC\u6CBB\u4E9E\u6642\u9593", "GT"}}, - {"Atlantic/St_Helena", GMT}, - {"Atlantic/Stanley", new String[] {"\u798f\u514b\u862d\u7fa4\u5cf6\u6642\u9593", "FKT", - "\u798f\u514b\u862d\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "FKST", - "\u798F\u514B\u862D\u7FA4\u5CF6\u6642\u9593", "FKT"}}, - {"Australia/ACT", EST_NSW}, - {"Australia/Adelaide", ADELAIDE}, - {"Australia/Brisbane", BRISBANE}, - {"Australia/Broken_Hill", BROKEN_HILL}, - {"Australia/Canberra", EST_NSW}, - {"Australia/Currie", EST_NSW}, - {"Australia/Darwin", DARWIN}, - {"Australia/Eucla", new String[] {"\u4E2D\u897F\u90E8\u6A19\u6E96\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "ACWST", - "\u4E2D\u897F\u90E8\u590F\u4EE4\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "ACWDT", - "\u4E2D\u897F\u90E8\u6642\u9593 (\u6FB3\u5927\u5229\u4E9E)", "ACWT"}}, - {"Australia/Hobart", TASMANIA}, - {"Australia/LHI", LORD_HOWE}, - {"Australia/Lindeman", BRISBANE}, - {"Australia/Lord_Howe", LORD_HOWE}, - {"Australia/Melbourne", VICTORIA}, - {"Australia/North", DARWIN}, - {"Australia/NSW", EST_NSW}, - {"Australia/Perth", WST_AUS}, - {"Australia/Queensland", BRISBANE}, - {"Australia/South", ADELAIDE}, - {"Australia/Sydney", EST_NSW}, - {"Australia/Tasmania", TASMANIA}, - {"Australia/Victoria", VICTORIA}, - {"Australia/West", WST_AUS}, - {"Australia/Yancowinna", BROKEN_HILL}, - {"BET", BRT}, - {"BST", BDT}, - {"Brazil/Acre", ACT}, - {"Brazil/DeNoronha", NORONHA}, - {"Brazil/East", BRT}, - {"Brazil/West", AMT}, - {"Canada/Atlantic", AST}, - {"Canada/Central", CST}, - {"Canada/Eastern", EST}, - {"Canada/Mountain", MST}, - {"Canada/Newfoundland", NST}, - {"Canada/Pacific", PST}, - {"Canada/Yukon", MST}, - {"Canada/Saskatchewan", CST}, - {"CAT", CAT}, - {"CET", CET}, - {"Chile/Continental", CLT}, - {"Chile/EasterIsland", EASTER}, - {"CST6CDT", CST}, - {"Cuba", CUBA}, - {"EAT", EAT}, - {"EET", EET}, - {"Egypt", EET}, - {"Eire", DUBLIN}, - {"EST5EDT", EST}, - {"Etc/Greenwich", GMT}, - {"Etc/UCT", UTC}, - {"Etc/Universal", UTC}, - {"Etc/UTC", UTC}, - {"Etc/Zulu", UTC}, - {"Europe/Amsterdam", CET}, - {"Europe/Andorra", CET}, - {"Europe/Athens", EET}, - {"Europe/Belfast", GMTBST}, - {"Europe/Belgrade", CET}, - {"Europe/Berlin", CET}, - {"Europe/Bratislava", CET}, - {"Europe/Brussels", CET}, - {"Europe/Budapest", CET}, - {"Europe/Busingen", CET}, - {"Europe/Chisinau", EET}, - {"Europe/Copenhagen", CET}, - {"Europe/Dublin", DUBLIN}, - {"Europe/Gibraltar", CET}, - {"Europe/Guernsey", GMTBST}, - {"Europe/Helsinki", EET}, - {"Europe/Isle_of_Man", GMTBST}, - {"Europe/Istanbul", EET}, - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, - {"Europe/Luxembourg", CET}, - {"Europe/Madrid", CET}, - {"Europe/Malta", CET}, - {"Europe/Mariehamn", EET}, - {"Europe/Minsk", MSK}, - {"Europe/Monaco", CET}, - {"Europe/Moscow", MSK}, - {"Europe/Nicosia", EET}, - {"Europe/Oslo", CET}, - {"Europe/Podgorica", CET}, - {"Europe/Prague", CET}, - {"Europe/Riga", EET}, - {"Europe/Rome", CET}, - {"Europe/Samara", new String[] {"\u6c99\u99ac\u62c9\u6642\u9593", "SAMT", - "\u6c99\u99ac\u62c9\u590f\u4ee4\u6642\u9593", "SAMST", - "\u6C99\u99AC\u62C9\u6642\u9593", "SAMT"}}, - {"Europe/San_Marino", CET}, - {"Europe/Sarajevo", CET}, - {"Europe/Simferopol", MSK}, - {"Europe/Skopje", CET}, - {"Europe/Sofia", EET}, - {"Europe/Stockholm", CET}, - {"Europe/Tallinn", EET}, - {"Europe/Tirane", CET}, - {"Europe/Tiraspol", EET}, - {"Europe/Uzhgorod", EET}, - {"Europe/Vaduz", CET}, - {"Europe/Vatican", CET}, - {"Europe/Vienna", CET}, - {"Europe/Vilnius", EET}, - {"Europe/Volgograd", MSK}, - {"Europe/Warsaw", CET}, - {"Europe/Zagreb", CET}, - {"Europe/Zaporozhye", EET}, - {"Europe/Zurich", CET}, - {"GB", GMTBST}, - {"GB-Eire", GMTBST}, - {"Greenwich", GMT}, - {"Hongkong", HKT}, - {"Iceland", GMT}, - {"Iran", IRT}, - {"IST", IST}, - {"Indian/Antananarivo", EAT}, - {"Indian/Chagos", new String[] {"\u5370\u5ea6\u6d0b\u5730\u5340\u6642\u9593", "IOT", - "\u5370\u5ea6\u6d0b\u5730\u5340\u590f\u4ee4\u6642\u9593", "IOST", - "\u82F1\u5C6C\u5370\u5EA6\u6D0B\u5730\u5340", "IOT"}}, - {"Indian/Christmas", new String[] {"\u8056\u8a95\u5cf6\u6642\u9593", "CXT", - "\u8056\u8a95\u5cf6\u590f\u4ee4\u6642\u9593", "CXST", - "\u8056\u8A95\u5CF6\u6642\u9593", "CIT"}}, - {"Indian/Cocos", new String[] {"\u53ef\u53ef\u65af\u7fa4\u5cf6\u6642\u9593", "CCT", - "\u53ef\u53ef\u65af\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "CCST", - "\u53EF\u53EF\u65AF\u7FA4\u5CF6\u6642\u9593", "CCT"}}, - {"Indian/Comoro", EAT}, - {"Indian/Kerguelen", new String[] {"\u6cd5\u570b\u5357\u534a\u7403\u53ca\u5357\u6975\u5c6c\u5730\u6642\u9593", "TFT", - "\u6cd5\u570b\u5357\u534a\u7403\u53ca\u5357\u6975\u5c6c\u5730\u590f\u4ee4\u6642\u9593", "TFST", - "\u6CD5\u570B\u5357\u534A\u7403\u53CA\u5357\u6975\u5C6C\u5730\u6642\u9593", "TFT"}}, - {"Indian/Mahe", new String[] {"\u585e\u5e2d\u723e\u7fa4\u5cf6\u6642\u9593", "SCT", - "\u585e\u5e2d\u723e\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "SCST", - "\u585E\u5E2D\u723E\u7FA4\u5CF6\u6642\u9593", "SCT"}}, - {"Indian/Maldives", new String[] {"\u99ac\u723e\u5730\u592b\u6642\u9593", "MVT", - "\u99ac\u723e\u5730\u592b\u590f\u4ee4\u6642\u9593", "MVST", - "\u99AC\u723E\u5730\u592B\u6642\u9593", "MVT"}}, - {"Indian/Mauritius", new String[] {"\u6469\u91cc\u897f\u65af\u6642\u9593", "MUT", - "\u6469\u91cc\u897f\u65af\u590f\u4ee4\u6642\u9593", "MUST", - "\u6469\u91CC\u897F\u65AF\u6642\u9593", "MUT"}}, - {"Indian/Mayotte", EAT}, - {"Indian/Reunion", new String[] {"\u7559\u5c3c\u65fa\u5cf6\u6642\u9593", "RET", - "\u7559\u5c3c\u65fa\u5cf6\u590f\u4ee4\u6642\u9593", "REST", - "\u7559\u5C3C\u65FA\u5CF6\u6642\u9593", "RET"}}, - {"Israel", ISRAEL}, - {"Jamaica", EST}, - {"Japan", JST}, - {"Kwajalein", MHT}, - {"Libya", EET}, - {"MET", CET}, - {"Mexico/BajaNorte", PST}, - {"Mexico/BajaSur", MST}, - {"Mexico/General", CST}, - {"MIT", WST_SAMOA}, - {"MST7MDT", MST}, - {"Navajo", MST}, - {"NET", ARMT}, - {"NST", NZST}, - {"NZ", NZST}, - {"NZ-CHAT", CHAST}, - {"PLT", PKT}, - {"Portugal", WET}, - {"PRT", AST}, - {"Pacific/Apia", WST_SAMOA}, - {"Pacific/Auckland", NZST}, - {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", - "Bougainville Daylight Time", "BST", - "Bougainville Time", "BT"}}, - {"Pacific/Chatham", CHAST}, - {"Pacific/Chuuk", CHUT}, - {"Pacific/Easter", EASTER}, - {"Pacific/Efate", new String[] {"\u74e6\u5974\u963f\u5716\u6642\u9593", "VUT", - "\u74e6\u5974\u963f\u5716\u590f\u4ee4\u6642\u9593", "VUST", - "\u74E6\u5974\u963F\u5716\u6642\u9593", "VUT"}}, - {"Pacific/Enderbury", new String[] {"\u83f2\u5c3c\u514b\u65af\u7fa4\u5cf6\u6642\u9593", "PHOT", - "\u83f2\u5c3c\u514b\u65af\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "PHOST", - "\u83F2\u5C3C\u514B\u65AF\u7FA4\u5CF6\u6642\u9593", "PHOT"}}, - {"Pacific/Fakaofo", new String[] {"\u6258\u514b\u52de\u7fa4\u5cf6\u6642\u9593", "TKT", - "\u6258\u514b\u52de\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "TKST", - "\u6258\u514B\u52DE\u7FA4\u5CF6\u6642\u9593", "TKT"}}, - {"Pacific/Fiji", new String[] {"\u6590\u6fdf\u6642\u9593", "FJT", - "\u6590\u6fdf\u590f\u4ee4\u6642\u9593", "FJST", - "\u6590\u6FDF\u6642\u9593", "FJT"}}, - {"Pacific/Funafuti", new String[] {"\u5410\u9b6f\u74e6\u6642\u9593", "TVT", - "\u5410\u9b6f\u74e6\u590f\u4ee4\u6642\u9593", "TVST", - "\u5410\u74E6\u9B6F\u6642\u9593", "TVT"}}, - {"Pacific/Galapagos", new String[] {"\u52a0\u62c9\u5df4\u54e5\u6642\u9593", "GALT", - "\u52a0\u62c9\u5df4\u54e5\u590f\u4ee4\u6642\u9593", "GALST", - "\u52A0\u62C9\u5DF4\u54E5\u6642\u9593", "GALT"}}, - {"Pacific/Gambier", GAMBIER}, - {"Pacific/Guadalcanal", SBT}, - {"Pacific/Guam", ChST}, - {"Pacific/Johnston", HST}, - {"Pacific/Kiritimati", new String[] {"Line Is. \u6642\u9593", "LINT", - "Line Is. \u590f\u4ee4\u6642\u9593", "LINST", - "\u5217\u5DBC\u7FA4\u5CF6\u6642\u9593", "LINT"}}, - {"Pacific/Kosrae", new String[] {"Kosrae \u6642\u9593", "KOST", - "Kosrae \u590f\u4ee4\u6642\u9593", "KOSST", - "Kosrae \u6642\u9593", "KOST"}}, - {"Pacific/Kwajalein", MHT}, - {"Pacific/Majuro", MHT}, - {"Pacific/Marquesas", new String[] {"\u99ac\u514b\u85a9\u65af\u6642\u9593", "MART", - "\u99ac\u514b\u85a9\u65af\u590f\u4ee4\u6642\u9593", "MARST", - "\u99AC\u514B\u85A9\u65AF\u6642\u9593", "MART"}}, - {"Pacific/Midway", SAMOA}, - {"Pacific/Nauru", new String[] {"\u8afe\u9b6f\u6642\u9593", "NRT", - "\u8afe\u9b6f\u590f\u4ee4\u6642\u9593", "NRST", - "\u8AFE\u9B6F\u6642\u9593", "NRT"}}, - {"Pacific/Niue", new String[] {"\u7d10\u5a01\u5cf6\u6642\u9593", "NUT", - "\u7d10\u5a01\u5cf6\u590f\u4ee4\u6642\u9593", "NUST", - "\u7D10\u5A01\u5CF6\u6642\u9593", "NUT"}}, - {"Pacific/Norfolk", new String[] {"\u8afe\u798f\u514b\u6642\u9593", "NFT", - "\u8afe\u798f\u514b\u590f\u4ee4\u6642\u9593", "NFST", - "\u8AFE\u798F\u514B\u6642\u9593", "NFT"}}, - {"Pacific/Noumea", new String[] {"\u65b0\u52a0\u52d2\u591a\u5c3c\u4e9e\u6642\u9593", "NCT", - "\u65b0\u52a0\u52d2\u591a\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "NCST", - "\u65B0\u52A0\u52D2\u591A\u5C3C\u4E9E\u6642\u9593", "NCT"}}, - {"Pacific/Pago_Pago", SAMOA}, - {"Pacific/Palau", new String[] {"\u5e1b\u7409\u6642\u9593", "PWT", - "\u5e1b\u7409\u590f\u4ee4\u6642\u9593", "PWST", - "\u5E1B\u7409\u6642\u9593", "PWT"}}, - {"Pacific/Pitcairn", PITCAIRN}, - {"Pacific/Pohnpei", PONT}, - {"Pacific/Ponape", PONT}, - {"Pacific/Port_Moresby", new String[] {"\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u6642\u9593", "PGT", - "\u5df4\u5e03\u4e9e\u65b0\u5e7e\u5167\u4e9e\u590f\u4ee4\u6642\u9593", "PGST", - "\u5DF4\u5E03\u4E9E\u65B0\u5E7E\u5167\u4E9E\u6642\u9593", "PGT"}}, - {"Pacific/Rarotonga", new String[] {"\u5eab\u514b\u7fa4\u5cf6\u6642\u9593", "CKT", - "\u5eab\u514b\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "CKHST", - "\u5EAB\u514B\u7FA4\u5CF6\u6642\u9593", "CKT"}}, - {"Pacific/Saipan", ChST}, - {"Pacific/Samoa", SAMOA}, - {"Pacific/Tahiti", new String[] {"\u5927\u6eaa\u5730\u5cf6\u6642\u9593", "TAHT", - "\u5927\u6eaa\u5730\u5cf6\u590f\u4ee4\u6642\u9593", "TAHST", - "\u5927\u6EAA\u5730\u6642\u9593", "TAHT"}}, - {"Pacific/Tarawa", new String[] {"\u5409\u4f2f\u7279\u7fa4\u5cf6\u6642\u9593", "GILT", - "\u5409\u4f2f\u7279\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "GILST", - "\u5409\u4F2F\u7279\u7FA4\u5CF6\u6642\u9593", "GILT"}}, - {"Pacific/Tongatapu", new String[] {"\u6771\u52a0\u6642\u9593", "TOT", - "\u6771\u52a0\u590f\u4ee4\u6642\u9593", "TOST", - "\u6771\u52A0\u6642\u9593", "TOT"}}, - {"Pacific/Truk", CHUT}, - {"Pacific/Wake", new String[] {"\u5a01\u514b\u6642\u9593", "WAKT", - "\u5a01\u514b\u590f\u4ee4\u6642\u9593", "WAKST", - "\u5A01\u514B\u6642\u9593", "WAKT"}}, - {"Pacific/Wallis", new String[] {"\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u6642\u9593", "WFT", - "\u74e6\u5229\u65af\u53ca\u798f\u675c\u7d0d\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "WFST", - "\u74E6\u5229\u65AF\u53CA\u798F\u675C\u7D0D\u7FA4\u5CF6\u6642\u9593", "WFT"}}, - {"Pacific/Yap", CHUT}, - {"Poland", CET}, - {"PRC", CTT}, - {"PST8PDT", PST}, - {"ROK", KST}, - {"Singapore", SGT}, - {"SST", SBT}, - {"SystemV/AST4", AST}, - {"SystemV/AST4ADT", AST}, - {"SystemV/CST6", CST}, - {"SystemV/CST6CDT", CST}, - {"SystemV/EST5", EST}, - {"SystemV/EST5EDT", EST}, - {"SystemV/HST10", HST}, - {"SystemV/MST7", MST}, - {"SystemV/MST7MDT", MST}, - {"SystemV/PST8", PST}, - {"SystemV/PST8PDT", PST}, - {"SystemV/YST9", AKST}, - {"SystemV/YST9YDT", AKST}, - {"Turkey", EET}, - {"UCT", UTC}, - {"Universal", UTC}, - {"US/Alaska", AKST}, - {"US/Aleutian", HST}, - {"US/Arizona", MST}, - {"US/Central", CST}, - {"US/Eastern", EST}, - {"US/Hawaii", HST}, - {"US/Indiana-Starke", CST}, - {"US/East-Indiana", EST}, - {"US/Michigan", EST}, - {"US/Mountain", MST}, - {"US/Pacific", PST}, - {"US/Samoa", SAMOA}, - {"VST", ICT}, - {"W-SU", MSK}, - {"WET", WET}, - {"Zulu", UTC}, - }; - } -} From 4fa4f15122213afea5cb25166c3b36a1c395b06c Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Fri, 30 May 2025 17:23:52 +0000 Subject: [PATCH 026/216] 8357882: Use UTF-8 encoded data in LocaleDataTest Reviewed-by: jlu, joehw --- test/jdk/sun/text/resources/LocaleData.cldr | 8168 ++++++++--------- .../sun/text/resources/LocaleDataTest.java | 127 +- 2 files changed, 4097 insertions(+), 4198 deletions(-) diff --git a/test/jdk/sun/text/resources/LocaleData.cldr b/test/jdk/sun/text/resources/LocaleData.cldr index b7eb72b23e8..c56ad663798 100644 --- a/test/jdk/sun/text/resources/LocaleData.cldr +++ b/test/jdk/sun/text/resources/LocaleData.cldr @@ -8,7 +8,7 @@ LocaleNames/en/es=Spanish # bug #4052679 -LocaleNames/fr/fr=fran\u00e7ais +LocaleNames/fr/fr=français # bug #4055602, 4290801, 8013836 CurrencyNames/pt_BR/BRL=R$ @@ -32,26 +32,26 @@ FormatData/pt_BR/DayAbbreviations/1=seg. FormatData/pt_BR/DayAbbreviations/2=ter. FormatData/pt_BR/DayNames/0=domingo FormatData/pt_BR/DayNames/1=segunda-feira -FormatData/pt_BR/DayNames/2=ter\u00e7a-feira +FormatData/pt_BR/DayNames/2=terça-feira FormatData/pt_BR/MonthNames/0=janeiro FormatData/pt_BR/MonthNames/1=fevereiro -FormatData/pt_BR/MonthNames/2=mar\u00e7o -LocaleNames/pt_BR/pt=portugu\u00eas +FormatData/pt_BR/MonthNames/2=março +LocaleNames/pt_BR/pt=português LocaleNames/pt_BR/PT=Portugal LocaleNames/pt_BR/BR=Brasil # bug #4066550 -FormatData/ja/Eras/0=\u7d00\u5143\u524d -FormatData/ja/Eras/1=\u897f\u66a6 +FormatData/ja/Eras/0=紀元前 +FormatData/ja/Eras/1=西暦 # bug #4067619 LocaleNames/en/LT=Lithuania # bug #4068012, 4290801, 4942982 -CurrencyNames/ru_RU/RUB=\u20bd +CurrencyNames/ru_RU/RUB=₽ FormatData/ru_RU/latn.NumberPatterns/0=#,##0.### -# FormatData/ru_RU/NumberPatterns/1=#,##0.##'\u0440.';-#,##0.##'\u0440.' # Changed; see bug 4122840 -FormatData/ru_RU/latn.NumberPatterns/2=#,##0\u00a0% +# FormatData/ru_RU/NumberPatterns/1=#,##0.##'р.';-#,##0.##'р.' # Changed; see bug 4122840 +FormatData/ru_RU/latn.NumberPatterns/2=#,##0 % # bug #4070174 FormatData/en_CA/latn.NumberElements/1=, @@ -82,60 +82,60 @@ FormatData/fr_FR/DatePatterns/0=EEEE d MMMM y # FormatData/it_IT/NumberPatterns/1='L.' #,##0;-'L.' #,##0 # Changed; see bug 4122840 # bug #4071782 -FormatData/ru/DayAbbreviations/0=\u0432\u0441 -FormatData/ru/DayAbbreviations/1=\u043f\u043d -FormatData/ru/DayAbbreviations/2=\u0432\u0442 -FormatData/ru/DayAbbreviations/3=\u0441\u0440 -FormatData/ru/DayAbbreviations/4=\u0447\u0442 -FormatData/ru/DayAbbreviations/5=\u043f\u0442 -FormatData/ru/DayAbbreviations/6=\u0441\u0431 +FormatData/ru/DayAbbreviations/0=вс +FormatData/ru/DayAbbreviations/1=пн +FormatData/ru/DayAbbreviations/2=вт +FormatData/ru/DayAbbreviations/3=ср +FormatData/ru/DayAbbreviations/4=чт +FormatData/ru/DayAbbreviations/5=пт +FormatData/ru/DayAbbreviations/6=сб # bug #4072013 - obsoleted by 6386647: Full date format in DateFormat does not include day of the week for UK locale #FormatData/en_GB/DatePatterns/0=dd MMMM yyyy # bug #4072388 -LocaleNames/cs/cs=\u010de\u0161tina +LocaleNames/cs/cs=čeština # bug #4072773 FormatData/ja/DatePatterns/2=y/MM/dd FormatData/ja/DatePatterns/3=y/MM/dd # bug #4075404, 4290801, 4942982 -CurrencyNames/ru_RU/RUB=\u20bd +CurrencyNames/ru_RU/RUB=₽ FormatData/ru_RU/TimePatterns/0=HH:mm:ss zzzz FormatData/ru_RU/TimePatterns/1=HH:mm:ss z FormatData/ru_RU/TimePatterns/2=HH:mm:ss FormatData/ru_RU/TimePatterns/3=HH:mm -FormatData/ru_RU/DatePatterns/0=EEEE, d MMMM y\u202f'\u0433'. -FormatData/ru_RU/DatePatterns/1=d MMMM y\u202f'\u0433'. -FormatData/ru_RU/DatePatterns/2=d MMM y\u202f'\u0433'. +FormatData/ru_RU/DatePatterns/0=EEEE, d MMMM y 'г'. +FormatData/ru_RU/DatePatterns/1=d MMMM y 'г'. +FormatData/ru_RU/DatePatterns/2=d MMM y 'г'. FormatData/ru_RU/DatePatterns/3=dd.MM.y FormatData/ru_RU/DateTimePatterns/0={1}, {0} # bug #4084356, 4290801 -CurrencyNames/pl_PL/PLN=z\u0142 +CurrencyNames/pl_PL/PLN=zł FormatData/pl_PL/latn.NumberPatterns/0=#,##0.### -# FormatData/pl_PL/NumberPatterns/1=#,##0.## z\u0142;-#,##0.## z\u0142 # Changed; see bug 4122840 +# FormatData/pl_PL/NumberPatterns/1=#,##0.## zł;-#,##0.## zł # Changed; see bug 4122840 FormatData/pl_PL/latn.NumberPatterns/2=#,##0% FormatData/pl_PL/DayNames/0=niedziela -FormatData/pl_PL/DayNames/1=poniedzia\u0142ek +FormatData/pl_PL/DayNames/1=poniedziałek FormatData/pl_PL/DayNames/2=wtorek -FormatData/pl_PL/DayNames/3=\u015broda +FormatData/pl_PL/DayNames/3=środa FormatData/pl_PL/DayNames/4=czwartek -FormatData/pl_PL/DayNames/5=pi\u0105tek +FormatData/pl_PL/DayNames/5=piątek FormatData/pl_PL/DayNames/6=sobota -FormatData/pl_PL/standalone.MonthNames/0=stycze\u0144 +FormatData/pl_PL/standalone.MonthNames/0=styczeń FormatData/pl_PL/standalone.MonthNames/1=luty FormatData/pl_PL/standalone.MonthNames/2=marzec -FormatData/pl_PL/standalone.MonthNames/3=kwiecie\u0144 +FormatData/pl_PL/standalone.MonthNames/3=kwiecień FormatData/pl_PL/standalone.MonthNames/4=maj FormatData/pl_PL/standalone.MonthNames/5=czerwiec FormatData/pl_PL/standalone.MonthNames/6=lipiec -FormatData/pl_PL/standalone.MonthNames/7=sierpie\u0144 -FormatData/pl_PL/standalone.MonthNames/8=wrzesie\u0144 -FormatData/pl_PL/standalone.MonthNames/9=pa\u017adziernik +FormatData/pl_PL/standalone.MonthNames/7=sierpień +FormatData/pl_PL/standalone.MonthNames/8=wrzesień +FormatData/pl_PL/standalone.MonthNames/9=październik FormatData/pl_PL/standalone.MonthNames/10=listopad -FormatData/pl_PL/standalone.MonthNames/11=grudzie\u0144 +FormatData/pl_PL/standalone.MonthNames/11=grudzień FormatData/pl_PL/standalone.MonthNames/12= LocaleNames/pl_PL/pl=polski FormatData/pl_PL/TimePatterns/0=HH:mm:ss zzzz @@ -149,15 +149,15 @@ FormatData/pl_PL/DatePatterns/2=d MMM y FormatData/pl_PL/DatePatterns/3=d.MM.y FormatData/pl_PL/DateTimePatterns/0={1} {0} FormatData/pl_PL/latn.NumberElements/0=, -FormatData/pl_PL/latn.NumberElements/1=\u00a0 +FormatData/pl_PL/latn.NumberElements/1=  FormatData/pl_PL/latn.NumberElements/2=; FormatData/pl_PL/latn.NumberElements/3=% FormatData/pl_PL/latn.NumberElements/4=0 FormatData/pl_PL/latn.NumberElements/5=# FormatData/pl_PL/latn.NumberElements/6=- FormatData/pl_PL/latn.NumberElements/7=E -FormatData/pl_PL/latn.NumberElements/8=\u2030 -FormatData/pl_PL/latn.NumberElements/9=\u221e +FormatData/pl_PL/latn.NumberElements/8=‰ +FormatData/pl_PL/latn.NumberElements/9=∞ FormatData/pl_PL/latn.NumberElements/10=NaN FormatData/pl_PL/Eras/0=p.n.e. FormatData/pl_PL/Eras/1=n.e. @@ -165,7 +165,7 @@ LocaleNames/pl_PL/PL=Polska FormatData/pl_PL/DayAbbreviations/0=niedz. FormatData/pl_PL/DayAbbreviations/1=pon. FormatData/pl_PL/DayAbbreviations/2=wt. -FormatData/pl_PL/DayAbbreviations/3=\u015br. +FormatData/pl_PL/DayAbbreviations/3=śr. FormatData/pl_PL/DayAbbreviations/4=czw. FormatData/pl_PL/DayAbbreviations/5=pt. FormatData/pl_PL/DayAbbreviations/6=sob. @@ -178,7 +178,7 @@ FormatData/pl_PL/MonthAbbreviations/5=cze FormatData/pl_PL/MonthAbbreviations/6=lip FormatData/pl_PL/MonthAbbreviations/7=sie FormatData/pl_PL/MonthAbbreviations/8=wrz -FormatData/pl_PL/MonthAbbreviations/9=pa\u017a +FormatData/pl_PL/MonthAbbreviations/9=paź FormatData/pl_PL/MonthAbbreviations/10=lis FormatData/pl_PL/MonthAbbreviations/11=gru FormatData/pl_PL/MonthAbbreviations/12= @@ -187,14 +187,14 @@ FormatData/pl_PL/AmPmMarkers/1=PM # bug #4087238, 4290801 # bug 4156708 - changed currency symbol from 00a5 to ffe5 -CurrencyNames/ja_JP/JPY=\uffe5 -# FormatData/ja_JP/NumberPatterns/1=\u00a5#,##0.00 # Changed; see bug 4122840 +CurrencyNames/ja_JP/JPY=¥ +# FormatData/ja_JP/NumberPatterns/1=¥#,##0.00 # Changed; see bug 4122840 # bug #4092361 -FormatData/en_US/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/en_US/TimePatterns/1=h:mm:ss\u202fa z -FormatData/en_US/TimePatterns/2=h:mm:ss\u202fa -FormatData/en_US/TimePatterns/3=h:mm\u202fa +FormatData/en_US/TimePatterns/0=h:mm:ss a zzzz +FormatData/en_US/TimePatterns/1=h:mm:ss a z +FormatData/en_US/TimePatterns/2=h:mm:ss a +FormatData/en_US/TimePatterns/3=h:mm a FormatData/en_US/DatePatterns/0=EEEE, MMMM d, y FormatData/en_US/DatePatterns/1=MMMM d, y FormatData/en_US/DatePatterns/2=MMM d, y @@ -202,121 +202,121 @@ FormatData/en_US/DatePatterns/3=M/d/yy FormatData/en_US/DateTimePatterns/0={1}, {0} # bug #4094033, 4290801, 4942982 -CurrencyNames/ru_RU/RUB=\u20bd +CurrencyNames/ru_RU/RUB=₽ FormatData/ru_RU/latn.NumberPatterns/0=#,##0.### -# FormatData/ru_RU/NumberPatterns/1=#,##0.##'\u0440.';-#,##0.##'\u0440.' # Changed; see bug 4122840 -FormatData/ru_RU/latn.NumberPatterns/2=#,##0\u00a0% -FormatData/ru_RU/MonthNames/0=\u044f\u043d\u0432\u0430\u0440\u044f -FormatData/ru_RU/MonthNames/1=\u0444\u0435\u0432\u0440\u0430\u043b\u044f -FormatData/ru_RU/MonthNames/2=\u043c\u0430\u0440\u0442\u0430 -FormatData/ru_RU/MonthNames/3=\u0430\u043f\u0440\u0435\u043b\u044f -FormatData/ru_RU/MonthNames/4=\u043c\u0430\u044f -FormatData/ru_RU/MonthNames/5=\u0438\u044e\u043d\u044f -FormatData/ru_RU/MonthNames/6=\u0438\u044e\u043b\u044f -FormatData/ru_RU/MonthNames/7=\u0430\u0432\u0433\u0443\u0441\u0442\u0430 -FormatData/ru_RU/MonthNames/8=\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f -FormatData/ru_RU/MonthNames/9=\u043e\u043a\u0442\u044f\u0431\u0440\u044f -FormatData/ru_RU/MonthNames/10=\u043d\u043e\u044f\u0431\u0440\u044f -FormatData/ru_RU/MonthNames/11=\u0434\u0435\u043a\u0430\u0431\u0440\u044f +# FormatData/ru_RU/NumberPatterns/1=#,##0.##'р.';-#,##0.##'р.' # Changed; see bug 4122840 +FormatData/ru_RU/latn.NumberPatterns/2=#,##0 % +FormatData/ru_RU/MonthNames/0=января +FormatData/ru_RU/MonthNames/1=февраля +FormatData/ru_RU/MonthNames/2=марта +FormatData/ru_RU/MonthNames/3=апреля +FormatData/ru_RU/MonthNames/4=мая +FormatData/ru_RU/MonthNames/5=июня +FormatData/ru_RU/MonthNames/6=июля +FormatData/ru_RU/MonthNames/7=августа +FormatData/ru_RU/MonthNames/8=сентября +FormatData/ru_RU/MonthNames/9=октября +FormatData/ru_RU/MonthNames/10=ноября +FormatData/ru_RU/MonthNames/11=декабря FormatData/ru_RU/MonthNames/12= -FormatData/ru_RU/standalone.MonthNames/0=\u044f\u043d\u0432\u0430\u0440\u044c -FormatData/ru_RU/standalone.MonthNames/1=\u0444\u0435\u0432\u0440\u0430\u043b\u044c -FormatData/ru_RU/standalone.MonthNames/2=\u043c\u0430\u0440\u0442 -FormatData/ru_RU/standalone.MonthNames/3=\u0430\u043f\u0440\u0435\u043b\u044c -FormatData/ru_RU/standalone.MonthNames/4=\u043c\u0430\u0439 -FormatData/ru_RU/standalone.MonthNames/5=\u0438\u044e\u043d\u044c -FormatData/ru_RU/standalone.MonthNames/6=\u0438\u044e\u043b\u044c -FormatData/ru_RU/standalone.MonthNames/7=\u0430\u0432\u0433\u0443\u0441\u0442 -FormatData/ru_RU/standalone.MonthNames/8=\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c -FormatData/ru_RU/standalone.MonthNames/9=\u043e\u043a\u0442\u044f\u0431\u0440\u044c -FormatData/ru_RU/standalone.MonthNames/10=\u043d\u043e\u044f\u0431\u0440\u044c -FormatData/ru_RU/standalone.MonthNames/11=\u0434\u0435\u043a\u0430\u0431\u0440\u044c +FormatData/ru_RU/standalone.MonthNames/0=январь +FormatData/ru_RU/standalone.MonthNames/1=февраль +FormatData/ru_RU/standalone.MonthNames/2=март +FormatData/ru_RU/standalone.MonthNames/3=апрель +FormatData/ru_RU/standalone.MonthNames/4=май +FormatData/ru_RU/standalone.MonthNames/5=июнь +FormatData/ru_RU/standalone.MonthNames/6=июль +FormatData/ru_RU/standalone.MonthNames/7=август +FormatData/ru_RU/standalone.MonthNames/8=сентябрь +FormatData/ru_RU/standalone.MonthNames/9=октябрь +FormatData/ru_RU/standalone.MonthNames/10=ноябрь +FormatData/ru_RU/standalone.MonthNames/11=декабрь FormatData/ru_RU/standalone.MonthNames/12= -FormatData/ru_RU/Eras/0=\u0434\u043e \u043d. \u044d. -FormatData/ru_RU/Eras/1=\u043d. \u044d. -LocaleNames/ru_RU/ru=\u0440\u0443\u0441\u0441\u043a\u0438\u0439 -FormatData/ru_RU/MonthAbbreviations/0=\u044f\u043d\u0432. -FormatData/ru_RU/MonthAbbreviations/1=\u0444\u0435\u0432\u0440. -FormatData/ru_RU/MonthAbbreviations/2=\u043c\u0430\u0440. -FormatData/ru_RU/MonthAbbreviations/3=\u0430\u043f\u0440. -FormatData/ru_RU/MonthAbbreviations/4=\u043c\u0430\u044f -FormatData/ru_RU/MonthAbbreviations/5=\u0438\u044e\u043d. -FormatData/ru_RU/MonthAbbreviations/6=\u0438\u044e\u043b. -FormatData/ru_RU/MonthAbbreviations/7=\u0430\u0432\u0433. -FormatData/ru_RU/MonthAbbreviations/8=\u0441\u0435\u043d\u0442. -FormatData/ru_RU/MonthAbbreviations/9=\u043e\u043a\u0442. -FormatData/ru_RU/MonthAbbreviations/10=\u043d\u043e\u044f\u0431. -FormatData/ru_RU/MonthAbbreviations/11=\u0434\u0435\u043a. +FormatData/ru_RU/Eras/0=до н. э. +FormatData/ru_RU/Eras/1=н. э. +LocaleNames/ru_RU/ru=русский +FormatData/ru_RU/MonthAbbreviations/0=янв. +FormatData/ru_RU/MonthAbbreviations/1=февр. +FormatData/ru_RU/MonthAbbreviations/2=мар. +FormatData/ru_RU/MonthAbbreviations/3=апр. +FormatData/ru_RU/MonthAbbreviations/4=мая +FormatData/ru_RU/MonthAbbreviations/5=июн. +FormatData/ru_RU/MonthAbbreviations/6=июл. +FormatData/ru_RU/MonthAbbreviations/7=авг. +FormatData/ru_RU/MonthAbbreviations/8=сент. +FormatData/ru_RU/MonthAbbreviations/9=окт. +FormatData/ru_RU/MonthAbbreviations/10=нояб. +FormatData/ru_RU/MonthAbbreviations/11=дек. FormatData/ru_RU/MonthAbbreviations/12= -# FormatData/ru_RU/standalone.MonthAbbreviations/0=\u044f\u043d\u0432 -# FormatData/ru_RU/standalone.MonthAbbreviations/1=\u0444\u0435\u0432 -# FormatData/ru_RU/standalone.MonthAbbreviations/2=\u043c\u0430\u0440 -# FormatData/ru_RU/standalone.MonthAbbreviations/3=\u0430\u043f\u0440 -# FormatData/ru_RU/standalone.MonthAbbreviations/4=\u043c\u0430\u0439 -# FormatData/ru_RU/standalone.MonthAbbreviations/5=\u0438\u044e\u043d -# FormatData/ru_RU/standalone.MonthAbbreviations/6=\u0438\u044e\u043b -# FormatData/ru_RU/standalone.MonthAbbreviations/7=\u0430\u0432\u0433 -# FormatData/ru_RU/standalone.MonthAbbreviations/8=\u0441\u0435\u043d -# FormatData/ru_RU/standalone.MonthAbbreviations/9=\u043e\u043a\u0442 -# FormatData/ru_RU/standalone.MonthAbbreviations/10=\u043d\u043e\u044f -# FormatData/ru_RU/standalone.MonthAbbreviations/11=\u0434\u0435\u043a +# FormatData/ru_RU/standalone.MonthAbbreviations/0=янв +# FormatData/ru_RU/standalone.MonthAbbreviations/1=фев +# FormatData/ru_RU/standalone.MonthAbbreviations/2=мар +# FormatData/ru_RU/standalone.MonthAbbreviations/3=апр +# FormatData/ru_RU/standalone.MonthAbbreviations/4=май +# FormatData/ru_RU/standalone.MonthAbbreviations/5=июн +# FormatData/ru_RU/standalone.MonthAbbreviations/6=июл +# FormatData/ru_RU/standalone.MonthAbbreviations/7=авг +# FormatData/ru_RU/standalone.MonthAbbreviations/8=сен +# FormatData/ru_RU/standalone.MonthAbbreviations/9=окт +# FormatData/ru_RU/standalone.MonthAbbreviations/10=ноя +# FormatData/ru_RU/standalone.MonthAbbreviations/11=дек # FormatData/ru_RU/standalone.MonthAbbreviations/12= -FormatData/ru_RU/standalone.MonthAbbreviations/0=\u044f\u043d\u0432. -FormatData/ru_RU/standalone.MonthAbbreviations/1=\u0444\u0435\u0432\u0440. -FormatData/ru_RU/standalone.MonthAbbreviations/2=\u043c\u0430\u0440\u0442 -FormatData/ru_RU/standalone.MonthAbbreviations/3=\u0430\u043f\u0440. -FormatData/ru_RU/standalone.MonthAbbreviations/4=\u043c\u0430\u0439 -FormatData/ru_RU/standalone.MonthAbbreviations/5=\u0438\u044e\u043d\u044c -FormatData/ru_RU/standalone.MonthAbbreviations/6=\u0438\u044e\u043b\u044c -FormatData/ru_RU/standalone.MonthAbbreviations/7=\u0430\u0432\u0433. -FormatData/ru_RU/standalone.MonthAbbreviations/8=\u0441\u0435\u043d\u0442. -FormatData/ru_RU/standalone.MonthAbbreviations/9=\u043e\u043a\u0442. -FormatData/ru_RU/standalone.MonthAbbreviations/10=\u043d\u043e\u044f\u0431. -FormatData/ru_RU/standalone.MonthAbbreviations/11=\u0434\u0435\u043a. +FormatData/ru_RU/standalone.MonthAbbreviations/0=янв. +FormatData/ru_RU/standalone.MonthAbbreviations/1=февр. +FormatData/ru_RU/standalone.MonthAbbreviations/2=март +FormatData/ru_RU/standalone.MonthAbbreviations/3=апр. +FormatData/ru_RU/standalone.MonthAbbreviations/4=май +FormatData/ru_RU/standalone.MonthAbbreviations/5=июнь +FormatData/ru_RU/standalone.MonthAbbreviations/6=июль +FormatData/ru_RU/standalone.MonthAbbreviations/7=авг. +FormatData/ru_RU/standalone.MonthAbbreviations/8=сент. +FormatData/ru_RU/standalone.MonthAbbreviations/9=окт. +FormatData/ru_RU/standalone.MonthAbbreviations/10=нояб. +FormatData/ru_RU/standalone.MonthAbbreviations/11=дек. FormatData/ru_RU/standalone.MonthAbbreviations/12= FormatData/ru_RU/TimePatterns/0=HH:mm:ss zzzz FormatData/ru_RU/TimePatterns/1=HH:mm:ss z FormatData/ru_RU/TimePatterns/2=HH:mm:ss FormatData/ru_RU/TimePatterns/3=HH:mm -FormatData/ru_RU/DatePatterns/0=EEEE, d MMMM y\u202f'\u0433'. -FormatData/ru_RU/DatePatterns/1=d MMMM y\u202f'\u0433'. -FormatData/ru_RU/DatePatterns/2=d MMM y\u202f'\u0433'. +FormatData/ru_RU/DatePatterns/0=EEEE, d MMMM y 'г'. +FormatData/ru_RU/DatePatterns/1=d MMMM y 'г'. +FormatData/ru_RU/DatePatterns/2=d MMM y 'г'. FormatData/ru_RU/DatePatterns/3=dd.MM.y FormatData/ru_RU/DateTimePatterns/0={1}, {0} -FormatData/ru_RU/DayNames/0=\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435 -FormatData/ru_RU/DayNames/1=\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a -FormatData/ru_RU/DayNames/2=\u0432\u0442\u043e\u0440\u043d\u0438\u043a -FormatData/ru_RU/DayNames/3=\u0441\u0440\u0435\u0434\u0430 -FormatData/ru_RU/DayNames/4=\u0447\u0435\u0442\u0432\u0435\u0440\u0433 -FormatData/ru_RU/DayNames/5=\u043f\u044f\u0442\u043d\u0438\u0446\u0430 -FormatData/ru_RU/DayNames/6=\u0441\u0443\u0431\u0431\u043e\u0442\u0430 +FormatData/ru_RU/DayNames/0=воскресенье +FormatData/ru_RU/DayNames/1=понедельник +FormatData/ru_RU/DayNames/2=вторник +FormatData/ru_RU/DayNames/3=среда +FormatData/ru_RU/DayNames/4=четверг +FormatData/ru_RU/DayNames/5=пятница +FormatData/ru_RU/DayNames/6=суббота FormatData/ru_RU/latn.NumberElements/0=, -FormatData/ru_RU/latn.NumberElements/1=\u00a0 +FormatData/ru_RU/latn.NumberElements/1=  FormatData/ru_RU/latn.NumberElements/2=; FormatData/ru_RU/latn.NumberElements/3=% FormatData/ru_RU/latn.NumberElements/4=0 FormatData/ru_RU/latn.NumberElements/5=# FormatData/ru_RU/latn.NumberElements/6=- FormatData/ru_RU/latn.NumberElements/7=E -FormatData/ru_RU/latn.NumberElements/8=\u2030 -FormatData/ru_RU/latn.NumberElements/9=\u221e -FormatData/ru_RU/latn.NumberElements/10=\u043d\u0435\u00a0\u0447\u0438\u0441\u043b\u043e -LocaleNames/ru_RU/RU=\u0420\u043e\u0441\u0441\u0438\u044f -FormatData/ru_RU/DayAbbreviations/0=\u0432\u0441 -FormatData/ru_RU/DayAbbreviations/1=\u043f\u043d -FormatData/ru_RU/DayAbbreviations/2=\u0432\u0442 -FormatData/ru_RU/DayAbbreviations/3=\u0441\u0440 -FormatData/ru_RU/DayAbbreviations/4=\u0447\u0442 -FormatData/ru_RU/DayAbbreviations/5=\u043f\u0442 -FormatData/ru_RU/DayAbbreviations/6=\u0441\u0431 +FormatData/ru_RU/latn.NumberElements/8=‰ +FormatData/ru_RU/latn.NumberElements/9=∞ +FormatData/ru_RU/latn.NumberElements/10=не число +LocaleNames/ru_RU/RU=Россия +FormatData/ru_RU/DayAbbreviations/0=вс +FormatData/ru_RU/DayAbbreviations/1=пн +FormatData/ru_RU/DayAbbreviations/2=вт +FormatData/ru_RU/DayAbbreviations/3=ср +FormatData/ru_RU/DayAbbreviations/4=чт +FormatData/ru_RU/DayAbbreviations/5=пт +FormatData/ru_RU/DayAbbreviations/6=сб FormatData/ru_RU/AmPmMarkers/0=AM FormatData/ru_RU/AmPmMarkers/1=PM # bug #4094371, 4098518, 4290801, 6558863 -FormatData/en_AU/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/en_AU/TimePatterns/1=h:mm:ss\u202fa z -FormatData/en_AU/TimePatterns/2=h:mm:ss\u202fa -FormatData/en_AU/TimePatterns/3=h:mm\u202fa +FormatData/en_AU/TimePatterns/0=h:mm:ss a zzzz +FormatData/en_AU/TimePatterns/1=h:mm:ss a z +FormatData/en_AU/TimePatterns/2=h:mm:ss a +FormatData/en_AU/TimePatterns/3=h:mm a FormatData/en_AU/DatePatterns/0=EEEE, d MMMM y FormatData/en_AU/DatePatterns/1=d MMMM y FormatData/en_AU/DatePatterns/2=d MMM y @@ -337,10 +337,10 @@ FormatData/en_AU/MonthNames/0=January FormatData/en_AU/MonthNames/1=February FormatData/en_AU/MonthNames/2=March # changed, bug 6558863 -FormatData/en_NZ/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/en_NZ/TimePatterns/1=h:mm:ss\u202fa z -FormatData/en_NZ/TimePatterns/2=h:mm:ss\u202fa -FormatData/en_NZ/TimePatterns/3=h:mm\u202fa +FormatData/en_NZ/TimePatterns/0=h:mm:ss a zzzz +FormatData/en_NZ/TimePatterns/1=h:mm:ss a z +FormatData/en_NZ/TimePatterns/2=h:mm:ss a +FormatData/en_NZ/TimePatterns/3=h:mm a FormatData/en_NZ/DatePatterns/0=EEEE, d MMMM y FormatData/en_NZ/DatePatterns/1=d MMMM y FormatData/en_NZ/DatePatterns/2=d MMM y @@ -387,10 +387,10 @@ CurrencyNames/es_AR/ARS=$ FormatData/es_AR/latn.NumberPatterns/0=#,##0.### # FormatData/es_AR/NumberPatterns/1=$#,##0.00;($#,##0.00) # Changed; see bug 4122840 FormatData/es_AR/latn.NumberPatterns/2=#,##0% -FormatData/es_AR/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_AR/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_AR/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_AR/TimePatterns/3=h:mm\u202fa +FormatData/es_AR/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_AR/TimePatterns/1=h:mm:ss a z +FormatData/es_AR/TimePatterns/2=h:mm:ss a +FormatData/es_AR/TimePatterns/3=h:mm a FormatData/es_AR/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_AR/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_AR/DatePatterns/2=d MMM y @@ -403,10 +403,10 @@ FormatData/es_BO/latn.NumberPatterns/0=#,##0.### # FormatData/es_BO/NumberPatterns/1=B$#,##0.00;(B$#,##0.00) # Changed; see bug 4122840 FormatData/es_BO/latn.NumberPatterns/2=#,##0% CurrencyNames/es_BO/BOB=Bs -FormatData/es_BO/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_BO/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_BO/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_BO/TimePatterns/3=h:mm\u202fa +FormatData/es_BO/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_BO/TimePatterns/1=h:mm:ss a z +FormatData/es_BO/TimePatterns/2=h:mm:ss a +FormatData/es_BO/TimePatterns/3=h:mm a FormatData/es_BO/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_BO/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_BO/DatePatterns/2=d MMM 'de' y @@ -433,10 +433,10 @@ FormatData/es_CO/latn.NumberPatterns/0=#,##0.### FormatData/es_CO/latn.NumberPatterns/2=#,##0% # changed currency symbol during 5102005 bugfix CurrencyNames/es_CO/COP=$ -FormatData/es_CO/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_CO/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_CO/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_CO/TimePatterns/3=h:mm\u202fa +FormatData/es_CO/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_CO/TimePatterns/1=h:mm:ss a z +FormatData/es_CO/TimePatterns/2=h:mm:ss a +FormatData/es_CO/TimePatterns/3=h:mm a FormatData/es_CO/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_CO/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_CO/DatePatterns/2=d/MM/y @@ -449,27 +449,27 @@ FormatData/es_CO/latn.NumberElements/2=; FormatData/es_CR/latn.NumberPatterns/0=#,##0.### # FormatData/es_CR/NumberPatterns/1=C#,##0.00;(C#,##0.00) # Changed; see bug 4122840 FormatData/es_CR/latn.NumberPatterns/2=#,##0% -CurrencyNames/es_CR/CRC=\u20a1 -FormatData/es_CR/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_CR/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_CR/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_CR/TimePatterns/3=h:mm\u202fa +CurrencyNames/es_CR/CRC=₡ +FormatData/es_CR/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_CR/TimePatterns/1=h:mm:ss a z +FormatData/es_CR/TimePatterns/2=h:mm:ss a +FormatData/es_CR/TimePatterns/3=h:mm a FormatData/es_CR/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_CR/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_CR/DatePatterns/2=d MMM y FormatData/es_CR/DatePatterns/3=d/M/yy FormatData/es_CR/DateTimePatterns/0={1}, {0} FormatData/es_CR/latn.NumberElements/0=, -FormatData/es_CR/latn.NumberElements/1=\u00a0 +FormatData/es_CR/latn.NumberElements/1=  FormatData/es_CR/latn.NumberElements/2=; FormatData/es_DO/latn.NumberPatterns/0=#,##0.### # FormatData/es_DO/NumberPatterns/1=RD$#,##0.00;(RD$#,##0.00) # Changed; see bug 4122840 FormatData/es_DO/latn.NumberPatterns/2=#,##0% CurrencyNames/es_DO/DOP=RD$ -FormatData/es_DO/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_DO/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_DO/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_DO/TimePatterns/3=h:mm\u202fa +FormatData/es_DO/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_DO/TimePatterns/1=h:mm:ss a z +FormatData/es_DO/TimePatterns/2=h:mm:ss a +FormatData/es_DO/TimePatterns/3=h:mm a FormatData/es_DO/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_DO/DatePatterns/1=d 'de' MMMM 'de' y # FormatData/es_DO/DatePatterns/2=MM/dd/yyyy # Changed: see bug 8037343 @@ -492,20 +492,20 @@ FormatData/es_EC/DateTimePatterns/0={1}, {0} FormatData/es_EC/latn.NumberElements/0=, FormatData/es_EC/latn.NumberElements/1=. FormatData/es_EC/latn.NumberElements/2=; -LocaleNames/es/ES=Espa\u00f1a +LocaleNames/es/ES=España LocaleNames/es/AR=Argentina LocaleNames/es/BO=Bolivia LocaleNames/es/CL=Chile LocaleNames/es/CO=Colombia LocaleNames/es/CR=Costa Rica -LocaleNames/es/DO=Rep\u00fablica Dominicana +LocaleNames/es/DO=República Dominicana LocaleNames/es/EC=Ecuador LocaleNames/es/GT=Guatemala LocaleNames/es/HN=Honduras -LocaleNames/es/MX=M\u00e9xico +LocaleNames/es/MX=México LocaleNames/es/NI=Nicaragua -LocaleNames/es/PA=Panam\u00e1 -LocaleNames/es/PE=Per\u00fa +LocaleNames/es/PA=Panamá +LocaleNames/es/PE=Perú LocaleNames/es/PR=Puerto Rico LocaleNames/es/PY=Paraguay # LocaleNames/es/SV=El SalvadorUY # Changed, see bug 4331446 @@ -515,10 +515,10 @@ FormatData/es_GT/latn.NumberPatterns/0=#,##0.### # FormatData/es_GT/NumberPatterns/1=Q#,##0.00;(Q#,##0.00) # Changed; see bug 4122840 FormatData/es_GT/latn.NumberPatterns/2=#,##0% CurrencyNames/es_GT/GTQ=Q -FormatData/es_GT/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_GT/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_GT/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_GT/TimePatterns/3=h:mm\u202fa +FormatData/es_GT/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_GT/TimePatterns/1=h:mm:ss a z +FormatData/es_GT/TimePatterns/2=h:mm:ss a +FormatData/es_GT/TimePatterns/3=h:mm a FormatData/es_GT/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_GT/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_GT/DatePatterns/2=d/MM/y @@ -531,10 +531,10 @@ FormatData/es_HN/latn.NumberPatterns/0=#,##0.### # FormatData/es_HN/NumberPatterns/1=L#,##0.00;(L#,##0.00) # Changed; see bug 4122840 FormatData/es_HN/latn.NumberPatterns/2=#,##0% CurrencyNames/es_HN/HNL=L -FormatData/es_HN/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_HN/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_HN/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_HN/TimePatterns/3=h:mm\u202fa +FormatData/es_HN/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_HN/TimePatterns/1=h:mm:ss a z +FormatData/es_HN/TimePatterns/2=h:mm:ss a +FormatData/es_HN/TimePatterns/3=h:mm a FormatData/es_HN/DatePatterns/0=EEEE dd 'de' MMMM 'de' y FormatData/es_HN/DatePatterns/1=dd 'de' MMMM 'de' y FormatData/es_HN/DatePatterns/2=d MMM y @@ -547,10 +547,10 @@ FormatData/es_MX/latn.NumberPatterns/0=#,##0.### # FormatData/es_MX/NumberPatterns/1=$#,##0.00;($#,##0.00) # Changed; see bug 4122840 FormatData/es_MX/latn.NumberPatterns/2=#,##0% CurrencyNames/es_MX/MXN=$ -FormatData/es_MX/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_MX/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_MX/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_MX/TimePatterns/3=h:mm\u202fa +FormatData/es_MX/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_MX/TimePatterns/1=h:mm:ss a z +FormatData/es_MX/TimePatterns/2=h:mm:ss a +FormatData/es_MX/TimePatterns/3=h:mm a FormatData/es_MX/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_MX/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_MX/DatePatterns/2=d MMM y @@ -563,10 +563,10 @@ FormatData/es_NI/latn.NumberPatterns/0=#,##0.### # FormatData/es_NI/NumberPatterns/1=$C#,##0.00;($C#,##0.00) # Changed; see bug 4122840 FormatData/es_NI/latn.NumberPatterns/2=#,##0% CurrencyNames/es_NI/NIO=C$ -FormatData/es_NI/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_NI/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_NI/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_NI/TimePatterns/3=h:mm\u202fa +FormatData/es_NI/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_NI/TimePatterns/1=h:mm:ss a z +FormatData/es_NI/TimePatterns/2=h:mm:ss a +FormatData/es_NI/TimePatterns/3=h:mm a FormatData/es_NI/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_NI/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_NI/DatePatterns/2=d MMM y @@ -579,10 +579,10 @@ FormatData/es_PA/latn.NumberPatterns/0=#,##0.### # FormatData/es_PA/NumberPatterns/1=B#,##0.00;(B#,##0.00) # Changed; see bug 4122840 FormatData/es_PA/latn.NumberPatterns/2=#,##0% CurrencyNames/es_PA/PAB=B/. -FormatData/es_PA/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_PA/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_PA/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_PA/TimePatterns/3=h:mm\u202fa +FormatData/es_PA/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_PA/TimePatterns/1=h:mm:ss a z +FormatData/es_PA/TimePatterns/2=h:mm:ss a +FormatData/es_PA/TimePatterns/3=h:mm a FormatData/es_PA/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_PA/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_PA/DatePatterns/2=MM/dd/y @@ -594,10 +594,10 @@ FormatData/es_PA/latn.NumberElements/2=; FormatData/es_PE/latn.NumberPatterns/0=#,##0.### # FormatData/es_PE/NumberPatterns/1=S/#,##0.00;S/-#,##0.00 # Changed; see bug 4122840 FormatData/es_PE/latn.NumberPatterns/2=#,##0% -FormatData/es_PE/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_PE/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_PE/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_PE/TimePatterns/3=h:mm\u202fa +FormatData/es_PE/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_PE/TimePatterns/1=h:mm:ss a z +FormatData/es_PE/TimePatterns/2=h:mm:ss a +FormatData/es_PE/TimePatterns/3=h:mm a FormatData/es_PE/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_PE/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_PE/DatePatterns/2=d MMM y @@ -610,10 +610,10 @@ FormatData/es_PR/latn.NumberPatterns/0=#,##0.### # FormatData/es_PR/NumberPatterns/1=$#,##0.00;($#,##0.00) # Changed; see bug 4122840 FormatData/es_PR/latn.NumberPatterns/2=#,##0% CurrencyNames/es_PR/USD=$ -FormatData/es_PR/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_PR/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_PR/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_PR/TimePatterns/3=h:mm\u202fa +FormatData/es_PR/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_PR/TimePatterns/1=h:mm:ss a z +FormatData/es_PR/TimePatterns/2=h:mm:ss a +FormatData/es_PR/TimePatterns/3=h:mm a FormatData/es_PR/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_PR/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_PR/DatePatterns/2=MM/dd/y @@ -626,10 +626,10 @@ CurrencyNames/es_PY/PYG=Gs. FormatData/es_PY/latn.NumberPatterns/0=#,##0.### # FormatData/es_PY/NumberPatterns/1=G#,##0.00;(G#,##0.00) # Changed; see bug 4122840 FormatData/es_PY/latn.NumberPatterns/2=#,##0% -FormatData/es_PY/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_PY/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_PY/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_PY/TimePatterns/3=h:mm\u202fa +FormatData/es_PY/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_PY/TimePatterns/1=h:mm:ss a z +FormatData/es_PY/TimePatterns/2=h:mm:ss a +FormatData/es_PY/TimePatterns/3=h:mm a FormatData/es_PY/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_PY/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_PY/DatePatterns/2=d MMM y @@ -641,10 +641,10 @@ FormatData/es_PY/latn.NumberElements/2=; FormatData/es_SV/latn.NumberPatterns/0=#,##0.### # FormatData/es_SV/NumberPatterns/1=C#,##0.00;(C#,##0.00) # Changed; see bug 4122840 FormatData/es_SV/latn.NumberPatterns/2=#,##0% -FormatData/es_SV/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_SV/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_SV/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_SV/TimePatterns/3=h:mm\u202fa +FormatData/es_SV/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_SV/TimePatterns/1=h:mm:ss a z +FormatData/es_SV/TimePatterns/2=h:mm:ss a +FormatData/es_SV/TimePatterns/3=h:mm a FormatData/es_SV/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_SV/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_SV/DatePatterns/2=d MMM y @@ -657,10 +657,10 @@ CurrencyNames/es_UY/UYU=$ FormatData/es_UY/latn.NumberPatterns/0=#,##0.### # FormatData/es_UY/NumberPatterns/1=NU$ #,##0.00;(NU$#,##0.00) # Changed; see bug 4122840 FormatData/es_UY/latn.NumberPatterns/2=#,##0% -FormatData/es_UY/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_UY/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_UY/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_UY/TimePatterns/3=h:mm\u202fa +FormatData/es_UY/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_UY/TimePatterns/1=h:mm:ss a z +FormatData/es_UY/TimePatterns/2=h:mm:ss a +FormatData/es_UY/TimePatterns/3=h:mm a FormatData/es_UY/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_UY/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_UY/DatePatterns/2=d MMM y @@ -673,10 +673,10 @@ FormatData/es_UY/latn.NumberElements/2=; FormatData/es_VE/latn.NumberPatterns/0=#,##0.### # FormatData/es_VE/NumberPatterns/1=Bs#,##0.00;Bs -#,##0.00 # Changed; see bug 4122840 FormatData/es_VE/latn.NumberPatterns/2=#,##0% -FormatData/es_VE/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_VE/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_VE/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_VE/TimePatterns/3=h:mm\u202fa +FormatData/es_VE/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_VE/TimePatterns/1=h:mm:ss a z +FormatData/es_VE/TimePatterns/2=h:mm:ss a +FormatData/es_VE/TimePatterns/3=h:mm a FormatData/es_VE/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_VE/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_VE/DatePatterns/2=d MMM y @@ -687,19 +687,19 @@ FormatData/es_VE/latn.NumberElements/1=. FormatData/es_VE/latn.NumberElements/2=; # bug #4099810, 4290801, 6868106, 6916787 -CurrencyNames/uk_UA/UAH=\u20b4 +CurrencyNames/uk_UA/UAH=₴ FormatData/uk_UA/latn.NumberPatterns/0=#,##0.### -# FormatData/uk_UA/NumberPatterns/1=#,##0.## '\u0433\u0440\u0432.';-#,##0.## '\u0433\u0440\u0432.' # Changed; see bug 4122840 +# FormatData/uk_UA/NumberPatterns/1=#,##0.## 'грв.';-#,##0.## 'грв.' # Changed; see bug 4122840 FormatData/uk_UA/latn.NumberPatterns/2=#,##0% # bug 6245766 -FormatData/uk/DatePatterns/0=EEEE, d MMMM y\u202f'\u0440'. -FormatData/uk/DatePatterns/1=d MMMM y\u202f'\u0440'. -FormatData/uk/DatePatterns/2=d MMM y\u202f'\u0440'. +FormatData/uk/DatePatterns/0=EEEE, d MMMM y 'р'. +FormatData/uk/DatePatterns/1=d MMMM y 'р'. +FormatData/uk/DatePatterns/2=d MMM y 'р'. FormatData/uk/DatePatterns/3=dd.MM.yy # bug #4103218 -# FormatData/ko_KR/NumberPatterns/1=\u20a9#,##0;-\u20a9#,##0 # Changed; see bug 4122840 +# FormatData/ko_KR/NumberPatterns/1=₩#,##0;-₩#,##0 # Changed; see bug 4122840 # bug #4103220 should be adequately tested by the above tests, which represent a pretty # good cross-section of the locale data @@ -721,1481 +721,1481 @@ FormatData/fr_CA/TimePatterns/0=HH 'h' mm 'min' ss 's' zzzz FormatData/fr_CA/TimePatterns/1=HH 'h' mm 'min' ss 's' z # bug #4113638, 4290801 -CurrencyNames/ar_AE/AED=\u062f.\u0625.\u200f +CurrencyNames/ar_AE/AED=د.إ.‏ FormatData/ar_AE/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_AE/NumberPatterns/1='\u062f.\u0625.\u200f' #,##0.###;'\u062f.\u0625.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_AE/NumberPatterns/1='د.إ.‏' #,##0.###;'د.إ.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_AE/arab.NumberPatterns/2=#,##0% -FormatData/ar_AE/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_AE/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_AE/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_AE/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_AE/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_AE/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_AE/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_AE/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_AE/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_AE/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_AE/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_AE/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_AE/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_AE/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_AE/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_AE/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_AE/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_AE/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_AE/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_AE/DayNames/0=الأحد +FormatData/ar_AE/DayNames/1=الاثنين +FormatData/ar_AE/DayNames/2=الثلاثاء +FormatData/ar_AE/DayNames/3=الأربعاء +FormatData/ar_AE/DayNames/4=الخميس +FormatData/ar_AE/DayNames/5=الجمعة +FormatData/ar_AE/DayNames/6=السبت +FormatData/ar_AE/MonthAbbreviations/0=يناير +FormatData/ar_AE/MonthAbbreviations/1=فبراير +FormatData/ar_AE/MonthAbbreviations/2=مارس +FormatData/ar_AE/MonthAbbreviations/3=أبريل +FormatData/ar_AE/MonthAbbreviations/4=مايو +FormatData/ar_AE/MonthAbbreviations/5=يونيو +FormatData/ar_AE/MonthAbbreviations/6=يوليو +FormatData/ar_AE/MonthAbbreviations/7=أغسطس +FormatData/ar_AE/MonthAbbreviations/8=سبتمبر +FormatData/ar_AE/MonthAbbreviations/9=أكتوبر +FormatData/ar_AE/MonthAbbreviations/10=نوفمبر +FormatData/ar_AE/MonthAbbreviations/11=ديسمبر FormatData/ar_AE/MonthAbbreviations/12= -FormatData/ar_AE/Eras/0=\u0642.\u0645 -FormatData/ar_AE/Eras/1=\u0645 -FormatData/ar_AE/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_AE/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_AE/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_AE/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_AE/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_AE/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_AE/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_AE/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_AE/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_AE/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_AE/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_AE/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_AE/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_AE/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_AE/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_AE/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_AE/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_AE/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_AE/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_AE/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_AE/Eras/0=ق.م +FormatData/ar_AE/Eras/1=م +FormatData/ar_AE/DayAbbreviations/0=الأحد +FormatData/ar_AE/DayAbbreviations/1=الاثنين +FormatData/ar_AE/DayAbbreviations/2=الثلاثاء +FormatData/ar_AE/DayAbbreviations/3=الأربعاء +FormatData/ar_AE/DayAbbreviations/4=الخميس +FormatData/ar_AE/DayAbbreviations/5=الجمعة +FormatData/ar_AE/DayAbbreviations/6=السبت +LocaleNames/ar_AE/ar=العربية +FormatData/ar_AE/MonthNames/0=يناير +FormatData/ar_AE/MonthNames/1=فبراير +FormatData/ar_AE/MonthNames/2=مارس +FormatData/ar_AE/MonthNames/3=أبريل +FormatData/ar_AE/MonthNames/4=مايو +FormatData/ar_AE/MonthNames/5=يونيو +FormatData/ar_AE/MonthNames/6=يوليو +FormatData/ar_AE/MonthNames/7=أغسطس +FormatData/ar_AE/MonthNames/8=سبتمبر +FormatData/ar_AE/MonthNames/9=أكتوبر +FormatData/ar_AE/MonthNames/10=نوفمبر +FormatData/ar_AE/MonthNames/11=ديسمبر FormatData/ar_AE/MonthNames/12= -FormatData/ar_AE/AmPmMarkers/0=\u0635 -FormatData/ar_AE/AmPmMarkers/1=\u0645 +FormatData/ar_AE/AmPmMarkers/0=ص +FormatData/ar_AE/AmPmMarkers/1=م FormatData/ar_AE/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_AE/TimePatterns/1=h:mm:ss a z FormatData/ar_AE/TimePatterns/2=h:mm:ss a FormatData/ar_AE/TimePatterns/3=h:mm a -FormatData/ar_AE/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_AE/DatePatterns/0=EEEE، d MMMM y FormatData/ar_AE/DatePatterns/1=d MMMM y -FormatData/ar_AE/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_AE/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_AE/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_AE/EG=\u0645\u0635\u0631 -LocaleNames/ar_AE/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_AE/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_AE/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_AE/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_AE/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_AE/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_AE/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_AE/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_AE/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_AE/QA=\u0642\u0637\u0631 -LocaleNames/ar_AE/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_AE/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_AE/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_AE/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_AE/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_AE/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_AE/arab.NumberElements/0=\u066b -FormatData/ar_AE/arab.NumberElements/1=\u066c -FormatData/ar_AE/arab.NumberElements/2=\u061b -FormatData/ar_AE/arab.NumberElements/3=\u066a\u061c -FormatData/ar_AE/arab.NumberElements/4=\u0660 +FormatData/ar_AE/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_AE/DatePatterns/3=d‏/M‏/y +FormatData/ar_AE/DateTimePatterns/0={1}، {0} +LocaleNames/ar_AE/EG=مصر +LocaleNames/ar_AE/DZ=الجزائر +LocaleNames/ar_AE/BH=البحرين +LocaleNames/ar_AE/IQ=العراق +LocaleNames/ar_AE/JO=الأردن +LocaleNames/ar_AE/KW=الكويت +LocaleNames/ar_AE/LB=لبنان +LocaleNames/ar_AE/LY=ليبيا +LocaleNames/ar_AE/MA=المغرب +LocaleNames/ar_AE/OM=عُمان +LocaleNames/ar_AE/QA=قطر +LocaleNames/ar_AE/SA=المملكة العربية السعودية +LocaleNames/ar_AE/SD=السودان +LocaleNames/ar_AE/SY=سوريا +LocaleNames/ar_AE/TN=تونس +LocaleNames/ar_AE/AE=الإمارات العربية المتحدة +LocaleNames/ar_AE/YE=اليمن +FormatData/ar_AE/arab.NumberElements/0=٫ +FormatData/ar_AE/arab.NumberElements/1=٬ +FormatData/ar_AE/arab.NumberElements/2=؛ +FormatData/ar_AE/arab.NumberElements/3=٪؜ +FormatData/ar_AE/arab.NumberElements/4=٠ FormatData/ar_AE/arab.NumberElements/5=# -FormatData/ar_AE/arab.NumberElements/6=\u061c- -FormatData/ar_AE/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_AE/arab.NumberElements/8=\u0609 -FormatData/ar_AE/arab.NumberElements/9=\u221e -FormatData/ar_AE/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_BH/BHD=\u062f.\u0628.\u200f +FormatData/ar_AE/arab.NumberElements/6=؜- +FormatData/ar_AE/arab.NumberElements/7=أس +FormatData/ar_AE/arab.NumberElements/8=؉ +FormatData/ar_AE/arab.NumberElements/9=∞ +FormatData/ar_AE/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_BH/BHD=د.ب.‏ FormatData/ar_BH/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_BH/NumberPatterns/1='\u062f.\u0628.\u200f' #,##0.###;'\u062f.\u0628.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_BH/NumberPatterns/1='د.ب.‏' #,##0.###;'د.ب.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_BH/arab.NumberPatterns/2=#,##0% -FormatData/ar_BH/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_BH/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_BH/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_BH/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_BH/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_BH/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_BH/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_BH/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_BH/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_BH/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_BH/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_BH/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_BH/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_BH/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_BH/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_BH/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_BH/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_BH/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_BH/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_BH/DayNames/0=الأحد +FormatData/ar_BH/DayNames/1=الاثنين +FormatData/ar_BH/DayNames/2=الثلاثاء +FormatData/ar_BH/DayNames/3=الأربعاء +FormatData/ar_BH/DayNames/4=الخميس +FormatData/ar_BH/DayNames/5=الجمعة +FormatData/ar_BH/DayNames/6=السبت +FormatData/ar_BH/MonthAbbreviations/0=يناير +FormatData/ar_BH/MonthAbbreviations/1=فبراير +FormatData/ar_BH/MonthAbbreviations/2=مارس +FormatData/ar_BH/MonthAbbreviations/3=أبريل +FormatData/ar_BH/MonthAbbreviations/4=مايو +FormatData/ar_BH/MonthAbbreviations/5=يونيو +FormatData/ar_BH/MonthAbbreviations/6=يوليو +FormatData/ar_BH/MonthAbbreviations/7=أغسطس +FormatData/ar_BH/MonthAbbreviations/8=سبتمبر +FormatData/ar_BH/MonthAbbreviations/9=أكتوبر +FormatData/ar_BH/MonthAbbreviations/10=نوفمبر +FormatData/ar_BH/MonthAbbreviations/11=ديسمبر FormatData/ar_BH/MonthAbbreviations/12= -FormatData/ar_BH/Eras/0=\u0642.\u0645 -FormatData/ar_BH/Eras/1=\u0645 -FormatData/ar_BH/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_BH/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_BH/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_BH/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_BH/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_BH/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_BH/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_BH/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_BH/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_BH/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_BH/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_BH/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_BH/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_BH/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_BH/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_BH/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_BH/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_BH/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_BH/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_BH/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_BH/Eras/0=ق.م +FormatData/ar_BH/Eras/1=م +FormatData/ar_BH/DayAbbreviations/0=الأحد +FormatData/ar_BH/DayAbbreviations/1=الاثنين +FormatData/ar_BH/DayAbbreviations/2=الثلاثاء +FormatData/ar_BH/DayAbbreviations/3=الأربعاء +FormatData/ar_BH/DayAbbreviations/4=الخميس +FormatData/ar_BH/DayAbbreviations/5=الجمعة +FormatData/ar_BH/DayAbbreviations/6=السبت +LocaleNames/ar_BH/ar=العربية +FormatData/ar_BH/MonthNames/0=يناير +FormatData/ar_BH/MonthNames/1=فبراير +FormatData/ar_BH/MonthNames/2=مارس +FormatData/ar_BH/MonthNames/3=أبريل +FormatData/ar_BH/MonthNames/4=مايو +FormatData/ar_BH/MonthNames/5=يونيو +FormatData/ar_BH/MonthNames/6=يوليو +FormatData/ar_BH/MonthNames/7=أغسطس +FormatData/ar_BH/MonthNames/8=سبتمبر +FormatData/ar_BH/MonthNames/9=أكتوبر +FormatData/ar_BH/MonthNames/10=نوفمبر +FormatData/ar_BH/MonthNames/11=ديسمبر FormatData/ar_BH/MonthNames/12= -FormatData/ar_BH/AmPmMarkers/0=\u0635 -FormatData/ar_BH/AmPmMarkers/1=\u0645 +FormatData/ar_BH/AmPmMarkers/0=ص +FormatData/ar_BH/AmPmMarkers/1=م FormatData/ar_BH/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_BH/TimePatterns/1=h:mm:ss a z FormatData/ar_BH/TimePatterns/2=h:mm:ss a FormatData/ar_BH/TimePatterns/3=h:mm a -FormatData/ar_BH/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_BH/DatePatterns/0=EEEE، d MMMM y FormatData/ar_BH/DatePatterns/1=d MMMM y -FormatData/ar_BH/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_BH/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_BH/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_BH/EG=\u0645\u0635\u0631 -LocaleNames/ar_BH/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_BH/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_BH/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_BH/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_BH/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_BH/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_BH/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_BH/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_BH/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_BH/QA=\u0642\u0637\u0631 -LocaleNames/ar_BH/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_BH/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_BH/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_BH/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_BH/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_BH/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_BH/arab.NumberElements/0=\u066b -FormatData/ar_BH/arab.NumberElements/1=\u066c -FormatData/ar_BH/arab.NumberElements/2=\u061b -FormatData/ar_BH/arab.NumberElements/3=\u066a\u061c -FormatData/ar_BH/arab.NumberElements/4=\u0660 +FormatData/ar_BH/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_BH/DatePatterns/3=d‏/M‏/y +FormatData/ar_BH/DateTimePatterns/0={1}، {0} +LocaleNames/ar_BH/EG=مصر +LocaleNames/ar_BH/DZ=الجزائر +LocaleNames/ar_BH/BH=البحرين +LocaleNames/ar_BH/IQ=العراق +LocaleNames/ar_BH/JO=الأردن +LocaleNames/ar_BH/KW=الكويت +LocaleNames/ar_BH/LB=لبنان +LocaleNames/ar_BH/LY=ليبيا +LocaleNames/ar_BH/MA=المغرب +LocaleNames/ar_BH/OM=عُمان +LocaleNames/ar_BH/QA=قطر +LocaleNames/ar_BH/SA=المملكة العربية السعودية +LocaleNames/ar_BH/SD=السودان +LocaleNames/ar_BH/SY=سوريا +LocaleNames/ar_BH/TN=تونس +LocaleNames/ar_BH/AE=الإمارات العربية المتحدة +LocaleNames/ar_BH/YE=اليمن +FormatData/ar_BH/arab.NumberElements/0=٫ +FormatData/ar_BH/arab.NumberElements/1=٬ +FormatData/ar_BH/arab.NumberElements/2=؛ +FormatData/ar_BH/arab.NumberElements/3=٪؜ +FormatData/ar_BH/arab.NumberElements/4=٠ FormatData/ar_BH/arab.NumberElements/5=# -FormatData/ar_BH/arab.NumberElements/6=\u061c- -FormatData/ar_BH/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_BH/arab.NumberElements/8=\u0609 -FormatData/ar_BH/arab.NumberElements/9=\u221e -FormatData/ar_BH/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_DZ/DZD=\u062f.\u062c.\u200f +FormatData/ar_BH/arab.NumberElements/6=؜- +FormatData/ar_BH/arab.NumberElements/7=أس +FormatData/ar_BH/arab.NumberElements/8=؉ +FormatData/ar_BH/arab.NumberElements/9=∞ +FormatData/ar_BH/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_DZ/DZD=د.ج.‏ FormatData/ar_DZ/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_DZ/NumberPatterns/1='\u062f.\u062c.\u200f' #,##0.###;'\u062f.\u062c.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_DZ/NumberPatterns/1='د.ج.‏' #,##0.###;'د.ج.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_DZ/arab.NumberPatterns/2=#,##0% -FormatData/ar_DZ/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_DZ/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_DZ/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_DZ/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_DZ/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_DZ/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_DZ/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_DZ/MonthAbbreviations/0=\u062c\u0627\u0646\u0641\u064a -FormatData/ar_DZ/MonthAbbreviations/1=\u0641\u064a\u0641\u0631\u064a -FormatData/ar_DZ/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_DZ/MonthAbbreviations/3=\u0623\u0641\u0631\u064a\u0644 -FormatData/ar_DZ/MonthAbbreviations/4=\u0645\u0627\u064a -FormatData/ar_DZ/MonthAbbreviations/5=\u062c\u0648\u0627\u0646 -FormatData/ar_DZ/MonthAbbreviations/6=\u062c\u0648\u064a\u0644\u064a\u0629 -FormatData/ar_DZ/MonthAbbreviations/7=\u0623\u0648\u062a -FormatData/ar_DZ/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_DZ/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_DZ/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_DZ/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_DZ/DayNames/0=الأحد +FormatData/ar_DZ/DayNames/1=الاثنين +FormatData/ar_DZ/DayNames/2=الثلاثاء +FormatData/ar_DZ/DayNames/3=الأربعاء +FormatData/ar_DZ/DayNames/4=الخميس +FormatData/ar_DZ/DayNames/5=الجمعة +FormatData/ar_DZ/DayNames/6=السبت +FormatData/ar_DZ/MonthAbbreviations/0=جانفي +FormatData/ar_DZ/MonthAbbreviations/1=فيفري +FormatData/ar_DZ/MonthAbbreviations/2=مارس +FormatData/ar_DZ/MonthAbbreviations/3=أفريل +FormatData/ar_DZ/MonthAbbreviations/4=ماي +FormatData/ar_DZ/MonthAbbreviations/5=جوان +FormatData/ar_DZ/MonthAbbreviations/6=جويلية +FormatData/ar_DZ/MonthAbbreviations/7=أوت +FormatData/ar_DZ/MonthAbbreviations/8=سبتمبر +FormatData/ar_DZ/MonthAbbreviations/9=أكتوبر +FormatData/ar_DZ/MonthAbbreviations/10=نوفمبر +FormatData/ar_DZ/MonthAbbreviations/11=ديسمبر FormatData/ar_DZ/MonthAbbreviations/12= -FormatData/ar_DZ/Eras/0=\u0642.\u0645 -FormatData/ar_DZ/Eras/1=\u0645 -FormatData/ar_DZ/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_DZ/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_DZ/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_DZ/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_DZ/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_DZ/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_DZ/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_DZ/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_DZ/MonthNames/0=\u062c\u0627\u0646\u0641\u064a -FormatData/ar_DZ/MonthNames/1=\u0641\u064a\u0641\u0631\u064a -FormatData/ar_DZ/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_DZ/MonthNames/3=\u0623\u0641\u0631\u064a\u0644 -FormatData/ar_DZ/MonthNames/4=\u0645\u0627\u064a -FormatData/ar_DZ/MonthNames/5=\u062c\u0648\u0627\u0646 -FormatData/ar_DZ/MonthNames/6=\u062c\u0648\u064a\u0644\u064a\u0629 -FormatData/ar_DZ/MonthNames/7=\u0623\u0648\u062a -FormatData/ar_DZ/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_DZ/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_DZ/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_DZ/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_DZ/Eras/0=ق.م +FormatData/ar_DZ/Eras/1=م +FormatData/ar_DZ/DayAbbreviations/0=الأحد +FormatData/ar_DZ/DayAbbreviations/1=الاثنين +FormatData/ar_DZ/DayAbbreviations/2=الثلاثاء +FormatData/ar_DZ/DayAbbreviations/3=الأربعاء +FormatData/ar_DZ/DayAbbreviations/4=الخميس +FormatData/ar_DZ/DayAbbreviations/5=الجمعة +FormatData/ar_DZ/DayAbbreviations/6=السبت +LocaleNames/ar_DZ/ar=العربية +FormatData/ar_DZ/MonthNames/0=جانفي +FormatData/ar_DZ/MonthNames/1=فيفري +FormatData/ar_DZ/MonthNames/2=مارس +FormatData/ar_DZ/MonthNames/3=أفريل +FormatData/ar_DZ/MonthNames/4=ماي +FormatData/ar_DZ/MonthNames/5=جوان +FormatData/ar_DZ/MonthNames/6=جويلية +FormatData/ar_DZ/MonthNames/7=أوت +FormatData/ar_DZ/MonthNames/8=سبتمبر +FormatData/ar_DZ/MonthNames/9=أكتوبر +FormatData/ar_DZ/MonthNames/10=نوفمبر +FormatData/ar_DZ/MonthNames/11=ديسمبر FormatData/ar_DZ/MonthNames/12= -FormatData/ar_DZ/AmPmMarkers/0=\u0635 -FormatData/ar_DZ/AmPmMarkers/1=\u0645 +FormatData/ar_DZ/AmPmMarkers/0=ص +FormatData/ar_DZ/AmPmMarkers/1=م FormatData/ar_DZ/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_DZ/TimePatterns/1=h:mm:ss a z FormatData/ar_DZ/TimePatterns/2=h:mm:ss a FormatData/ar_DZ/TimePatterns/3=h:mm a -FormatData/ar_DZ/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_DZ/DatePatterns/0=EEEE، d MMMM y FormatData/ar_DZ/DatePatterns/1=d MMMM y -FormatData/ar_DZ/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_DZ/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_DZ/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_DZ/EG=\u0645\u0635\u0631 -LocaleNames/ar_DZ/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_DZ/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_DZ/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_DZ/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_DZ/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_DZ/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_DZ/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_DZ/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_DZ/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_DZ/QA=\u0642\u0637\u0631 -LocaleNames/ar_DZ/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_DZ/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_DZ/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_DZ/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_DZ/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_DZ/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_DZ/arab.NumberElements/0=\u066b -FormatData/ar_DZ/arab.NumberElements/1=\u066c -FormatData/ar_DZ/arab.NumberElements/2=\u061b -FormatData/ar_DZ/arab.NumberElements/3=\u066a\u061c -FormatData/ar_DZ/arab.NumberElements/4=\u0660 +FormatData/ar_DZ/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_DZ/DatePatterns/3=d‏/M‏/y +FormatData/ar_DZ/DateTimePatterns/0={1}، {0} +LocaleNames/ar_DZ/EG=مصر +LocaleNames/ar_DZ/DZ=الجزائر +LocaleNames/ar_DZ/BH=البحرين +LocaleNames/ar_DZ/IQ=العراق +LocaleNames/ar_DZ/JO=الأردن +LocaleNames/ar_DZ/KW=الكويت +LocaleNames/ar_DZ/LB=لبنان +LocaleNames/ar_DZ/LY=ليبيا +LocaleNames/ar_DZ/MA=المغرب +LocaleNames/ar_DZ/OM=عُمان +LocaleNames/ar_DZ/QA=قطر +LocaleNames/ar_DZ/SA=المملكة العربية السعودية +LocaleNames/ar_DZ/SD=السودان +LocaleNames/ar_DZ/SY=سوريا +LocaleNames/ar_DZ/TN=تونس +LocaleNames/ar_DZ/AE=الإمارات العربية المتحدة +LocaleNames/ar_DZ/YE=اليمن +FormatData/ar_DZ/arab.NumberElements/0=٫ +FormatData/ar_DZ/arab.NumberElements/1=٬ +FormatData/ar_DZ/arab.NumberElements/2=؛ +FormatData/ar_DZ/arab.NumberElements/3=٪؜ +FormatData/ar_DZ/arab.NumberElements/4=٠ FormatData/ar_DZ/arab.NumberElements/5=# -FormatData/ar_DZ/arab.NumberElements/6=\u061c- -FormatData/ar_DZ/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_DZ/arab.NumberElements/8=\u0609 -FormatData/ar_DZ/arab.NumberElements/9=\u221e -FormatData/ar_DZ/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_EG/EGP=\u062c.\u0645.\u200f +FormatData/ar_DZ/arab.NumberElements/6=؜- +FormatData/ar_DZ/arab.NumberElements/7=أس +FormatData/ar_DZ/arab.NumberElements/8=؉ +FormatData/ar_DZ/arab.NumberElements/9=∞ +FormatData/ar_DZ/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_EG/EGP=ج.م.‏ FormatData/ar_EG/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_EG/NumberPatterns/1='\u062c.\u0645.\u200f' #,##0.###;'\u062c.\u0645.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_EG/NumberPatterns/1='ج.م.‏' #,##0.###;'ج.م.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_EG/arab.NumberPatterns/2=#,##0% -FormatData/ar_EG/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_EG/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_EG/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_EG/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_EG/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_EG/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_EG/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_EG/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_EG/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_EG/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_EG/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_EG/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_EG/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_EG/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_EG/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_EG/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_EG/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_EG/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_EG/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_EG/DayNames/0=الأحد +FormatData/ar_EG/DayNames/1=الاثنين +FormatData/ar_EG/DayNames/2=الثلاثاء +FormatData/ar_EG/DayNames/3=الأربعاء +FormatData/ar_EG/DayNames/4=الخميس +FormatData/ar_EG/DayNames/5=الجمعة +FormatData/ar_EG/DayNames/6=السبت +FormatData/ar_EG/MonthAbbreviations/0=يناير +FormatData/ar_EG/MonthAbbreviations/1=فبراير +FormatData/ar_EG/MonthAbbreviations/2=مارس +FormatData/ar_EG/MonthAbbreviations/3=أبريل +FormatData/ar_EG/MonthAbbreviations/4=مايو +FormatData/ar_EG/MonthAbbreviations/5=يونيو +FormatData/ar_EG/MonthAbbreviations/6=يوليو +FormatData/ar_EG/MonthAbbreviations/7=أغسطس +FormatData/ar_EG/MonthAbbreviations/8=سبتمبر +FormatData/ar_EG/MonthAbbreviations/9=أكتوبر +FormatData/ar_EG/MonthAbbreviations/10=نوفمبر +FormatData/ar_EG/MonthAbbreviations/11=ديسمبر FormatData/ar_EG/MonthAbbreviations/12= -FormatData/ar_EG/Eras/0=\u0642.\u0645 -FormatData/ar_EG/Eras/1=\u0645 -FormatData/ar_EG/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_EG/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_EG/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_EG/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_EG/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_EG/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_EG/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_EG/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_EG/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_EG/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_EG/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_EG/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_EG/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_EG/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_EG/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_EG/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_EG/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_EG/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_EG/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_EG/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_EG/Eras/0=ق.م +FormatData/ar_EG/Eras/1=م +FormatData/ar_EG/DayAbbreviations/0=الأحد +FormatData/ar_EG/DayAbbreviations/1=الاثنين +FormatData/ar_EG/DayAbbreviations/2=الثلاثاء +FormatData/ar_EG/DayAbbreviations/3=الأربعاء +FormatData/ar_EG/DayAbbreviations/4=الخميس +FormatData/ar_EG/DayAbbreviations/5=الجمعة +FormatData/ar_EG/DayAbbreviations/6=السبت +LocaleNames/ar_EG/ar=العربية +FormatData/ar_EG/MonthNames/0=يناير +FormatData/ar_EG/MonthNames/1=فبراير +FormatData/ar_EG/MonthNames/2=مارس +FormatData/ar_EG/MonthNames/3=أبريل +FormatData/ar_EG/MonthNames/4=مايو +FormatData/ar_EG/MonthNames/5=يونيو +FormatData/ar_EG/MonthNames/6=يوليو +FormatData/ar_EG/MonthNames/7=أغسطس +FormatData/ar_EG/MonthNames/8=سبتمبر +FormatData/ar_EG/MonthNames/9=أكتوبر +FormatData/ar_EG/MonthNames/10=نوفمبر +FormatData/ar_EG/MonthNames/11=ديسمبر FormatData/ar_EG/MonthNames/12= -FormatData/ar_EG/AmPmMarkers/0=\u0635 -FormatData/ar_EG/AmPmMarkers/1=\u0645 +FormatData/ar_EG/AmPmMarkers/0=ص +FormatData/ar_EG/AmPmMarkers/1=م FormatData/ar_EG/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_EG/TimePatterns/1=h:mm:ss a z FormatData/ar_EG/TimePatterns/2=h:mm:ss a FormatData/ar_EG/TimePatterns/3=h:mm a -FormatData/ar_EG/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_EG/DatePatterns/0=EEEE، d MMMM y FormatData/ar_EG/DatePatterns/1=d MMMM y -FormatData/ar_EG/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_EG/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_EG/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_EG/EG=\u0645\u0635\u0631 -LocaleNames/ar_EG/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_EG/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_EG/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_EG/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_EG/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_EG/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_EG/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_EG/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_EG/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_EG/QA=\u0642\u0637\u0631 -LocaleNames/ar_EG/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_EG/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_EG/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_EG/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_EG/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_EG/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_EG/arab.NumberElements/0=\u066b -FormatData/ar_EG/arab.NumberElements/1=\u066c -FormatData/ar_EG/arab.NumberElements/2=\u061b -FormatData/ar_EG/arab.NumberElements/3=\u066a\u061c -FormatData/ar_EG/arab.NumberElements/4=\u0660 +FormatData/ar_EG/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_EG/DatePatterns/3=d‏/M‏/y +FormatData/ar_EG/DateTimePatterns/0={1}، {0} +LocaleNames/ar_EG/EG=مصر +LocaleNames/ar_EG/DZ=الجزائر +LocaleNames/ar_EG/BH=البحرين +LocaleNames/ar_EG/IQ=العراق +LocaleNames/ar_EG/JO=الأردن +LocaleNames/ar_EG/KW=الكويت +LocaleNames/ar_EG/LB=لبنان +LocaleNames/ar_EG/LY=ليبيا +LocaleNames/ar_EG/MA=المغرب +LocaleNames/ar_EG/OM=عُمان +LocaleNames/ar_EG/QA=قطر +LocaleNames/ar_EG/SA=المملكة العربية السعودية +LocaleNames/ar_EG/SD=السودان +LocaleNames/ar_EG/SY=سوريا +LocaleNames/ar_EG/TN=تونس +LocaleNames/ar_EG/AE=الإمارات العربية المتحدة +LocaleNames/ar_EG/YE=اليمن +FormatData/ar_EG/arab.NumberElements/0=٫ +FormatData/ar_EG/arab.NumberElements/1=٬ +FormatData/ar_EG/arab.NumberElements/2=؛ +FormatData/ar_EG/arab.NumberElements/3=٪؜ +FormatData/ar_EG/arab.NumberElements/4=٠ FormatData/ar_EG/arab.NumberElements/5=# -FormatData/ar_EG/arab.NumberElements/6=\u061c- -FormatData/ar_EG/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_EG/arab.NumberElements/8=\u0609 -FormatData/ar_EG/arab.NumberElements/9=\u221e -FormatData/ar_EG/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_IQ/IQD=\u062f.\u0639.\u200f +FormatData/ar_EG/arab.NumberElements/6=؜- +FormatData/ar_EG/arab.NumberElements/7=أس +FormatData/ar_EG/arab.NumberElements/8=؉ +FormatData/ar_EG/arab.NumberElements/9=∞ +FormatData/ar_EG/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_IQ/IQD=د.ع.‏ FormatData/ar_IQ/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_IQ/NumberPatterns/1='\u062f.\u0639.\u200f' #,##0.###;'\u062f.\u0639.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_IQ/NumberPatterns/1='د.ع.‏' #,##0.###;'د.ع.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_IQ/arab.NumberPatterns/2=#,##0% -FormatData/ar_IQ/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_IQ/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_IQ/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_IQ/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_IQ/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_IQ/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_IQ/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_IQ/MonthAbbreviations/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_IQ/MonthAbbreviations/1=\u0634\u0628\u0627\u0637 -FormatData/ar_IQ/MonthAbbreviations/2=\u0622\u0630\u0627\u0631 -FormatData/ar_IQ/MonthAbbreviations/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_IQ/MonthAbbreviations/4=\u0623\u064a\u0627\u0631 -FormatData/ar_IQ/MonthAbbreviations/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_IQ/MonthAbbreviations/6=\u062a\u0645\u0648\u0632 -FormatData/ar_IQ/MonthAbbreviations/7=\u0622\u0628 -FormatData/ar_IQ/MonthAbbreviations/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_IQ/MonthAbbreviations/9=\u062a\u0634\u0631\u064a\u0646\u00a0\u0627\u0644\u0623\u0648\u0644 -FormatData/ar_IQ/MonthAbbreviations/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_IQ/MonthAbbreviations/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +FormatData/ar_IQ/DayNames/0=الأحد +FormatData/ar_IQ/DayNames/1=الاثنين +FormatData/ar_IQ/DayNames/2=الثلاثاء +FormatData/ar_IQ/DayNames/3=الأربعاء +FormatData/ar_IQ/DayNames/4=الخميس +FormatData/ar_IQ/DayNames/5=الجمعة +FormatData/ar_IQ/DayNames/6=السبت +FormatData/ar_IQ/MonthAbbreviations/0=كانون الثاني +FormatData/ar_IQ/MonthAbbreviations/1=شباط +FormatData/ar_IQ/MonthAbbreviations/2=آذار +FormatData/ar_IQ/MonthAbbreviations/3=نيسان +FormatData/ar_IQ/MonthAbbreviations/4=أيار +FormatData/ar_IQ/MonthAbbreviations/5=حزيران +FormatData/ar_IQ/MonthAbbreviations/6=تموز +FormatData/ar_IQ/MonthAbbreviations/7=آب +FormatData/ar_IQ/MonthAbbreviations/8=أيلول +FormatData/ar_IQ/MonthAbbreviations/9=تشرين الأول +FormatData/ar_IQ/MonthAbbreviations/10=تشرين الثاني +FormatData/ar_IQ/MonthAbbreviations/11=كانون الأول FormatData/ar_IQ/MonthAbbreviations/12= -FormatData/ar_IQ/Eras/0=\u0642.\u0645 -FormatData/ar_IQ/Eras/1=\u0645 -FormatData/ar_IQ/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_IQ/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_IQ/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_IQ/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_IQ/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_IQ/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_IQ/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_IQ/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_IQ/MonthNames/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_IQ/MonthNames/1=\u0634\u0628\u0627\u0637 -FormatData/ar_IQ/MonthNames/2=\u0622\u0630\u0627\u0631 -FormatData/ar_IQ/MonthNames/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_IQ/MonthNames/4=\u0623\u064a\u0627\u0631 -FormatData/ar_IQ/MonthNames/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_IQ/MonthNames/6=\u062a\u0645\u0648\u0632 -FormatData/ar_IQ/MonthNames/7=\u0622\u0628 -FormatData/ar_IQ/MonthNames/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_IQ/MonthNames/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_IQ/MonthNames/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_IQ/MonthNames/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +FormatData/ar_IQ/Eras/0=ق.م +FormatData/ar_IQ/Eras/1=م +FormatData/ar_IQ/DayAbbreviations/0=الأحد +FormatData/ar_IQ/DayAbbreviations/1=الاثنين +FormatData/ar_IQ/DayAbbreviations/2=الثلاثاء +FormatData/ar_IQ/DayAbbreviations/3=الأربعاء +FormatData/ar_IQ/DayAbbreviations/4=الخميس +FormatData/ar_IQ/DayAbbreviations/5=الجمعة +FormatData/ar_IQ/DayAbbreviations/6=السبت +LocaleNames/ar_IQ/ar=العربية +FormatData/ar_IQ/MonthNames/0=كانون الثاني +FormatData/ar_IQ/MonthNames/1=شباط +FormatData/ar_IQ/MonthNames/2=آذار +FormatData/ar_IQ/MonthNames/3=نيسان +FormatData/ar_IQ/MonthNames/4=أيار +FormatData/ar_IQ/MonthNames/5=حزيران +FormatData/ar_IQ/MonthNames/6=تموز +FormatData/ar_IQ/MonthNames/7=آب +FormatData/ar_IQ/MonthNames/8=أيلول +FormatData/ar_IQ/MonthNames/9=تشرين الأول +FormatData/ar_IQ/MonthNames/10=تشرين الثاني +FormatData/ar_IQ/MonthNames/11=كانون الأول FormatData/ar_IQ/MonthNames/12= -FormatData/ar_IQ/AmPmMarkers/0=\u0635 -FormatData/ar_IQ/AmPmMarkers/1=\u0645 +FormatData/ar_IQ/AmPmMarkers/0=ص +FormatData/ar_IQ/AmPmMarkers/1=م FormatData/ar_IQ/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_IQ/TimePatterns/1=h:mm:ss a z FormatData/ar_IQ/TimePatterns/2=h:mm:ss a FormatData/ar_IQ/TimePatterns/3=h:mm a -FormatData/ar_IQ/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_IQ/DatePatterns/0=EEEE، d MMMM y FormatData/ar_IQ/DatePatterns/1=d MMMM y -FormatData/ar_IQ/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_IQ/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_IQ/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_IQ/EG=\u0645\u0635\u0631 -LocaleNames/ar_IQ/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_IQ/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_IQ/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_IQ/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_IQ/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_IQ/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_IQ/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_IQ/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_IQ/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_IQ/QA=\u0642\u0637\u0631 -LocaleNames/ar_IQ/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_IQ/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_IQ/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_IQ/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_IQ/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_IQ/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_IQ/arab.NumberElements/0=\u066b -FormatData/ar_IQ/arab.NumberElements/1=\u066c -FormatData/ar_IQ/arab.NumberElements/2=\u061b -FormatData/ar_IQ/arab.NumberElements/3=\u066a\u061c -FormatData/ar_IQ/arab.NumberElements/4=\u0660 +FormatData/ar_IQ/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_IQ/DatePatterns/3=d‏/M‏/y +FormatData/ar_IQ/DateTimePatterns/0={1}، {0} +LocaleNames/ar_IQ/EG=مصر +LocaleNames/ar_IQ/DZ=الجزائر +LocaleNames/ar_IQ/BH=البحرين +LocaleNames/ar_IQ/IQ=العراق +LocaleNames/ar_IQ/JO=الأردن +LocaleNames/ar_IQ/KW=الكويت +LocaleNames/ar_IQ/LB=لبنان +LocaleNames/ar_IQ/LY=ليبيا +LocaleNames/ar_IQ/MA=المغرب +LocaleNames/ar_IQ/OM=عُمان +LocaleNames/ar_IQ/QA=قطر +LocaleNames/ar_IQ/SA=المملكة العربية السعودية +LocaleNames/ar_IQ/SD=السودان +LocaleNames/ar_IQ/SY=سوريا +LocaleNames/ar_IQ/TN=تونس +LocaleNames/ar_IQ/AE=الإمارات العربية المتحدة +LocaleNames/ar_IQ/YE=اليمن +FormatData/ar_IQ/arab.NumberElements/0=٫ +FormatData/ar_IQ/arab.NumberElements/1=٬ +FormatData/ar_IQ/arab.NumberElements/2=؛ +FormatData/ar_IQ/arab.NumberElements/3=٪؜ +FormatData/ar_IQ/arab.NumberElements/4=٠ FormatData/ar_IQ/arab.NumberElements/5=# -FormatData/ar_IQ/arab.NumberElements/6=\u061c- -FormatData/ar_IQ/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_IQ/arab.NumberElements/8=\u0609 -FormatData/ar_IQ/arab.NumberElements/9=\u221e -FormatData/ar_IQ/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 +FormatData/ar_IQ/arab.NumberElements/6=؜- +FormatData/ar_IQ/arab.NumberElements/7=أس +FormatData/ar_IQ/arab.NumberElements/8=؉ +FormatData/ar_IQ/arab.NumberElements/9=∞ +FormatData/ar_IQ/arab.NumberElements/10=ليس رقمًا FormatData/ar_JO/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_JO/NumberPatterns/1='\u062f.\u0623.\u200f' #,##0.###;'\u062f.\u0623.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_JO/NumberPatterns/1='د.أ.‏' #,##0.###;'د.أ.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_JO/arab.NumberPatterns/2=#,##0% -CurrencyNames/ar_JO/JOD=\u062f.\u0623.\u200f -FormatData/ar_JO/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_JO/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_JO/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_JO/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_JO/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_JO/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_JO/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_JO/MonthNames/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_JO/MonthNames/1=\u0634\u0628\u0627\u0637 -FormatData/ar_JO/MonthNames/2=\u0622\u0630\u0627\u0631 -FormatData/ar_JO/MonthNames/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_JO/MonthNames/4=\u0623\u064a\u0627\u0631 -FormatData/ar_JO/MonthNames/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_JO/MonthNames/6=\u062a\u0645\u0648\u0632 -FormatData/ar_JO/MonthNames/7=\u0622\u0628 -FormatData/ar_JO/MonthNames/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_JO/MonthNames/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_JO/MonthNames/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_JO/MonthNames/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +CurrencyNames/ar_JO/JOD=د.أ.‏ +FormatData/ar_JO/DayAbbreviations/0=الأحد +FormatData/ar_JO/DayAbbreviations/1=الاثنين +FormatData/ar_JO/DayAbbreviations/2=الثلاثاء +FormatData/ar_JO/DayAbbreviations/3=الأربعاء +FormatData/ar_JO/DayAbbreviations/4=الخميس +FormatData/ar_JO/DayAbbreviations/5=الجمعة +FormatData/ar_JO/DayAbbreviations/6=السبت +FormatData/ar_JO/MonthNames/0=كانون الثاني +FormatData/ar_JO/MonthNames/1=شباط +FormatData/ar_JO/MonthNames/2=آذار +FormatData/ar_JO/MonthNames/3=نيسان +FormatData/ar_JO/MonthNames/4=أيار +FormatData/ar_JO/MonthNames/5=حزيران +FormatData/ar_JO/MonthNames/6=تموز +FormatData/ar_JO/MonthNames/7=آب +FormatData/ar_JO/MonthNames/8=أيلول +FormatData/ar_JO/MonthNames/9=تشرين الأول +FormatData/ar_JO/MonthNames/10=تشرين الثاني +FormatData/ar_JO/MonthNames/11=كانون الأول FormatData/ar_JO/MonthNames/12= -FormatData/ar_JO/MonthAbbreviations/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_JO/MonthAbbreviations/1=\u0634\u0628\u0627\u0637 -FormatData/ar_JO/MonthAbbreviations/2=\u0622\u0630\u0627\u0631 -FormatData/ar_JO/MonthAbbreviations/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_JO/MonthAbbreviations/4=\u0623\u064a\u0627\u0631 -FormatData/ar_JO/MonthAbbreviations/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_JO/MonthAbbreviations/6=\u062a\u0645\u0648\u0632 -FormatData/ar_JO/MonthAbbreviations/7=\u0622\u0628 -FormatData/ar_JO/MonthAbbreviations/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_JO/MonthAbbreviations/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_JO/MonthAbbreviations/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_JO/MonthAbbreviations/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +FormatData/ar_JO/MonthAbbreviations/0=كانون الثاني +FormatData/ar_JO/MonthAbbreviations/1=شباط +FormatData/ar_JO/MonthAbbreviations/2=آذار +FormatData/ar_JO/MonthAbbreviations/3=نيسان +FormatData/ar_JO/MonthAbbreviations/4=أيار +FormatData/ar_JO/MonthAbbreviations/5=حزيران +FormatData/ar_JO/MonthAbbreviations/6=تموز +FormatData/ar_JO/MonthAbbreviations/7=آب +FormatData/ar_JO/MonthAbbreviations/8=أيلول +FormatData/ar_JO/MonthAbbreviations/9=تشرين الأول +FormatData/ar_JO/MonthAbbreviations/10=تشرين الثاني +FormatData/ar_JO/MonthAbbreviations/11=كانون الأول FormatData/ar_JO/MonthAbbreviations/12= -FormatData/ar_JO/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_JO/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_JO/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_JO/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_JO/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_JO/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_JO/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_JO/Eras/0=\u0642.\u0645 -FormatData/ar_JO/Eras/1=\u0645 -LocaleNames/ar_JO/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_JO/AmPmMarkers/0=\u0635 -FormatData/ar_JO/AmPmMarkers/1=\u0645 +FormatData/ar_JO/DayNames/0=الأحد +FormatData/ar_JO/DayNames/1=الاثنين +FormatData/ar_JO/DayNames/2=الثلاثاء +FormatData/ar_JO/DayNames/3=الأربعاء +FormatData/ar_JO/DayNames/4=الخميس +FormatData/ar_JO/DayNames/5=الجمعة +FormatData/ar_JO/DayNames/6=السبت +FormatData/ar_JO/Eras/0=ق.م +FormatData/ar_JO/Eras/1=م +LocaleNames/ar_JO/ar=العربية +FormatData/ar_JO/AmPmMarkers/0=ص +FormatData/ar_JO/AmPmMarkers/1=م FormatData/ar_JO/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_JO/TimePatterns/1=h:mm:ss a z FormatData/ar_JO/TimePatterns/2=h:mm:ss a FormatData/ar_JO/TimePatterns/3=h:mm a -FormatData/ar_JO/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_JO/DatePatterns/0=EEEE، d MMMM y FormatData/ar_JO/DatePatterns/1=d MMMM y -FormatData/ar_JO/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_JO/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_JO/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_JO/EG=\u0645\u0635\u0631 -LocaleNames/ar_JO/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_JO/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_JO/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_JO/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_JO/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_JO/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_JO/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_JO/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_JO/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_JO/QA=\u0642\u0637\u0631 -LocaleNames/ar_JO/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_JO/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_JO/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_JO/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_JO/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_JO/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_JO/arab.NumberElements/0=\u066b -FormatData/ar_JO/arab.NumberElements/1=\u066c -FormatData/ar_JO/arab.NumberElements/2=\u061b -FormatData/ar_JO/arab.NumberElements/3=\u066a\u061c -FormatData/ar_JO/arab.NumberElements/4=\u0660 +FormatData/ar_JO/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_JO/DatePatterns/3=d‏/M‏/y +FormatData/ar_JO/DateTimePatterns/0={1}، {0} +LocaleNames/ar_JO/EG=مصر +LocaleNames/ar_JO/DZ=الجزائر +LocaleNames/ar_JO/BH=البحرين +LocaleNames/ar_JO/IQ=العراق +LocaleNames/ar_JO/JO=الأردن +LocaleNames/ar_JO/KW=الكويت +LocaleNames/ar_JO/LB=لبنان +LocaleNames/ar_JO/LY=ليبيا +LocaleNames/ar_JO/MA=المغرب +LocaleNames/ar_JO/OM=عُمان +LocaleNames/ar_JO/QA=قطر +LocaleNames/ar_JO/SA=المملكة العربية السعودية +LocaleNames/ar_JO/SD=السودان +LocaleNames/ar_JO/SY=سوريا +LocaleNames/ar_JO/TN=تونس +LocaleNames/ar_JO/AE=الإمارات العربية المتحدة +LocaleNames/ar_JO/YE=اليمن +FormatData/ar_JO/arab.NumberElements/0=٫ +FormatData/ar_JO/arab.NumberElements/1=٬ +FormatData/ar_JO/arab.NumberElements/2=؛ +FormatData/ar_JO/arab.NumberElements/3=٪؜ +FormatData/ar_JO/arab.NumberElements/4=٠ FormatData/ar_JO/arab.NumberElements/5=# -FormatData/ar_JO/arab.NumberElements/6=\u061c- -FormatData/ar_JO/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_JO/arab.NumberElements/8=\u0609 -FormatData/ar_JO/arab.NumberElements/9=\u221e -FormatData/ar_JO/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_KW/KWD=\u062f.\u0643.\u200f +FormatData/ar_JO/arab.NumberElements/6=؜- +FormatData/ar_JO/arab.NumberElements/7=أس +FormatData/ar_JO/arab.NumberElements/8=؉ +FormatData/ar_JO/arab.NumberElements/9=∞ +FormatData/ar_JO/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_KW/KWD=د.ك.‏ FormatData/ar_KW/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_KW/NumberPatterns/1='\u062f.\u0643.\u200f' #,##0.###;'\u062f.\u0643.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_KW/NumberPatterns/1='د.ك.‏' #,##0.###;'د.ك.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_KW/arab.NumberPatterns/2=#,##0% -FormatData/ar_KW/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_KW/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_KW/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_KW/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_KW/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_KW/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_KW/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_KW/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_KW/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_KW/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_KW/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_KW/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_KW/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_KW/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_KW/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_KW/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_KW/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_KW/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_KW/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_KW/DayNames/0=الأحد +FormatData/ar_KW/DayNames/1=الاثنين +FormatData/ar_KW/DayNames/2=الثلاثاء +FormatData/ar_KW/DayNames/3=الأربعاء +FormatData/ar_KW/DayNames/4=الخميس +FormatData/ar_KW/DayNames/5=الجمعة +FormatData/ar_KW/DayNames/6=السبت +FormatData/ar_KW/MonthAbbreviations/0=يناير +FormatData/ar_KW/MonthAbbreviations/1=فبراير +FormatData/ar_KW/MonthAbbreviations/2=مارس +FormatData/ar_KW/MonthAbbreviations/3=أبريل +FormatData/ar_KW/MonthAbbreviations/4=مايو +FormatData/ar_KW/MonthAbbreviations/5=يونيو +FormatData/ar_KW/MonthAbbreviations/6=يوليو +FormatData/ar_KW/MonthAbbreviations/7=أغسطس +FormatData/ar_KW/MonthAbbreviations/8=سبتمبر +FormatData/ar_KW/MonthAbbreviations/9=أكتوبر +FormatData/ar_KW/MonthAbbreviations/10=نوفمبر +FormatData/ar_KW/MonthAbbreviations/11=ديسمبر FormatData/ar_KW/MonthAbbreviations/12= -FormatData/ar_KW/Eras/0=\u0642.\u0645 -FormatData/ar_KW/Eras/1=\u0645 -FormatData/ar_KW/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_KW/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_KW/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_KW/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_KW/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_KW/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_KW/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_KW/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_KW/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_KW/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_KW/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_KW/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_KW/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_KW/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_KW/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_KW/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_KW/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_KW/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_KW/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_KW/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_KW/Eras/0=ق.م +FormatData/ar_KW/Eras/1=م +FormatData/ar_KW/DayAbbreviations/0=الأحد +FormatData/ar_KW/DayAbbreviations/1=الاثنين +FormatData/ar_KW/DayAbbreviations/2=الثلاثاء +FormatData/ar_KW/DayAbbreviations/3=الأربعاء +FormatData/ar_KW/DayAbbreviations/4=الخميس +FormatData/ar_KW/DayAbbreviations/5=الجمعة +FormatData/ar_KW/DayAbbreviations/6=السبت +LocaleNames/ar_KW/ar=العربية +FormatData/ar_KW/MonthNames/0=يناير +FormatData/ar_KW/MonthNames/1=فبراير +FormatData/ar_KW/MonthNames/2=مارس +FormatData/ar_KW/MonthNames/3=أبريل +FormatData/ar_KW/MonthNames/4=مايو +FormatData/ar_KW/MonthNames/5=يونيو +FormatData/ar_KW/MonthNames/6=يوليو +FormatData/ar_KW/MonthNames/7=أغسطس +FormatData/ar_KW/MonthNames/8=سبتمبر +FormatData/ar_KW/MonthNames/9=أكتوبر +FormatData/ar_KW/MonthNames/10=نوفمبر +FormatData/ar_KW/MonthNames/11=ديسمبر FormatData/ar_KW/MonthNames/12= -FormatData/ar_KW/AmPmMarkers/0=\u0635 -FormatData/ar_KW/AmPmMarkers/1=\u0645 +FormatData/ar_KW/AmPmMarkers/0=ص +FormatData/ar_KW/AmPmMarkers/1=م FormatData/ar_KW/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_KW/TimePatterns/1=h:mm:ss a z FormatData/ar_KW/TimePatterns/2=h:mm:ss a FormatData/ar_KW/TimePatterns/3=h:mm a -FormatData/ar_KW/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_KW/DatePatterns/0=EEEE، d MMMM y FormatData/ar_KW/DatePatterns/1=d MMMM y -FormatData/ar_KW/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_KW/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_KW/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_KW/EG=\u0645\u0635\u0631 -LocaleNames/ar_KW/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_KW/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_KW/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_KW/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_KW/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_KW/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_KW/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_KW/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_KW/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_KW/QA=\u0642\u0637\u0631 -LocaleNames/ar_KW/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_KW/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_KW/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_KW/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_KW/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_KW/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_KW/arab.NumberElements/0=\u066b -FormatData/ar_KW/arab.NumberElements/1=\u066c -FormatData/ar_KW/arab.NumberElements/2=\u061b -FormatData/ar_KW/arab.NumberElements/3=\u066a\u061c -FormatData/ar_KW/arab.NumberElements/4=\u0660 +FormatData/ar_KW/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_KW/DatePatterns/3=d‏/M‏/y +FormatData/ar_KW/DateTimePatterns/0={1}، {0} +LocaleNames/ar_KW/EG=مصر +LocaleNames/ar_KW/DZ=الجزائر +LocaleNames/ar_KW/BH=البحرين +LocaleNames/ar_KW/IQ=العراق +LocaleNames/ar_KW/JO=الأردن +LocaleNames/ar_KW/KW=الكويت +LocaleNames/ar_KW/LB=لبنان +LocaleNames/ar_KW/LY=ليبيا +LocaleNames/ar_KW/MA=المغرب +LocaleNames/ar_KW/OM=عُمان +LocaleNames/ar_KW/QA=قطر +LocaleNames/ar_KW/SA=المملكة العربية السعودية +LocaleNames/ar_KW/SD=السودان +LocaleNames/ar_KW/SY=سوريا +LocaleNames/ar_KW/TN=تونس +LocaleNames/ar_KW/AE=الإمارات العربية المتحدة +LocaleNames/ar_KW/YE=اليمن +FormatData/ar_KW/arab.NumberElements/0=٫ +FormatData/ar_KW/arab.NumberElements/1=٬ +FormatData/ar_KW/arab.NumberElements/2=؛ +FormatData/ar_KW/arab.NumberElements/3=٪؜ +FormatData/ar_KW/arab.NumberElements/4=٠ FormatData/ar_KW/arab.NumberElements/5=# -FormatData/ar_KW/arab.NumberElements/6=\u061c- -FormatData/ar_KW/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_KW/arab.NumberElements/8=\u0609 -FormatData/ar_KW/arab.NumberElements/9=\u221e -FormatData/ar_KW/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 +FormatData/ar_KW/arab.NumberElements/6=؜- +FormatData/ar_KW/arab.NumberElements/7=أس +FormatData/ar_KW/arab.NumberElements/8=؉ +FormatData/ar_KW/arab.NumberElements/9=∞ +FormatData/ar_KW/arab.NumberElements/10=ليس رقمًا FormatData/ar_LB/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_LB/NumberPatterns/1='\u0644.\u0644.\u200f' #,##0.###;'\u0644.\u0644.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_LB/NumberPatterns/1='ل.ل.‏' #,##0.###;'ل.ل.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_LB/arab.NumberPatterns/2=#,##0% -CurrencyNames/ar_LB/LBP=\u0644.\u0644.\u200f -FormatData/ar_LB/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_LB/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_LB/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_LB/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_LB/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_LB/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_LB/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_LB/MonthNames/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_LB/MonthNames/1=\u0634\u0628\u0627\u0637 -FormatData/ar_LB/MonthNames/2=\u0622\u0630\u0627\u0631 -FormatData/ar_LB/MonthNames/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_LB/MonthNames/4=\u0623\u064a\u0627\u0631 -FormatData/ar_LB/MonthNames/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_LB/MonthNames/6=\u062a\u0645\u0648\u0632 -FormatData/ar_LB/MonthNames/7=\u0622\u0628 -FormatData/ar_LB/MonthNames/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_LB/MonthNames/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_LB/MonthNames/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_LB/MonthNames/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +CurrencyNames/ar_LB/LBP=ل.ل.‏ +FormatData/ar_LB/DayAbbreviations/0=الأحد +FormatData/ar_LB/DayAbbreviations/1=الاثنين +FormatData/ar_LB/DayAbbreviations/2=الثلاثاء +FormatData/ar_LB/DayAbbreviations/3=الأربعاء +FormatData/ar_LB/DayAbbreviations/4=الخميس +FormatData/ar_LB/DayAbbreviations/5=الجمعة +FormatData/ar_LB/DayAbbreviations/6=السبت +FormatData/ar_LB/MonthNames/0=كانون الثاني +FormatData/ar_LB/MonthNames/1=شباط +FormatData/ar_LB/MonthNames/2=آذار +FormatData/ar_LB/MonthNames/3=نيسان +FormatData/ar_LB/MonthNames/4=أيار +FormatData/ar_LB/MonthNames/5=حزيران +FormatData/ar_LB/MonthNames/6=تموز +FormatData/ar_LB/MonthNames/7=آب +FormatData/ar_LB/MonthNames/8=أيلول +FormatData/ar_LB/MonthNames/9=تشرين الأول +FormatData/ar_LB/MonthNames/10=تشرين الثاني +FormatData/ar_LB/MonthNames/11=كانون الأول FormatData/ar_LB/MonthNames/12= -FormatData/ar_LB/MonthAbbreviations/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_LB/MonthAbbreviations/1=\u0634\u0628\u0627\u0637 -FormatData/ar_LB/MonthAbbreviations/2=\u0622\u0630\u0627\u0631 -FormatData/ar_LB/MonthAbbreviations/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_LB/MonthAbbreviations/4=\u0623\u064a\u0627\u0631 -FormatData/ar_LB/MonthAbbreviations/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_LB/MonthAbbreviations/6=\u062a\u0645\u0648\u0632 -FormatData/ar_LB/MonthAbbreviations/7=\u0622\u0628 -FormatData/ar_LB/MonthAbbreviations/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_LB/MonthAbbreviations/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_LB/MonthAbbreviations/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_LB/MonthAbbreviations/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +FormatData/ar_LB/MonthAbbreviations/0=كانون الثاني +FormatData/ar_LB/MonthAbbreviations/1=شباط +FormatData/ar_LB/MonthAbbreviations/2=آذار +FormatData/ar_LB/MonthAbbreviations/3=نيسان +FormatData/ar_LB/MonthAbbreviations/4=أيار +FormatData/ar_LB/MonthAbbreviations/5=حزيران +FormatData/ar_LB/MonthAbbreviations/6=تموز +FormatData/ar_LB/MonthAbbreviations/7=آب +FormatData/ar_LB/MonthAbbreviations/8=أيلول +FormatData/ar_LB/MonthAbbreviations/9=تشرين الأول +FormatData/ar_LB/MonthAbbreviations/10=تشرين الثاني +FormatData/ar_LB/MonthAbbreviations/11=كانون الأول FormatData/ar_LB/MonthAbbreviations/12= -FormatData/ar_LB/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_LB/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_LB/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_LB/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_LB/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_LB/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_LB/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_LB/Eras/0=\u0642.\u0645 -FormatData/ar_LB/Eras/1=\u0645 -LocaleNames/ar_LB/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_LB/AmPmMarkers/0=\u0635 -FormatData/ar_LB/AmPmMarkers/1=\u0645 +FormatData/ar_LB/DayNames/0=الأحد +FormatData/ar_LB/DayNames/1=الاثنين +FormatData/ar_LB/DayNames/2=الثلاثاء +FormatData/ar_LB/DayNames/3=الأربعاء +FormatData/ar_LB/DayNames/4=الخميس +FormatData/ar_LB/DayNames/5=الجمعة +FormatData/ar_LB/DayNames/6=السبت +FormatData/ar_LB/Eras/0=ق.م +FormatData/ar_LB/Eras/1=م +LocaleNames/ar_LB/ar=العربية +FormatData/ar_LB/AmPmMarkers/0=ص +FormatData/ar_LB/AmPmMarkers/1=م FormatData/ar_LB/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_LB/TimePatterns/1=h:mm:ss a z FormatData/ar_LB/TimePatterns/2=h:mm:ss a FormatData/ar_LB/TimePatterns/3=h:mm a -FormatData/ar_LB/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_LB/DatePatterns/0=EEEE، d MMMM y FormatData/ar_LB/DatePatterns/1=d MMMM y -FormatData/ar_LB/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_LB/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_LB/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_LB/EG=\u0645\u0635\u0631 -LocaleNames/ar_LB/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_LB/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_LB/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_LB/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_LB/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_LB/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_LB/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_LB/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_LB/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_LB/QA=\u0642\u0637\u0631 -LocaleNames/ar_LB/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_LB/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_LB/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_LB/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_LB/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_LB/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_LB/arab.NumberElements/0=\u066b -FormatData/ar_LB/arab.NumberElements/1=\u066c -FormatData/ar_LB/arab.NumberElements/2=\u061b -FormatData/ar_LB/arab.NumberElements/3=\u066a\u061c -FormatData/ar_LB/arab.NumberElements/4=\u0660 +FormatData/ar_LB/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_LB/DatePatterns/3=d‏/M‏/y +FormatData/ar_LB/DateTimePatterns/0={1}، {0} +LocaleNames/ar_LB/EG=مصر +LocaleNames/ar_LB/DZ=الجزائر +LocaleNames/ar_LB/BH=البحرين +LocaleNames/ar_LB/IQ=العراق +LocaleNames/ar_LB/JO=الأردن +LocaleNames/ar_LB/KW=الكويت +LocaleNames/ar_LB/LB=لبنان +LocaleNames/ar_LB/LY=ليبيا +LocaleNames/ar_LB/MA=المغرب +LocaleNames/ar_LB/OM=عُمان +LocaleNames/ar_LB/QA=قطر +LocaleNames/ar_LB/SA=المملكة العربية السعودية +LocaleNames/ar_LB/SD=السودان +LocaleNames/ar_LB/SY=سوريا +LocaleNames/ar_LB/TN=تونس +LocaleNames/ar_LB/AE=الإمارات العربية المتحدة +LocaleNames/ar_LB/YE=اليمن +FormatData/ar_LB/arab.NumberElements/0=٫ +FormatData/ar_LB/arab.NumberElements/1=٬ +FormatData/ar_LB/arab.NumberElements/2=؛ +FormatData/ar_LB/arab.NumberElements/3=٪؜ +FormatData/ar_LB/arab.NumberElements/4=٠ FormatData/ar_LB/arab.NumberElements/5=# -FormatData/ar_LB/arab.NumberElements/6=\u061c- -FormatData/ar_LB/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_LB/arab.NumberElements/8=\u0609 -FormatData/ar_LB/arab.NumberElements/9=\u221e -FormatData/ar_LB/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_LY/LYD=\u062f.\u0644.\u200f +FormatData/ar_LB/arab.NumberElements/6=؜- +FormatData/ar_LB/arab.NumberElements/7=أس +FormatData/ar_LB/arab.NumberElements/8=؉ +FormatData/ar_LB/arab.NumberElements/9=∞ +FormatData/ar_LB/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_LY/LYD=د.ل.‏ FormatData/ar_LY/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_LY/NumberPatterns/1='\u062f.\u0644.\u200f' #,##0.###;'\u062f.\u0644.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_LY/NumberPatterns/1='د.ل.‏' #,##0.###;'د.ل.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_LY/arab.NumberPatterns/2=#,##0% -FormatData/ar_LY/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_LY/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_LY/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_LY/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_LY/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_LY/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_LY/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_LY/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_LY/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_LY/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_LY/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_LY/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_LY/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_LY/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_LY/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_LY/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_LY/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_LY/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_LY/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_LY/DayNames/0=الأحد +FormatData/ar_LY/DayNames/1=الاثنين +FormatData/ar_LY/DayNames/2=الثلاثاء +FormatData/ar_LY/DayNames/3=الأربعاء +FormatData/ar_LY/DayNames/4=الخميس +FormatData/ar_LY/DayNames/5=الجمعة +FormatData/ar_LY/DayNames/6=السبت +FormatData/ar_LY/MonthAbbreviations/0=يناير +FormatData/ar_LY/MonthAbbreviations/1=فبراير +FormatData/ar_LY/MonthAbbreviations/2=مارس +FormatData/ar_LY/MonthAbbreviations/3=أبريل +FormatData/ar_LY/MonthAbbreviations/4=مايو +FormatData/ar_LY/MonthAbbreviations/5=يونيو +FormatData/ar_LY/MonthAbbreviations/6=يوليو +FormatData/ar_LY/MonthAbbreviations/7=أغسطس +FormatData/ar_LY/MonthAbbreviations/8=سبتمبر +FormatData/ar_LY/MonthAbbreviations/9=أكتوبر +FormatData/ar_LY/MonthAbbreviations/10=نوفمبر +FormatData/ar_LY/MonthAbbreviations/11=ديسمبر FormatData/ar_LY/MonthAbbreviations/12= -FormatData/ar_LY/Eras/0=\u0642.\u0645 -FormatData/ar_LY/Eras/1=\u0645 -FormatData/ar_LY/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_LY/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_LY/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_LY/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_LY/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_LY/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_LY/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_LY/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_LY/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_LY/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_LY/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_LY/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_LY/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_LY/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_LY/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_LY/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_LY/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_LY/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_LY/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_LY/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_LY/Eras/0=ق.م +FormatData/ar_LY/Eras/1=م +FormatData/ar_LY/DayAbbreviations/0=الأحد +FormatData/ar_LY/DayAbbreviations/1=الاثنين +FormatData/ar_LY/DayAbbreviations/2=الثلاثاء +FormatData/ar_LY/DayAbbreviations/3=الأربعاء +FormatData/ar_LY/DayAbbreviations/4=الخميس +FormatData/ar_LY/DayAbbreviations/5=الجمعة +FormatData/ar_LY/DayAbbreviations/6=السبت +LocaleNames/ar_LY/ar=العربية +FormatData/ar_LY/MonthNames/0=يناير +FormatData/ar_LY/MonthNames/1=فبراير +FormatData/ar_LY/MonthNames/2=مارس +FormatData/ar_LY/MonthNames/3=أبريل +FormatData/ar_LY/MonthNames/4=مايو +FormatData/ar_LY/MonthNames/5=يونيو +FormatData/ar_LY/MonthNames/6=يوليو +FormatData/ar_LY/MonthNames/7=أغسطس +FormatData/ar_LY/MonthNames/8=سبتمبر +FormatData/ar_LY/MonthNames/9=أكتوبر +FormatData/ar_LY/MonthNames/10=نوفمبر +FormatData/ar_LY/MonthNames/11=ديسمبر FormatData/ar_LY/MonthNames/12= -FormatData/ar_LY/AmPmMarkers/0=\u0635 -FormatData/ar_LY/AmPmMarkers/1=\u0645 +FormatData/ar_LY/AmPmMarkers/0=ص +FormatData/ar_LY/AmPmMarkers/1=م FormatData/ar_LY/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_LY/TimePatterns/1=h:mm:ss a z FormatData/ar_LY/TimePatterns/2=h:mm:ss a FormatData/ar_LY/TimePatterns/3=h:mm a -FormatData/ar_LY/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_LY/DatePatterns/0=EEEE، d MMMM y FormatData/ar_LY/DatePatterns/1=d MMMM y -FormatData/ar_LY/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_LY/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_LY/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_LY/EG=\u0645\u0635\u0631 -LocaleNames/ar_LY/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_LY/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_LY/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_LY/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_LY/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_LY/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_LY/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_LY/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_LY/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_LY/QA=\u0642\u0637\u0631 -LocaleNames/ar_LY/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_LY/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_LY/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_LY/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_LY/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_LY/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_LY/arab.NumberElements/0=\u066b -FormatData/ar_LY/arab.NumberElements/1=\u066c -FormatData/ar_LY/arab.NumberElements/2=\u061b -FormatData/ar_LY/arab.NumberElements/3=\u066a\u061c -FormatData/ar_LY/arab.NumberElements/4=\u0660 +FormatData/ar_LY/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_LY/DatePatterns/3=d‏/M‏/y +FormatData/ar_LY/DateTimePatterns/0={1}، {0} +LocaleNames/ar_LY/EG=مصر +LocaleNames/ar_LY/DZ=الجزائر +LocaleNames/ar_LY/BH=البحرين +LocaleNames/ar_LY/IQ=العراق +LocaleNames/ar_LY/JO=الأردن +LocaleNames/ar_LY/KW=الكويت +LocaleNames/ar_LY/LB=لبنان +LocaleNames/ar_LY/LY=ليبيا +LocaleNames/ar_LY/MA=المغرب +LocaleNames/ar_LY/OM=عُمان +LocaleNames/ar_LY/QA=قطر +LocaleNames/ar_LY/SA=المملكة العربية السعودية +LocaleNames/ar_LY/SD=السودان +LocaleNames/ar_LY/SY=سوريا +LocaleNames/ar_LY/TN=تونس +LocaleNames/ar_LY/AE=الإمارات العربية المتحدة +LocaleNames/ar_LY/YE=اليمن +FormatData/ar_LY/arab.NumberElements/0=٫ +FormatData/ar_LY/arab.NumberElements/1=٬ +FormatData/ar_LY/arab.NumberElements/2=؛ +FormatData/ar_LY/arab.NumberElements/3=٪؜ +FormatData/ar_LY/arab.NumberElements/4=٠ FormatData/ar_LY/arab.NumberElements/5=# -FormatData/ar_LY/arab.NumberElements/6=\u061c- -FormatData/ar_LY/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_LY/arab.NumberElements/8=\u0609 -FormatData/ar_LY/arab.NumberElements/9=\u221e -FormatData/ar_LY/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_MA/MAD=\u062f.\u0645.\u200f +FormatData/ar_LY/arab.NumberElements/6=؜- +FormatData/ar_LY/arab.NumberElements/7=أس +FormatData/ar_LY/arab.NumberElements/8=؉ +FormatData/ar_LY/arab.NumberElements/9=∞ +FormatData/ar_LY/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_MA/MAD=د.م.‏ FormatData/ar_MA/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_MA/NumberPatterns/1='\u062f.\u0645.\u200f' #,##0.###;'\u062f.\u0645.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_MA/NumberPatterns/1='د.م.‏' #,##0.###;'د.م.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_MA/arab.NumberPatterns/2=#,##0% -FormatData/ar_MA/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_MA/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_MA/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_MA/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_MA/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_MA/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_MA/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_MA/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_MA/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_MA/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_MA/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_MA/MonthAbbreviations/4=\u0645\u0627\u064a -FormatData/ar_MA/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_MA/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648\u0632 -FormatData/ar_MA/MonthAbbreviations/7=\u063a\u0634\u062a -FormatData/ar_MA/MonthAbbreviations/8=\u0634\u062a\u0646\u0628\u0631 -FormatData/ar_MA/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_MA/MonthAbbreviations/10=\u0646\u0648\u0646\u0628\u0631 -FormatData/ar_MA/MonthAbbreviations/11=\u062f\u062c\u0646\u0628\u0631 +FormatData/ar_MA/DayNames/0=الأحد +FormatData/ar_MA/DayNames/1=الاثنين +FormatData/ar_MA/DayNames/2=الثلاثاء +FormatData/ar_MA/DayNames/3=الأربعاء +FormatData/ar_MA/DayNames/4=الخميس +FormatData/ar_MA/DayNames/5=الجمعة +FormatData/ar_MA/DayNames/6=السبت +FormatData/ar_MA/MonthAbbreviations/0=يناير +FormatData/ar_MA/MonthAbbreviations/1=فبراير +FormatData/ar_MA/MonthAbbreviations/2=مارس +FormatData/ar_MA/MonthAbbreviations/3=أبريل +FormatData/ar_MA/MonthAbbreviations/4=ماي +FormatData/ar_MA/MonthAbbreviations/5=يونيو +FormatData/ar_MA/MonthAbbreviations/6=يوليوز +FormatData/ar_MA/MonthAbbreviations/7=غشت +FormatData/ar_MA/MonthAbbreviations/8=شتنبر +FormatData/ar_MA/MonthAbbreviations/9=أكتوبر +FormatData/ar_MA/MonthAbbreviations/10=نونبر +FormatData/ar_MA/MonthAbbreviations/11=دجنبر FormatData/ar_MA/MonthAbbreviations/12= -FormatData/ar_MA/Eras/0=\u0642.\u0645 -FormatData/ar_MA/Eras/1=\u0645 -FormatData/ar_MA/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_MA/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_MA/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_MA/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_MA/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_MA/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_MA/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_MA/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_MA/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_MA/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_MA/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_MA/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_MA/MonthNames/4=\u0645\u0627\u064a -FormatData/ar_MA/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_MA/MonthNames/6=\u064a\u0648\u0644\u064a\u0648\u0632 -FormatData/ar_MA/MonthNames/7=\u063a\u0634\u062a -FormatData/ar_MA/MonthNames/8=\u0634\u062a\u0646\u0628\u0631 -FormatData/ar_MA/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_MA/MonthNames/10=\u0646\u0648\u0646\u0628\u0631 -FormatData/ar_MA/MonthNames/11=\u062f\u062c\u0646\u0628\u0631 +FormatData/ar_MA/Eras/0=ق.م +FormatData/ar_MA/Eras/1=م +FormatData/ar_MA/DayAbbreviations/0=الأحد +FormatData/ar_MA/DayAbbreviations/1=الاثنين +FormatData/ar_MA/DayAbbreviations/2=الثلاثاء +FormatData/ar_MA/DayAbbreviations/3=الأربعاء +FormatData/ar_MA/DayAbbreviations/4=الخميس +FormatData/ar_MA/DayAbbreviations/5=الجمعة +FormatData/ar_MA/DayAbbreviations/6=السبت +LocaleNames/ar_MA/ar=العربية +FormatData/ar_MA/MonthNames/0=يناير +FormatData/ar_MA/MonthNames/1=فبراير +FormatData/ar_MA/MonthNames/2=مارس +FormatData/ar_MA/MonthNames/3=أبريل +FormatData/ar_MA/MonthNames/4=ماي +FormatData/ar_MA/MonthNames/5=يونيو +FormatData/ar_MA/MonthNames/6=يوليوز +FormatData/ar_MA/MonthNames/7=غشت +FormatData/ar_MA/MonthNames/8=شتنبر +FormatData/ar_MA/MonthNames/9=أكتوبر +FormatData/ar_MA/MonthNames/10=نونبر +FormatData/ar_MA/MonthNames/11=دجنبر FormatData/ar_MA/MonthNames/12= -FormatData/ar_MA/AmPmMarkers/0=\u0635 -FormatData/ar_MA/AmPmMarkers/1=\u0645 +FormatData/ar_MA/AmPmMarkers/0=ص +FormatData/ar_MA/AmPmMarkers/1=م FormatData/ar_MA/TimePatterns/0=HH:mm:ss zzzz FormatData/ar_MA/TimePatterns/1=HH:mm:ss z FormatData/ar_MA/TimePatterns/2=HH:mm:ss FormatData/ar_MA/TimePatterns/3=HH:mm -FormatData/ar_MA/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_MA/DatePatterns/0=EEEE، d MMMM y FormatData/ar_MA/DatePatterns/1=d MMMM y -FormatData/ar_MA/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_MA/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_MA/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_MA/EG=\u0645\u0635\u0631 -LocaleNames/ar_MA/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_MA/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_MA/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_MA/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_MA/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_MA/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_MA/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_MA/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_MA/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_MA/QA=\u0642\u0637\u0631 -LocaleNames/ar_MA/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_MA/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_MA/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_MA/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_MA/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_MA/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_MA/arab.NumberElements/0=\u066b -FormatData/ar_MA/arab.NumberElements/1=\u066c -FormatData/ar_MA/arab.NumberElements/2=\u061b -FormatData/ar_MA/arab.NumberElements/3=\u066a\u061c -FormatData/ar_MA/arab.NumberElements/4=\u0660 +FormatData/ar_MA/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_MA/DatePatterns/3=d‏/M‏/y +FormatData/ar_MA/DateTimePatterns/0={1}، {0} +LocaleNames/ar_MA/EG=مصر +LocaleNames/ar_MA/DZ=الجزائر +LocaleNames/ar_MA/BH=البحرين +LocaleNames/ar_MA/IQ=العراق +LocaleNames/ar_MA/JO=الأردن +LocaleNames/ar_MA/KW=الكويت +LocaleNames/ar_MA/LB=لبنان +LocaleNames/ar_MA/LY=ليبيا +LocaleNames/ar_MA/MA=المغرب +LocaleNames/ar_MA/OM=عُمان +LocaleNames/ar_MA/QA=قطر +LocaleNames/ar_MA/SA=المملكة العربية السعودية +LocaleNames/ar_MA/SD=السودان +LocaleNames/ar_MA/SY=سوريا +LocaleNames/ar_MA/TN=تونس +LocaleNames/ar_MA/AE=الإمارات العربية المتحدة +LocaleNames/ar_MA/YE=اليمن +FormatData/ar_MA/arab.NumberElements/0=٫ +FormatData/ar_MA/arab.NumberElements/1=٬ +FormatData/ar_MA/arab.NumberElements/2=؛ +FormatData/ar_MA/arab.NumberElements/3=٪؜ +FormatData/ar_MA/arab.NumberElements/4=٠ FormatData/ar_MA/arab.NumberElements/5=# -FormatData/ar_MA/arab.NumberElements/6=\u061c- -FormatData/ar_MA/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_MA/arab.NumberElements/8=\u0609 -FormatData/ar_MA/arab.NumberElements/9=\u221e -FormatData/ar_MA/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_OM/OMR=\u0631.\u0639.\u200f +FormatData/ar_MA/arab.NumberElements/6=؜- +FormatData/ar_MA/arab.NumberElements/7=أس +FormatData/ar_MA/arab.NumberElements/8=؉ +FormatData/ar_MA/arab.NumberElements/9=∞ +FormatData/ar_MA/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_OM/OMR=ر.ع.‏ FormatData/ar_OM/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_OM/NumberPatterns/1='\u0631.\u0639.\u200f' #,##0.###;'\u0631.\u0639.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_OM/NumberPatterns/1='ر.ع.‏' #,##0.###;'ر.ع.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_OM/arab.NumberPatterns/2=#,##0% -FormatData/ar_OM/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_OM/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_OM/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_OM/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_OM/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_OM/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_OM/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_OM/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_OM/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_OM/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_OM/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_OM/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_OM/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_OM/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_OM/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_OM/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_OM/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_OM/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_OM/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_OM/DayNames/0=الأحد +FormatData/ar_OM/DayNames/1=الاثنين +FormatData/ar_OM/DayNames/2=الثلاثاء +FormatData/ar_OM/DayNames/3=الأربعاء +FormatData/ar_OM/DayNames/4=الخميس +FormatData/ar_OM/DayNames/5=الجمعة +FormatData/ar_OM/DayNames/6=السبت +FormatData/ar_OM/MonthAbbreviations/0=يناير +FormatData/ar_OM/MonthAbbreviations/1=فبراير +FormatData/ar_OM/MonthAbbreviations/2=مارس +FormatData/ar_OM/MonthAbbreviations/3=أبريل +FormatData/ar_OM/MonthAbbreviations/4=مايو +FormatData/ar_OM/MonthAbbreviations/5=يونيو +FormatData/ar_OM/MonthAbbreviations/6=يوليو +FormatData/ar_OM/MonthAbbreviations/7=أغسطس +FormatData/ar_OM/MonthAbbreviations/8=سبتمبر +FormatData/ar_OM/MonthAbbreviations/9=أكتوبر +FormatData/ar_OM/MonthAbbreviations/10=نوفمبر +FormatData/ar_OM/MonthAbbreviations/11=ديسمبر FormatData/ar_OM/MonthAbbreviations/12= -FormatData/ar_OM/Eras/0=\u0642.\u0645 -FormatData/ar_OM/Eras/1=\u0645 -FormatData/ar_OM/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_OM/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_OM/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_OM/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_OM/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_OM/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_OM/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_OM/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_OM/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_OM/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_OM/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_OM/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_OM/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_OM/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_OM/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_OM/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_OM/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_OM/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_OM/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_OM/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_OM/Eras/0=ق.م +FormatData/ar_OM/Eras/1=م +FormatData/ar_OM/DayAbbreviations/0=الأحد +FormatData/ar_OM/DayAbbreviations/1=الاثنين +FormatData/ar_OM/DayAbbreviations/2=الثلاثاء +FormatData/ar_OM/DayAbbreviations/3=الأربعاء +FormatData/ar_OM/DayAbbreviations/4=الخميس +FormatData/ar_OM/DayAbbreviations/5=الجمعة +FormatData/ar_OM/DayAbbreviations/6=السبت +LocaleNames/ar_OM/ar=العربية +FormatData/ar_OM/MonthNames/0=يناير +FormatData/ar_OM/MonthNames/1=فبراير +FormatData/ar_OM/MonthNames/2=مارس +FormatData/ar_OM/MonthNames/3=أبريل +FormatData/ar_OM/MonthNames/4=مايو +FormatData/ar_OM/MonthNames/5=يونيو +FormatData/ar_OM/MonthNames/6=يوليو +FormatData/ar_OM/MonthNames/7=أغسطس +FormatData/ar_OM/MonthNames/8=سبتمبر +FormatData/ar_OM/MonthNames/9=أكتوبر +FormatData/ar_OM/MonthNames/10=نوفمبر +FormatData/ar_OM/MonthNames/11=ديسمبر FormatData/ar_OM/MonthNames/12= -FormatData/ar_OM/AmPmMarkers/0=\u0635 -FormatData/ar_OM/AmPmMarkers/1=\u0645 +FormatData/ar_OM/AmPmMarkers/0=ص +FormatData/ar_OM/AmPmMarkers/1=م FormatData/ar_OM/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_OM/TimePatterns/1=h:mm:ss a z FormatData/ar_OM/TimePatterns/2=h:mm:ss a FormatData/ar_OM/TimePatterns/3=h:mm a -FormatData/ar_OM/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_OM/DatePatterns/0=EEEE، d MMMM y FormatData/ar_OM/DatePatterns/1=d MMMM y -FormatData/ar_OM/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_OM/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_OM/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_OM/EG=\u0645\u0635\u0631 -LocaleNames/ar_OM/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_OM/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_OM/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_OM/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_OM/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_OM/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_OM/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_OM/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_OM/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_OM/QA=\u0642\u0637\u0631 -LocaleNames/ar_OM/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_OM/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_OM/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_OM/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_OM/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_OM/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_OM/arab.NumberElements/0=\u066b -FormatData/ar_OM/arab.NumberElements/1=\u066c -FormatData/ar_OM/arab.NumberElements/2=\u061b -FormatData/ar_OM/arab.NumberElements/3=\u066a\u061c -FormatData/ar_OM/arab.NumberElements/4=\u0660 +FormatData/ar_OM/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_OM/DatePatterns/3=d‏/M‏/y +FormatData/ar_OM/DateTimePatterns/0={1}، {0} +LocaleNames/ar_OM/EG=مصر +LocaleNames/ar_OM/DZ=الجزائر +LocaleNames/ar_OM/BH=البحرين +LocaleNames/ar_OM/IQ=العراق +LocaleNames/ar_OM/JO=الأردن +LocaleNames/ar_OM/KW=الكويت +LocaleNames/ar_OM/LB=لبنان +LocaleNames/ar_OM/LY=ليبيا +LocaleNames/ar_OM/MA=المغرب +LocaleNames/ar_OM/OM=عُمان +LocaleNames/ar_OM/QA=قطر +LocaleNames/ar_OM/SA=المملكة العربية السعودية +LocaleNames/ar_OM/SD=السودان +LocaleNames/ar_OM/SY=سوريا +LocaleNames/ar_OM/TN=تونس +LocaleNames/ar_OM/AE=الإمارات العربية المتحدة +LocaleNames/ar_OM/YE=اليمن +FormatData/ar_OM/arab.NumberElements/0=٫ +FormatData/ar_OM/arab.NumberElements/1=٬ +FormatData/ar_OM/arab.NumberElements/2=؛ +FormatData/ar_OM/arab.NumberElements/3=٪؜ +FormatData/ar_OM/arab.NumberElements/4=٠ FormatData/ar_OM/arab.NumberElements/5=# -FormatData/ar_OM/arab.NumberElements/6=\u061c- -FormatData/ar_OM/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_OM/arab.NumberElements/8=\u0609 -FormatData/ar_OM/arab.NumberElements/9=\u221e -FormatData/ar_OM/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_QA/QAR=\u0631.\u0642.\u200f +FormatData/ar_OM/arab.NumberElements/6=؜- +FormatData/ar_OM/arab.NumberElements/7=أس +FormatData/ar_OM/arab.NumberElements/8=؉ +FormatData/ar_OM/arab.NumberElements/9=∞ +FormatData/ar_OM/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_QA/QAR=ر.ق.‏ FormatData/ar_QA/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_QA/NumberPatterns/1='\u0631.\u0642.\u200f' #,##0.###;'\u0631.\u0642.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_QA/NumberPatterns/1='ر.ق.‏' #,##0.###;'ر.ق.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_QA/arab.NumberPatterns/2=#,##0% -FormatData/ar_QA/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_QA/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_QA/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_QA/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_QA/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_QA/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_QA/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_QA/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_QA/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_QA/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_QA/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_QA/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_QA/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_QA/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_QA/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_QA/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_QA/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_QA/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_QA/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_QA/DayNames/0=الأحد +FormatData/ar_QA/DayNames/1=الاثنين +FormatData/ar_QA/DayNames/2=الثلاثاء +FormatData/ar_QA/DayNames/3=الأربعاء +FormatData/ar_QA/DayNames/4=الخميس +FormatData/ar_QA/DayNames/5=الجمعة +FormatData/ar_QA/DayNames/6=السبت +FormatData/ar_QA/MonthAbbreviations/0=يناير +FormatData/ar_QA/MonthAbbreviations/1=فبراير +FormatData/ar_QA/MonthAbbreviations/2=مارس +FormatData/ar_QA/MonthAbbreviations/3=أبريل +FormatData/ar_QA/MonthAbbreviations/4=مايو +FormatData/ar_QA/MonthAbbreviations/5=يونيو +FormatData/ar_QA/MonthAbbreviations/6=يوليو +FormatData/ar_QA/MonthAbbreviations/7=أغسطس +FormatData/ar_QA/MonthAbbreviations/8=سبتمبر +FormatData/ar_QA/MonthAbbreviations/9=أكتوبر +FormatData/ar_QA/MonthAbbreviations/10=نوفمبر +FormatData/ar_QA/MonthAbbreviations/11=ديسمبر FormatData/ar_QA/MonthAbbreviations/12= -FormatData/ar_QA/Eras/0=\u0642.\u0645 -FormatData/ar_QA/Eras/1=\u0645 -FormatData/ar_QA/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_QA/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_QA/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_QA/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_QA/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_QA/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_QA/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_QA/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_QA/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_QA/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_QA/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_QA/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_QA/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_QA/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_QA/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_QA/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_QA/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_QA/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_QA/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_QA/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_QA/Eras/0=ق.م +FormatData/ar_QA/Eras/1=م +FormatData/ar_QA/DayAbbreviations/0=الأحد +FormatData/ar_QA/DayAbbreviations/1=الاثنين +FormatData/ar_QA/DayAbbreviations/2=الثلاثاء +FormatData/ar_QA/DayAbbreviations/3=الأربعاء +FormatData/ar_QA/DayAbbreviations/4=الخميس +FormatData/ar_QA/DayAbbreviations/5=الجمعة +FormatData/ar_QA/DayAbbreviations/6=السبت +LocaleNames/ar_QA/ar=العربية +FormatData/ar_QA/MonthNames/0=يناير +FormatData/ar_QA/MonthNames/1=فبراير +FormatData/ar_QA/MonthNames/2=مارس +FormatData/ar_QA/MonthNames/3=أبريل +FormatData/ar_QA/MonthNames/4=مايو +FormatData/ar_QA/MonthNames/5=يونيو +FormatData/ar_QA/MonthNames/6=يوليو +FormatData/ar_QA/MonthNames/7=أغسطس +FormatData/ar_QA/MonthNames/8=سبتمبر +FormatData/ar_QA/MonthNames/9=أكتوبر +FormatData/ar_QA/MonthNames/10=نوفمبر +FormatData/ar_QA/MonthNames/11=ديسمبر FormatData/ar_QA/MonthNames/12= -FormatData/ar_QA/AmPmMarkers/0=\u0635 -FormatData/ar_QA/AmPmMarkers/1=\u0645 +FormatData/ar_QA/AmPmMarkers/0=ص +FormatData/ar_QA/AmPmMarkers/1=م FormatData/ar_QA/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_QA/TimePatterns/1=h:mm:ss a z FormatData/ar_QA/TimePatterns/2=h:mm:ss a FormatData/ar_QA/TimePatterns/3=h:mm a -FormatData/ar_QA/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_QA/DatePatterns/0=EEEE، d MMMM y FormatData/ar_QA/DatePatterns/1=d MMMM y -FormatData/ar_QA/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_QA/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_QA/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_QA/EG=\u0645\u0635\u0631 -LocaleNames/ar_QA/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_QA/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_QA/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_QA/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_QA/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_QA/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_QA/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_QA/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_QA/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_QA/QA=\u0642\u0637\u0631 -LocaleNames/ar_QA/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_QA/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_QA/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_QA/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_QA/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_QA/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_QA/arab.NumberElements/0=\u066b -FormatData/ar_QA/arab.NumberElements/1=\u066c -FormatData/ar_QA/arab.NumberElements/2=\u061b -FormatData/ar_QA/arab.NumberElements/3=\u066a\u061c -FormatData/ar_QA/arab.NumberElements/4=\u0660 +FormatData/ar_QA/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_QA/DatePatterns/3=d‏/M‏/y +FormatData/ar_QA/DateTimePatterns/0={1}، {0} +LocaleNames/ar_QA/EG=مصر +LocaleNames/ar_QA/DZ=الجزائر +LocaleNames/ar_QA/BH=البحرين +LocaleNames/ar_QA/IQ=العراق +LocaleNames/ar_QA/JO=الأردن +LocaleNames/ar_QA/KW=الكويت +LocaleNames/ar_QA/LB=لبنان +LocaleNames/ar_QA/LY=ليبيا +LocaleNames/ar_QA/MA=المغرب +LocaleNames/ar_QA/OM=عُمان +LocaleNames/ar_QA/QA=قطر +LocaleNames/ar_QA/SA=المملكة العربية السعودية +LocaleNames/ar_QA/SD=السودان +LocaleNames/ar_QA/SY=سوريا +LocaleNames/ar_QA/TN=تونس +LocaleNames/ar_QA/AE=الإمارات العربية المتحدة +LocaleNames/ar_QA/YE=اليمن +FormatData/ar_QA/arab.NumberElements/0=٫ +FormatData/ar_QA/arab.NumberElements/1=٬ +FormatData/ar_QA/arab.NumberElements/2=؛ +FormatData/ar_QA/arab.NumberElements/3=٪؜ +FormatData/ar_QA/arab.NumberElements/4=٠ FormatData/ar_QA/arab.NumberElements/5=# -FormatData/ar_QA/arab.NumberElements/6=\u061c- -FormatData/ar_QA/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_QA/arab.NumberElements/8=\u0609 -FormatData/ar_QA/arab.NumberElements/9=\u221e -FormatData/ar_QA/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_SA/SAR=\u0631.\u0633.\u200f +FormatData/ar_QA/arab.NumberElements/6=؜- +FormatData/ar_QA/arab.NumberElements/7=أس +FormatData/ar_QA/arab.NumberElements/8=؉ +FormatData/ar_QA/arab.NumberElements/9=∞ +FormatData/ar_QA/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_SA/SAR=ر.س.‏ FormatData/ar_SA/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_SA/NumberPatterns/1='\u0631.\u0633.\u200f' #,##0.###;'\u0631.\u0633.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_SA/NumberPatterns/1='ر.س.‏' #,##0.###;'ر.س.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_SA/arab.NumberPatterns/2=#,##0% -FormatData/ar_SA/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SA/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SA/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SA/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SA/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SA/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SA/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_SA/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_SA/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_SA/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_SA/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_SA/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_SA/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_SA/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_SA/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_SA/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_SA/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_SA/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_SA/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_SA/DayNames/0=الأحد +FormatData/ar_SA/DayNames/1=الاثنين +FormatData/ar_SA/DayNames/2=الثلاثاء +FormatData/ar_SA/DayNames/3=الأربعاء +FormatData/ar_SA/DayNames/4=الخميس +FormatData/ar_SA/DayNames/5=الجمعة +FormatData/ar_SA/DayNames/6=السبت +FormatData/ar_SA/MonthAbbreviations/0=يناير +FormatData/ar_SA/MonthAbbreviations/1=فبراير +FormatData/ar_SA/MonthAbbreviations/2=مارس +FormatData/ar_SA/MonthAbbreviations/3=أبريل +FormatData/ar_SA/MonthAbbreviations/4=مايو +FormatData/ar_SA/MonthAbbreviations/5=يونيو +FormatData/ar_SA/MonthAbbreviations/6=يوليو +FormatData/ar_SA/MonthAbbreviations/7=أغسطس +FormatData/ar_SA/MonthAbbreviations/8=سبتمبر +FormatData/ar_SA/MonthAbbreviations/9=أكتوبر +FormatData/ar_SA/MonthAbbreviations/10=نوفمبر +FormatData/ar_SA/MonthAbbreviations/11=ديسمبر FormatData/ar_SA/MonthAbbreviations/12= -FormatData/ar_SA/Eras/0=\u0642.\u0645 -FormatData/ar_SA/Eras/1=\u0645 -FormatData/ar_SA/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SA/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SA/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SA/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SA/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SA/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SA/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_SA/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_SA/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_SA/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_SA/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_SA/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_SA/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_SA/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_SA/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_SA/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_SA/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_SA/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_SA/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_SA/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_SA/Eras/0=ق.م +FormatData/ar_SA/Eras/1=م +FormatData/ar_SA/DayAbbreviations/0=الأحد +FormatData/ar_SA/DayAbbreviations/1=الاثنين +FormatData/ar_SA/DayAbbreviations/2=الثلاثاء +FormatData/ar_SA/DayAbbreviations/3=الأربعاء +FormatData/ar_SA/DayAbbreviations/4=الخميس +FormatData/ar_SA/DayAbbreviations/5=الجمعة +FormatData/ar_SA/DayAbbreviations/6=السبت +LocaleNames/ar_SA/ar=العربية +FormatData/ar_SA/MonthNames/0=يناير +FormatData/ar_SA/MonthNames/1=فبراير +FormatData/ar_SA/MonthNames/2=مارس +FormatData/ar_SA/MonthNames/3=أبريل +FormatData/ar_SA/MonthNames/4=مايو +FormatData/ar_SA/MonthNames/5=يونيو +FormatData/ar_SA/MonthNames/6=يوليو +FormatData/ar_SA/MonthNames/7=أغسطس +FormatData/ar_SA/MonthNames/8=سبتمبر +FormatData/ar_SA/MonthNames/9=أكتوبر +FormatData/ar_SA/MonthNames/10=نوفمبر +FormatData/ar_SA/MonthNames/11=ديسمبر FormatData/ar_SA/MonthNames/12= -FormatData/ar_SA/AmPmMarkers/0=\u0635 -FormatData/ar_SA/AmPmMarkers/1=\u0645 +FormatData/ar_SA/AmPmMarkers/0=ص +FormatData/ar_SA/AmPmMarkers/1=م FormatData/ar_SA/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_SA/TimePatterns/1=h:mm:ss a z FormatData/ar_SA/TimePatterns/2=h:mm:ss a FormatData/ar_SA/TimePatterns/3=h:mm a -FormatData/ar_SA/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_SA/DatePatterns/0=EEEE، d MMMM y FormatData/ar_SA/DatePatterns/1=d MMMM y -FormatData/ar_SA/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_SA/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_SA/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_SA/EG=\u0645\u0635\u0631 -LocaleNames/ar_SA/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_SA/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_SA/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_SA/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_SA/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_SA/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_SA/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_SA/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_SA/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_SA/QA=\u0642\u0637\u0631 -LocaleNames/ar_SA/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_SA/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_SA/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_SA/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_SA/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_SA/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_SA/arab.NumberElements/0=\u066b -FormatData/ar_SA/arab.NumberElements/1=\u066c -FormatData/ar_SA/arab.NumberElements/2=\u061b -FormatData/ar_SA/arab.NumberElements/3=\u066a\u061c -FormatData/ar_SA/arab.NumberElements/4=\u0660 +FormatData/ar_SA/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_SA/DatePatterns/3=d‏/M‏/y +FormatData/ar_SA/DateTimePatterns/0={1}، {0} +LocaleNames/ar_SA/EG=مصر +LocaleNames/ar_SA/DZ=الجزائر +LocaleNames/ar_SA/BH=البحرين +LocaleNames/ar_SA/IQ=العراق +LocaleNames/ar_SA/JO=الأردن +LocaleNames/ar_SA/KW=الكويت +LocaleNames/ar_SA/LB=لبنان +LocaleNames/ar_SA/LY=ليبيا +LocaleNames/ar_SA/MA=المغرب +LocaleNames/ar_SA/OM=عُمان +LocaleNames/ar_SA/QA=قطر +LocaleNames/ar_SA/SA=المملكة العربية السعودية +LocaleNames/ar_SA/SD=السودان +LocaleNames/ar_SA/SY=سوريا +LocaleNames/ar_SA/TN=تونس +LocaleNames/ar_SA/AE=الإمارات العربية المتحدة +LocaleNames/ar_SA/YE=اليمن +FormatData/ar_SA/arab.NumberElements/0=٫ +FormatData/ar_SA/arab.NumberElements/1=٬ +FormatData/ar_SA/arab.NumberElements/2=؛ +FormatData/ar_SA/arab.NumberElements/3=٪؜ +FormatData/ar_SA/arab.NumberElements/4=٠ FormatData/ar_SA/arab.NumberElements/5=# -FormatData/ar_SA/arab.NumberElements/6=\u061c- -FormatData/ar_SA/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_SA/arab.NumberElements/8=\u0609 -FormatData/ar_SA/arab.NumberElements/9=\u221e -FormatData/ar_SA/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 +FormatData/ar_SA/arab.NumberElements/6=؜- +FormatData/ar_SA/arab.NumberElements/7=أس +FormatData/ar_SA/arab.NumberElements/8=؉ +FormatData/ar_SA/arab.NumberElements/9=∞ +FormatData/ar_SA/arab.NumberElements/10=ليس رقمًا # changed for 4945388, removed for 6531591, see bellow -# CurrencyNames/ar_SD/SDD=\u062c.\u0633.\u200f +# CurrencyNames/ar_SD/SDD=ج.س.‏ FormatData/ar_SD/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_SD/NumberPatterns/1='\u062c.\u0633.\u200f' #,##0.###;'\u062c.\u0633.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_SD/NumberPatterns/1='ج.س.‏' #,##0.###;'ج.س.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_SD/arab.NumberPatterns/2=#,##0% -FormatData/ar_SD/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SD/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SD/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SD/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SD/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SD/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SD/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_SD/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_SD/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_SD/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_SD/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_SD/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_SD/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_SD/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_SD/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_SD/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_SD/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_SD/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_SD/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_SD/DayNames/0=الأحد +FormatData/ar_SD/DayNames/1=الاثنين +FormatData/ar_SD/DayNames/2=الثلاثاء +FormatData/ar_SD/DayNames/3=الأربعاء +FormatData/ar_SD/DayNames/4=الخميس +FormatData/ar_SD/DayNames/5=الجمعة +FormatData/ar_SD/DayNames/6=السبت +FormatData/ar_SD/MonthAbbreviations/0=يناير +FormatData/ar_SD/MonthAbbreviations/1=فبراير +FormatData/ar_SD/MonthAbbreviations/2=مارس +FormatData/ar_SD/MonthAbbreviations/3=أبريل +FormatData/ar_SD/MonthAbbreviations/4=مايو +FormatData/ar_SD/MonthAbbreviations/5=يونيو +FormatData/ar_SD/MonthAbbreviations/6=يوليو +FormatData/ar_SD/MonthAbbreviations/7=أغسطس +FormatData/ar_SD/MonthAbbreviations/8=سبتمبر +FormatData/ar_SD/MonthAbbreviations/9=أكتوبر +FormatData/ar_SD/MonthAbbreviations/10=نوفمبر +FormatData/ar_SD/MonthAbbreviations/11=ديسمبر FormatData/ar_SD/MonthAbbreviations/12= -FormatData/ar_SD/Eras/0=\u0642.\u0645 -FormatData/ar_SD/Eras/1=\u0645 -FormatData/ar_SD/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SD/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SD/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SD/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SD/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SD/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SD/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_SD/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_SD/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_SD/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_SD/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_SD/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_SD/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_SD/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_SD/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_SD/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_SD/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_SD/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_SD/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_SD/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_SD/Eras/0=ق.م +FormatData/ar_SD/Eras/1=م +FormatData/ar_SD/DayAbbreviations/0=الأحد +FormatData/ar_SD/DayAbbreviations/1=الاثنين +FormatData/ar_SD/DayAbbreviations/2=الثلاثاء +FormatData/ar_SD/DayAbbreviations/3=الأربعاء +FormatData/ar_SD/DayAbbreviations/4=الخميس +FormatData/ar_SD/DayAbbreviations/5=الجمعة +FormatData/ar_SD/DayAbbreviations/6=السبت +LocaleNames/ar_SD/ar=العربية +FormatData/ar_SD/MonthNames/0=يناير +FormatData/ar_SD/MonthNames/1=فبراير +FormatData/ar_SD/MonthNames/2=مارس +FormatData/ar_SD/MonthNames/3=أبريل +FormatData/ar_SD/MonthNames/4=مايو +FormatData/ar_SD/MonthNames/5=يونيو +FormatData/ar_SD/MonthNames/6=يوليو +FormatData/ar_SD/MonthNames/7=أغسطس +FormatData/ar_SD/MonthNames/8=سبتمبر +FormatData/ar_SD/MonthNames/9=أكتوبر +FormatData/ar_SD/MonthNames/10=نوفمبر +FormatData/ar_SD/MonthNames/11=ديسمبر FormatData/ar_SD/MonthNames/12= -FormatData/ar_SD/AmPmMarkers/0=\u0635 -FormatData/ar_SD/AmPmMarkers/1=\u0645 +FormatData/ar_SD/AmPmMarkers/0=ص +FormatData/ar_SD/AmPmMarkers/1=م FormatData/ar_SD/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_SD/TimePatterns/1=h:mm:ss a z FormatData/ar_SD/TimePatterns/2=h:mm:ss a FormatData/ar_SD/TimePatterns/3=h:mm a -FormatData/ar_SD/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_SD/DatePatterns/0=EEEE، d MMMM y FormatData/ar_SD/DatePatterns/1=d MMMM y -FormatData/ar_SD/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_SD/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_SD/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_SD/EG=\u0645\u0635\u0631 -LocaleNames/ar_SD/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_SD/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_SD/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_SD/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_SD/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_SD/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_SD/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_SD/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_SD/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_SD/QA=\u0642\u0637\u0631 -LocaleNames/ar_SD/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_SD/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_SD/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_SD/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_SD/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_SD/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_SD/arab.NumberElements/0=\u066b -FormatData/ar_SD/arab.NumberElements/1=\u066c -FormatData/ar_SD/arab.NumberElements/2=\u061b -FormatData/ar_SD/arab.NumberElements/3=\u066a\u061c -FormatData/ar_SD/arab.NumberElements/4=\u0660 +FormatData/ar_SD/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_SD/DatePatterns/3=d‏/M‏/y +FormatData/ar_SD/DateTimePatterns/0={1}، {0} +LocaleNames/ar_SD/EG=مصر +LocaleNames/ar_SD/DZ=الجزائر +LocaleNames/ar_SD/BH=البحرين +LocaleNames/ar_SD/IQ=العراق +LocaleNames/ar_SD/JO=الأردن +LocaleNames/ar_SD/KW=الكويت +LocaleNames/ar_SD/LB=لبنان +LocaleNames/ar_SD/LY=ليبيا +LocaleNames/ar_SD/MA=المغرب +LocaleNames/ar_SD/OM=عُمان +LocaleNames/ar_SD/QA=قطر +LocaleNames/ar_SD/SA=المملكة العربية السعودية +LocaleNames/ar_SD/SD=السودان +LocaleNames/ar_SD/SY=سوريا +LocaleNames/ar_SD/TN=تونس +LocaleNames/ar_SD/AE=الإمارات العربية المتحدة +LocaleNames/ar_SD/YE=اليمن +FormatData/ar_SD/arab.NumberElements/0=٫ +FormatData/ar_SD/arab.NumberElements/1=٬ +FormatData/ar_SD/arab.NumberElements/2=؛ +FormatData/ar_SD/arab.NumberElements/3=٪؜ +FormatData/ar_SD/arab.NumberElements/4=٠ FormatData/ar_SD/arab.NumberElements/5=# -FormatData/ar_SD/arab.NumberElements/6=\u061c- -FormatData/ar_SD/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_SD/arab.NumberElements/8=\u0609 -FormatData/ar_SD/arab.NumberElements/9=\u221e -FormatData/ar_SD/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 +FormatData/ar_SD/arab.NumberElements/6=؜- +FormatData/ar_SD/arab.NumberElements/7=أس +FormatData/ar_SD/arab.NumberElements/8=؉ +FormatData/ar_SD/arab.NumberElements/9=∞ +FormatData/ar_SD/arab.NumberElements/10=ليس رقمًا FormatData/ar_SY/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_SY/NumberPatterns/1='\u0644.\u0633.\u200f' #,##0.###;'\u0644.\u0633.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_SY/NumberPatterns/1='ل.س.‏' #,##0.###;'ل.س.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_SY/arab.NumberPatterns/2=#,##0% -CurrencyNames/ar_SY/SYP=\u0644.\u0633.\u200f -FormatData/ar_SY/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SY/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SY/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SY/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SY/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SY/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SY/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_SY/MonthNames/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_SY/MonthNames/1=\u0634\u0628\u0627\u0637 -FormatData/ar_SY/MonthNames/2=\u0622\u0630\u0627\u0631 -FormatData/ar_SY/MonthNames/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_SY/MonthNames/4=\u0623\u064a\u0627\u0631 -FormatData/ar_SY/MonthNames/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_SY/MonthNames/6=\u062a\u0645\u0648\u0632 -FormatData/ar_SY/MonthNames/7=\u0622\u0628 -FormatData/ar_SY/MonthNames/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_SY/MonthNames/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_SY/MonthNames/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_SY/MonthNames/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +CurrencyNames/ar_SY/SYP=ل.س.‏ +FormatData/ar_SY/DayAbbreviations/0=الأحد +FormatData/ar_SY/DayAbbreviations/1=الاثنين +FormatData/ar_SY/DayAbbreviations/2=الثلاثاء +FormatData/ar_SY/DayAbbreviations/3=الأربعاء +FormatData/ar_SY/DayAbbreviations/4=الخميس +FormatData/ar_SY/DayAbbreviations/5=الجمعة +FormatData/ar_SY/DayAbbreviations/6=السبت +FormatData/ar_SY/MonthNames/0=كانون الثاني +FormatData/ar_SY/MonthNames/1=شباط +FormatData/ar_SY/MonthNames/2=آذار +FormatData/ar_SY/MonthNames/3=نيسان +FormatData/ar_SY/MonthNames/4=أيار +FormatData/ar_SY/MonthNames/5=حزيران +FormatData/ar_SY/MonthNames/6=تموز +FormatData/ar_SY/MonthNames/7=آب +FormatData/ar_SY/MonthNames/8=أيلول +FormatData/ar_SY/MonthNames/9=تشرين الأول +FormatData/ar_SY/MonthNames/10=تشرين الثاني +FormatData/ar_SY/MonthNames/11=كانون الأول FormatData/ar_SY/MonthNames/12= -FormatData/ar_SY/MonthAbbreviations/0=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_SY/MonthAbbreviations/1=\u0634\u0628\u0627\u0637 -FormatData/ar_SY/MonthAbbreviations/2=\u0622\u0630\u0627\u0631 -FormatData/ar_SY/MonthAbbreviations/3=\u0646\u064a\u0633\u0627\u0646 -FormatData/ar_SY/MonthAbbreviations/4=\u0623\u064a\u0627\u0631 -FormatData/ar_SY/MonthAbbreviations/5=\u062d\u0632\u064a\u0631\u0627\u0646 -FormatData/ar_SY/MonthAbbreviations/6=\u062a\u0645\u0648\u0632 -FormatData/ar_SY/MonthAbbreviations/7=\u0622\u0628 -FormatData/ar_SY/MonthAbbreviations/8=\u0623\u064a\u0644\u0648\u0644 -FormatData/ar_SY/MonthAbbreviations/9=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644 -FormatData/ar_SY/MonthAbbreviations/10=\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a -FormatData/ar_SY/MonthAbbreviations/11=\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644 +FormatData/ar_SY/MonthAbbreviations/0=كانون الثاني +FormatData/ar_SY/MonthAbbreviations/1=شباط +FormatData/ar_SY/MonthAbbreviations/2=آذار +FormatData/ar_SY/MonthAbbreviations/3=نيسان +FormatData/ar_SY/MonthAbbreviations/4=أيار +FormatData/ar_SY/MonthAbbreviations/5=حزيران +FormatData/ar_SY/MonthAbbreviations/6=تموز +FormatData/ar_SY/MonthAbbreviations/7=آب +FormatData/ar_SY/MonthAbbreviations/8=أيلول +FormatData/ar_SY/MonthAbbreviations/9=تشرين الأول +FormatData/ar_SY/MonthAbbreviations/10=تشرين الثاني +FormatData/ar_SY/MonthAbbreviations/11=كانون الأول FormatData/ar_SY/MonthAbbreviations/12= -FormatData/ar_SY/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_SY/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_SY/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_SY/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_SY/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_SY/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_SY/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_SY/Eras/0=\u0642.\u0645 -FormatData/ar_SY/Eras/1=\u0645 -LocaleNames/ar_SY/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_SY/AmPmMarkers/0=\u0635 -FormatData/ar_SY/AmPmMarkers/1=\u0645 +FormatData/ar_SY/DayNames/0=الأحد +FormatData/ar_SY/DayNames/1=الاثنين +FormatData/ar_SY/DayNames/2=الثلاثاء +FormatData/ar_SY/DayNames/3=الأربعاء +FormatData/ar_SY/DayNames/4=الخميس +FormatData/ar_SY/DayNames/5=الجمعة +FormatData/ar_SY/DayNames/6=السبت +FormatData/ar_SY/Eras/0=ق.م +FormatData/ar_SY/Eras/1=م +LocaleNames/ar_SY/ar=العربية +FormatData/ar_SY/AmPmMarkers/0=ص +FormatData/ar_SY/AmPmMarkers/1=م FormatData/ar_SY/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_SY/TimePatterns/1=h:mm:ss a z FormatData/ar_SY/TimePatterns/2=h:mm:ss a FormatData/ar_SY/TimePatterns/3=h:mm a -FormatData/ar_SY/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_SY/DatePatterns/0=EEEE، d MMMM y FormatData/ar_SY/DatePatterns/1=d MMMM y -FormatData/ar_SY/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_SY/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_SY/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_SY/EG=\u0645\u0635\u0631 -LocaleNames/ar_SY/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_SY/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_SY/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_SY/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_SY/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_SY/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_SY/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_SY/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_SY/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_SY/QA=\u0642\u0637\u0631 -LocaleNames/ar_SY/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_SY/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_SY/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_SY/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_SY/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_SY/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_SY/arab.NumberElements/0=\u066b -FormatData/ar_SY/arab.NumberElements/1=\u066c -FormatData/ar_SY/arab.NumberElements/2=\u061b -FormatData/ar_SY/arab.NumberElements/3=\u066a\u061c -FormatData/ar_SY/arab.NumberElements/4=\u0660 +FormatData/ar_SY/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_SY/DatePatterns/3=d‏/M‏/y +FormatData/ar_SY/DateTimePatterns/0={1}، {0} +LocaleNames/ar_SY/EG=مصر +LocaleNames/ar_SY/DZ=الجزائر +LocaleNames/ar_SY/BH=البحرين +LocaleNames/ar_SY/IQ=العراق +LocaleNames/ar_SY/JO=الأردن +LocaleNames/ar_SY/KW=الكويت +LocaleNames/ar_SY/LB=لبنان +LocaleNames/ar_SY/LY=ليبيا +LocaleNames/ar_SY/MA=المغرب +LocaleNames/ar_SY/OM=عُمان +LocaleNames/ar_SY/QA=قطر +LocaleNames/ar_SY/SA=المملكة العربية السعودية +LocaleNames/ar_SY/SD=السودان +LocaleNames/ar_SY/SY=سوريا +LocaleNames/ar_SY/TN=تونس +LocaleNames/ar_SY/AE=الإمارات العربية المتحدة +LocaleNames/ar_SY/YE=اليمن +FormatData/ar_SY/arab.NumberElements/0=٫ +FormatData/ar_SY/arab.NumberElements/1=٬ +FormatData/ar_SY/arab.NumberElements/2=؛ +FormatData/ar_SY/arab.NumberElements/3=٪؜ +FormatData/ar_SY/arab.NumberElements/4=٠ FormatData/ar_SY/arab.NumberElements/5=# -FormatData/ar_SY/arab.NumberElements/6=\u061c- -FormatData/ar_SY/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_SY/arab.NumberElements/8=\u0609 -FormatData/ar_SY/arab.NumberElements/9=\u221e -FormatData/ar_SY/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_TN/TND=\u062f.\u062a.\u200f +FormatData/ar_SY/arab.NumberElements/6=؜- +FormatData/ar_SY/arab.NumberElements/7=أس +FormatData/ar_SY/arab.NumberElements/8=؉ +FormatData/ar_SY/arab.NumberElements/9=∞ +FormatData/ar_SY/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_TN/TND=د.ت.‏ FormatData/ar_TN/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_TN/NumberPatterns/1='\u062f.\u062a.\u200f' #,##0.###;'\u062f.\u062a.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_TN/NumberPatterns/1='د.ت.‏' #,##0.###;'د.ت.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_TN/arab.NumberPatterns/2=#,##0% -FormatData/ar_TN/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_TN/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_TN/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_TN/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_TN/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_TN/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_TN/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_TN/MonthAbbreviations/0=\u062c\u0627\u0646\u0641\u064a -FormatData/ar_TN/MonthAbbreviations/1=\u0641\u064a\u0641\u0631\u064a -FormatData/ar_TN/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_TN/MonthAbbreviations/3=\u0623\u0641\u0631\u064a\u0644 -FormatData/ar_TN/MonthAbbreviations/4=\u0645\u0627\u064a -FormatData/ar_TN/MonthAbbreviations/5=\u062c\u0648\u0627\u0646 -FormatData/ar_TN/MonthAbbreviations/6=\u062c\u0648\u064a\u0644\u064a\u0629 -FormatData/ar_TN/MonthAbbreviations/7=\u0623\u0648\u062a -FormatData/ar_TN/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_TN/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_TN/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_TN/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_TN/DayNames/0=الأحد +FormatData/ar_TN/DayNames/1=الاثنين +FormatData/ar_TN/DayNames/2=الثلاثاء +FormatData/ar_TN/DayNames/3=الأربعاء +FormatData/ar_TN/DayNames/4=الخميس +FormatData/ar_TN/DayNames/5=الجمعة +FormatData/ar_TN/DayNames/6=السبت +FormatData/ar_TN/MonthAbbreviations/0=جانفي +FormatData/ar_TN/MonthAbbreviations/1=فيفري +FormatData/ar_TN/MonthAbbreviations/2=مارس +FormatData/ar_TN/MonthAbbreviations/3=أفريل +FormatData/ar_TN/MonthAbbreviations/4=ماي +FormatData/ar_TN/MonthAbbreviations/5=جوان +FormatData/ar_TN/MonthAbbreviations/6=جويلية +FormatData/ar_TN/MonthAbbreviations/7=أوت +FormatData/ar_TN/MonthAbbreviations/8=سبتمبر +FormatData/ar_TN/MonthAbbreviations/9=أكتوبر +FormatData/ar_TN/MonthAbbreviations/10=نوفمبر +FormatData/ar_TN/MonthAbbreviations/11=ديسمبر FormatData/ar_TN/MonthAbbreviations/12= -FormatData/ar_TN/Eras/0=\u0642.\u0645 -FormatData/ar_TN/Eras/1=\u0645 -FormatData/ar_TN/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_TN/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_TN/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_TN/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_TN/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_TN/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_TN/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_TN/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_TN/MonthNames/0=\u062c\u0627\u0646\u0641\u064a -FormatData/ar_TN/MonthNames/1=\u0641\u064a\u0641\u0631\u064a -FormatData/ar_TN/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_TN/MonthNames/3=\u0623\u0641\u0631\u064a\u0644 -FormatData/ar_TN/MonthNames/4=\u0645\u0627\u064a -FormatData/ar_TN/MonthNames/5=\u062c\u0648\u0627\u0646 -FormatData/ar_TN/MonthNames/6=\u062c\u0648\u064a\u0644\u064a\u0629 -FormatData/ar_TN/MonthNames/7=\u0623\u0648\u062a -FormatData/ar_TN/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_TN/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_TN/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_TN/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_TN/Eras/0=ق.م +FormatData/ar_TN/Eras/1=م +FormatData/ar_TN/DayAbbreviations/0=الأحد +FormatData/ar_TN/DayAbbreviations/1=الاثنين +FormatData/ar_TN/DayAbbreviations/2=الثلاثاء +FormatData/ar_TN/DayAbbreviations/3=الأربعاء +FormatData/ar_TN/DayAbbreviations/4=الخميس +FormatData/ar_TN/DayAbbreviations/5=الجمعة +FormatData/ar_TN/DayAbbreviations/6=السبت +LocaleNames/ar_TN/ar=العربية +FormatData/ar_TN/MonthNames/0=جانفي +FormatData/ar_TN/MonthNames/1=فيفري +FormatData/ar_TN/MonthNames/2=مارس +FormatData/ar_TN/MonthNames/3=أفريل +FormatData/ar_TN/MonthNames/4=ماي +FormatData/ar_TN/MonthNames/5=جوان +FormatData/ar_TN/MonthNames/6=جويلية +FormatData/ar_TN/MonthNames/7=أوت +FormatData/ar_TN/MonthNames/8=سبتمبر +FormatData/ar_TN/MonthNames/9=أكتوبر +FormatData/ar_TN/MonthNames/10=نوفمبر +FormatData/ar_TN/MonthNames/11=ديسمبر FormatData/ar_TN/MonthNames/12= -FormatData/ar_TN/AmPmMarkers/0=\u0635 -FormatData/ar_TN/AmPmMarkers/1=\u0645 +FormatData/ar_TN/AmPmMarkers/0=ص +FormatData/ar_TN/AmPmMarkers/1=م FormatData/ar_TN/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_TN/TimePatterns/1=h:mm:ss a z FormatData/ar_TN/TimePatterns/2=h:mm:ss a FormatData/ar_TN/TimePatterns/3=h:mm a -FormatData/ar_TN/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_TN/DatePatterns/0=EEEE، d MMMM y FormatData/ar_TN/DatePatterns/1=d MMMM y -FormatData/ar_TN/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_TN/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_TN/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_TN/EG=\u0645\u0635\u0631 -LocaleNames/ar_TN/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_TN/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_TN/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_TN/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_TN/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_TN/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_TN/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_TN/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_TN/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_TN/QA=\u0642\u0637\u0631 -LocaleNames/ar_TN/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_TN/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_TN/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_TN/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_TN/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_TN/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_TN/arab.NumberElements/0=\u066b -FormatData/ar_TN/arab.NumberElements/1=\u066c -FormatData/ar_TN/arab.NumberElements/2=\u061b -FormatData/ar_TN/arab.NumberElements/3=\u066a\u061c -FormatData/ar_TN/arab.NumberElements/4=\u0660 +FormatData/ar_TN/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_TN/DatePatterns/3=d‏/M‏/y +FormatData/ar_TN/DateTimePatterns/0={1}، {0} +LocaleNames/ar_TN/EG=مصر +LocaleNames/ar_TN/DZ=الجزائر +LocaleNames/ar_TN/BH=البحرين +LocaleNames/ar_TN/IQ=العراق +LocaleNames/ar_TN/JO=الأردن +LocaleNames/ar_TN/KW=الكويت +LocaleNames/ar_TN/LB=لبنان +LocaleNames/ar_TN/LY=ليبيا +LocaleNames/ar_TN/MA=المغرب +LocaleNames/ar_TN/OM=عُمان +LocaleNames/ar_TN/QA=قطر +LocaleNames/ar_TN/SA=المملكة العربية السعودية +LocaleNames/ar_TN/SD=السودان +LocaleNames/ar_TN/SY=سوريا +LocaleNames/ar_TN/TN=تونس +LocaleNames/ar_TN/AE=الإمارات العربية المتحدة +LocaleNames/ar_TN/YE=اليمن +FormatData/ar_TN/arab.NumberElements/0=٫ +FormatData/ar_TN/arab.NumberElements/1=٬ +FormatData/ar_TN/arab.NumberElements/2=؛ +FormatData/ar_TN/arab.NumberElements/3=٪؜ +FormatData/ar_TN/arab.NumberElements/4=٠ FormatData/ar_TN/arab.NumberElements/5=# -FormatData/ar_TN/arab.NumberElements/6=\u061c- -FormatData/ar_TN/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_TN/arab.NumberElements/8=\u0609 -FormatData/ar_TN/arab.NumberElements/9=\u221e -FormatData/ar_TN/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 -CurrencyNames/ar_YE/YER=\u0631.\u064a.\u200f +FormatData/ar_TN/arab.NumberElements/6=؜- +FormatData/ar_TN/arab.NumberElements/7=أس +FormatData/ar_TN/arab.NumberElements/8=؉ +FormatData/ar_TN/arab.NumberElements/9=∞ +FormatData/ar_TN/arab.NumberElements/10=ليس رقمًا +CurrencyNames/ar_YE/YER=ر.ي.‏ FormatData/ar_YE/arab.NumberPatterns/0=#,##0.### -# FormatData/ar_YE/NumberPatterns/1='\u0631.\u064a.\u200f' #,##0.###;'\u0631.\u064a.\u200f' #,##0.###- # Changed; see bug 4122840 +# FormatData/ar_YE/NumberPatterns/1='ر.ي.‏' #,##0.###;'ر.ي.‏' #,##0.###- # Changed; see bug 4122840 FormatData/ar_YE/arab.NumberPatterns/2=#,##0% -FormatData/ar_YE/DayNames/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_YE/DayNames/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_YE/DayNames/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_YE/DayNames/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_YE/DayNames/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_YE/DayNames/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_YE/DayNames/6=\u0627\u0644\u0633\u0628\u062a -FormatData/ar_YE/MonthAbbreviations/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_YE/MonthAbbreviations/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_YE/MonthAbbreviations/2=\u0645\u0627\u0631\u0633 -FormatData/ar_YE/MonthAbbreviations/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_YE/MonthAbbreviations/4=\u0645\u0627\u064a\u0648 -FormatData/ar_YE/MonthAbbreviations/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_YE/MonthAbbreviations/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_YE/MonthAbbreviations/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_YE/MonthAbbreviations/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_YE/MonthAbbreviations/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_YE/MonthAbbreviations/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_YE/MonthAbbreviations/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_YE/DayNames/0=الأحد +FormatData/ar_YE/DayNames/1=الاثنين +FormatData/ar_YE/DayNames/2=الثلاثاء +FormatData/ar_YE/DayNames/3=الأربعاء +FormatData/ar_YE/DayNames/4=الخميس +FormatData/ar_YE/DayNames/5=الجمعة +FormatData/ar_YE/DayNames/6=السبت +FormatData/ar_YE/MonthAbbreviations/0=يناير +FormatData/ar_YE/MonthAbbreviations/1=فبراير +FormatData/ar_YE/MonthAbbreviations/2=مارس +FormatData/ar_YE/MonthAbbreviations/3=أبريل +FormatData/ar_YE/MonthAbbreviations/4=مايو +FormatData/ar_YE/MonthAbbreviations/5=يونيو +FormatData/ar_YE/MonthAbbreviations/6=يوليو +FormatData/ar_YE/MonthAbbreviations/7=أغسطس +FormatData/ar_YE/MonthAbbreviations/8=سبتمبر +FormatData/ar_YE/MonthAbbreviations/9=أكتوبر +FormatData/ar_YE/MonthAbbreviations/10=نوفمبر +FormatData/ar_YE/MonthAbbreviations/11=ديسمبر FormatData/ar_YE/MonthAbbreviations/12= -FormatData/ar_YE/Eras/0=\u0642.\u0645 -FormatData/ar_YE/Eras/1=\u0645 -FormatData/ar_YE/DayAbbreviations/0=\u0627\u0644\u0623\u062d\u062f -FormatData/ar_YE/DayAbbreviations/1=\u0627\u0644\u0627\u062b\u0646\u064a\u0646 -FormatData/ar_YE/DayAbbreviations/2=\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621 -FormatData/ar_YE/DayAbbreviations/3=\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621 -FormatData/ar_YE/DayAbbreviations/4=\u0627\u0644\u062e\u0645\u064a\u0633 -FormatData/ar_YE/DayAbbreviations/5=\u0627\u0644\u062c\u0645\u0639\u0629 -FormatData/ar_YE/DayAbbreviations/6=\u0627\u0644\u0633\u0628\u062a -LocaleNames/ar_YE/ar=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 -FormatData/ar_YE/MonthNames/0=\u064a\u0646\u0627\u064a\u0631 -FormatData/ar_YE/MonthNames/1=\u0641\u0628\u0631\u0627\u064a\u0631 -FormatData/ar_YE/MonthNames/2=\u0645\u0627\u0631\u0633 -FormatData/ar_YE/MonthNames/3=\u0623\u0628\u0631\u064a\u0644 -FormatData/ar_YE/MonthNames/4=\u0645\u0627\u064a\u0648 -FormatData/ar_YE/MonthNames/5=\u064a\u0648\u0646\u064a\u0648 -FormatData/ar_YE/MonthNames/6=\u064a\u0648\u0644\u064a\u0648 -FormatData/ar_YE/MonthNames/7=\u0623\u063a\u0633\u0637\u0633 -FormatData/ar_YE/MonthNames/8=\u0633\u0628\u062a\u0645\u0628\u0631 -FormatData/ar_YE/MonthNames/9=\u0623\u0643\u062a\u0648\u0628\u0631 -FormatData/ar_YE/MonthNames/10=\u0646\u0648\u0641\u0645\u0628\u0631 -FormatData/ar_YE/MonthNames/11=\u062f\u064a\u0633\u0645\u0628\u0631 +FormatData/ar_YE/Eras/0=ق.م +FormatData/ar_YE/Eras/1=م +FormatData/ar_YE/DayAbbreviations/0=الأحد +FormatData/ar_YE/DayAbbreviations/1=الاثنين +FormatData/ar_YE/DayAbbreviations/2=الثلاثاء +FormatData/ar_YE/DayAbbreviations/3=الأربعاء +FormatData/ar_YE/DayAbbreviations/4=الخميس +FormatData/ar_YE/DayAbbreviations/5=الجمعة +FormatData/ar_YE/DayAbbreviations/6=السبت +LocaleNames/ar_YE/ar=العربية +FormatData/ar_YE/MonthNames/0=يناير +FormatData/ar_YE/MonthNames/1=فبراير +FormatData/ar_YE/MonthNames/2=مارس +FormatData/ar_YE/MonthNames/3=أبريل +FormatData/ar_YE/MonthNames/4=مايو +FormatData/ar_YE/MonthNames/5=يونيو +FormatData/ar_YE/MonthNames/6=يوليو +FormatData/ar_YE/MonthNames/7=أغسطس +FormatData/ar_YE/MonthNames/8=سبتمبر +FormatData/ar_YE/MonthNames/9=أكتوبر +FormatData/ar_YE/MonthNames/10=نوفمبر +FormatData/ar_YE/MonthNames/11=ديسمبر FormatData/ar_YE/MonthNames/12= -FormatData/ar_YE/AmPmMarkers/0=\u0635 -FormatData/ar_YE/AmPmMarkers/1=\u0645 +FormatData/ar_YE/AmPmMarkers/0=ص +FormatData/ar_YE/AmPmMarkers/1=م FormatData/ar_YE/TimePatterns/0=h:mm:ss a zzzz FormatData/ar_YE/TimePatterns/1=h:mm:ss a z FormatData/ar_YE/TimePatterns/2=h:mm:ss a FormatData/ar_YE/TimePatterns/3=h:mm a -FormatData/ar_YE/DatePatterns/0=EEEE\u060c d MMMM y +FormatData/ar_YE/DatePatterns/0=EEEE، d MMMM y FormatData/ar_YE/DatePatterns/1=d MMMM y -FormatData/ar_YE/DatePatterns/2=dd\u200f/MM\u200f/y -FormatData/ar_YE/DatePatterns/3=d\u200f/M\u200f/y -FormatData/ar_YE/DateTimePatterns/0={1}\u060c {0} -LocaleNames/ar_YE/EG=\u0645\u0635\u0631 -LocaleNames/ar_YE/DZ=\u0627\u0644\u062c\u0632\u0627\u0626\u0631 -LocaleNames/ar_YE/BH=\u0627\u0644\u0628\u062d\u0631\u064a\u0646 -LocaleNames/ar_YE/IQ=\u0627\u0644\u0639\u0631\u0627\u0642 -LocaleNames/ar_YE/JO=\u0627\u0644\u0623\u0631\u062f\u0646 -LocaleNames/ar_YE/KW=\u0627\u0644\u0643\u0648\u064a\u062a -LocaleNames/ar_YE/LB=\u0644\u0628\u0646\u0627\u0646 -LocaleNames/ar_YE/LY=\u0644\u064a\u0628\u064a\u0627 -LocaleNames/ar_YE/MA=\u0627\u0644\u0645\u063a\u0631\u0628 -LocaleNames/ar_YE/OM=\u0639\u064f\u0645\u0627\u0646 -LocaleNames/ar_YE/QA=\u0642\u0637\u0631 -LocaleNames/ar_YE/SA=\u0627\u0644\u0645\u0645\u0644\u0643\u0629 \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629 -LocaleNames/ar_YE/SD=\u0627\u0644\u0633\u0648\u062f\u0627\u0646 -LocaleNames/ar_YE/SY=\u0633\u0648\u0631\u064a\u0627 -LocaleNames/ar_YE/TN=\u062a\u0648\u0646\u0633 -LocaleNames/ar_YE/AE=\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062a \u0627\u0644\u0639\u0631\u0628\u064a\u0629 \u0627\u0644\u0645\u062a\u062d\u062f\u0629 -LocaleNames/ar_YE/YE=\u0627\u0644\u064a\u0645\u0646 -FormatData/ar_YE/arab.NumberElements/0=\u066b -FormatData/ar_YE/arab.NumberElements/1=\u066c -FormatData/ar_YE/arab.NumberElements/2=\u061b -FormatData/ar_YE/arab.NumberElements/3=\u066a\u061c -FormatData/ar_YE/arab.NumberElements/4=\u0660 +FormatData/ar_YE/DatePatterns/2=dd‏/MM‏/y +FormatData/ar_YE/DatePatterns/3=d‏/M‏/y +FormatData/ar_YE/DateTimePatterns/0={1}، {0} +LocaleNames/ar_YE/EG=مصر +LocaleNames/ar_YE/DZ=الجزائر +LocaleNames/ar_YE/BH=البحرين +LocaleNames/ar_YE/IQ=العراق +LocaleNames/ar_YE/JO=الأردن +LocaleNames/ar_YE/KW=الكويت +LocaleNames/ar_YE/LB=لبنان +LocaleNames/ar_YE/LY=ليبيا +LocaleNames/ar_YE/MA=المغرب +LocaleNames/ar_YE/OM=عُمان +LocaleNames/ar_YE/QA=قطر +LocaleNames/ar_YE/SA=المملكة العربية السعودية +LocaleNames/ar_YE/SD=السودان +LocaleNames/ar_YE/SY=سوريا +LocaleNames/ar_YE/TN=تونس +LocaleNames/ar_YE/AE=الإمارات العربية المتحدة +LocaleNames/ar_YE/YE=اليمن +FormatData/ar_YE/arab.NumberElements/0=٫ +FormatData/ar_YE/arab.NumberElements/1=٬ +FormatData/ar_YE/arab.NumberElements/2=؛ +FormatData/ar_YE/arab.NumberElements/3=٪؜ +FormatData/ar_YE/arab.NumberElements/4=٠ FormatData/ar_YE/arab.NumberElements/5=# -FormatData/ar_YE/arab.NumberElements/6=\u061c- -FormatData/ar_YE/arab.NumberElements/7=\u0623\u0633 -FormatData/ar_YE/arab.NumberElements/8=\u0609 -FormatData/ar_YE/arab.NumberElements/9=\u221e -FormatData/ar_YE/arab.NumberElements/10=\u0644\u064a\u0633\u00a0\u0631\u0642\u0645\u064b\u0627 +FormatData/ar_YE/arab.NumberElements/6=؜- +FormatData/ar_YE/arab.NumberElements/7=أس +FormatData/ar_YE/arab.NumberElements/8=؉ +FormatData/ar_YE/arab.NumberElements/9=∞ +FormatData/ar_YE/arab.NumberElements/10=ليس رقمًا # bug #4113654 (this is obviously not an exhaustive test; I'm trying it here for a single # inheritance chain only. This bug fix also gets tested fairly well by the tests for all # the other bugs as given above) FormatData//latn.NumberPatterns/0=#,##0.### -# FormatData//NumberPatterns/1=\u00a4 #,##0.00;-\u00a4 #,##0.00 # Changed; see bug 4122840 +# FormatData//NumberPatterns/1=¤ #,##0.00;-¤ #,##0.00 # Changed; see bug 4122840 FormatData//latn.NumberPatterns/2=#,##0% FormatData/fr/latn.NumberPatterns/0=#,##0.### -# FormatData/fr/NumberPatterns/1=\u00a4 #,##0.00;-\u00a4 #,##0.00 # Changed; see bug 4122840 +# FormatData/fr/NumberPatterns/1=¤ #,##0.00;-¤ #,##0.00 # Changed; see bug 4122840 # FormatData/fr/NumberPatterns/2=#,##0% # changed, see bug 6547501 CurrencyNames/fr_FR/FRF=F -CurrencyNames/fr_FR/EUR=\u20ac +CurrencyNames/fr_FR/EUR=€ FormatData/fr_FR/latn.NumberPatterns/0=#,##0.### # FormatData/fr_FR/NumberPatterns/1=#,##0.00 F;-#,##0.00 F # Changed; see bug 4122840 # FormatData/fr_FR/NumberPatterns/2=#,##0% # changed; see bug 6547501 @@ -2207,19 +2207,19 @@ FormatData/fr_FR/DayNames/4=jeudi FormatData/fr_FR/DayNames/5=vendredi FormatData/fr_FR/DayNames/6=samedi FormatData/fr_FR/MonthNames/0=janvier -FormatData/fr_FR/MonthNames/1=f\u00e9vrier +FormatData/fr_FR/MonthNames/1=février FormatData/fr_FR/MonthNames/2=mars FormatData/fr_FR/MonthNames/3=avril FormatData/fr_FR/MonthNames/4=mai FormatData/fr_FR/MonthNames/5=juin FormatData/fr_FR/MonthNames/6=juillet -FormatData/fr_FR/MonthNames/7=ao\u00fbt +FormatData/fr_FR/MonthNames/7=août FormatData/fr_FR/MonthNames/8=septembre FormatData/fr_FR/MonthNames/9=octobre FormatData/fr_FR/MonthNames/10=novembre -FormatData/fr_FR/MonthNames/11=d\u00e9cembre +FormatData/fr_FR/MonthNames/11=décembre FormatData/fr_FR/MonthNames/12= -LocaleNames/fr_FR/fr=fran\u00e7ais +LocaleNames/fr_FR/fr=français LocaleNames/fr_FR/en=anglais LocaleNames/fr_FR/de=allemand LocaleNames/fr_FR/da=danois @@ -2229,10 +2229,10 @@ LocaleNames/fr_FR/fi=finnois LocaleNames/fr_FR/it=italien LocaleNames/fr_FR/ja=japonais #bug 4965260 -LocaleNames/fr_FR/nl=n\u00e9erlandais -LocaleNames/fr_FR/no=norv\u00e9gien +LocaleNames/fr_FR/nl=néerlandais +LocaleNames/fr_FR/no=norvégien LocaleNames/fr_FR/pt=portugais -LocaleNames/fr_FR/sv=su\u00e9dois +LocaleNames/fr_FR/sv=suédois LocaleNames/fr_FR/tr=turc FormatData/fr_FR/TimePatterns/0=HH:mm:ss zzzz FormatData/fr_FR/TimePatterns/1=HH:mm:ss z @@ -2244,24 +2244,24 @@ FormatData/fr_FR/DatePatterns/2=d MMM y FormatData/fr_FR/DatePatterns/3=dd/MM/y FormatData/fr_FR/DateTimePatterns/0={1}, {0} FormatData/fr_FR/latn.NumberElements/0=, -FormatData/fr_FR/latn.NumberElements/1=\u202f +FormatData/fr_FR/latn.NumberElements/1=  FormatData/fr_FR/latn.NumberElements/2=; FormatData/fr_FR/latn.NumberElements/3=% FormatData/fr_FR/latn.NumberElements/4=0 FormatData/fr_FR/latn.NumberElements/5=# FormatData/fr_FR/latn.NumberElements/6=- FormatData/fr_FR/latn.NumberElements/7=E -FormatData/fr_FR/latn.NumberElements/8=\u2030 -FormatData/fr_FR/latn.NumberElements/9=\u221e +FormatData/fr_FR/latn.NumberElements/8=‰ +FormatData/fr_FR/latn.NumberElements/9=∞ FormatData/fr_FR/latn.NumberElements/10=NaN FormatData/fr_FR/Eras/0=av. J.-C. FormatData/fr_FR/Eras/1=ap. J.-C. LocaleNames/fr_FR/FR=France -LocaleNames/fr_FR/US=\u00c9tats-Unis +LocaleNames/fr_FR/US=États-Unis LocaleNames/fr_FR/DK=Danemark LocaleNames/fr_FR/DE=Allemagne LocaleNames/fr_FR/AT=Autriche -LocaleNames/fr_FR/GR=Gr\u00e8ce +LocaleNames/fr_FR/GR=Grèce LocaleNames/fr_FR/ES=Espagne LocaleNames/fr_FR/FI=Finlande LocaleNames/fr_FR/IT=Italie @@ -2270,9 +2270,9 @@ LocaleNames/fr_FR/BE=Belgique LocaleNames/fr_FR/CA=Canada LocaleNames/fr_FR/JP=Japon LocaleNames/fr_FR/NL=Pays-Bas -LocaleNames/fr_FR/NO=Norv\u00e8ge +LocaleNames/fr_FR/NO=Norvège LocaleNames/fr_FR/PT=Portugal -LocaleNames/fr_FR/SE=Su\u00e8de +LocaleNames/fr_FR/SE=Suède LocaleNames/fr_FR/TR=Turquie FormatData/fr_FR/DayAbbreviations/0=dim. FormatData/fr_FR/DayAbbreviations/1=lun. @@ -2282,132 +2282,132 @@ FormatData/fr_FR/DayAbbreviations/4=jeu. FormatData/fr_FR/DayAbbreviations/5=ven. FormatData/fr_FR/DayAbbreviations/6=sam. FormatData/fr_FR/MonthAbbreviations/0=janv. -FormatData/fr_FR/MonthAbbreviations/1=f\u00e9vr. +FormatData/fr_FR/MonthAbbreviations/1=févr. FormatData/fr_FR/MonthAbbreviations/2=mars FormatData/fr_FR/MonthAbbreviations/3=avr. FormatData/fr_FR/MonthAbbreviations/4=mai FormatData/fr_FR/MonthAbbreviations/5=juin FormatData/fr_FR/MonthAbbreviations/6=juil. -FormatData/fr_FR/MonthAbbreviations/7=ao\u00fbt +FormatData/fr_FR/MonthAbbreviations/7=août FormatData/fr_FR/MonthAbbreviations/8=sept. FormatData/fr_FR/MonthAbbreviations/9=oct. FormatData/fr_FR/MonthAbbreviations/10=nov. -FormatData/fr_FR/MonthAbbreviations/11=d\u00e9c. +FormatData/fr_FR/MonthAbbreviations/11=déc. FormatData/fr_FR/MonthAbbreviations/12= FormatData/fr_FR/AmPmMarkers/0=AM FormatData/fr_FR/AmPmMarkers/1=PM # bug #4117054 -FormatData/ja_JP/AmPmMarkers/0=\u5348\u524d -FormatData/ja_JP/AmPmMarkers/1=\u5348\u5f8c +FormatData/ja_JP/AmPmMarkers/0=午前 +FormatData/ja_JP/AmPmMarkers/1=午後 # bug #4122840, 4290801 -FormatData/ar_AE/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_BH/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_DZ/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_EG/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_IQ/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_JO/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_KW/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_LB/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_LY/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_MA/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_OM/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_QA/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_SA/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_SD/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_SY/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_TN/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/ar_YE/arab.NumberPatterns/1=\u200f#,##0.00\u00a0\u00a4 -FormatData/en_AU/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/en_NZ/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/en_ZA/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_AR/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00 -FormatData/es_BO/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_CL/latn.NumberPatterns/1=\u00a4#,##0.00;\u00a4-#,##0.00 -FormatData/es_CO/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00 -FormatData/es_CR/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_DO/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_EC/latn.NumberPatterns/1=\u00a4#,##0.00;\u00a4-#,##0.00 -FormatData/es_GT/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_HN/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_MX/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_NI/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_PA/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_PE/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00 -FormatData/es_PR/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_PY/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00;\u00a4\u00a0-#,##0.00 -FormatData/es_SV/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/es_UY/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00 -FormatData/es_VE/latn.NumberPatterns/1=\u00a4#,##0.00;\u00a4-#,##0.00 -FormatData/fr_FR/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -FormatData/it_IT/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -#FormatData/ja_JP/NumberPatterns/1=\u00a4#,##0.00 #see bug 4175306 -FormatData/ko_KR/latn.NumberPatterns/1=\u00a4#,##0.00 -FormatData/pl_PL/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -FormatData/pt_BR/latn.NumberPatterns/1=\u00a4\u00a0#,##0.00 +FormatData/ar_AE/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_BH/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_DZ/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_EG/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_IQ/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_JO/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_KW/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_LB/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_LY/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_MA/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_OM/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_QA/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_SA/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_SD/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_SY/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_TN/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/ar_YE/arab.NumberPatterns/1=‏#,##0.00 ¤ +FormatData/en_AU/latn.NumberPatterns/1=¤#,##0.00 +FormatData/en_NZ/latn.NumberPatterns/1=¤#,##0.00 +FormatData/en_ZA/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_AR/latn.NumberPatterns/1=¤ #,##0.00 +FormatData/es_BO/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_CL/latn.NumberPatterns/1=¤#,##0.00;¤-#,##0.00 +FormatData/es_CO/latn.NumberPatterns/1=¤ #,##0.00 +FormatData/es_CR/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_DO/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_EC/latn.NumberPatterns/1=¤#,##0.00;¤-#,##0.00 +FormatData/es_GT/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_HN/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_MX/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_NI/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_PA/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_PE/latn.NumberPatterns/1=¤ #,##0.00 +FormatData/es_PR/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_PY/latn.NumberPatterns/1=¤ #,##0.00;¤ -#,##0.00 +FormatData/es_SV/latn.NumberPatterns/1=¤#,##0.00 +FormatData/es_UY/latn.NumberPatterns/1=¤ #,##0.00 +FormatData/es_VE/latn.NumberPatterns/1=¤#,##0.00;¤-#,##0.00 +FormatData/fr_FR/latn.NumberPatterns/1=#,##0.00 ¤ +FormatData/it_IT/latn.NumberPatterns/1=#,##0.00 ¤ +#FormatData/ja_JP/NumberPatterns/1=¤#,##0.00 #see bug 4175306 +FormatData/ko_KR/latn.NumberPatterns/1=¤#,##0.00 +FormatData/pl_PL/latn.NumberPatterns/1=#,##0.00 ¤ +FormatData/pt_BR/latn.NumberPatterns/1=¤ #,##0.00 #Changed; see 4936845 -FormatData/ru_RU/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -FormatData/uk_UA/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 +FormatData/ru_RU/latn.NumberPatterns/1=#,##0.00 ¤ +FormatData/uk_UA/latn.NumberPatterns/1=#,##0.00 ¤ # bug #4139860 FormatData/cs/DatePatterns/0=EEEE d. MMMM y FormatData/cs/DatePatterns/1=d. MMMM y FormatData/cs/DatePatterns/2=d. M. y FormatData/cs/DatePatterns/3=dd.MM.yy -FormatData/cs/latn.NumberElements/1=\u00a0 +FormatData/cs/latn.NumberElements/1=  FormatData/cs_CZ/latn.NumberPatterns/0=#,##0.### -FormatData/cs_CZ/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -FormatData/cs_CZ/latn.NumberPatterns/2=#,##0\u00a0% +FormatData/cs_CZ/latn.NumberPatterns/1=#,##0.00 ¤ +FormatData/cs_CZ/latn.NumberPatterns/2=#,##0 % #bug #4135752 -FormatData/th_TH/latn.NumberPatterns/1=\u00a4#,##0.00 -CurrencyNames/th_TH/THB=\u0e3f +FormatData/th_TH/latn.NumberPatterns/1=¤#,##0.00 +CurrencyNames/th_TH/THB=฿ #bug #4153698 # TimeZoneNames/zh_HK/zoneStrings/0/1=Hong Kong Standard Time # changed, see bug 4261506 # TimeZoneNames/zh_HK/zoneStrings/0/2=HKST # changed, see bug 4261506 -LocaleNames/zh/HK=\u4e2d\u56fd\u9999\u6e2f\u7279\u522b\u884c\u653f\u533a -FormatData/zh_HK/MonthNames/0=1\u6708 -FormatData/zh_HK/MonthNames/1=2\u6708 -FormatData/zh_HK/MonthNames/2=3\u6708 -FormatData/zh_HK/MonthNames/3=4\u6708 -FormatData/zh_HK/MonthAbbreviations/0=1\u6708 -FormatData/zh_HK/MonthAbbreviations/1=2\u6708 -FormatData/zh_HK/MonthAbbreviations/2=3\u6708 -FormatData/zh_HK/MonthAbbreviations/3=4\u6708 -FormatData/zh_HK/DayNames/0=\u661f\u671f\u65e5 -FormatData/zh_HK/DayNames/1=\u661f\u671f\u4e00 -FormatData/zh_HK/DayNames/2=\u661f\u671f\u4e8c -FormatData/zh_HK/DayAbbreviations/0=\u9031\u65e5 -FormatData/zh_HK/DayAbbreviations/1=\u9031\u4e00 -FormatData/zh_HK/DayAbbreviations/2=\u9031\u4e8c -FormatData/zh_HK/latn.NumberPatterns/1=\u00a4#,##0.00 +LocaleNames/zh/HK=中国香港特别行政区 +FormatData/zh_HK/MonthNames/0=1月 +FormatData/zh_HK/MonthNames/1=2月 +FormatData/zh_HK/MonthNames/2=3月 +FormatData/zh_HK/MonthNames/3=4月 +FormatData/zh_HK/MonthAbbreviations/0=1月 +FormatData/zh_HK/MonthAbbreviations/1=2月 +FormatData/zh_HK/MonthAbbreviations/2=3月 +FormatData/zh_HK/MonthAbbreviations/3=4月 +FormatData/zh_HK/DayNames/0=星期日 +FormatData/zh_HK/DayNames/1=星期一 +FormatData/zh_HK/DayNames/2=星期二 +FormatData/zh_HK/DayAbbreviations/0=週日 +FormatData/zh_HK/DayAbbreviations/1=週一 +FormatData/zh_HK/DayAbbreviations/2=週二 +FormatData/zh_HK/latn.NumberPatterns/1=¤#,##0.00 CurrencyNames/zh_HK/HKD=HK$ FormatData/zh_HK/TimePatterns/0=ah:mm:ss [zzzz] FormatData/zh_HK/TimePatterns/1=ah:mm:ss [z] FormatData/zh_HK/TimePatterns/2=ah:mm:ss FormatData/zh_HK/TimePatterns/3=ah:mm -FormatData/zh_HK/DatePatterns/0=y\u5e74M\u6708d\u65e5EEEE -FormatData/zh_HK/DatePatterns/1=y\u5e74M\u6708d\u65e5 -FormatData/zh_HK/DatePatterns/2=y\u5e74M\u6708d\u65e5 +FormatData/zh_HK/DatePatterns/0=y年M月d日EEEE +FormatData/zh_HK/DatePatterns/1=y年M月d日 +FormatData/zh_HK/DatePatterns/2=y年M月d日 FormatData/zh_HK/DatePatterns/3=d/M/y FormatData/zh_HK/DateTimePatterns/0={1} {0} #bug #4149569 -LocaleNames/tr/TR=T\u00fcrkiye +LocaleNames/tr/TR=Türkiye #bug 4175306 -FormatData/es_ES/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 -FormatData/ja_JP/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/es_ES/latn.NumberPatterns/1=#,##0.00 ¤ +FormatData/ja_JP/latn.NumberPatterns/1=¤#,##0.00 #bug #4215747 - commented out by mfang due to 4900884 -#FormatData/ko/TimePatterns/0=a h'\uc2dc' m'\ubd84' s'\ucd08' z -#FormatData/ko/TimePatterns/1=a h'\uc2dc' m'\ubd84' s'\ucd08' +#FormatData/ko/TimePatterns/0=a h'시' m'분' s'초' z +#FormatData/ko/TimePatterns/1=a h'시' m'분' s'초' #bug 4900884 -FormatData/ko/TimePatterns/0=a h\uc2dc m\ubd84 s\ucd08 zzzz -FormatData/ko/TimePatterns/1=a h\uc2dc m\ubd84 s\ucd08 z +FormatData/ko/TimePatterns/0=a h시 m분 s초 zzzz +FormatData/ko/TimePatterns/1=a h시 m분 s초 z FormatData/ko/TimePatterns/2=a h:mm:ss FormatData/ko/TimePatterns/3=a h:mm @@ -2415,111 +2415,111 @@ FormatData/ko/TimePatterns/3=a h:mm LocaleNames/es/SV=El Salvador #bug nobugid, 4290801, 4942982 -CurrencyNames/ru_RU/RUB=\u20bd +CurrencyNames/ru_RU/RUB=₽ #bug 4826794 -LocaleNames/ru_RU/MM=\u041c\u044c\u044f\u043d\u043c\u0430 (\u0411\u0438\u0440\u043c\u0430) +LocaleNames/ru_RU/MM=Мьянма (Бирма) #bug 4945388 -CurrencyNames/bg_BG/BGN=\u043b\u0432. +CurrencyNames/bg_BG/BGN=лв. #bug 4794068 FormatData/ca_ES/latn.NumberPatterns/0=#,##0.### #bug 5032580 -FormatData/sk/DayNames/0=nede\u013ea +FormatData/sk/DayNames/0=nedeľa FormatData/sk/DayAbbreviations/5=pi #bug 5074431 -FormatData/bg/DayNames/4=\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a +FormatData/bg/DayNames/4=четвъртък #bug 2121133 -FormatData/sv/latn.NumberElements/1=\u00a0 +FormatData/sv/latn.NumberElements/1=  #bug 6208712 -LocaleNames/zh/tw=\u5951\u7ef4\u8bed +LocaleNames/zh/tw=契维语 #bug 6277696 #zh_SG, id, id_ID, en_MT, mt_MT, en_PH, el, el_CY, ms, ms_MY #zh_SG -FormatData/zh_SG/DayAbbreviations/0=\u5468\u65e5 -FormatData/zh_SG/DayAbbreviations/1=\u5468\u4e00 -FormatData/zh_SG/DayAbbreviations/2=\u5468\u4e8c -FormatData/zh_SG/DayAbbreviations/3=\u5468\u4e09 -FormatData/zh_SG/DayAbbreviations/4=\u5468\u56db -FormatData/zh_SG/DayAbbreviations/5=\u5468\u4e94 -FormatData/zh_SG/DayAbbreviations/6=\u5468\u516d +FormatData/zh_SG/DayAbbreviations/0=周日 +FormatData/zh_SG/DayAbbreviations/1=周一 +FormatData/zh_SG/DayAbbreviations/2=周二 +FormatData/zh_SG/DayAbbreviations/3=周三 +FormatData/zh_SG/DayAbbreviations/4=周四 +FormatData/zh_SG/DayAbbreviations/5=周五 +FormatData/zh_SG/DayAbbreviations/6=周六 FormatData/zh_SG/latn.NumberPatterns/0=#,##0.### -FormatData/zh_SG/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/zh_SG/latn.NumberPatterns/1=¤#,##0.00 FormatData/zh_SG/latn.NumberPatterns/2=#,##0% CurrencyNames/zh_SG/SGD=$ FormatData/zh_SG/TimePatterns/0=zzzz ah:mm:ss FormatData/zh_SG/TimePatterns/1=z ah:mm:ss FormatData/zh_SG/TimePatterns/2=ah:mm:ss FormatData/zh_SG/TimePatterns/3=ah:mm -FormatData/zh_SG/DatePatterns/0=y\u5e74M\u6708d\u65e5EEEE -FormatData/zh_SG/DatePatterns/1=y\u5e74M\u6708d\u65e5 -FormatData/zh_SG/DatePatterns/2=y\u5e74M\u6708d\u65e5 +FormatData/zh_SG/DatePatterns/0=y年M月d日EEEE +FormatData/zh_SG/DatePatterns/1=y年M月d日 +FormatData/zh_SG/DatePatterns/2=y年M月d日 FormatData/zh_SG/DatePatterns/3=dd/MM/yy FormatData/zh_SG/DateTimePatterns/0={1} {0} -LocaleNames/zh_SG/ae=\u963f\u7ef4\u65af\u5854\u8bed -LocaleNames/zh_SG/ak=\u963f\u80af\u8bed -LocaleNames/zh_SG/cr=\u514b\u91cc\u8bed -LocaleNames/zh_SG/cu=\u6559\u4f1a\u65af\u62c9\u592b\u8bed -LocaleNames/zh_SG/ff=\u5bcc\u62c9\u8bed -LocaleNames/zh_SG/gv=\u9a6c\u6069\u8bed -LocaleNames/zh_SG/ig=\u4f0a\u535a\u8bed -LocaleNames/zh_SG/ii=\u51c9\u5c71\u5f5d\u8bed -LocaleNames/zh_SG/ko=\u97e9\u8bed -LocaleNames/zh_SG/kw=\u5eb7\u6c83\u5c14\u8bed -LocaleNames/zh_SG/lg=\u5362\u5e72\u8fbe\u8bed -LocaleNames/zh_SG/li=\u6797\u5821\u8bed -LocaleNames/zh_SG/lu=\u9c81\u5df4\u52a0\u4e39\u52a0\u8bed -LocaleNames/zh_SG/nd=\u5317\u6069\u5fb7\u8d1d\u52d2\u8bed -LocaleNames/zh_SG/nr=\u5357\u6069\u5fb7\u8d1d\u52d2\u8bed -LocaleNames/zh_SG/sc=\u8428\u4e01\u8bed -LocaleNames/zh_SG/ty=\u5854\u5e0c\u63d0\u8bed -LocaleNames/zh_SG/AS=\u7f8e\u5c5e\u8428\u6469\u4e9a -LocaleNames/zh_SG/AU=\u6fb3\u5927\u5229\u4e9a -LocaleNames/zh_SG/BD=\u5b5f\u52a0\u62c9\u56fd -LocaleNames/zh_SG/BV=\u5e03\u97e6\u5c9b -LocaleNames/zh_SG/BZ=\u4f2f\u5229\u5179 -LocaleNames/zh_SG/CZ=\u6377\u514b -LocaleNames/zh_SG/ER=\u5384\u7acb\u7279\u91cc\u4e9a -LocaleNames/zh_SG/FK=\u798f\u514b\u5170\u7fa4\u5c9b -LocaleNames/zh_SG/FM=\u5bc6\u514b\u7f57\u5c3c\u897f\u4e9a -LocaleNames/zh_SG/GS=\u5357\u4e54\u6cbb\u4e9a\u548c\u5357\u6851\u5a01\u5947\u7fa4\u5c9b -LocaleNames/zh_SG/GW=\u51e0\u5185\u4e9a\u6bd4\u7ecd -LocaleNames/zh_SG/HK=\u4e2d\u56fd\u9999\u6e2f\u7279\u522b\u884c\u653f\u533a -LocaleNames/zh_SG/HM=\u8d6b\u5fb7\u5c9b\u548c\u9ea6\u514b\u5510\u7eb3\u7fa4\u5c9b -LocaleNames/zh_SG/ID=\u5370\u5ea6\u5c3c\u897f\u4e9a -LocaleNames/zh_SG/KR=\u97e9\u56fd -LocaleNames/zh_SG/LA=\u8001\u631d -LocaleNames/zh_SG/MK=\u5317\u9a6c\u5176\u987f -LocaleNames/zh_SG/MO=\u4e2d\u56fd\u6fb3\u95e8\u7279\u522b\u884c\u653f\u533a -LocaleNames/zh_SG/MP=\u5317\u9a6c\u91cc\u4e9a\u7eb3\u7fa4\u5c9b -LocaleNames/zh_SG/NU=\u7ebd\u57c3 -LocaleNames/zh_SG/NZ=\u65b0\u897f\u5170 -LocaleNames/zh_SG/PF=\u6cd5\u5c5e\u6ce2\u5229\u5c3c\u897f\u4e9a -LocaleNames/zh_SG/PM=\u5723\u76ae\u57c3\u5c14\u548c\u5bc6\u514b\u9686\u7fa4\u5c9b -LocaleNames/zh_SG/PN=\u76ae\u7279\u51ef\u6069\u7fa4\u5c9b -LocaleNames/zh_SG/PR=\u6ce2\u591a\u9ece\u5404 -LocaleNames/zh_SG/PS=\u5df4\u52d2\u65af\u5766\u9886\u571f -LocaleNames/zh_SG/RE=\u7559\u5c3c\u6c6a -LocaleNames/zh_SG/SA=\u6c99\u7279\u963f\u62c9\u4f2f -LocaleNames/zh_SG/SH=\u5723\u8d6b\u52d2\u62ff -LocaleNames/zh_SG/SJ=\u65af\u74e6\u5c14\u5df4\u548c\u626c\u9a6c\u5ef6 -LocaleNames/zh_SG/SL=\u585e\u62c9\u5229\u6602 -LocaleNames/zh_SG/TC=\u7279\u514b\u65af\u548c\u51ef\u79d1\u65af\u7fa4\u5c9b -LocaleNames/zh_SG/TK=\u6258\u514b\u52b3 -LocaleNames/zh_SG/TW=\u53f0\u6e7e -LocaleNames/zh_SG/UM=\u7f8e\u56fd\u672c\u571f\u5916\u5c0f\u5c9b\u5c7f -LocaleNames/zh_SG/WF=\u74e6\u5229\u65af\u548c\u5bcc\u56fe\u7eb3 -LocaleNames/zh_SG/WS=\u8428\u6469\u4e9a -LocaleNames/zh_SG/YT=\u9a6c\u7ea6\u7279 +LocaleNames/zh_SG/ae=阿维斯塔语 +LocaleNames/zh_SG/ak=阿肯语 +LocaleNames/zh_SG/cr=克里语 +LocaleNames/zh_SG/cu=教会斯拉夫语 +LocaleNames/zh_SG/ff=富拉语 +LocaleNames/zh_SG/gv=马恩语 +LocaleNames/zh_SG/ig=伊博语 +LocaleNames/zh_SG/ii=凉山彝语 +LocaleNames/zh_SG/ko=韩语 +LocaleNames/zh_SG/kw=康沃尔语 +LocaleNames/zh_SG/lg=卢干达语 +LocaleNames/zh_SG/li=林堡语 +LocaleNames/zh_SG/lu=鲁巴加丹加语 +LocaleNames/zh_SG/nd=北恩德贝勒语 +LocaleNames/zh_SG/nr=南恩德贝勒语 +LocaleNames/zh_SG/sc=萨丁语 +LocaleNames/zh_SG/ty=塔希提语 +LocaleNames/zh_SG/AS=美属萨摩亚 +LocaleNames/zh_SG/AU=澳大利亚 +LocaleNames/zh_SG/BD=孟加拉国 +LocaleNames/zh_SG/BV=布韦岛 +LocaleNames/zh_SG/BZ=伯利兹 +LocaleNames/zh_SG/CZ=捷克 +LocaleNames/zh_SG/ER=厄立特里亚 +LocaleNames/zh_SG/FK=福克兰群岛 +LocaleNames/zh_SG/FM=密克罗尼西亚 +LocaleNames/zh_SG/GS=南乔治亚和南桑威奇群岛 +LocaleNames/zh_SG/GW=几内亚比绍 +LocaleNames/zh_SG/HK=中国香港特别行政区 +LocaleNames/zh_SG/HM=赫德岛和麦克唐纳群岛 +LocaleNames/zh_SG/ID=印度尼西亚 +LocaleNames/zh_SG/KR=韩国 +LocaleNames/zh_SG/LA=老挝 +LocaleNames/zh_SG/MK=北马其顿 +LocaleNames/zh_SG/MO=中国澳门特别行政区 +LocaleNames/zh_SG/MP=北马里亚纳群岛 +LocaleNames/zh_SG/NU=纽埃 +LocaleNames/zh_SG/NZ=新西兰 +LocaleNames/zh_SG/PF=法属波利尼西亚 +LocaleNames/zh_SG/PM=圣皮埃尔和密克隆群岛 +LocaleNames/zh_SG/PN=皮特凯恩群岛 +LocaleNames/zh_SG/PR=波多黎各 +LocaleNames/zh_SG/PS=巴勒斯坦领土 +LocaleNames/zh_SG/RE=留尼汪 +LocaleNames/zh_SG/SA=沙特阿拉伯 +LocaleNames/zh_SG/SH=圣赫勒拿 +LocaleNames/zh_SG/SJ=斯瓦尔巴和扬马延 +LocaleNames/zh_SG/SL=塞拉利昂 +LocaleNames/zh_SG/TC=特克斯和凯科斯群岛 +LocaleNames/zh_SG/TK=托克劳 +LocaleNames/zh_SG/TW=台湾 +LocaleNames/zh_SG/UM=美国本土外小岛屿 +LocaleNames/zh_SG/WF=瓦利斯和富图纳 +LocaleNames/zh_SG/WS=萨摩亚 +LocaleNames/zh_SG/YT=马约特 #en_SG FormatData/en_SG/latn.NumberPatterns/0=#,##0.### -FormatData/en_SG/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/en_SG/latn.NumberPatterns/1=¤#,##0.00 FormatData/en_SG/latn.NumberPatterns/2=#,##0% CurrencyNames/en_SG/SGD=$ LocaleNames/en_SG/kj=Kuanyama @@ -2531,14 +2531,14 @@ LocaleNames/en_SG/pa=Punjabi LocaleNames/en_SG/rm=Romansh LocaleNames/en_SG/to=Tongan LocaleNames/en_SG/CC=Cocos (Keeling) Islands -LocaleNames/en_SG/CI=C\u00f4te d\u2019Ivoire +LocaleNames/en_SG/CI=Côte d’Ivoire LocaleNames/en_SG/GS=South Georgia & South Sandwich Islands LocaleNames/en_SG/HM=Heard & McDonald Islands LocaleNames/en_SG/KN=St Kitts & Nevis LocaleNames/en_SG/PM=St Pierre & Miquelon LocaleNames/en_SG/PS=Palestinian Territories LocaleNames/en_SG/SJ=Svalbard & Jan Mayen -LocaleNames/en_SG/ST=S\u00e3o Tom\u00e9 & Pr\u00edncipe +LocaleNames/en_SG/ST=São Tomé & Príncipe LocaleNames/en_SG/TC=Turks & Caicos Islands LocaleNames/en_SG/TL=Timor-Leste LocaleNames/en_SG/VC=St Vincent & the Grenadines @@ -2586,7 +2586,7 @@ FormatData/in/DayAbbreviations/6=Sab FormatData/in/Eras/0=SM FormatData/in/Eras/1=M FormatData/in/latn.NumberPatterns/0=#,##0.### -FormatData/in/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/in/latn.NumberPatterns/1=¤#,##0.00 FormatData/in/latn.NumberPatterns/2=#,##0% FormatData/in/latn.NumberElements/0=, FormatData/in/latn.NumberElements/1=. @@ -2596,8 +2596,8 @@ FormatData/in/latn.NumberElements/4=0 FormatData/in/latn.NumberElements/5=# FormatData/in/latn.NumberElements/6=- FormatData/in/latn.NumberElements/7=E -FormatData/in/latn.NumberElements/8=\u2030 -FormatData/in/latn.NumberElements/9=\u221e +FormatData/in/latn.NumberElements/8=‰ +FormatData/in/latn.NumberElements/9=∞ FormatData/in/latn.NumberElements/10=NaN FormatData/in/TimePatterns/0=HH.mm.ss zzzz FormatData/in/TimePatterns/1=HH.mm.ss z @@ -2620,7 +2620,7 @@ FormatData/in_ID/DatePatterns/3=dd/MM/yy FormatData/in_ID/DateTimePatterns/0={1} {0} #en_MT FormatData/en_MT/latn.NumberPatterns/0=#,##0.### -FormatData/en_MT/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/en_MT/latn.NumberPatterns/1=¤#,##0.00 FormatData/en_MT/latn.NumberPatterns/2=#,##0% FormatData/en_MT/TimePatterns/0=HH:mm:ss zzzz FormatData/en_MT/TimePatterns/1=HH:mm:ss z @@ -2631,7 +2631,7 @@ FormatData/en_MT/DatePatterns/1=dd MMMM y FormatData/en_MT/DatePatterns/2=dd MMM y FormatData/en_MT/DatePatterns/3=dd/MM/y FormatData/en_MT/DateTimePatterns/0={1}, {0} -CurrencyNames/en_MT/EUR=\u20ac +CurrencyNames/en_MT/EUR=€ LocaleNames/en_MT/kj=Kuanyama LocaleNames/en_MT/kl=Kalaallisut LocaleNames/en_MT/ny=Nyanja @@ -2641,31 +2641,31 @@ LocaleNames/en_MT/pa=Punjabi LocaleNames/en_MT/rm=Romansh LocaleNames/en_MT/to=Tongan LocaleNames/en_MT/CC=Cocos (Keeling) Islands -LocaleNames/en_MT/CI=C\u00f4te d\u2019Ivoire +LocaleNames/en_MT/CI=Côte d’Ivoire LocaleNames/en_MT/GS=South Georgia & South Sandwich Islands LocaleNames/en_MT/HM=Heard & McDonald Islands LocaleNames/en_MT/KN=St Kitts & Nevis LocaleNames/en_MT/PM=St Pierre & Miquelon LocaleNames/en_MT/PS=Palestinian Territories LocaleNames/en_MT/SJ=Svalbard & Jan Mayen -LocaleNames/en_MT/ST=S\u00e3o Tom\u00e9 & Pr\u00edncipe +LocaleNames/en_MT/ST=São Tomé & Príncipe LocaleNames/en_MT/TC=Turks & Caicos Islands LocaleNames/en_MT/TL=Timor-Leste LocaleNames/en_MT/VC=St Vincent & the Grenadines LocaleNames/en_MT/WF=Wallis & Futuna #mt_MT FormatData/mt_MT/latn.NumberPatterns/0=#,##0.### -FormatData/mt_MT/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/mt_MT/latn.NumberPatterns/1=¤#,##0.00 FormatData/mt_MT/latn.NumberPatterns/2=#,##0% -CurrencyNames/mt_MT/EUR=\u20ac +CurrencyNames/mt_MT/EUR=€ #en_PH FormatData/en_PH/latn.NumberPatterns/0=#,##0.### -FormatData/en_PH/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/en_PH/latn.NumberPatterns/1=¤#,##0.00 FormatData/en_PH/latn.NumberPatterns/2=#,##0% -FormatData/en_PH/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/en_PH/TimePatterns/1=h:mm:ss\u202fa z -FormatData/en_PH/TimePatterns/2=h:mm:ss\u202fa -FormatData/en_PH/TimePatterns/3=h:mm\u202fa +FormatData/en_PH/TimePatterns/0=h:mm:ss a zzzz +FormatData/en_PH/TimePatterns/1=h:mm:ss a z +FormatData/en_PH/TimePatterns/2=h:mm:ss a +FormatData/en_PH/TimePatterns/3=h:mm a FormatData/en_PH/DatePatterns/0=EEEE, MMMM d, y FormatData/en_PH/DatePatterns/1=MMMM d, y FormatData/en_PH/DatePatterns/2=MMM d, y @@ -2680,56 +2680,56 @@ LocaleNames/en_PH/pa=Punjabi LocaleNames/en_PH/rm=Romansh LocaleNames/en_PH/to=Tongan LocaleNames/en_PH/CC=Cocos (Keeling) Islands -LocaleNames/en_PH/CI=C\u00f4te d\u2019Ivoire +LocaleNames/en_PH/CI=Côte d’Ivoire LocaleNames/en_PH/GS=South Georgia & South Sandwich Islands LocaleNames/en_PH/HM=Heard & McDonald Islands LocaleNames/en_PH/KN=St. Kitts & Nevis LocaleNames/en_PH/PM=St. Pierre & Miquelon LocaleNames/en_PH/PS=Palestinian Territories LocaleNames/en_PH/SJ=Svalbard & Jan Mayen -LocaleNames/en_PH/ST=S\u00e3o Tom\u00e9 & Pr\u00edncipe +LocaleNames/en_PH/ST=São Tomé & Príncipe #el -FormatData/el/standalone.MonthNames/0=\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/1=\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/2=\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/3=\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/4=\u039c\u03ac\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/5=\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/6=\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/7=\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2 -FormatData/el/standalone.MonthNames/8=\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/9=\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/10=\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2 -FormatData/el/standalone.MonthNames/11=\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2 +FormatData/el/standalone.MonthNames/0=Ιανουάριος +FormatData/el/standalone.MonthNames/1=Φεβρουάριος +FormatData/el/standalone.MonthNames/2=Μάρτιος +FormatData/el/standalone.MonthNames/3=Απρίλιος +FormatData/el/standalone.MonthNames/4=Μάιος +FormatData/el/standalone.MonthNames/5=Ιούνιος +FormatData/el/standalone.MonthNames/6=Ιούλιος +FormatData/el/standalone.MonthNames/7=Αύγουστος +FormatData/el/standalone.MonthNames/8=Σεπτέμβριος +FormatData/el/standalone.MonthNames/9=Οκτώβριος +FormatData/el/standalone.MonthNames/10=Νοέμβριος +FormatData/el/standalone.MonthNames/11=Δεκέμβριος FormatData/el/standalone.MonthNames/12= -FormatData/el/MonthAbbreviations/0=\u0399\u03b1\u03bd -FormatData/el/MonthAbbreviations/1=\u03a6\u03b5\u03b2 -FormatData/el/MonthAbbreviations/2=\u039c\u03b1\u03c1 -FormatData/el/MonthAbbreviations/3=\u0391\u03c0\u03c1 -FormatData/el/MonthAbbreviations/4=\u039c\u03b1\u0390 -FormatData/el/MonthAbbreviations/5=\u0399\u03bf\u03c5\u03bd -FormatData/el/MonthAbbreviations/6=\u0399\u03bf\u03c5\u03bb -FormatData/el/MonthAbbreviations/7=\u0391\u03c5\u03b3 -FormatData/el/MonthAbbreviations/8=\u03a3\u03b5\u03c0 -FormatData/el/MonthAbbreviations/9=\u039f\u03ba\u03c4 -FormatData/el/MonthAbbreviations/10=\u039d\u03bf\u03b5 -FormatData/el/MonthAbbreviations/11=\u0394\u03b5\u03ba -FormatData/el/DayNames/0=\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae -FormatData/el/DayNames/1=\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1 -FormatData/el/DayNames/2=\u03a4\u03c1\u03af\u03c4\u03b7 -FormatData/el/DayNames/3=\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7 -FormatData/el/DayNames/4=\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7 -FormatData/el/DayNames/5=\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae -FormatData/el/DayNames/6=\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf -FormatData/el/DayAbbreviations/0=\u039a\u03c5\u03c1 -FormatData/el/DayAbbreviations/1=\u0394\u03b5\u03c5 -FormatData/el/DayAbbreviations/2=\u03a4\u03c1\u03af -FormatData/el/DayAbbreviations/3=\u03a4\u03b5\u03c4 -FormatData/el/DayAbbreviations/4=\u03a0\u03ad\u03bc -FormatData/el/DayAbbreviations/5=\u03a0\u03b1\u03c1 -FormatData/el/DayAbbreviations/6=\u03a3\u03ac\u03b2 -FormatData/el/AmPmMarkers/0=\u03c0.\u03bc. -FormatData/el/AmPmMarkers/1=\u03bc.\u03bc. +FormatData/el/MonthAbbreviations/0=Ιαν +FormatData/el/MonthAbbreviations/1=Φεβ +FormatData/el/MonthAbbreviations/2=Μαρ +FormatData/el/MonthAbbreviations/3=Απρ +FormatData/el/MonthAbbreviations/4=Μαΐ +FormatData/el/MonthAbbreviations/5=Ιουν +FormatData/el/MonthAbbreviations/6=Ιουλ +FormatData/el/MonthAbbreviations/7=Αυγ +FormatData/el/MonthAbbreviations/8=Σεπ +FormatData/el/MonthAbbreviations/9=Οκτ +FormatData/el/MonthAbbreviations/10=Νοε +FormatData/el/MonthAbbreviations/11=Δεκ +FormatData/el/DayNames/0=Κυριακή +FormatData/el/DayNames/1=Δευτέρα +FormatData/el/DayNames/2=Τρίτη +FormatData/el/DayNames/3=Τετάρτη +FormatData/el/DayNames/4=Πέμπτη +FormatData/el/DayNames/5=Παρασκευή +FormatData/el/DayNames/6=Σάββατο +FormatData/el/DayAbbreviations/0=Κυρ +FormatData/el/DayAbbreviations/1=Δευ +FormatData/el/DayAbbreviations/2=Τρί +FormatData/el/DayAbbreviations/3=Τετ +FormatData/el/DayAbbreviations/4=Πέμ +FormatData/el/DayAbbreviations/5=Παρ +FormatData/el/DayAbbreviations/6=Σάβ +FormatData/el/AmPmMarkers/0=π.μ. +FormatData/el/AmPmMarkers/1=μ.μ. FormatData/el/latn.NumberElements/0=, FormatData/el/latn.NumberElements/1=. FormatData/el/latn.NumberElements/2=; @@ -2738,353 +2738,353 @@ FormatData/el/latn.NumberElements/4=0 FormatData/el/latn.NumberElements/5=# FormatData/el/latn.NumberElements/6=- FormatData/el/latn.NumberElements/7=e -FormatData/el/latn.NumberElements/8=\u2030 -FormatData/el/latn.NumberElements/9=\u221e +FormatData/el/latn.NumberElements/8=‰ +FormatData/el/latn.NumberElements/9=∞ FormatData/el/latn.NumberElements/10=NaN -FormatData/el/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/el/TimePatterns/1=h:mm:ss\u202fa z -FormatData/el/TimePatterns/2=h:mm:ss\u202fa -FormatData/el/TimePatterns/3=h:mm\u202fa +FormatData/el/TimePatterns/0=h:mm:ss a zzzz +FormatData/el/TimePatterns/1=h:mm:ss a z +FormatData/el/TimePatterns/2=h:mm:ss a +FormatData/el/TimePatterns/3=h:mm a FormatData/el/DatePatterns/0=EEEE d MMMM y FormatData/el/DatePatterns/1=d MMMM y FormatData/el/DatePatterns/2=d MMM y FormatData/el/DatePatterns/3=d/M/yy FormatData/el/DateTimePatterns/0={1} - {0} -LocaleNames/el/GR=\u0395\u03bb\u03bb\u03ac\u03b4\u03b1 +LocaleNames/el/GR=Ελλάδα #el_CY #bug 6483191 -FormatData/el_CY/MonthNames/0=\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/1=\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/2=\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/3=\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/4=\u039c\u03b1\u0390\u03bf\u03c5 -FormatData/el_CY/MonthNames/5=\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/6=\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/7=\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5 -FormatData/el_CY/MonthNames/8=\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/9=\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/10=\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5 -FormatData/el_CY/MonthNames/11=\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5 +FormatData/el_CY/MonthNames/0=Ιανουαρίου +FormatData/el_CY/MonthNames/1=Φεβρουαρίου +FormatData/el_CY/MonthNames/2=Μαρτίου +FormatData/el_CY/MonthNames/3=Απριλίου +FormatData/el_CY/MonthNames/4=Μαΐου +FormatData/el_CY/MonthNames/5=Ιουνίου +FormatData/el_CY/MonthNames/6=Ιουλίου +FormatData/el_CY/MonthNames/7=Αυγούστου +FormatData/el_CY/MonthNames/8=Σεπτεμβρίου +FormatData/el_CY/MonthNames/9=Οκτωβρίου +FormatData/el_CY/MonthNames/10=Νοεμβρίου +FormatData/el_CY/MonthNames/11=Δεκεμβρίου FormatData/el_CY/MonthNames/12= -FormatData/el_CY/AmPmMarkers/0=\u03c0.\u03bc. -FormatData/el_CY/AmPmMarkers/1=\u03bc.\u03bc. -FormatData/el_CY/Eras/0=\u03c0.\u03a7. -FormatData/el_CY/Eras/1=\u03bc.\u03a7. +FormatData/el_CY/AmPmMarkers/0=π.μ. +FormatData/el_CY/AmPmMarkers/1=μ.μ. +FormatData/el_CY/Eras/0=π.Χ. +FormatData/el_CY/Eras/1=μ.Χ. FormatData/el_CY/latn.NumberPatterns/0=#,##0.### -FormatData/el_CY/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 +FormatData/el_CY/latn.NumberPatterns/1=#,##0.00 ¤ FormatData/el_CY/latn.NumberPatterns/2=#,##0% -FormatData/el_CY/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/el_CY/TimePatterns/1=h:mm:ss\u202fa z -FormatData/el_CY/TimePatterns/2=h:mm:ss\u202fa -FormatData/el_CY/TimePatterns/3=h:mm\u202fa +FormatData/el_CY/TimePatterns/0=h:mm:ss a zzzz +FormatData/el_CY/TimePatterns/1=h:mm:ss a z +FormatData/el_CY/TimePatterns/2=h:mm:ss a +FormatData/el_CY/TimePatterns/3=h:mm a FormatData/el_CY/DatePatterns/0=EEEE d MMMM y FormatData/el_CY/DatePatterns/1=d MMMM y FormatData/el_CY/DatePatterns/2=d MMM y FormatData/el_CY/DatePatterns/3=d/M/yy FormatData/el_CY/DateTimePatterns/0={1} - {0} -LocaleNames/el_CY/ar=\u0391\u03c1\u03b1\u03b2\u03b9\u03ba\u03ac -LocaleNames/el_CY/be=\u039b\u03b5\u03c5\u03ba\u03bf\u03c1\u03c9\u03c3\u03b9\u03ba\u03ac -LocaleNames/el_CY/bg=\u0392\u03bf\u03c5\u03bb\u03b3\u03b1\u03c1\u03b9\u03ba\u03ac -LocaleNames/el_CY/bo=\u0398\u03b9\u03b2\u03b5\u03c4\u03b9\u03b1\u03bd\u03ac -LocaleNames/el_CY/bs=\u0392\u03bf\u03c3\u03bd\u03b9\u03b1\u03ba\u03ac -LocaleNames/el_CY/bn=\u0392\u03b5\u03b3\u03b3\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/ca=\u039a\u03b1\u03c4\u03b1\u03bb\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/co=\u039a\u03bf\u03c1\u03c3\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/cs=\u03a4\u03c3\u03b5\u03c7\u03b9\u03ba\u03ac -LocaleNames/el_CY/cy=\u039f\u03c5\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/da=\u0394\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/de=\u0393\u03b5\u03c1\u03bc\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/el=\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/en=\u0391\u03b3\u03b3\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/es=\u0399\u03c3\u03c0\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/et=\u0395\u03c3\u03b8\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/eu=\u0392\u03b1\u03c3\u03ba\u03b9\u03ba\u03ac -LocaleNames/el_CY/fa=\u03a0\u03b5\u03c1\u03c3\u03b9\u03ba\u03ac -LocaleNames/el_CY/fi=\u03a6\u03b9\u03bd\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/fr=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/ga=\u0399\u03c1\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/gd=\u03a3\u03ba\u03c9\u03c4\u03b9\u03ba\u03ac \u039a\u03b5\u03bb\u03c4\u03b9\u03ba\u03ac -LocaleNames/el_CY/he=\u0395\u03b2\u03c1\u03b1\u03ca\u03ba\u03ac -LocaleNames/el_CY/hi=\u03a7\u03af\u03bd\u03c4\u03b9 -LocaleNames/el_CY/hr=\u039a\u03c1\u03bf\u03b1\u03c4\u03b9\u03ba\u03ac -LocaleNames/el_CY/hu=\u039f\u03c5\u03b3\u03b3\u03c1\u03b9\u03ba\u03ac -LocaleNames/el_CY/hy=\u0391\u03c1\u03bc\u03b5\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/id=\u0399\u03bd\u03b4\u03bf\u03bd\u03b7\u03c3\u03b9\u03b1\u03ba\u03ac -LocaleNames/el_CY/is=\u0399\u03c3\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/it=\u0399\u03c4\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/ja=\u0399\u03b1\u03c0\u03c9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/ka=\u0393\u03b5\u03c9\u03c1\u03b3\u03b9\u03b1\u03bd\u03ac -LocaleNames/el_CY/ko=\u039a\u03bf\u03c1\u03b5\u03b1\u03c4\u03b9\u03ba\u03ac -LocaleNames/el_CY/la=\u039b\u03b1\u03c4\u03b9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/lt=\u039b\u03b9\u03b8\u03bf\u03c5\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/lv=\u039b\u03b5\u03c4\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/mk=\u03a3\u03bb\u03b1\u03b2\u03bf\u03bc\u03b1\u03ba\u03b5\u03b4\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/mn=\u039c\u03bf\u03b3\u03b3\u03bf\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/mt=\u039c\u03b1\u03bb\u03c4\u03b5\u03b6\u03b9\u03ba\u03ac -LocaleNames/el_CY/nl=\u039f\u03bb\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/no=\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03b9\u03ba\u03ac -LocaleNames/el_CY/pl=\u03a0\u03bf\u03bb\u03c9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/pt=\u03a0\u03bf\u03c1\u03c4\u03bf\u03b3\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el_CY/ro=\u03a1\u03bf\u03c5\u03bc\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/ru=\u03a1\u03c9\u03c3\u03b9\u03ba\u03ac -LocaleNames/el_CY/sk=\u03a3\u03bb\u03bf\u03b2\u03b1\u03ba\u03b9\u03ba\u03ac -LocaleNames/el_CY/sl=\u03a3\u03bb\u03bf\u03b2\u03b5\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/sq=\u0391\u03bb\u03b2\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/sr=\u03a3\u03b5\u03c1\u03b2\u03b9\u03ba\u03ac -LocaleNames/el_CY/sv=\u03a3\u03bf\u03c5\u03b7\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/th=\u03a4\u03b1\u03ca\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el_CY/tr=\u03a4\u03bf\u03c5\u03c1\u03ba\u03b9\u03ba\u03ac -LocaleNames/el_CY/uk=\u039f\u03c5\u03ba\u03c1\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el_CY/vi=\u0392\u03b9\u03b5\u03c4\u03bd\u03b1\u03bc\u03b9\u03ba\u03ac -LocaleNames/el_CY/yi=\u0393\u03af\u03bd\u03c4\u03b9\u03c2 -LocaleNames/el_CY/zh=\u039a\u03b9\u03bd\u03b5\u03b6\u03b9\u03ba\u03ac -LocaleNames/el_CY/AD=\u0391\u03bd\u03b4\u03cc\u03c1\u03b1 -LocaleNames/el_CY/AE=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b1 \u0391\u03c1\u03b1\u03b2\u03b9\u03ba\u03ac \u0395\u03bc\u03b9\u03c1\u03ac\u03c4\u03b1 -LocaleNames/el_CY/AF=\u0391\u03c6\u03b3\u03b1\u03bd\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/AG=\u0391\u03bd\u03c4\u03af\u03b3\u03ba\u03bf\u03c5\u03b1 \u03ba\u03b1\u03b9 \u039c\u03c0\u03b1\u03c1\u03bc\u03c0\u03bf\u03cd\u03bd\u03c4\u03b1 -LocaleNames/el_CY/AI=\u0391\u03bd\u03b3\u03ba\u03bf\u03c5\u03af\u03bb\u03b1 -LocaleNames/el_CY/AL=\u0391\u03bb\u03b2\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/AM=\u0391\u03c1\u03bc\u03b5\u03bd\u03af\u03b1 -LocaleNames/el_CY/AO=\u0391\u03b3\u03ba\u03cc\u03bb\u03b1 -LocaleNames/el_CY/AQ=\u0391\u03bd\u03c4\u03b1\u03c1\u03ba\u03c4\u03b9\u03ba\u03ae -LocaleNames/el_CY/AR=\u0391\u03c1\u03b3\u03b5\u03bd\u03c4\u03b9\u03bd\u03ae -LocaleNames/el_CY/AS=\u0391\u03bc\u03b5\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ae \u03a3\u03b1\u03bc\u03cc\u03b1 -LocaleNames/el_CY/AT=\u0391\u03c5\u03c3\u03c4\u03c1\u03af\u03b1 -LocaleNames/el_CY/AU=\u0391\u03c5\u03c3\u03c4\u03c1\u03b1\u03bb\u03af\u03b1 -LocaleNames/el_CY/AW=\u0391\u03c1\u03bf\u03cd\u03bc\u03c0\u03b1 -LocaleNames/el_CY/AX=\u039d\u03ae\u03c3\u03bf\u03b9 \u038c\u03bb\u03b1\u03bd\u03c4 -LocaleNames/el_CY/AZ=\u0391\u03b6\u03b5\u03c1\u03bc\u03c0\u03b1\u03ca\u03c4\u03b6\u03ac\u03bd -LocaleNames/el_CY/BA=\u0392\u03bf\u03c3\u03bd\u03af\u03b1 - \u0395\u03c1\u03b6\u03b5\u03b3\u03bf\u03b2\u03af\u03bd\u03b7 -LocaleNames/el_CY/BB=\u039c\u03c0\u03b1\u03c1\u03bc\u03c0\u03ad\u03b9\u03bd\u03c4\u03bf\u03c2 -LocaleNames/el_CY/BD=\u039c\u03c0\u03b1\u03bd\u03b3\u03ba\u03bb\u03b1\u03bd\u03c4\u03ad\u03c2 -LocaleNames/el_CY/BE=\u0392\u03ad\u03bb\u03b3\u03b9\u03bf -LocaleNames/el_CY/BF=\u039c\u03c0\u03bf\u03c5\u03c1\u03ba\u03af\u03bd\u03b1 \u03a6\u03ac\u03c3\u03bf -LocaleNames/el_CY/BG=\u0392\u03bf\u03c5\u03bb\u03b3\u03b1\u03c1\u03af\u03b1 -LocaleNames/el_CY/BH=\u039c\u03c0\u03b1\u03c7\u03c1\u03ad\u03b9\u03bd -LocaleNames/el_CY/BI=\u039c\u03c0\u03bf\u03c5\u03c1\u03bf\u03cd\u03bd\u03c4\u03b9 -LocaleNames/el_CY/BJ=\u039c\u03c0\u03b5\u03bd\u03af\u03bd -LocaleNames/el_CY/BM=\u0392\u03b5\u03c1\u03bc\u03bf\u03cd\u03b4\u03b5\u03c2 -LocaleNames/el_CY/BN=\u039c\u03c0\u03c1\u03bf\u03c5\u03bd\u03ad\u03b9 -LocaleNames/el_CY/BO=\u0392\u03bf\u03bb\u03b9\u03b2\u03af\u03b1 -LocaleNames/el_CY/BR=\u0392\u03c1\u03b1\u03b6\u03b9\u03bb\u03af\u03b1 -LocaleNames/el_CY/BS=\u039c\u03c0\u03b1\u03c7\u03ac\u03bc\u03b5\u03c2 -LocaleNames/el_CY/BT=\u039c\u03c0\u03bf\u03c5\u03c4\u03ac\u03bd -LocaleNames/el_CY/BV=\u039d\u03ae\u03c3\u03bf\u03c2 \u039c\u03c0\u03bf\u03c5\u03b2\u03ad -LocaleNames/el_CY/BW=\u039c\u03c0\u03bf\u03c4\u03c3\u03bf\u03c5\u03ac\u03bd\u03b1 -LocaleNames/el_CY/BY=\u039b\u03b5\u03c5\u03ba\u03bf\u03c1\u03c9\u03c3\u03af\u03b1 -LocaleNames/el_CY/BZ=\u039c\u03c0\u03b5\u03bb\u03af\u03b6 -LocaleNames/el_CY/CA=\u039a\u03b1\u03bd\u03b1\u03b4\u03ac\u03c2 -LocaleNames/el_CY/CC=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03cc\u03ba\u03bf\u03c2 (\u039a\u03af\u03bb\u03b9\u03bd\u03b3\u03ba) -LocaleNames/el_CY/CD=\u039a\u03bf\u03bd\u03b3\u03ba\u03cc - \u039a\u03b9\u03bd\u03c3\u03ac\u03c3\u03b1 -LocaleNames/el_CY/CF=\u039a\u03b5\u03bd\u03c4\u03c1\u03bf\u03b1\u03c6\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ae \u0394\u03b7\u03bc\u03bf\u03ba\u03c1\u03b1\u03c4\u03af\u03b1 -LocaleNames/el_CY/CG=\u039a\u03bf\u03bd\u03b3\u03ba\u03cc - \u039c\u03c0\u03c1\u03b1\u03b6\u03b1\u03b2\u03af\u03bb -LocaleNames/el_CY/CH=\u0395\u03bb\u03b2\u03b5\u03c4\u03af\u03b1 -LocaleNames/el_CY/CI=\u0391\u03ba\u03c4\u03ae \u0395\u03bb\u03b5\u03c6\u03b1\u03bd\u03c4\u03bf\u03c3\u03c4\u03bf\u03cd -LocaleNames/el_CY/CK=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03bf\u03c5\u03ba -LocaleNames/el_CY/CL=\u03a7\u03b9\u03bb\u03ae -LocaleNames/el_CY/CM=\u039a\u03b1\u03bc\u03b5\u03c1\u03bf\u03cd\u03bd -LocaleNames/el_CY/CN=\u039a\u03af\u03bd\u03b1 -LocaleNames/el_CY/CO=\u039a\u03bf\u03bb\u03bf\u03bc\u03b2\u03af\u03b1 -LocaleNames/el_CY/CR=\u039a\u03cc\u03c3\u03c4\u03b1 \u03a1\u03af\u03ba\u03b1 -LocaleNames/el_CY/CU=\u039a\u03bf\u03cd\u03b2\u03b1 -LocaleNames/el_CY/CV=\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf \u0391\u03ba\u03c1\u03c9\u03c4\u03ae\u03c1\u03b9\u03bf -LocaleNames/el_CY/CX=\u039d\u03ae\u03c3\u03bf\u03c2 \u03c4\u03c9\u03bd \u03a7\u03c1\u03b9\u03c3\u03c4\u03bf\u03c5\u03b3\u03ad\u03bd\u03bd\u03c9\u03bd -LocaleNames/el_CY/CY=\u039a\u03cd\u03c0\u03c1\u03bf\u03c2 -LocaleNames/el_CY/CZ=\u03a4\u03c3\u03b5\u03c7\u03af\u03b1 -LocaleNames/el_CY/DE=\u0393\u03b5\u03c1\u03bc\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/DJ=\u03a4\u03b6\u03b9\u03bc\u03c0\u03bf\u03c5\u03c4\u03af -LocaleNames/el_CY/DK=\u0394\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/DM=\u039d\u03c4\u03bf\u03bc\u03af\u03bd\u03b9\u03ba\u03b1 -LocaleNames/el_CY/DO=\u0394\u03bf\u03bc\u03b9\u03bd\u03b9\u03ba\u03b1\u03bd\u03ae \u0394\u03b7\u03bc\u03bf\u03ba\u03c1\u03b1\u03c4\u03af\u03b1 -LocaleNames/el_CY/DZ=\u0391\u03bb\u03b3\u03b5\u03c1\u03af\u03b1 -LocaleNames/el_CY/EC=\u0399\u03c3\u03b7\u03bc\u03b5\u03c1\u03b9\u03bd\u03cc\u03c2 -LocaleNames/el_CY/EE=\u0395\u03c3\u03b8\u03bf\u03bd\u03af\u03b1 -LocaleNames/el_CY/EG=\u0391\u03af\u03b3\u03c5\u03c0\u03c4\u03bf\u03c2 -LocaleNames/el_CY/EH=\u0394\u03c5\u03c4\u03b9\u03ba\u03ae \u03a3\u03b1\u03c7\u03ac\u03c1\u03b1 -LocaleNames/el_CY/ER=\u0395\u03c1\u03c5\u03b8\u03c1\u03b1\u03af\u03b1 -LocaleNames/el_CY/ES=\u0399\u03c3\u03c0\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/ET=\u0391\u03b9\u03b8\u03b9\u03bf\u03c0\u03af\u03b1 -LocaleNames/el_CY/FI=\u03a6\u03b9\u03bd\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/FJ=\u03a6\u03af\u03c4\u03b6\u03b9 -LocaleNames/el_CY/FK=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a6\u03cc\u03ba\u03bb\u03b1\u03bd\u03c4 -LocaleNames/el_CY/FM=\u039c\u03b9\u03ba\u03c1\u03bf\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el_CY/FO=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a6\u03b5\u03c1\u03cc\u03b5\u03c2 -LocaleNames/el_CY/FR=\u0393\u03b1\u03bb\u03bb\u03af\u03b1 -LocaleNames/el_CY/GA=\u0393\u03ba\u03b1\u03bc\u03c0\u03cc\u03bd -LocaleNames/el_CY/GB=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03bf \u0392\u03b1\u03c3\u03af\u03bb\u03b5\u03b9\u03bf -LocaleNames/el_CY/GD=\u0393\u03c1\u03b5\u03bd\u03ac\u03b4\u03b1 -LocaleNames/el_CY/GE=\u0393\u03b5\u03c9\u03c1\u03b3\u03af\u03b1 -LocaleNames/el_CY/GF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ae \u0393\u03bf\u03c5\u03b9\u03ac\u03bd\u03b1 -LocaleNames/el_CY/GH=\u0393\u03ba\u03ac\u03bd\u03b1 -LocaleNames/el_CY/GI=\u0393\u03b9\u03b2\u03c1\u03b1\u03bb\u03c4\u03ac\u03c1 -LocaleNames/el_CY/GL=\u0393\u03c1\u03bf\u03b9\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/GM=\u0393\u03ba\u03ac\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el_CY/GN=\u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el_CY/GP=\u0393\u03bf\u03c5\u03b1\u03b4\u03b5\u03bb\u03bf\u03cd\u03c0\u03b7 -LocaleNames/el_CY/GQ=\u0399\u03c3\u03b7\u03bc\u03b5\u03c1\u03b9\u03bd\u03ae \u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el_CY/GS=\u039d\u03ae\u03c3\u03bf\u03b9 \u039d\u03cc\u03c4\u03b9\u03b1 \u0393\u03b5\u03c9\u03c1\u03b3\u03af\u03b1 \u03ba\u03b1\u03b9 \u039d\u03cc\u03c4\u03b9\u03b5\u03c2 \u03a3\u03ac\u03bd\u03c4\u03bf\u03c5\u03b9\u03c4\u03c2 -LocaleNames/el_CY/GT=\u0393\u03bf\u03c5\u03b1\u03c4\u03b5\u03bc\u03ac\u03bb\u03b1 -LocaleNames/el_CY/GU=\u0393\u03ba\u03bf\u03c5\u03ac\u03bc -LocaleNames/el_CY/GW=\u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 \u039c\u03c0\u03b9\u03c3\u03ac\u03bf\u03c5 -LocaleNames/el_CY/GY=\u0393\u03bf\u03c5\u03b9\u03ac\u03bd\u03b1 -LocaleNames/el_CY/HK=\u03a7\u03bf\u03bd\u03b3\u03ba \u039a\u03bf\u03bd\u03b3\u03ba \u0395\u0394\u03a0 \u039a\u03af\u03bd\u03b1\u03c2 -LocaleNames/el_CY/HM=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a7\u03b5\u03c1\u03bd\u03c4 \u03ba\u03b1\u03b9 \u039c\u03b1\u03ba\u03bd\u03c4\u03cc\u03bd\u03b1\u03bb\u03bd\u03c4 -LocaleNames/el_CY/HN=\u039f\u03bd\u03b4\u03bf\u03cd\u03c1\u03b1 -LocaleNames/el_CY/HR=\u039a\u03c1\u03bf\u03b1\u03c4\u03af\u03b1 -LocaleNames/el_CY/HT=\u0391\u03ca\u03c4\u03ae -LocaleNames/el_CY/HU=\u039f\u03c5\u03b3\u03b3\u03b1\u03c1\u03af\u03b1 -LocaleNames/el_CY/ID=\u0399\u03bd\u03b4\u03bf\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el_CY/IE=\u0399\u03c1\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/IL=\u0399\u03c3\u03c1\u03b1\u03ae\u03bb -LocaleNames/el_CY/IN=\u0399\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/IO=\u0392\u03c1\u03b5\u03c4\u03b1\u03bd\u03b9\u03ba\u03ac \u0395\u03b4\u03ac\u03c6\u03b7 \u0399\u03bd\u03b4\u03b9\u03ba\u03bf\u03cd \u03a9\u03ba\u03b5\u03b1\u03bd\u03bf\u03cd -LocaleNames/el_CY/IQ=\u0399\u03c1\u03ac\u03ba -LocaleNames/el_CY/IR=\u0399\u03c1\u03ac\u03bd -LocaleNames/el_CY/IS=\u0399\u03c3\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/IT=\u0399\u03c4\u03b1\u03bb\u03af\u03b1 -LocaleNames/el_CY/JM=\u03a4\u03b6\u03b1\u03bc\u03ac\u03b9\u03ba\u03b1 -LocaleNames/el_CY/JO=\u0399\u03bf\u03c1\u03b4\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/JP=\u0399\u03b1\u03c0\u03c9\u03bd\u03af\u03b1 -LocaleNames/el_CY/KE=\u039a\u03ad\u03bd\u03c5\u03b1 -LocaleNames/el_CY/KG=\u039a\u03b9\u03c1\u03b3\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/KH=\u039a\u03b1\u03bc\u03c0\u03cc\u03c4\u03b6\u03b7 -LocaleNames/el_CY/KI=\u039a\u03b9\u03c1\u03b9\u03bc\u03c0\u03ac\u03c4\u03b9 -LocaleNames/el_CY/KM=\u039a\u03bf\u03bc\u03cc\u03c1\u03b5\u03c2 -LocaleNames/el_CY/KN=\u03a3\u03b5\u03bd \u039a\u03b9\u03c4\u03c2 \u03ba\u03b1\u03b9 \u039d\u03ad\u03b2\u03b9\u03c2 -LocaleNames/el_CY/KP=\u0392\u03cc\u03c1\u03b5\u03b9\u03b1 \u039a\u03bf\u03c1\u03ad\u03b1 -LocaleNames/el_CY/KR=\u039d\u03cc\u03c4\u03b9\u03b1 \u039a\u03bf\u03c1\u03ad\u03b1 -LocaleNames/el_CY/KW=\u039a\u03bf\u03c5\u03b2\u03ad\u03b9\u03c4 -LocaleNames/el_CY/KY=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03ad\u03b9\u03bc\u03b1\u03bd -LocaleNames/el_CY/KZ=\u039a\u03b1\u03b6\u03b1\u03ba\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/LA=\u039b\u03ac\u03bf\u03c2 -LocaleNames/el_CY/LB=\u039b\u03af\u03b2\u03b1\u03bd\u03bf\u03c2 -LocaleNames/el_CY/LC=\u0391\u03b3\u03af\u03b1 \u039b\u03bf\u03c5\u03ba\u03af\u03b1 -LocaleNames/el_CY/LI=\u039b\u03b9\u03c7\u03c4\u03b5\u03bd\u03c3\u03c4\u03ac\u03b9\u03bd -LocaleNames/el_CY/LK=\u03a3\u03c1\u03b9 \u039b\u03ac\u03bd\u03ba\u03b1 -LocaleNames/el_CY/LR=\u039b\u03b9\u03b2\u03b5\u03c1\u03af\u03b1 -LocaleNames/el_CY/LS=\u039b\u03b5\u03c3\u03cc\u03c4\u03bf -LocaleNames/el_CY/LT=\u039b\u03b9\u03b8\u03bf\u03c5\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/LU=\u039b\u03bf\u03c5\u03be\u03b5\u03bc\u03b2\u03bf\u03cd\u03c1\u03b3\u03bf -LocaleNames/el_CY/LV=\u039b\u03b5\u03c4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el_CY/LY=\u039b\u03b9\u03b2\u03cd\u03b7 -LocaleNames/el_CY/MA=\u039c\u03b1\u03c1\u03cc\u03ba\u03bf -LocaleNames/el_CY/MC=\u039c\u03bf\u03bd\u03b1\u03ba\u03cc -LocaleNames/el_CY/MD=\u039c\u03bf\u03bb\u03b4\u03b1\u03b2\u03af\u03b1 -LocaleNames/el_CY/MG=\u039c\u03b1\u03b4\u03b1\u03b3\u03b1\u03c3\u03ba\u03ac\u03c1\u03b7 -LocaleNames/el_CY/MH=\u039d\u03ae\u03c3\u03bf\u03b9 \u039c\u03ac\u03c1\u03c3\u03b1\u03bb -LocaleNames/el_CY/MK=\u0392\u03cc\u03c1\u03b5\u03b9\u03b1 \u039c\u03b1\u03ba\u03b5\u03b4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el_CY/ML=\u039c\u03ac\u03bb\u03b9 -LocaleNames/el_CY/MM=\u039c\u03b9\u03b1\u03bd\u03bc\u03ac\u03c1 (\u0392\u03b9\u03c1\u03bc\u03b1\u03bd\u03af\u03b1) -LocaleNames/el_CY/MN=\u039c\u03bf\u03b3\u03b3\u03bf\u03bb\u03af\u03b1 -LocaleNames/el_CY/MO=\u039c\u03b1\u03ba\u03ac\u03bf \u0395\u0394\u03a0 \u039a\u03af\u03bd\u03b1\u03c2 -LocaleNames/el_CY/MP=\u039d\u03ae\u03c3\u03bf\u03b9 \u0392\u03cc\u03c1\u03b5\u03b9\u03b5\u03c2 \u039c\u03b1\u03c1\u03b9\u03ac\u03bd\u03b5\u03c2 -LocaleNames/el_CY/MQ=\u039c\u03b1\u03c1\u03c4\u03b9\u03bd\u03af\u03ba\u03b1 -LocaleNames/el_CY/MR=\u039c\u03b1\u03c5\u03c1\u03b9\u03c4\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/MS=\u039c\u03bf\u03bd\u03c3\u03b5\u03c1\u03ac\u03c4 -LocaleNames/el_CY/MT=\u039c\u03ac\u03bb\u03c4\u03b1 -LocaleNames/el_CY/MU=\u039c\u03b1\u03c5\u03c1\u03af\u03ba\u03b9\u03bf\u03c2 -LocaleNames/el_CY/MV=\u039c\u03b1\u03bb\u03b4\u03af\u03b2\u03b5\u03c2 -LocaleNames/el_CY/MW=\u039c\u03b1\u03bb\u03ac\u03bf\u03c5\u03b9 -LocaleNames/el_CY/MX=\u039c\u03b5\u03be\u03b9\u03ba\u03cc -LocaleNames/el_CY/MY=\u039c\u03b1\u03bb\u03b1\u03b9\u03c3\u03af\u03b1 -LocaleNames/el_CY/MZ=\u039c\u03bf\u03b6\u03b1\u03bc\u03b2\u03af\u03ba\u03b7 -LocaleNames/el_CY/NA=\u039d\u03b1\u03bc\u03af\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el_CY/NC=\u039d\u03ad\u03b1 \u039a\u03b1\u03bb\u03b7\u03b4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el_CY/NE=\u039d\u03af\u03b3\u03b7\u03c1\u03b1\u03c2 -LocaleNames/el_CY/NF=\u039d\u03ae\u03c3\u03bf\u03c2 \u039d\u03cc\u03c1\u03c6\u03bf\u03bb\u03ba -LocaleNames/el_CY/NG=\u039d\u03b9\u03b3\u03b7\u03c1\u03af\u03b1 -LocaleNames/el_CY/NI=\u039d\u03b9\u03ba\u03b1\u03c1\u03ac\u03b3\u03bf\u03c5\u03b1 -LocaleNames/el_CY/NL=\u039a\u03ac\u03c4\u03c9 \u03a7\u03ce\u03c1\u03b5\u03c2 -LocaleNames/el_CY/NO=\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03af\u03b1 -LocaleNames/el_CY/NP=\u039d\u03b5\u03c0\u03ac\u03bb -LocaleNames/el_CY/NR=\u039d\u03b1\u03bf\u03c5\u03c1\u03bf\u03cd -LocaleNames/el_CY/NU=\u039d\u03b9\u03bf\u03cd\u03b5 -LocaleNames/el_CY/NZ=\u039d\u03ad\u03b1 \u0396\u03b7\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el_CY/OM=\u039f\u03bc\u03ac\u03bd -LocaleNames/el_CY/PA=\u03a0\u03b1\u03bd\u03b1\u03bc\u03ac\u03c2 -LocaleNames/el_CY/PE=\u03a0\u03b5\u03c1\u03bf\u03cd -LocaleNames/el_CY/PF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ae \u03a0\u03bf\u03bb\u03c5\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el_CY/PG=\u03a0\u03b1\u03c0\u03bf\u03cd\u03b1 \u039d\u03ad\u03b1 \u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el_CY/PH=\u03a6\u03b9\u03bb\u03b9\u03c0\u03c0\u03af\u03bd\u03b5\u03c2 -LocaleNames/el_CY/PK=\u03a0\u03b1\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/PL=\u03a0\u03bf\u03bb\u03c9\u03bd\u03af\u03b1 -LocaleNames/el_CY/PM=\u03a3\u03b5\u03bd \u03a0\u03b9\u03b5\u03c1 \u03ba\u03b1\u03b9 \u039c\u03b9\u03ba\u03b5\u03bb\u03cc\u03bd -LocaleNames/el_CY/PN=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a0\u03af\u03c4\u03ba\u03b5\u03c1\u03bd -LocaleNames/el_CY/PR=\u03a0\u03bf\u03c5\u03ad\u03c1\u03c4\u03bf \u03a1\u03af\u03ba\u03bf -LocaleNames/el_CY/PS=\u03a0\u03b1\u03bb\u03b1\u03b9\u03c3\u03c4\u03b9\u03bd\u03b9\u03b1\u03ba\u03ac \u0395\u03b4\u03ac\u03c6\u03b7 -LocaleNames/el_CY/PT=\u03a0\u03bf\u03c1\u03c4\u03bf\u03b3\u03b1\u03bb\u03af\u03b1 -LocaleNames/el_CY/PW=\u03a0\u03b1\u03bb\u03ac\u03bf\u03c5 -LocaleNames/el_CY/PY=\u03a0\u03b1\u03c1\u03b1\u03b3\u03bf\u03c5\u03ac\u03b7 -LocaleNames/el_CY/QA=\u039a\u03b1\u03c4\u03ac\u03c1 -LocaleNames/el_CY/RE=\u03a1\u03b5\u03ca\u03bd\u03b9\u03cc\u03bd -LocaleNames/el_CY/RO=\u03a1\u03bf\u03c5\u03bc\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/RU=\u03a1\u03c9\u03c3\u03af\u03b1 -LocaleNames/el_CY/RW=\u03a1\u03bf\u03c5\u03ac\u03bd\u03c4\u03b1 -LocaleNames/el_CY/SA=\u03a3\u03b1\u03bf\u03c5\u03b4\u03b9\u03ba\u03ae \u0391\u03c1\u03b1\u03b2\u03af\u03b1 -LocaleNames/el_CY/SB=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a3\u03bf\u03bb\u03bf\u03bc\u03ce\u03bd\u03c4\u03bf\u03c2 -LocaleNames/el_CY/SC=\u03a3\u03b5\u03cb\u03c7\u03ad\u03bb\u03bb\u03b5\u03c2 -LocaleNames/el_CY/SD=\u03a3\u03bf\u03c5\u03b4\u03ac\u03bd -LocaleNames/el_CY/SE=\u03a3\u03bf\u03c5\u03b7\u03b4\u03af\u03b1 -LocaleNames/el_CY/SG=\u03a3\u03b9\u03b3\u03ba\u03b1\u03c0\u03bf\u03cd\u03c1\u03b7 -LocaleNames/el_CY/SH=\u0391\u03b3\u03af\u03b1 \u0395\u03bb\u03ad\u03bd\u03b7 -LocaleNames/el_CY/SI=\u03a3\u03bb\u03bf\u03b2\u03b5\u03bd\u03af\u03b1 -LocaleNames/el_CY/SJ=\u03a3\u03b2\u03ac\u03bb\u03bc\u03c0\u03b1\u03c1\u03bd\u03c4 \u03ba\u03b1\u03b9 \u0393\u03b9\u03b1\u03bd \u039c\u03b1\u03b3\u03b9\u03ad\u03bd -LocaleNames/el_CY/SK=\u03a3\u03bb\u03bf\u03b2\u03b1\u03ba\u03af\u03b1 -LocaleNames/el_CY/SL=\u03a3\u03b9\u03ad\u03c1\u03b1 \u039b\u03b5\u03cc\u03bd\u03b5 -LocaleNames/el_CY/SM=\u0386\u03b3\u03b9\u03bf\u03c2 \u039c\u03b1\u03c1\u03af\u03bd\u03bf\u03c2 -LocaleNames/el_CY/SN=\u03a3\u03b5\u03bd\u03b5\u03b3\u03ac\u03bb\u03b7 -LocaleNames/el_CY/SO=\u03a3\u03bf\u03bc\u03b1\u03bb\u03af\u03b1 -LocaleNames/el_CY/SR=\u03a3\u03bf\u03c5\u03c1\u03b9\u03bd\u03ac\u03bc -LocaleNames/el_CY/ST=\u03a3\u03ac\u03bf \u03a4\u03bf\u03bc\u03ad \u03ba\u03b1\u03b9 \u03a0\u03c1\u03af\u03bd\u03c3\u03b9\u03c0\u03b5 -LocaleNames/el_CY/SV=\u0395\u03bb \u03a3\u03b1\u03bb\u03b2\u03b1\u03b4\u03cc\u03c1 -LocaleNames/el_CY/SY=\u03a3\u03c5\u03c1\u03af\u03b1 -LocaleNames/el_CY/SZ=\u0395\u03c3\u03bf\u03c5\u03b1\u03c4\u03af\u03bd\u03b9 -LocaleNames/el_CY/TC=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a4\u03b5\u03c1\u03ba\u03c2 \u03ba\u03b1\u03b9 \u039a\u03ac\u03b9\u03ba\u03bf\u03c2 -LocaleNames/el_CY/TD=\u03a4\u03c3\u03b1\u03bd\u03c4 -LocaleNames/el_CY/TF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac \u039d\u03cc\u03c4\u03b9\u03b1 \u0395\u03b4\u03ac\u03c6\u03b7 -LocaleNames/el_CY/TG=\u03a4\u03cc\u03b3\u03ba\u03bf -LocaleNames/el_CY/TH=\u03a4\u03b1\u03ca\u03bb\u03ac\u03bd\u03b4\u03b7 -LocaleNames/el_CY/TJ=\u03a4\u03b1\u03c4\u03b6\u03b9\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/TK=\u03a4\u03bf\u03ba\u03b5\u03bb\u03ac\u03bf\u03c5 -LocaleNames/el_CY/TL=\u03a4\u03b9\u03bc\u03cc\u03c1-\u039b\u03ad\u03c3\u03c4\u03b5 -LocaleNames/el_CY/TM=\u03a4\u03bf\u03c5\u03c1\u03ba\u03bc\u03b5\u03bd\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/TN=\u03a4\u03c5\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el_CY/TO=\u03a4\u03cc\u03bd\u03b3\u03ba\u03b1 -LocaleNames/el_CY/TR=\u03a4\u03bf\u03c5\u03c1\u03ba\u03af\u03b1 -LocaleNames/el_CY/TT=\u03a4\u03c1\u03b9\u03bd\u03b9\u03bd\u03c4\u03ac\u03bd\u03c4 \u03ba\u03b1\u03b9 \u03a4\u03bf\u03bc\u03c0\u03ac\u03b3\u03ba\u03bf -LocaleNames/el_CY/TV=\u03a4\u03bf\u03c5\u03b2\u03b1\u03bb\u03bf\u03cd -LocaleNames/el_CY/TW=\u03a4\u03b1\u03ca\u03b2\u03ac\u03bd -LocaleNames/el_CY/TZ=\u03a4\u03b1\u03bd\u03b6\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/UA=\u039f\u03c5\u03ba\u03c1\u03b1\u03bd\u03af\u03b1 -LocaleNames/el_CY/UG=\u039f\u03c5\u03b3\u03ba\u03ac\u03bd\u03c4\u03b1 -LocaleNames/el_CY/UM=\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03b5\u03c2 \u039d\u03b7\u03c3\u03af\u03b4\u03b5\u03c2 \u0397\u03a0\u0391 -LocaleNames/el_CY/US=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a0\u03bf\u03bb\u03b9\u03c4\u03b5\u03af\u03b5\u03c2 -LocaleNames/el_CY/UY=\u039f\u03c5\u03c1\u03bf\u03c5\u03b3\u03bf\u03c5\u03ac\u03b7 -LocaleNames/el_CY/UZ=\u039f\u03c5\u03b6\u03bc\u03c0\u03b5\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el_CY/VA=\u0392\u03b1\u03c4\u03b9\u03ba\u03b1\u03bd\u03cc -LocaleNames/el_CY/VC=\u0386\u03b3\u03b9\u03bf\u03c2 \u0392\u03b9\u03ba\u03ad\u03bd\u03c4\u03b9\u03bf\u03c2 \u03ba\u03b1\u03b9 \u0393\u03c1\u03b5\u03bd\u03b1\u03b4\u03af\u03bd\u03b5\u03c2 -LocaleNames/el_CY/VE=\u0392\u03b5\u03bd\u03b5\u03b6\u03bf\u03c5\u03ad\u03bb\u03b1 -LocaleNames/el_CY/VG=\u0392\u03c1\u03b5\u03c4\u03b1\u03bd\u03b9\u03ba\u03ad\u03c2 \u03a0\u03b1\u03c1\u03b8\u03ad\u03bd\u03b5\u03c2 \u039d\u03ae\u03c3\u03bf\u03b9 -LocaleNames/el_CY/VI=\u0391\u03bc\u03b5\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ad\u03c2 \u03a0\u03b1\u03c1\u03b8\u03ad\u03bd\u03b5\u03c2 \u039d\u03ae\u03c3\u03bf\u03b9 -LocaleNames/el_CY/VN=\u0392\u03b9\u03b5\u03c4\u03bd\u03ac\u03bc -LocaleNames/el_CY/VU=\u0392\u03b1\u03bd\u03bf\u03c5\u03ac\u03c4\u03bf\u03c5 -LocaleNames/el_CY/WF=\u0393\u03bf\u03c5\u03ac\u03bb\u03b9\u03c2 \u03ba\u03b1\u03b9 \u03a6\u03bf\u03c5\u03c4\u03bf\u03cd\u03bd\u03b1 -LocaleNames/el_CY/WS=\u03a3\u03b1\u03bc\u03cc\u03b1 -LocaleNames/el_CY/YE=\u03a5\u03b5\u03bc\u03ad\u03bd\u03b7 -LocaleNames/el_CY/YT=\u039c\u03b1\u03b3\u03b9\u03cc\u03c4 -LocaleNames/el_CY/ZA=\u039d\u03cc\u03c4\u03b9\u03b1 \u0391\u03c6\u03c1\u03b9\u03ba\u03ae -LocaleNames/el_CY/ZM=\u0396\u03ac\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el_CY/ZW=\u0396\u03b9\u03bc\u03c0\u03ac\u03bc\u03c0\u03bf\u03c5\u03b5 -CurrencyNames/el_CY/EUR=\u20ac +LocaleNames/el_CY/ar=Αραβικά +LocaleNames/el_CY/be=Λευκορωσικά +LocaleNames/el_CY/bg=Βουλγαρικά +LocaleNames/el_CY/bo=Θιβετιανά +LocaleNames/el_CY/bs=Βοσνιακά +LocaleNames/el_CY/bn=Βεγγαλικά +LocaleNames/el_CY/ca=Καταλανικά +LocaleNames/el_CY/co=Κορσικανικά +LocaleNames/el_CY/cs=Τσεχικά +LocaleNames/el_CY/cy=Ουαλικά +LocaleNames/el_CY/da=Δανικά +LocaleNames/el_CY/de=Γερμανικά +LocaleNames/el_CY/el=Ελληνικά +LocaleNames/el_CY/en=Αγγλικά +LocaleNames/el_CY/es=Ισπανικά +LocaleNames/el_CY/et=Εσθονικά +LocaleNames/el_CY/eu=Βασκικά +LocaleNames/el_CY/fa=Περσικά +LocaleNames/el_CY/fi=Φινλανδικά +LocaleNames/el_CY/fr=Γαλλικά +LocaleNames/el_CY/ga=Ιρλανδικά +LocaleNames/el_CY/gd=Σκωτικά Κελτικά +LocaleNames/el_CY/he=Εβραϊκά +LocaleNames/el_CY/hi=Χίντι +LocaleNames/el_CY/hr=Κροατικά +LocaleNames/el_CY/hu=Ουγγρικά +LocaleNames/el_CY/hy=Αρμενικά +LocaleNames/el_CY/id=Ινδονησιακά +LocaleNames/el_CY/is=Ισλανδικά +LocaleNames/el_CY/it=Ιταλικά +LocaleNames/el_CY/ja=Ιαπωνικά +LocaleNames/el_CY/ka=Γεωργιανά +LocaleNames/el_CY/ko=Κορεατικά +LocaleNames/el_CY/la=Λατινικά +LocaleNames/el_CY/lt=Λιθουανικά +LocaleNames/el_CY/lv=Λετονικά +LocaleNames/el_CY/mk=Σλαβομακεδονικά +LocaleNames/el_CY/mn=Μογγολικά +LocaleNames/el_CY/mt=Μαλτεζικά +LocaleNames/el_CY/nl=Ολλανδικά +LocaleNames/el_CY/no=Νορβηγικά +LocaleNames/el_CY/pl=Πολωνικά +LocaleNames/el_CY/pt=Πορτογαλικά +LocaleNames/el_CY/ro=Ρουμανικά +LocaleNames/el_CY/ru=Ρωσικά +LocaleNames/el_CY/sk=Σλοβακικά +LocaleNames/el_CY/sl=Σλοβενικά +LocaleNames/el_CY/sq=Αλβανικά +LocaleNames/el_CY/sr=Σερβικά +LocaleNames/el_CY/sv=Σουηδικά +LocaleNames/el_CY/th=Ταϊλανδικά +LocaleNames/el_CY/tr=Τουρκικά +LocaleNames/el_CY/uk=Ουκρανικά +LocaleNames/el_CY/vi=Βιετναμικά +LocaleNames/el_CY/yi=Γίντις +LocaleNames/el_CY/zh=Κινεζικά +LocaleNames/el_CY/AD=Ανδόρα +LocaleNames/el_CY/AE=Ηνωμένα Αραβικά Εμιράτα +LocaleNames/el_CY/AF=Αφγανιστάν +LocaleNames/el_CY/AG=Αντίγκουα και Μπαρμπούντα +LocaleNames/el_CY/AI=Ανγκουίλα +LocaleNames/el_CY/AL=Αλβανία +LocaleNames/el_CY/AM=Αρμενία +LocaleNames/el_CY/AO=Αγκόλα +LocaleNames/el_CY/AQ=Ανταρκτική +LocaleNames/el_CY/AR=Αργεντινή +LocaleNames/el_CY/AS=Αμερικανική Σαμόα +LocaleNames/el_CY/AT=Αυστρία +LocaleNames/el_CY/AU=Αυστραλία +LocaleNames/el_CY/AW=Αρούμπα +LocaleNames/el_CY/AX=Νήσοι Όλαντ +LocaleNames/el_CY/AZ=Αζερμπαϊτζάν +LocaleNames/el_CY/BA=Βοσνία - Ερζεγοβίνη +LocaleNames/el_CY/BB=Μπαρμπέιντος +LocaleNames/el_CY/BD=Μπανγκλαντές +LocaleNames/el_CY/BE=Βέλγιο +LocaleNames/el_CY/BF=Μπουρκίνα Φάσο +LocaleNames/el_CY/BG=Βουλγαρία +LocaleNames/el_CY/BH=Μπαχρέιν +LocaleNames/el_CY/BI=Μπουρούντι +LocaleNames/el_CY/BJ=Μπενίν +LocaleNames/el_CY/BM=Βερμούδες +LocaleNames/el_CY/BN=Μπρουνέι +LocaleNames/el_CY/BO=Βολιβία +LocaleNames/el_CY/BR=Βραζιλία +LocaleNames/el_CY/BS=Μπαχάμες +LocaleNames/el_CY/BT=Μπουτάν +LocaleNames/el_CY/BV=Νήσος Μπουβέ +LocaleNames/el_CY/BW=Μποτσουάνα +LocaleNames/el_CY/BY=Λευκορωσία +LocaleNames/el_CY/BZ=Μπελίζ +LocaleNames/el_CY/CA=Καναδάς +LocaleNames/el_CY/CC=Νήσοι Κόκος (Κίλινγκ) +LocaleNames/el_CY/CD=Κονγκό - Κινσάσα +LocaleNames/el_CY/CF=Κεντροαφρικανική Δημοκρατία +LocaleNames/el_CY/CG=Κονγκό - Μπραζαβίλ +LocaleNames/el_CY/CH=Ελβετία +LocaleNames/el_CY/CI=Ακτή Ελεφαντοστού +LocaleNames/el_CY/CK=Νήσοι Κουκ +LocaleNames/el_CY/CL=Χιλή +LocaleNames/el_CY/CM=Καμερούν +LocaleNames/el_CY/CN=Κίνα +LocaleNames/el_CY/CO=Κολομβία +LocaleNames/el_CY/CR=Κόστα Ρίκα +LocaleNames/el_CY/CU=Κούβα +LocaleNames/el_CY/CV=Πράσινο Ακρωτήριο +LocaleNames/el_CY/CX=Νήσος των Χριστουγέννων +LocaleNames/el_CY/CY=Κύπρος +LocaleNames/el_CY/CZ=Τσεχία +LocaleNames/el_CY/DE=Γερμανία +LocaleNames/el_CY/DJ=Τζιμπουτί +LocaleNames/el_CY/DK=Δανία +LocaleNames/el_CY/DM=Ντομίνικα +LocaleNames/el_CY/DO=Δομινικανή Δημοκρατία +LocaleNames/el_CY/DZ=Αλγερία +LocaleNames/el_CY/EC=Ισημερινός +LocaleNames/el_CY/EE=Εσθονία +LocaleNames/el_CY/EG=Αίγυπτος +LocaleNames/el_CY/EH=Δυτική Σαχάρα +LocaleNames/el_CY/ER=Ερυθραία +LocaleNames/el_CY/ES=Ισπανία +LocaleNames/el_CY/ET=Αιθιοπία +LocaleNames/el_CY/FI=Φινλανδία +LocaleNames/el_CY/FJ=Φίτζι +LocaleNames/el_CY/FK=Νήσοι Φόκλαντ +LocaleNames/el_CY/FM=Μικρονησία +LocaleNames/el_CY/FO=Νήσοι Φερόες +LocaleNames/el_CY/FR=Γαλλία +LocaleNames/el_CY/GA=Γκαμπόν +LocaleNames/el_CY/GB=Ηνωμένο Βασίλειο +LocaleNames/el_CY/GD=Γρενάδα +LocaleNames/el_CY/GE=Γεωργία +LocaleNames/el_CY/GF=Γαλλική Γουιάνα +LocaleNames/el_CY/GH=Γκάνα +LocaleNames/el_CY/GI=Γιβραλτάρ +LocaleNames/el_CY/GL=Γροιλανδία +LocaleNames/el_CY/GM=Γκάμπια +LocaleNames/el_CY/GN=Γουινέα +LocaleNames/el_CY/GP=Γουαδελούπη +LocaleNames/el_CY/GQ=Ισημερινή Γουινέα +LocaleNames/el_CY/GS=Νήσοι Νότια Γεωργία και Νότιες Σάντουιτς +LocaleNames/el_CY/GT=Γουατεμάλα +LocaleNames/el_CY/GU=Γκουάμ +LocaleNames/el_CY/GW=Γουινέα Μπισάου +LocaleNames/el_CY/GY=Γουιάνα +LocaleNames/el_CY/HK=Χονγκ Κονγκ ΕΔΠ Κίνας +LocaleNames/el_CY/HM=Νήσοι Χερντ και Μακντόναλντ +LocaleNames/el_CY/HN=Ονδούρα +LocaleNames/el_CY/HR=Κροατία +LocaleNames/el_CY/HT=Αϊτή +LocaleNames/el_CY/HU=Ουγγαρία +LocaleNames/el_CY/ID=Ινδονησία +LocaleNames/el_CY/IE=Ιρλανδία +LocaleNames/el_CY/IL=Ισραήλ +LocaleNames/el_CY/IN=Ινδία +LocaleNames/el_CY/IO=Βρετανικά Εδάφη Ινδικού Ωκεανού +LocaleNames/el_CY/IQ=Ιράκ +LocaleNames/el_CY/IR=Ιράν +LocaleNames/el_CY/IS=Ισλανδία +LocaleNames/el_CY/IT=Ιταλία +LocaleNames/el_CY/JM=Τζαμάικα +LocaleNames/el_CY/JO=Ιορδανία +LocaleNames/el_CY/JP=Ιαπωνία +LocaleNames/el_CY/KE=Κένυα +LocaleNames/el_CY/KG=Κιργιστάν +LocaleNames/el_CY/KH=Καμπότζη +LocaleNames/el_CY/KI=Κιριμπάτι +LocaleNames/el_CY/KM=Κομόρες +LocaleNames/el_CY/KN=Σεν Κιτς και Νέβις +LocaleNames/el_CY/KP=Βόρεια Κορέα +LocaleNames/el_CY/KR=Νότια Κορέα +LocaleNames/el_CY/KW=Κουβέιτ +LocaleNames/el_CY/KY=Νήσοι Κέιμαν +LocaleNames/el_CY/KZ=Καζακστάν +LocaleNames/el_CY/LA=Λάος +LocaleNames/el_CY/LB=Λίβανος +LocaleNames/el_CY/LC=Αγία Λουκία +LocaleNames/el_CY/LI=Λιχτενστάιν +LocaleNames/el_CY/LK=Σρι Λάνκα +LocaleNames/el_CY/LR=Λιβερία +LocaleNames/el_CY/LS=Λεσότο +LocaleNames/el_CY/LT=Λιθουανία +LocaleNames/el_CY/LU=Λουξεμβούργο +LocaleNames/el_CY/LV=Λετονία +LocaleNames/el_CY/LY=Λιβύη +LocaleNames/el_CY/MA=Μαρόκο +LocaleNames/el_CY/MC=Μονακό +LocaleNames/el_CY/MD=Μολδαβία +LocaleNames/el_CY/MG=Μαδαγασκάρη +LocaleNames/el_CY/MH=Νήσοι Μάρσαλ +LocaleNames/el_CY/MK=Βόρεια Μακεδονία +LocaleNames/el_CY/ML=Μάλι +LocaleNames/el_CY/MM=Μιανμάρ (Βιρμανία) +LocaleNames/el_CY/MN=Μογγολία +LocaleNames/el_CY/MO=Μακάο ΕΔΠ Κίνας +LocaleNames/el_CY/MP=Νήσοι Βόρειες Μαριάνες +LocaleNames/el_CY/MQ=Μαρτινίκα +LocaleNames/el_CY/MR=Μαυριτανία +LocaleNames/el_CY/MS=Μονσεράτ +LocaleNames/el_CY/MT=Μάλτα +LocaleNames/el_CY/MU=Μαυρίκιος +LocaleNames/el_CY/MV=Μαλδίβες +LocaleNames/el_CY/MW=Μαλάουι +LocaleNames/el_CY/MX=Μεξικό +LocaleNames/el_CY/MY=Μαλαισία +LocaleNames/el_CY/MZ=Μοζαμβίκη +LocaleNames/el_CY/NA=Ναμίμπια +LocaleNames/el_CY/NC=Νέα Καληδονία +LocaleNames/el_CY/NE=Νίγηρας +LocaleNames/el_CY/NF=Νήσος Νόρφολκ +LocaleNames/el_CY/NG=Νιγηρία +LocaleNames/el_CY/NI=Νικαράγουα +LocaleNames/el_CY/NL=Κάτω Χώρες +LocaleNames/el_CY/NO=Νορβηγία +LocaleNames/el_CY/NP=Νεπάλ +LocaleNames/el_CY/NR=Ναουρού +LocaleNames/el_CY/NU=Νιούε +LocaleNames/el_CY/NZ=Νέα Ζηλανδία +LocaleNames/el_CY/OM=Ομάν +LocaleNames/el_CY/PA=Παναμάς +LocaleNames/el_CY/PE=Περού +LocaleNames/el_CY/PF=Γαλλική Πολυνησία +LocaleNames/el_CY/PG=Παπούα Νέα Γουινέα +LocaleNames/el_CY/PH=Φιλιππίνες +LocaleNames/el_CY/PK=Πακιστάν +LocaleNames/el_CY/PL=Πολωνία +LocaleNames/el_CY/PM=Σεν Πιερ και Μικελόν +LocaleNames/el_CY/PN=Νήσοι Πίτκερν +LocaleNames/el_CY/PR=Πουέρτο Ρίκο +LocaleNames/el_CY/PS=Παλαιστινιακά Εδάφη +LocaleNames/el_CY/PT=Πορτογαλία +LocaleNames/el_CY/PW=Παλάου +LocaleNames/el_CY/PY=Παραγουάη +LocaleNames/el_CY/QA=Κατάρ +LocaleNames/el_CY/RE=Ρεϊνιόν +LocaleNames/el_CY/RO=Ρουμανία +LocaleNames/el_CY/RU=Ρωσία +LocaleNames/el_CY/RW=Ρουάντα +LocaleNames/el_CY/SA=Σαουδική Αραβία +LocaleNames/el_CY/SB=Νήσοι Σολομώντος +LocaleNames/el_CY/SC=Σεϋχέλλες +LocaleNames/el_CY/SD=Σουδάν +LocaleNames/el_CY/SE=Σουηδία +LocaleNames/el_CY/SG=Σιγκαπούρη +LocaleNames/el_CY/SH=Αγία Ελένη +LocaleNames/el_CY/SI=Σλοβενία +LocaleNames/el_CY/SJ=Σβάλμπαρντ και Γιαν Μαγιέν +LocaleNames/el_CY/SK=Σλοβακία +LocaleNames/el_CY/SL=Σιέρα Λεόνε +LocaleNames/el_CY/SM=Άγιος Μαρίνος +LocaleNames/el_CY/SN=Σενεγάλη +LocaleNames/el_CY/SO=Σομαλία +LocaleNames/el_CY/SR=Σουρινάμ +LocaleNames/el_CY/ST=Σάο Τομέ και Πρίνσιπε +LocaleNames/el_CY/SV=Ελ Σαλβαδόρ +LocaleNames/el_CY/SY=Συρία +LocaleNames/el_CY/SZ=Εσουατίνι +LocaleNames/el_CY/TC=Νήσοι Τερκς και Κάικος +LocaleNames/el_CY/TD=Τσαντ +LocaleNames/el_CY/TF=Γαλλικά Νότια Εδάφη +LocaleNames/el_CY/TG=Τόγκο +LocaleNames/el_CY/TH=Ταϊλάνδη +LocaleNames/el_CY/TJ=Τατζικιστάν +LocaleNames/el_CY/TK=Τοκελάου +LocaleNames/el_CY/TL=Τιμόρ-Λέστε +LocaleNames/el_CY/TM=Τουρκμενιστάν +LocaleNames/el_CY/TN=Τυνησία +LocaleNames/el_CY/TO=Τόνγκα +LocaleNames/el_CY/TR=Τουρκία +LocaleNames/el_CY/TT=Τρινιντάντ και Τομπάγκο +LocaleNames/el_CY/TV=Τουβαλού +LocaleNames/el_CY/TW=Ταϊβάν +LocaleNames/el_CY/TZ=Τανζανία +LocaleNames/el_CY/UA=Ουκρανία +LocaleNames/el_CY/UG=Ουγκάντα +LocaleNames/el_CY/UM=Απομακρυσμένες Νησίδες ΗΠΑ +LocaleNames/el_CY/US=Ηνωμένες Πολιτείες +LocaleNames/el_CY/UY=Ουρουγουάη +LocaleNames/el_CY/UZ=Ουζμπεκιστάν +LocaleNames/el_CY/VA=Βατικανό +LocaleNames/el_CY/VC=Άγιος Βικέντιος και Γρεναδίνες +LocaleNames/el_CY/VE=Βενεζουέλα +LocaleNames/el_CY/VG=Βρετανικές Παρθένες Νήσοι +LocaleNames/el_CY/VI=Αμερικανικές Παρθένες Νήσοι +LocaleNames/el_CY/VN=Βιετνάμ +LocaleNames/el_CY/VU=Βανουάτου +LocaleNames/el_CY/WF=Γουάλις και Φουτούνα +LocaleNames/el_CY/WS=Σαμόα +LocaleNames/el_CY/YE=Υεμένη +LocaleNames/el_CY/YT=Μαγιότ +LocaleNames/el_CY/ZA=Νότια Αφρική +LocaleNames/el_CY/ZM=Ζάμπια +LocaleNames/el_CY/ZW=Ζιμπάμπουε +CurrencyNames/el_CY/EUR=€ #ms_MY and ms FormatData/ms_MY/latn.NumberPatterns/0=#,##0.### -FormatData/ms_MY/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/ms_MY/latn.NumberPatterns/1=¤#,##0.00 FormatData/ms_MY/latn.NumberPatterns/2=#,##0% -FormatData/ms_MY/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/ms_MY/TimePatterns/1=h:mm:ss\u202fa z -FormatData/ms_MY/TimePatterns/2=h:mm:ss\u202fa -FormatData/ms_MY/TimePatterns/3=h:mm\u202fa +FormatData/ms_MY/TimePatterns/0=h:mm:ss a zzzz +FormatData/ms_MY/TimePatterns/1=h:mm:ss a z +FormatData/ms_MY/TimePatterns/2=h:mm:ss a +FormatData/ms_MY/TimePatterns/3=h:mm a FormatData/ms_MY/DatePatterns/0=EEEE, d MMMM y FormatData/ms_MY/DatePatterns/1=d MMMM y FormatData/ms_MY/DatePatterns/2=d MMM y @@ -3099,7 +3099,7 @@ LocaleNames/ms/CA=Kanada LocaleNames/ms/CC=Kepulauan Cocos (Keeling) LocaleNames/ms/CD=Congo - Kinshasa LocaleNames/ms/CF=Republik Afrika Tengah -LocaleNames/ms/CI=Cote d\u2019Ivoire +LocaleNames/ms/CI=Cote d’Ivoire LocaleNames/ms/CL=Chile LocaleNames/ms/CM=Cameroon LocaleNames/ms/CN=China @@ -3165,68 +3165,68 @@ LocaleNames/ms/ZA=Afrika Selatan FormatData/es_US/Eras/0=a.C. FormatData/es_US/Eras/1=d.C. FormatData/es_US/latn.NumberPatterns/0=#,##0.### -FormatData/es_US/latn.NumberPatterns/1=\u00a4#,##0.00 +FormatData/es_US/latn.NumberPatterns/1=¤#,##0.00 FormatData/es_US/latn.NumberPatterns/2=#,##0% -FormatData/es_US/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_US/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_US/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_US/TimePatterns/3=h:mm\u202fa +FormatData/es_US/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_US/TimePatterns/1=h:mm:ss a z +FormatData/es_US/TimePatterns/2=h:mm:ss a +FormatData/es_US/TimePatterns/3=h:mm a FormatData/es_US/DatePatterns/0=EEEE, d 'de' MMMM 'de' y FormatData/es_US/DatePatterns/1=d 'de' MMMM 'de' y FormatData/es_US/DatePatterns/2=d MMM y FormatData/es_US/DatePatterns/3=d/M/y FormatData/es_US/DateTimePatterns/0={1}, {0} LocaleNames/es_US/aa=afar -LocaleNames/es_US/ae=av\u00e9stico +LocaleNames/es_US/ae=avéstico LocaleNames/es_US/ak=akan -LocaleNames/es_US/an=aragon\u00e9s +LocaleNames/es_US/an=aragonés LocaleNames/es_US/av=avar LocaleNames/es_US/ay=aimara LocaleNames/es_US/az=azerbaiyano LocaleNames/es_US/ba=baskir LocaleNames/es_US/bm=bambara -LocaleNames/es_US/bn=bengal\u00ed +LocaleNames/es_US/bn=bengalí LocaleNames/es_US/bs=bosnio LocaleNames/es_US/ce=checheno LocaleNames/es_US/ch=chamorro LocaleNames/es_US/cr=cree -LocaleNames/es_US/cu=eslavo eclesi\u00e1stico +LocaleNames/es_US/cu=eslavo eclesiástico LocaleNames/es_US/cv=chuvasio LocaleNames/es_US/dv=divehi -LocaleNames/es_US/ee=ew\u00e9 +LocaleNames/es_US/ee=ewé LocaleNames/es_US/eu=euskera LocaleNames/es_US/ff=fula -LocaleNames/es_US/fo=fero\u00e9s -LocaleNames/es_US/fy=fris\u00f3n occidental -LocaleNames/es_US/gu=gurayat\u00ed -LocaleNames/es_US/gv=man\u00e9s +LocaleNames/es_US/fo=feroés +LocaleNames/es_US/fy=frisón occidental +LocaleNames/es_US/gu=gurayatí +LocaleNames/es_US/gv=manés LocaleNames/es_US/hi=hindi LocaleNames/es_US/ho=hiri motu LocaleNames/es_US/ht=criollo haitiano LocaleNames/es_US/hz=herero LocaleNames/es_US/ie=interlingue LocaleNames/es_US/ig=igbo -LocaleNames/es_US/ii=yi de Sichu\u00e1n +LocaleNames/es_US/ii=yi de Sichuán LocaleNames/es_US/io=ido -LocaleNames/es_US/jv=javan\u00e9s +LocaleNames/es_US/jv=javanés LocaleNames/es_US/kg=kongo LocaleNames/es_US/ki=kikuyu LocaleNames/es_US/kj=kuanyama LocaleNames/es_US/kk=kazajo LocaleNames/es_US/km=jemer -LocaleNames/es_US/kn=canar\u00e9s +LocaleNames/es_US/kn=canarés LocaleNames/es_US/kr=kanuri LocaleNames/es_US/ks=cachemiro LocaleNames/es_US/ku=kurdo LocaleNames/es_US/kv=komi -LocaleNames/es_US/kw=c\u00f3rnico -LocaleNames/es_US/ky=kirgu\u00eds -LocaleNames/es_US/lb=luxemburgu\u00e9s +LocaleNames/es_US/kw=córnico +LocaleNames/es_US/ky=kirguís +LocaleNames/es_US/lb=luxemburgués LocaleNames/es_US/lg=ganda -LocaleNames/es_US/li=limburgu\u00e9s +LocaleNames/es_US/li=limburgués LocaleNames/es_US/lu=luba-katanga -LocaleNames/es_US/mh=marshal\u00e9s -LocaleNames/es_US/mr=marat\u00ed +LocaleNames/es_US/mh=marshalés +LocaleNames/es_US/mr=maratí LocaleNames/es_US/nb=noruego bokmal LocaleNames/es_US/nd=ndebele del norte LocaleNames/es_US/ng=ndonga @@ -3236,7 +3236,7 @@ LocaleNames/es_US/nv=navajo LocaleNames/es_US/ny=nyanja LocaleNames/es_US/oc=occitano LocaleNames/es_US/oj=ojibwa -LocaleNames/es_US/os=os\u00e9tico +LocaleNames/es_US/os=osético LocaleNames/es_US/pi=pali LocaleNames/es_US/rm=romanche LocaleNames/es_US/rn=kirundi @@ -3248,7 +3248,7 @@ LocaleNames/es_US/sl=esloveno LocaleNames/es_US/sn=shona LocaleNames/es_US/ss=siswati LocaleNames/es_US/st=sesotho del sur -LocaleNames/es_US/su=sundan\u00e9s +LocaleNames/es_US/su=sundanés LocaleNames/es_US/sw=swahili LocaleNames/es_US/tg=tayiko LocaleNames/es_US/tn=setsuana @@ -3259,7 +3259,7 @@ LocaleNames/es_US/ug=uigur LocaleNames/es_US/uk=ucraniano LocaleNames/es_US/uz=uzbeko LocaleNames/es_US/ve=venda -LocaleNames/es_US/wa=val\u00f3n +LocaleNames/es_US/wa=valón LocaleNames/es_US/za=zhuang LocaleNames/es_US/BA=Bosnia y Herzegovina LocaleNames/es_US/CC=Islas Cocos @@ -3269,14 +3269,14 @@ LocaleNames/es_US/EH=Sahara Occidental LocaleNames/es_US/FK=Islas Malvinas LocaleNames/es_US/HK=RAE de Hong Kong (China) LocaleNames/es_US/KM=Comoras -LocaleNames/es_US/LC=Santa Luc\u00eda +LocaleNames/es_US/LC=Santa Lucía LocaleNames/es_US/LS=Lesoto LocaleNames/es_US/MO=RAE de Macao (China) LocaleNames/es_US/MW=Malaui -LocaleNames/es_US/NL=Pa\u00edses Bajos +LocaleNames/es_US/NL=Países Bajos LocaleNames/es_US/NU=Niue -LocaleNames/es_US/PG=Pap\u00faa Nueva Guinea -LocaleNames/es_US/PK=Pakist\u00e1n +LocaleNames/es_US/PG=Papúa Nueva Guinea +LocaleNames/es_US/PK=Pakistán LocaleNames/es_US/PN=Islas Pitcairn LocaleNames/es_US/PS=Territorios Palestinos LocaleNames/es_US/PW=Palaos @@ -3286,169 +3286,169 @@ LocaleNames/es_US/SH=Santa Elena LocaleNames/es_US/TF=Territorios Australes Franceses LocaleNames/es_US/TK=Tokelau LocaleNames/es_US/TT=Trinidad y Tobago -LocaleNames/es_US/VI=Islas V\u00edrgenes de EE. UU. +LocaleNames/es_US/VI=Islas Vírgenes de EE. UU. CurrencyNames/es_US/USD=$ #bug 4400849 LocaleNames/pt/aa=afar -LocaleNames/pt/ab=abc\u00e1zio -LocaleNames/pt/ae=av\u00e9stico -LocaleNames/pt/af=afric\u00e2ner -LocaleNames/pt/am=am\u00e1rico -LocaleNames/pt/an=aragon\u00eas -LocaleNames/pt/ar=\u00e1rabe -LocaleNames/pt/as=assam\u00eas -LocaleNames/pt/av=av\u00e1rico -LocaleNames/pt/ay=aimar\u00e1 +LocaleNames/pt/ab=abcázio +LocaleNames/pt/ae=avéstico +LocaleNames/pt/af=africâner +LocaleNames/pt/am=amárico +LocaleNames/pt/an=aragonês +LocaleNames/pt/ar=árabe +LocaleNames/pt/as=assamês +LocaleNames/pt/av=avárico +LocaleNames/pt/ay=aimará LocaleNames/pt/az=azerbaijano LocaleNames/pt/ba=bashkir LocaleNames/pt/be=bielorrusso -LocaleNames/pt/bg=b\u00falgaro -LocaleNames/pt/bi=bislam\u00e1 +LocaleNames/pt/bg=búlgaro +LocaleNames/pt/bi=bislamá LocaleNames/pt/bm=bambara LocaleNames/pt/bn=bengali LocaleNames/pt/bo=tibetano -LocaleNames/pt/br=bret\u00e3o -LocaleNames/pt/bs=b\u00f3snio -LocaleNames/pt/ca=catal\u00e3o +LocaleNames/pt/br=bretão +LocaleNames/pt/bs=bósnio +LocaleNames/pt/ca=catalão LocaleNames/pt/ce=checheno LocaleNames/pt/ch=chamorro LocaleNames/pt/co=corso LocaleNames/pt/cr=cree LocaleNames/pt/cs=tcheco -LocaleNames/pt/cu=eslavo eclesi\u00e1stico +LocaleNames/pt/cu=eslavo eclesiástico LocaleNames/pt/cv=tchuvache -LocaleNames/pt/cy=gal\u00eas -LocaleNames/pt/da=dinamarqu\u00eas -LocaleNames/pt/de=alem\u00e3o +LocaleNames/pt/cy=galês +LocaleNames/pt/da=dinamarquês +LocaleNames/pt/de=alemão LocaleNames/pt/dv=divehi LocaleNames/pt/dz=dzonga LocaleNames/pt/ee=ewe LocaleNames/pt/el=grego -LocaleNames/pt/en=ingl\u00eas +LocaleNames/pt/en=inglês LocaleNames/pt/eo=esperanto LocaleNames/pt/es=espanhol LocaleNames/pt/et=estoniano LocaleNames/pt/eu=basco LocaleNames/pt/fa=persa LocaleNames/pt/ff=fula -LocaleNames/pt/fi=finland\u00eas +LocaleNames/pt/fi=finlandês LocaleNames/pt/fj=fijiano -LocaleNames/pt/fo=fero\u00eas -LocaleNames/pt/fr=franc\u00eas -LocaleNames/pt/fy=fr\u00edsio ocidental -LocaleNames/pt/ga=irland\u00eas -LocaleNames/pt/gd=ga\u00e9lico escoc\u00eas +LocaleNames/pt/fo=feroês +LocaleNames/pt/fr=francês +LocaleNames/pt/fy=frísio ocidental +LocaleNames/pt/ga=irlandês +LocaleNames/pt/gd=gaélico escocês LocaleNames/pt/gl=galego LocaleNames/pt/gn=guarani LocaleNames/pt/gu=guzerate LocaleNames/pt/gv=manx -LocaleNames/pt/ha=hau\u00e7\u00e1 +LocaleNames/pt/ha=hauçá LocaleNames/pt/he=hebraico -LocaleNames/pt/hi=h\u00edndi +LocaleNames/pt/hi=híndi LocaleNames/pt/ho=hiri motu LocaleNames/pt/hr=croata LocaleNames/pt/ht=haitiano -LocaleNames/pt/hu=h\u00fangaro -LocaleNames/pt/hy=arm\u00eanio +LocaleNames/pt/hu=húngaro +LocaleNames/pt/hy=armênio LocaleNames/pt/hz=herero -LocaleNames/pt/ia=interl\u00edngua -LocaleNames/pt/id=indon\u00e9sio +LocaleNames/pt/ia=interlíngua +LocaleNames/pt/id=indonésio LocaleNames/pt/ie=interlingue LocaleNames/pt/ig=igbo LocaleNames/pt/ii=sichuan yi LocaleNames/pt/io=ido -LocaleNames/pt/is=island\u00eas +LocaleNames/pt/is=islandês LocaleNames/pt/it=italiano LocaleNames/pt/iu=inuktitut -LocaleNames/pt/ja=japon\u00eas +LocaleNames/pt/ja=japonês LocaleNames/pt/ka=georgiano -LocaleNames/pt/kg=congol\u00eas +LocaleNames/pt/kg=congolês LocaleNames/pt/ki=quicuio LocaleNames/pt/kj=cuanhama LocaleNames/pt/kk=cazaque -LocaleNames/pt/kl=groenland\u00eas +LocaleNames/pt/kl=groenlandês LocaleNames/pt/km=khmer LocaleNames/pt/kn=canarim LocaleNames/pt/ko=coreano -LocaleNames/pt/kr=can\u00fari +LocaleNames/pt/kr=canúri LocaleNames/pt/ks=caxemira LocaleNames/pt/ku=curdo LocaleNames/pt/kv=komi -LocaleNames/pt/kw=c\u00f3rnico +LocaleNames/pt/kw=córnico LocaleNames/pt/ky=quirguiz LocaleNames/pt/la=latim -LocaleNames/pt/lb=luxemburgu\u00eas +LocaleNames/pt/lb=luxemburguês LocaleNames/pt/lg=luganda -LocaleNames/pt/li=limburgu\u00eas +LocaleNames/pt/li=limburguês LocaleNames/pt/ln=lingala LocaleNames/pt/lo=laosiano LocaleNames/pt/lt=lituano LocaleNames/pt/lu=luba-catanga -LocaleNames/pt/lv=let\u00e3o +LocaleNames/pt/lv=letão LocaleNames/pt/mg=malgaxe -LocaleNames/pt/mh=marshal\u00eas +LocaleNames/pt/mh=marshalês LocaleNames/pt/mi=maori -LocaleNames/pt/mk=maced\u00f4nio +LocaleNames/pt/mk=macedônio LocaleNames/pt/ml=malaiala LocaleNames/pt/mn=mongol LocaleNames/pt/mr=marati LocaleNames/pt/ms=malaio -LocaleNames/pt/mt=malt\u00eas -LocaleNames/pt/my=birman\u00eas +LocaleNames/pt/mt=maltês +LocaleNames/pt/my=birmanês LocaleNames/pt/na=nauruano -LocaleNames/pt/nb=bokm\u00e5l noruegu\u00eas +LocaleNames/pt/nb=bokmål norueguês LocaleNames/pt/nd=ndebele do norte -LocaleNames/pt/ne=nepal\u00eas +LocaleNames/pt/ne=nepalês LocaleNames/pt/ng=dongo -LocaleNames/pt/nl=holand\u00eas -LocaleNames/pt/nn=nynorsk noruegu\u00eas -LocaleNames/pt/no=noruegu\u00eas +LocaleNames/pt/nl=holandês +LocaleNames/pt/nn=nynorsk norueguês +LocaleNames/pt/no=norueguês LocaleNames/pt/nr=ndebele do sul LocaleNames/pt/nv=navajo LocaleNames/pt/ny=nianja -LocaleNames/pt/oc=occit\u00e2nico +LocaleNames/pt/oc=occitânico LocaleNames/pt/oj=ojibwa LocaleNames/pt/om=oromo -LocaleNames/pt/or=ori\u00e1 +LocaleNames/pt/or=oriá LocaleNames/pt/os=osseto LocaleNames/pt/pa=panjabi -LocaleNames/pt/pi=p\u00e1li -LocaleNames/pt/pl=polon\u00eas +LocaleNames/pt/pi=páli +LocaleNames/pt/pl=polonês LocaleNames/pt/ps=pashto -LocaleNames/pt/pt=portugu\u00eas -LocaleNames/pt/qu=qu\u00edchua +LocaleNames/pt/pt=português +LocaleNames/pt/qu=quíchua LocaleNames/pt/rm=romanche LocaleNames/pt/rn=rundi LocaleNames/pt/ro=romeno LocaleNames/pt/ru=russo LocaleNames/pt/rw=quiniaruanda -LocaleNames/pt/sa=s\u00e2nscrito +LocaleNames/pt/sa=sânscrito LocaleNames/pt/sc=sardo LocaleNames/pt/sd=sindi LocaleNames/pt/se=sami setentrional LocaleNames/pt/sg=sango -LocaleNames/pt/si=cingal\u00eas +LocaleNames/pt/si=cingalês LocaleNames/pt/sk=eslovaco LocaleNames/pt/sl=esloveno LocaleNames/pt/so=somali -LocaleNames/pt/sq=alban\u00eas -LocaleNames/pt/sr=s\u00e9rvio -LocaleNames/pt/ss=su\u00e1zi +LocaleNames/pt/sq=albanês +LocaleNames/pt/sr=sérvio +LocaleNames/pt/ss=suázi LocaleNames/pt/st=soto do sul -LocaleNames/pt/su=sundan\u00eas +LocaleNames/pt/su=sundanês LocaleNames/pt/sv=sueco -LocaleNames/pt/sw=sua\u00edli -LocaleNames/pt/ta=t\u00e2mil -LocaleNames/pt/te=t\u00e9lugo +LocaleNames/pt/sw=suaíli +LocaleNames/pt/ta=tâmil +LocaleNames/pt/te=télugo LocaleNames/pt/tg=tadjique -LocaleNames/pt/th=tailand\u00eas -LocaleNames/pt/ti=tigr\u00ednia +LocaleNames/pt/th=tailandês +LocaleNames/pt/ti=tigrínia LocaleNames/pt/tk=turcomeno LocaleNames/pt/tn=tswana -LocaleNames/pt/to=tongan\u00eas +LocaleNames/pt/to=tonganês LocaleNames/pt/tr=turco LocaleNames/pt/ts=tsonga -LocaleNames/pt/tt=t\u00e1rtaro +LocaleNames/pt/tt=tártaro LocaleNames/pt/tw=twi LocaleNames/pt/ty=taitiano LocaleNames/pt/ug=uigur @@ -3458,628 +3458,628 @@ LocaleNames/pt/uz=uzbeque LocaleNames/pt/ve=venda LocaleNames/pt/vi=vietnamita LocaleNames/pt/vo=volapuque -LocaleNames/pt/wa=val\u00e3o +LocaleNames/pt/wa=valão LocaleNames/pt/wo=uolofe LocaleNames/pt/xh=xhosa -LocaleNames/pt/yi=i\u00eddiche -LocaleNames/pt/yo=iorub\u00e1 +LocaleNames/pt/yi=iídiche +LocaleNames/pt/yo=iorubá LocaleNames/pt/za=zhuang -LocaleNames/pt/zh=chin\u00eas +LocaleNames/pt/zh=chinês LocaleNames/pt/zu=zulu -LocaleNames/pt/AE=Emirados \u00c1rabes Unidos -LocaleNames/pt/AF=Afeganist\u00e3o -LocaleNames/pt/AG=Ant\u00edgua e Barbuda -LocaleNames/pt/AL=Alb\u00e2nia -LocaleNames/pt/AM=Arm\u00eania -LocaleNames/pt/AQ=Ant\u00e1rtida +LocaleNames/pt/AE=Emirados Árabes Unidos +LocaleNames/pt/AF=Afeganistão +LocaleNames/pt/AG=Antígua e Barbuda +LocaleNames/pt/AL=Albânia +LocaleNames/pt/AM=Armênia +LocaleNames/pt/AQ=Antártida LocaleNames/pt/AS=Samoa Americana -LocaleNames/pt/AT=\u00c1ustria -LocaleNames/pt/AU=Austr\u00e1lia -LocaleNames/pt/AZ=Azerbaij\u00e3o -LocaleNames/pt/BA=B\u00f3snia e Herzegovina -LocaleNames/pt/BE=B\u00e9lgica +LocaleNames/pt/AT=Áustria +LocaleNames/pt/AU=Austrália +LocaleNames/pt/AZ=Azerbaijão +LocaleNames/pt/BA=Bósnia e Herzegovina +LocaleNames/pt/BE=Bélgica LocaleNames/pt/BF=Burquina Faso -LocaleNames/pt/BG=Bulg\u00e1ria +LocaleNames/pt/BG=Bulgária LocaleNames/pt/BH=Barein LocaleNames/pt/BM=Bermudas -LocaleNames/pt/BO=Bol\u00edvia +LocaleNames/pt/BO=Bolívia LocaleNames/pt/BR=Brasil -LocaleNames/pt/BT=But\u00e3o +LocaleNames/pt/BT=Butão LocaleNames/pt/BV=Ilha Bouvet LocaleNames/pt/BW=Botsuana -LocaleNames/pt/CA=Canad\u00e1 +LocaleNames/pt/CA=Canadá LocaleNames/pt/CC=Ilhas Cocos (Keeling) LocaleNames/pt/CD=Congo - Kinshasa -LocaleNames/pt/CF=Rep\u00fablica Centro-Africana -LocaleNames/pt/CH=Su\u00ed\u00e7a +LocaleNames/pt/CF=República Centro-Africana +LocaleNames/pt/CH=Suíça LocaleNames/pt/CI=Costa do Marfim LocaleNames/pt/CK=Ilhas Cook -LocaleNames/pt/CM=Camar\u00f5es -LocaleNames/pt/CO=Col\u00f4mbia +LocaleNames/pt/CM=Camarões +LocaleNames/pt/CO=Colômbia LocaleNames/pt/CV=Cabo Verde LocaleNames/pt/CX=Ilha Christmas LocaleNames/pt/CY=Chipre -LocaleNames/pt/CZ=Tch\u00e9quia +LocaleNames/pt/CZ=Tchéquia LocaleNames/pt/DE=Alemanha LocaleNames/pt/DJ=Djibuti LocaleNames/pt/DK=Dinamarca -LocaleNames/pt/DO=Rep\u00fablica Dominicana -LocaleNames/pt/DZ=Arg\u00e9lia +LocaleNames/pt/DO=República Dominicana +LocaleNames/pt/DZ=Argélia LocaleNames/pt/EC=Equador -LocaleNames/pt/EE=Est\u00f4nia +LocaleNames/pt/EE=Estônia LocaleNames/pt/EG=Egito LocaleNames/pt/EH=Saara Ocidental LocaleNames/pt/ER=Eritreia LocaleNames/pt/ES=Espanha -LocaleNames/pt/ET=Eti\u00f3pia -LocaleNames/pt/FI=Finl\u00e2ndia +LocaleNames/pt/ET=Etiópia +LocaleNames/pt/FI=Finlândia LocaleNames/pt/FK=Ilhas Malvinas -LocaleNames/pt/FM=Micron\u00e9sia -LocaleNames/pt/FO=Ilhas Faro\u00e9 -LocaleNames/pt/FR=Fran\u00e7a -LocaleNames/pt/GA=Gab\u00e3o +LocaleNames/pt/FM=Micronésia +LocaleNames/pt/FO=Ilhas Faroé +LocaleNames/pt/FR=França +LocaleNames/pt/GA=Gabão LocaleNames/pt/GB=Reino Unido LocaleNames/pt/GD=Granada -LocaleNames/pt/GE=Ge\u00f3rgia +LocaleNames/pt/GE=Geórgia LocaleNames/pt/GF=Guiana Francesa LocaleNames/pt/GH=Gana -LocaleNames/pt/GL=Groenl\u00e2ndia -LocaleNames/pt/GM=G\u00e2mbia -LocaleNames/pt/GN=Guin\u00e9 +LocaleNames/pt/GL=Groenlândia +LocaleNames/pt/GM=Gâmbia +LocaleNames/pt/GN=Guiné LocaleNames/pt/GP=Guadalupe -LocaleNames/pt/GQ=Guin\u00e9 Equatorial -LocaleNames/pt/GR=Gr\u00e9cia -LocaleNames/pt/GS=Ilhas Ge\u00f3rgia do Sul e Sandwich do Sul -LocaleNames/pt/GW=Guin\u00e9-Bissau +LocaleNames/pt/GQ=Guiné Equatorial +LocaleNames/pt/GR=Grécia +LocaleNames/pt/GS=Ilhas Geórgia do Sul e Sandwich do Sul +LocaleNames/pt/GW=Guiné-Bissau LocaleNames/pt/GY=Guiana LocaleNames/pt/HK=Hong Kong, RAE da China LocaleNames/pt/HM=Ilhas Heard e McDonald -LocaleNames/pt/HR=Cro\u00e1cia +LocaleNames/pt/HR=Croácia LocaleNames/pt/HU=Hungria -LocaleNames/pt/ID=Indon\u00e9sia +LocaleNames/pt/ID=Indonésia LocaleNames/pt/IE=Irlanda -LocaleNames/pt/IN=\u00cdndia -LocaleNames/pt/IO=Territ\u00f3rio Brit\u00e2nico do Oceano \u00cdndico +LocaleNames/pt/IN=Índia +LocaleNames/pt/IO=Território Britânico do Oceano Índico LocaleNames/pt/IQ=Iraque -LocaleNames/pt/IR=Ir\u00e3 -LocaleNames/pt/IS=Isl\u00e2ndia -LocaleNames/pt/IT=It\u00e1lia -LocaleNames/pt/JO=Jord\u00e2nia -LocaleNames/pt/JP=Jap\u00e3o -LocaleNames/pt/KE=Qu\u00eania -LocaleNames/pt/KG=Quirguist\u00e3o +LocaleNames/pt/IR=Irã +LocaleNames/pt/IS=Islândia +LocaleNames/pt/IT=Itália +LocaleNames/pt/JO=Jordânia +LocaleNames/pt/JP=Japão +LocaleNames/pt/KE=Quênia +LocaleNames/pt/KG=Quirguistão LocaleNames/pt/KH=Camboja LocaleNames/pt/KI=Quiribati LocaleNames/pt/KM=Comores -LocaleNames/pt/KN=S\u00e3o Crist\u00f3v\u00e3o e N\u00e9vis +LocaleNames/pt/KN=São Cristóvão e Névis LocaleNames/pt/KP=Coreia do Norte LocaleNames/pt/KR=Coreia do Sul LocaleNames/pt/KY=Ilhas Cayman -LocaleNames/pt/KZ=Cazaquist\u00e3o +LocaleNames/pt/KZ=Cazaquistão LocaleNames/pt/LA=Laos -LocaleNames/pt/LB=L\u00edbano -LocaleNames/pt/LC=Santa L\u00facia -LocaleNames/pt/LR=Lib\u00e9ria +LocaleNames/pt/LB=Líbano +LocaleNames/pt/LC=Santa Lúcia +LocaleNames/pt/LR=Libéria LocaleNames/pt/LS=Lesoto -LocaleNames/pt/LT=Litu\u00e2nia +LocaleNames/pt/LT=Lituânia LocaleNames/pt/LU=Luxemburgo -LocaleNames/pt/LV=Let\u00f4nia -LocaleNames/pt/LY=L\u00edbia +LocaleNames/pt/LV=Letônia +LocaleNames/pt/LY=Líbia LocaleNames/pt/MA=Marrocos -LocaleNames/pt/MC=M\u00f4naco -LocaleNames/pt/MD=Mold\u00e1via +LocaleNames/pt/MC=Mônaco +LocaleNames/pt/MD=Moldávia LocaleNames/pt/MH=Ilhas Marshall -LocaleNames/pt/MK=Maced\u00f4nia do Norte -LocaleNames/pt/MM=Mianmar (Birm\u00e2nia) -LocaleNames/pt/MN=Mong\u00f3lia +LocaleNames/pt/MK=Macedônia do Norte +LocaleNames/pt/MM=Mianmar (Birmânia) +LocaleNames/pt/MN=Mongólia LocaleNames/pt/MO=Macau, RAE da China LocaleNames/pt/MP=Ilhas Marianas do Norte LocaleNames/pt/MQ=Martinica -LocaleNames/pt/MR=Maurit\u00e2nia -LocaleNames/pt/MU=Maur\u00edcio +LocaleNames/pt/MR=Mauritânia +LocaleNames/pt/MU=Maurício LocaleNames/pt/MV=Maldivas -LocaleNames/pt/MX=M\u00e9xico -LocaleNames/pt/MY=Mal\u00e1sia -LocaleNames/pt/MZ=Mo\u00e7ambique -LocaleNames/pt/NA=Nam\u00edbia -LocaleNames/pt/NC=Nova Caled\u00f4nia -LocaleNames/pt/NE=N\u00edger +LocaleNames/pt/MX=México +LocaleNames/pt/MY=Malásia +LocaleNames/pt/MZ=Moçambique +LocaleNames/pt/NA=Namíbia +LocaleNames/pt/NC=Nova Caledônia +LocaleNames/pt/NE=Níger LocaleNames/pt/NF=Ilha Norfolk -LocaleNames/pt/NG=Nig\u00e9ria -LocaleNames/pt/NI=Nicar\u00e1gua -LocaleNames/pt/NL=Pa\u00edses Baixos +LocaleNames/pt/NG=Nigéria +LocaleNames/pt/NI=Nicarágua +LocaleNames/pt/NL=Países Baixos LocaleNames/pt/NO=Noruega -LocaleNames/pt/NZ=Nova Zel\u00e2ndia -LocaleNames/pt/OM=Om\u00e3 -LocaleNames/pt/PA=Panam\u00e1 -LocaleNames/pt/PF=Polin\u00e9sia Francesa -LocaleNames/pt/PG=Papua-Nova Guin\u00e9 +LocaleNames/pt/NZ=Nova Zelândia +LocaleNames/pt/OM=Omã +LocaleNames/pt/PA=Panamá +LocaleNames/pt/PF=Polinésia Francesa +LocaleNames/pt/PG=Papua-Nova Guiné LocaleNames/pt/PH=Filipinas -LocaleNames/pt/PK=Paquist\u00e3o -LocaleNames/pt/PL=Pol\u00f4nia -LocaleNames/pt/PM=S\u00e3o Pedro e Miquel\u00e3o +LocaleNames/pt/PK=Paquistão +LocaleNames/pt/PL=Polônia +LocaleNames/pt/PM=São Pedro e Miquelão LocaleNames/pt/PR=Porto Rico -LocaleNames/pt/PS=Territ\u00f3rios palestinos +LocaleNames/pt/PS=Territórios palestinos LocaleNames/pt/PY=Paraguai LocaleNames/pt/QA=Catar -LocaleNames/pt/RE=Reuni\u00e3o -LocaleNames/pt/RO=Rom\u00eania -LocaleNames/pt/RU=R\u00fassia +LocaleNames/pt/RE=Reunião +LocaleNames/pt/RO=Romênia +LocaleNames/pt/RU=Rússia LocaleNames/pt/RW=Ruanda -LocaleNames/pt/SA=Ar\u00e1bia Saudita -LocaleNames/pt/SB=Ilhas Salom\u00e3o -LocaleNames/pt/SD=Sud\u00e3o -LocaleNames/pt/SE=Su\u00e9cia +LocaleNames/pt/SA=Arábia Saudita +LocaleNames/pt/SB=Ilhas Salomão +LocaleNames/pt/SD=Sudão +LocaleNames/pt/SE=Suécia LocaleNames/pt/SG=Singapura LocaleNames/pt/SH=Santa Helena -LocaleNames/pt/SI=Eslov\u00eania +LocaleNames/pt/SI=Eslovênia LocaleNames/pt/SJ=Svalbard e Jan Mayen -LocaleNames/pt/SK=Eslov\u00e1quia +LocaleNames/pt/SK=Eslováquia LocaleNames/pt/SL=Serra Leoa -LocaleNames/pt/SO=Som\u00e1lia -LocaleNames/pt/ST=S\u00e3o Tom\u00e9 e Pr\u00edncipe -LocaleNames/pt/SY=S\u00edria -LocaleNames/pt/SZ=Essuat\u00edni +LocaleNames/pt/SO=Somália +LocaleNames/pt/ST=São Tomé e Príncipe +LocaleNames/pt/SY=Síria +LocaleNames/pt/SZ=Essuatíni LocaleNames/pt/TC=Ilhas Turcas e Caicos LocaleNames/pt/TD=Chade -LocaleNames/pt/TF=Territ\u00f3rios Franceses do Sul -LocaleNames/pt/TH=Tail\u00e2ndia -LocaleNames/pt/TJ=Tadjiquist\u00e3o +LocaleNames/pt/TF=Territórios Franceses do Sul +LocaleNames/pt/TH=Tailândia +LocaleNames/pt/TJ=Tadjiquistão LocaleNames/pt/TL=Timor-Leste -LocaleNames/pt/TM=Turcomenist\u00e3o -LocaleNames/pt/TN=Tun\u00edsia +LocaleNames/pt/TM=Turcomenistão +LocaleNames/pt/TN=Tunísia LocaleNames/pt/TR=Turquia LocaleNames/pt/TT=Trinidad e Tobago -LocaleNames/pt/TZ=Tanz\u00e2nia -LocaleNames/pt/UA=Ucr\u00e2nia +LocaleNames/pt/TZ=Tanzânia +LocaleNames/pt/UA=Ucrânia LocaleNames/pt/UM=Ilhas Menores Distantes dos EUA LocaleNames/pt/US=Estados Unidos LocaleNames/pt/UY=Uruguai -LocaleNames/pt/UZ=Uzbequist\u00e3o +LocaleNames/pt/UZ=Uzbequistão LocaleNames/pt/VA=Cidade do Vaticano -LocaleNames/pt/VC=S\u00e3o Vicente e Granadinas -LocaleNames/pt/VG=Ilhas Virgens Brit\u00e2nicas +LocaleNames/pt/VC=São Vicente e Granadinas +LocaleNames/pt/VG=Ilhas Virgens Britânicas LocaleNames/pt/VI=Ilhas Virgens Americanas -LocaleNames/pt/VN=Vietn\u00e3 +LocaleNames/pt/VN=Vietnã LocaleNames/pt/WF=Wallis e Futuna -LocaleNames/pt/YE=I\u00eamen -LocaleNames/pt/ZA=\u00c1frica do Sul -LocaleNames/pt/ZM=Z\u00e2mbia -LocaleNames/pt/ZW=Zimb\u00e1bue +LocaleNames/pt/YE=Iêmen +LocaleNames/pt/ZA=África do Sul +LocaleNames/pt/ZM=Zâmbia +LocaleNames/pt/ZW=Zimbábue # pt_PT LocaleNames/pt_PT/cs=checo -LocaleNames/pt_PT/et=est\u00f3nio +LocaleNames/pt_PT/et=estónio LocaleNames/pt_PT/pl=polaco LocaleNames/pt_PT/sl=esloveno -LocaleNames/pt_PT/AE=Emirados \u00c1rabes Unidos -LocaleNames/pt_PT/AM=Arm\u00e9nia -LocaleNames/pt_PT/AQ=Ant\u00e1rtida -LocaleNames/pt_PT/AZ=Azerbaij\u00e3o -LocaleNames/pt_PT/BA=B\u00f3snia e Herzegovina +LocaleNames/pt_PT/AE=Emirados Árabes Unidos +LocaleNames/pt_PT/AM=Arménia +LocaleNames/pt_PT/AQ=Antártida +LocaleNames/pt_PT/AZ=Azerbaijão +LocaleNames/pt_PT/BA=Bósnia e Herzegovina LocaleNames/pt_PT/BJ=Benim -LocaleNames/pt_PT/BY=Bielorr\u00fassia -LocaleNames/pt_PT/CM=Camar\u00f5es +LocaleNames/pt_PT/BY=Bielorrússia +LocaleNames/pt_PT/CM=Camarões LocaleNames/pt_PT/CX=Ilha do Natal -LocaleNames/pt_PT/CZ=Ch\u00e9quia -LocaleNames/pt_PT/EE=Est\u00f3nia +LocaleNames/pt_PT/CZ=Chéquia +LocaleNames/pt_PT/EE=Estónia LocaleNames/pt_PT/EG=Egito LocaleNames/pt_PT/EH=Sara Ocidental LocaleNames/pt_PT/ER=Eritreia LocaleNames/pt_PT/FK=Ilhas Falkland -LocaleNames/pt_PT/GL=Gronel\u00e2ndia -LocaleNames/pt_PT/GS=Ilhas Ge\u00f3rgia do Sul e Sandwich do Sul -LocaleNames/pt_PT/GW=Guin\u00e9-Bissau +LocaleNames/pt_PT/GL=Gronelândia +LocaleNames/pt_PT/GS=Ilhas Geórgia do Sul e Sandwich do Sul +LocaleNames/pt_PT/GW=Guiné-Bissau LocaleNames/pt_PT/HK=Hong Kong, RAE da China -LocaleNames/pt_PT/KE=Qu\u00e9nia -LocaleNames/pt_PT/KG=Quirguist\u00e3o -LocaleNames/pt_PT/KN=S\u00e3o Crist\u00f3v\u00e3o e Neves +LocaleNames/pt_PT/KE=Quénia +LocaleNames/pt_PT/KG=Quirguistão +LocaleNames/pt_PT/KN=São Cristóvão e Neves LocaleNames/pt_PT/KP=Coreia do Norte LocaleNames/pt_PT/KR=Coreia do Sul -LocaleNames/pt_PT/KY=Ilhas Caim\u00e3o -LocaleNames/pt_PT/KZ=Cazaquist\u00e3o +LocaleNames/pt_PT/KY=Ilhas Caimão +LocaleNames/pt_PT/KZ=Cazaquistão LocaleNames/pt_PT/LA=Laos -LocaleNames/pt_PT/LV=Let\u00f3nia -LocaleNames/pt_PT/MC=M\u00f3naco -LocaleNames/pt_PT/MD=Mold\u00e1via -LocaleNames/pt_PT/MG=Madag\u00e1scar -LocaleNames/pt_PT/MK=Maced\u00f3nia do Norte +LocaleNames/pt_PT/LV=Letónia +LocaleNames/pt_PT/MC=Mónaco +LocaleNames/pt_PT/MD=Moldávia +LocaleNames/pt_PT/MG=Madagáscar +LocaleNames/pt_PT/MK=Macedónia do Norte LocaleNames/pt_PT/MO=Macau, RAE da China LocaleNames/pt_PT/MP=Ilhas Marianas do Norte -LocaleNames/pt_PT/MU=Maur\u00edcia -LocaleNames/pt_PT/NC=Nova Caled\u00f3nia -LocaleNames/pt_PT/PG=Papua-Nova Guin\u00e9 -LocaleNames/pt_PT/PL=Pol\u00f3nia -LocaleNames/pt_PT/PS=Territ\u00f3rios palestinianos -LocaleNames/pt_PT/RE=Reuni\u00e3o -LocaleNames/pt_PT/RO=Rom\u00e9nia +LocaleNames/pt_PT/MU=Maurícia +LocaleNames/pt_PT/NC=Nova Caledónia +LocaleNames/pt_PT/PG=Papua-Nova Guiné +LocaleNames/pt_PT/PL=Polónia +LocaleNames/pt_PT/PS=Territórios palestinianos +LocaleNames/pt_PT/RE=Reunião +LocaleNames/pt_PT/RO=Roménia LocaleNames/pt_PT/SC=Seicheles LocaleNames/pt_PT/SG=Singapura -LocaleNames/pt_PT/SI=Eslov\u00e9nia -LocaleNames/pt_PT/SM=S\u00e3o Marinho +LocaleNames/pt_PT/SI=Eslovénia +LocaleNames/pt_PT/SM=São Marinho LocaleNames/pt_PT/TC=Ilhas Turcas e Caicos LocaleNames/pt_PT/TD=Chade -LocaleNames/pt_PT/TF=Territ\u00f3rios Austrais Franceses -LocaleNames/pt_PT/TJ=Tajiquist\u00e3o -LocaleNames/pt_PT/TM=Turquemenist\u00e3o +LocaleNames/pt_PT/TF=Territórios Austrais Franceses +LocaleNames/pt_PT/TJ=Tajiquistão +LocaleNames/pt_PT/TM=Turquemenistão LocaleNames/pt_PT/UM=Ilhas Menores Afastadas dos EUA -LocaleNames/pt_PT/UZ=Usbequist\u00e3o +LocaleNames/pt_PT/UZ=Usbequistão LocaleNames/pt_PT/VA=Cidade do Vaticano -LocaleNames/pt_PT/VC=S\u00e3o Vicente e Granadinas -LocaleNames/pt_PT/VG=Ilhas Virgens Brit\u00e2nicas +LocaleNames/pt_PT/VC=São Vicente e Granadinas +LocaleNames/pt_PT/VG=Ilhas Virgens Britânicas LocaleNames/pt_PT/VI=Ilhas Virgens dos EUA LocaleNames/pt_PT/VN=Vietname -LocaleNames/pt_PT/YE=I\u00e9men +LocaleNames/pt_PT/YE=Iémen #bug 6290792 Gaelic support -LocaleNames/ga/ab=Abc\u00e1isis -LocaleNames/ga/ae=Aiv\u00e9istis -LocaleNames/ga/af=Afrac\u00e1inis +LocaleNames/ga/ab=Abcáisis +LocaleNames/ga/ae=Aivéistis +LocaleNames/ga/af=Afracáinis LocaleNames/ga/ar=Araibis LocaleNames/ga/as=Asaimis -LocaleNames/ga/az=Asarbaise\u00e1inis -LocaleNames/ga/ba=Baisc\u00edris -LocaleNames/ga/be=Bealar\u00faisis -LocaleNames/ga/bg=Bulg\u00e1iris -LocaleNames/ga/bn=Beang\u00e1ilis -LocaleNames/ga/bo=Tib\u00e9idis -LocaleNames/ga/br=Briot\u00e1inis +LocaleNames/ga/az=Asarbaiseáinis +LocaleNames/ga/ba=Baiscíris +LocaleNames/ga/be=Bealarúisis +LocaleNames/ga/bg=Bulgáiris +LocaleNames/ga/bn=Beangáilis +LocaleNames/ga/bo=Tibéidis +LocaleNames/ga/br=Briotáinis LocaleNames/ga/bs=Boisnis -LocaleNames/ga/ca=Catal\u00f3inis +LocaleNames/ga/ca=Catalóinis LocaleNames/ga/ce=Seisnis LocaleNames/ga/co=Corsaicis -LocaleNames/ga/cr=Cra\u00eds +LocaleNames/ga/cr=Craís LocaleNames/ga/cs=Seicis LocaleNames/ga/cu=Slavais na hEaglaise LocaleNames/ga/cv=Suvaisis LocaleNames/ga/cy=Breatnais LocaleNames/ga/da=Danmhairgis -LocaleNames/ga/de=Gearm\u00e1inis -LocaleNames/ga/el=Gr\u00e9igis -LocaleNames/ga/en=B\u00e9arla -LocaleNames/ga/es=Sp\u00e1innis -LocaleNames/ga/et=East\u00f3inis +LocaleNames/ga/de=Gearmáinis +LocaleNames/ga/el=Gréigis +LocaleNames/ga/en=Béarla +LocaleNames/ga/es=Spáinnis +LocaleNames/ga/et=Eastóinis LocaleNames/ga/eu=Bascais LocaleNames/ga/fa=Peirsis LocaleNames/ga/fi=Fionlainnis LocaleNames/ga/fj=Fidsis -LocaleNames/ga/fo=Far\u00f3is +LocaleNames/ga/fo=Faróis LocaleNames/ga/fr=Fraincis LocaleNames/ga/fy=Freaslainnis Iartharach LocaleNames/ga/ga=Gaeilge LocaleNames/ga/gd=Gaeilge na hAlban -LocaleNames/ga/gu=G\u00faisear\u00e1itis +LocaleNames/ga/gu=Gúisearáitis LocaleNames/ga/gv=Manainnis LocaleNames/ga/he=Eabhrais -LocaleNames/ga/hi=Hiond\u00fais -LocaleNames/ga/hr=Cr\u00f3itis -LocaleNames/ga/hu=Ung\u00e1iris -LocaleNames/ga/hy=Airm\u00e9inis -LocaleNames/ga/id=Indin\u00e9isis -LocaleNames/ga/is=\u00cdoslainnis -LocaleNames/ga/it=Iod\u00e1ilis -LocaleNames/ga/iu=Ion\u00faitis -LocaleNames/ga/ja=Seap\u00e1inis -LocaleNames/ga/jv=I\u00e1ivis +LocaleNames/ga/hi=Hiondúis +LocaleNames/ga/hr=Cróitis +LocaleNames/ga/hu=Ungáiris +LocaleNames/ga/hy=Airméinis +LocaleNames/ga/id=Indinéisis +LocaleNames/ga/is=Íoslainnis +LocaleNames/ga/it=Iodáilis +LocaleNames/ga/iu=Ionúitis +LocaleNames/ga/ja=Seapáinis +LocaleNames/ga/jv=Iáivis LocaleNames/ga/ka=Seoirsis LocaleNames/ga/kk=Casaicis LocaleNames/ga/kn=Cannadais -LocaleNames/ga/ko=C\u00f3ir\u00e9is -LocaleNames/ga/ks=Caism\u00edris +LocaleNames/ga/ko=Cóiréis +LocaleNames/ga/ks=Caismíris LocaleNames/ga/kw=Coirnis LocaleNames/ga/ky=Cirgisis LocaleNames/ga/la=Laidin LocaleNames/ga/lb=Lucsambuirgis LocaleNames/ga/lo=Laoisis -LocaleNames/ga/lt=Liotu\u00e1inis +LocaleNames/ga/lt=Liotuáinis LocaleNames/ga/lv=Laitvis -LocaleNames/ga/mg=Malag\u00e1isis +LocaleNames/ga/mg=Malagáisis LocaleNames/ga/mi=Maorais -LocaleNames/ga/mk=Macad\u00f3inis -LocaleNames/ga/ml=Mail\u00e9alaimis -LocaleNames/ga/mn=Mong\u00f3ilis +LocaleNames/ga/mk=Macadóinis +LocaleNames/ga/ml=Mailéalaimis +LocaleNames/ga/mn=Mongóilis LocaleNames/ga/mr=Maraitis -LocaleNames/ga/mt=M\u00e1ltais +LocaleNames/ga/mt=Máltais LocaleNames/ga/my=Burmais -LocaleNames/ga/na=N\u00e1r\u00fais -LocaleNames/ga/nb=Bocm\u00e1l +LocaleNames/ga/na=Nárúis +LocaleNames/ga/nb=Bocmál LocaleNames/ga/ne=Neipeailis LocaleNames/ga/nl=Ollainnis LocaleNames/ga/nn=Nua-Ioruais LocaleNames/ga/no=Ioruais -LocaleNames/ga/nv=Navach\u00f3is -LocaleNames/ga/oc=Ocsat\u00e1inis -LocaleNames/ga/os=Ois\u00e9itis -LocaleNames/ga/pa=Puinse\u00e1ibis +LocaleNames/ga/nv=Navachóis +LocaleNames/ga/oc=Ocsatáinis +LocaleNames/ga/os=Oiséitis +LocaleNames/ga/pa=Puinseáibis LocaleNames/ga/pl=Polainnis LocaleNames/ga/ps=Paistis -LocaleNames/ga/pt=Portaing\u00e9ilis +LocaleNames/ga/pt=Portaingéilis LocaleNames/ga/qu=Ceatsuais -LocaleNames/ga/ro=R\u00f3m\u00e1inis -LocaleNames/ga/ru=R\u00faisis +LocaleNames/ga/ro=Rómáinis +LocaleNames/ga/ru=Rúisis LocaleNames/ga/sa=Sanscrait -LocaleNames/ga/sc=Saird\u00ednis +LocaleNames/ga/sc=Sairdínis LocaleNames/ga/sd=Sindis -LocaleNames/ga/se=S\u00e1imis an Tuaiscirt -LocaleNames/ga/sk=Sl\u00f3vaicis -LocaleNames/ga/sl=Sl\u00f3iv\u00e9inis -LocaleNames/ga/sm=Sam\u00f3is -LocaleNames/ga/so=Som\u00e1ilis -LocaleNames/ga/sq=Alb\u00e1inis +LocaleNames/ga/se=Sáimis an Tuaiscirt +LocaleNames/ga/sk=Slóvaicis +LocaleNames/ga/sl=Slóivéinis +LocaleNames/ga/sm=Samóis +LocaleNames/ga/so=Somáilis +LocaleNames/ga/sq=Albáinis LocaleNames/ga/sr=Seirbis LocaleNames/ga/sv=Sualainnis -LocaleNames/ga/sw=Svaha\u00edlis +LocaleNames/ga/sw=Svahaílis LocaleNames/ga/ta=Tamailis -LocaleNames/ga/th=T\u00e9alainnis -LocaleNames/ga/tl=Tag\u00e1laigis +LocaleNames/ga/th=Téalainnis +LocaleNames/ga/tl=Tagálaigis LocaleNames/ga/tr=Tuircis LocaleNames/ga/tt=Tatairis -LocaleNames/ga/ty=Taih\u00edtis -LocaleNames/ga/uk=\u00dacr\u00e1inis -LocaleNames/ga/ur=Urd\u00fais -LocaleNames/ga/uz=\u00daisb\u00e9iceast\u00e1inis -LocaleNames/ga/vi=V\u00edtneaimis -LocaleNames/ga/wa=Vall\u00fanais -LocaleNames/ga/yi=Gi\u00fadais -LocaleNames/ga/zh=S\u00ednis -LocaleNames/ga/zu=S\u00fal\u00fais -LocaleNames/ga/AD=And\u00f3ra -LocaleNames/ga/AE=Aontas na n\u00c9im\u00edr\u00edochta\u00ed Arabacha -LocaleNames/ga/AF=an Afganast\u00e1in -LocaleNames/ga/AG=Antigua agus Barb\u00fada -LocaleNames/ga/AL=an Alb\u00e1in -LocaleNames/ga/AM=an Airm\u00e9in -LocaleNames/ga/AO=Ang\u00f3la +LocaleNames/ga/ty=Taihítis +LocaleNames/ga/uk=Úcráinis +LocaleNames/ga/ur=Urdúis +LocaleNames/ga/uz=Úisbéiceastáinis +LocaleNames/ga/vi=Vítneaimis +LocaleNames/ga/wa=Vallúnais +LocaleNames/ga/yi=Giúdais +LocaleNames/ga/zh=Sínis +LocaleNames/ga/zu=Súlúis +LocaleNames/ga/AD=Andóra +LocaleNames/ga/AE=Aontas na nÉimíríochtaí Arabacha +LocaleNames/ga/AF=an Afganastáin +LocaleNames/ga/AG=Antigua agus Barbúda +LocaleNames/ga/AL=an Albáin +LocaleNames/ga/AM=an Airméin +LocaleNames/ga/AO=Angóla LocaleNames/ga/AQ=Antartaice -LocaleNames/ga/AR=an Airgint\u00edn -LocaleNames/ga/AS=Sam\u00f3 Mheirice\u00e1 +LocaleNames/ga/AR=an Airgintín +LocaleNames/ga/AS=Samó Mheiriceá LocaleNames/ga/AT=an Ostair -LocaleNames/ga/AU=an Astr\u00e1il -LocaleNames/ga/AZ=an Asarbaise\u00e1in -LocaleNames/ga/BA=an Bhoisnia agus an Heirseagaiv\u00e9in -LocaleNames/ga/BB=Barbad\u00f3s -LocaleNames/ga/BD=an Bhanglaid\u00e9is +LocaleNames/ga/AU=an Astráil +LocaleNames/ga/AZ=an Asarbaiseáin +LocaleNames/ga/BA=an Bhoisnia agus an Heirseagaivéin +LocaleNames/ga/BB=Barbadós +LocaleNames/ga/BD=an Bhanglaidéis LocaleNames/ga/BE=an Bheilg -LocaleNames/ga/BF=Buirc\u00edne Fas\u00f3 -LocaleNames/ga/BG=an Bhulg\u00e1ir -LocaleNames/ga/BH=Bair\u00e9in -LocaleNames/ga/BI=an Bhur\u00fain +LocaleNames/ga/BF=Buircíne Fasó +LocaleNames/ga/BG=an Bhulgáir +LocaleNames/ga/BH=Bairéin +LocaleNames/ga/BI=an Bhurúin LocaleNames/ga/BJ=Beinin -LocaleNames/ga/BM=Beirmi\u00fada -LocaleNames/ga/BN=Br\u00fain\u00e9 +LocaleNames/ga/BM=Beirmiúda +LocaleNames/ga/BN=Brúiné LocaleNames/ga/BO=an Bholaiv -LocaleNames/ga/BR=an Bhrasa\u00edl -LocaleNames/ga/BS=na Bah\u00e1ma\u00ed -LocaleNames/ga/BT=an Bh\u00fat\u00e1in -LocaleNames/ga/BV=Oile\u00e1n Bouvet -LocaleNames/ga/BW=an Bhotsu\u00e1in -LocaleNames/ga/BY=an Bhealar\u00fais -LocaleNames/ga/BZ=an Bheil\u00eds +LocaleNames/ga/BR=an Bhrasaíl +LocaleNames/ga/BS=na Bahámaí +LocaleNames/ga/BT=an Bhútáin +LocaleNames/ga/BV=Oileán Bouvet +LocaleNames/ga/BW=an Bhotsuáin +LocaleNames/ga/BY=an Bhealarúis +LocaleNames/ga/BZ=an Bheilís LocaleNames/ga/CA=Ceanada -LocaleNames/ga/CC=Oile\u00e1in Cocos (Keeling) -LocaleNames/ga/CD=Poblacht Dhaonlathach an Chong\u00f3 -LocaleNames/ga/CF=Poblacht na hAfraice L\u00e1ir -LocaleNames/ga/CG=Cong\u00f3-Brazzaville -LocaleNames/ga/CH=an Eilv\u00e9is -LocaleNames/ga/CI=An C\u00f3sta Eabhair -LocaleNames/ga/CK=Oile\u00e1in Cook +LocaleNames/ga/CC=Oileáin Cocos (Keeling) +LocaleNames/ga/CD=Poblacht Dhaonlathach an Chongó +LocaleNames/ga/CF=Poblacht na hAfraice Láir +LocaleNames/ga/CG=Congó-Brazzaville +LocaleNames/ga/CH=an Eilvéis +LocaleNames/ga/CI=An Cósta Eabhair +LocaleNames/ga/CK=Oileáin Cook LocaleNames/ga/CL=an tSile -LocaleNames/ga/CM=Camar\u00fan -LocaleNames/ga/CN=an tS\u00edn -LocaleNames/ga/CO=an Chol\u00f3im -LocaleNames/ga/CR=C\u00f3sta R\u00edce -LocaleNames/ga/CU=C\u00faba +LocaleNames/ga/CM=Camarún +LocaleNames/ga/CN=an tSín +LocaleNames/ga/CO=an Cholóim +LocaleNames/ga/CR=Cósta Ríce +LocaleNames/ga/CU=Cúba LocaleNames/ga/CV=Rinn Verde -LocaleNames/ga/CX=Oile\u00e1n na Nollag +LocaleNames/ga/CX=Oileán na Nollag LocaleNames/ga/CY=an Chipir LocaleNames/ga/CZ=an tSeicia -LocaleNames/ga/DE=an Ghearm\u00e1in +LocaleNames/ga/DE=an Ghearmáin LocaleNames/ga/DK=an Danmhairg LocaleNames/ga/DM=Doiminice LocaleNames/ga/DO=an Phoblacht Dhoiminiceach -LocaleNames/ga/DZ=An Ailg\u00e9ir -LocaleNames/ga/EC=Eacuad\u00f3r -LocaleNames/ga/EE=an East\u00f3in -LocaleNames/ga/EG=An \u00c9igipt -LocaleNames/ga/EH=An Sah\u00e1ra Thiar -LocaleNames/ga/ES=an Sp\u00e1inn -LocaleNames/ga/ET=an Aet\u00f3ip +LocaleNames/ga/DZ=An Ailgéir +LocaleNames/ga/EC=Eacuadór +LocaleNames/ga/EE=an Eastóin +LocaleNames/ga/EG=An Éigipt +LocaleNames/ga/EH=An Sahára Thiar +LocaleNames/ga/ES=an Spáinn +LocaleNames/ga/ET=an Aetóip LocaleNames/ga/FI=an Fhionlainn -LocaleNames/ga/FJ=Fids\u00ed -LocaleNames/ga/FK=Oile\u00e1in Fh\u00e1clainne -LocaleNames/ga/FM=an Mhicrin\u00e9is -LocaleNames/ga/FO=Oile\u00e1in Fhar\u00f3 +LocaleNames/ga/FJ=Fidsí +LocaleNames/ga/FK=Oileáin Fháclainne +LocaleNames/ga/FM=an Mhicrinéis +LocaleNames/ga/FO=Oileáin Fharó LocaleNames/ga/FR=an Fhrainc -LocaleNames/ga/GA=an Ghab\u00fain -LocaleNames/ga/GB=an R\u00edocht Aontaithe +LocaleNames/ga/GA=an Ghabúin +LocaleNames/ga/GB=an Ríocht Aontaithe LocaleNames/ga/GE=an tSeoirsia -LocaleNames/ga/GF=Gu\u00e1in na Fraince -LocaleNames/ga/GH=G\u00e1na -LocaleNames/ga/GI=Giobr\u00e1ltar +LocaleNames/ga/GF=Guáin na Fraince +LocaleNames/ga/GH=Gána +LocaleNames/ga/GI=Giobráltar LocaleNames/ga/GL=an Ghraonlainn LocaleNames/ga/GM=An Ghaimbia LocaleNames/ga/GN=An Ghuine -LocaleNames/ga/GP=Guadal\u00faip -LocaleNames/ga/GQ=an Ghuine Mhe\u00e1nchiorclach -LocaleNames/ga/GR=an Ghr\u00e9ig -LocaleNames/ga/GS=An tSeoirsia Theas agus Oile\u00e1in Sandwich Theas +LocaleNames/ga/GP=Guadalúip +LocaleNames/ga/GQ=an Ghuine Mheánchiorclach +LocaleNames/ga/GR=an Ghréig +LocaleNames/ga/GS=An tSeoirsia Theas agus Oileáin Sandwich Theas LocaleNames/ga/GT=Guatamala LocaleNames/ga/GW=Guine Bissau -LocaleNames/ga/GY=An Ghu\u00e1in -LocaleNames/ga/HM=Oile\u00e1n Heard agus Oile\u00e1in McDonald -LocaleNames/ga/HN=Hond\u00faras -LocaleNames/ga/HR=an Chr\u00f3it -LocaleNames/ga/HT=H\u00e1\u00edt\u00ed -LocaleNames/ga/HU=an Ung\u00e1ir -LocaleNames/ga/ID=an Indin\u00e9is -LocaleNames/ga/IE=\u00c9ire +LocaleNames/ga/GY=An Ghuáin +LocaleNames/ga/HM=Oileán Heard agus Oileáin McDonald +LocaleNames/ga/HN=Hondúras +LocaleNames/ga/HR=an Chróit +LocaleNames/ga/HT=Háítí +LocaleNames/ga/HU=an Ungáir +LocaleNames/ga/ID=an Indinéis +LocaleNames/ga/IE=Éire LocaleNames/ga/IL=Iosrael LocaleNames/ga/IN=an India -LocaleNames/ga/IO=Cr\u00edoch Aig\u00e9an Indiach na Breataine -LocaleNames/ga/IQ=an Iar\u00e1ic -LocaleNames/ga/IR=an Iar\u00e1in -LocaleNames/ga/IS=an \u00cdoslainn -LocaleNames/ga/IT=an Iod\u00e1il -LocaleNames/ga/JM=Iam\u00e1ice -LocaleNames/ga/JO=an Iord\u00e1in -LocaleNames/ga/JP=an tSeap\u00e1in -LocaleNames/ga/KE=an Ch\u00e9inia -LocaleNames/ga/KG=an Chirgeast\u00e1in -LocaleNames/ga/KH=an Chamb\u00f3id +LocaleNames/ga/IO=Críoch Aigéan Indiach na Breataine +LocaleNames/ga/IQ=an Iaráic +LocaleNames/ga/IR=an Iaráin +LocaleNames/ga/IS=an Íoslainn +LocaleNames/ga/IT=an Iodáil +LocaleNames/ga/JM=Iamáice +LocaleNames/ga/JO=an Iordáin +LocaleNames/ga/JP=an tSeapáin +LocaleNames/ga/KE=an Chéinia +LocaleNames/ga/KG=an Chirgeastáin +LocaleNames/ga/KH=an Chambóid LocaleNames/ga/KI=Ciribeas -LocaleNames/ga/KM=Oile\u00e1in Chom\u00f3ra -LocaleNames/ga/KN=San Cr\u00edost\u00f3ir-Nimheas -LocaleNames/ga/KP=an Ch\u00f3ir\u00e9 Thuaidh -LocaleNames/ga/KR=an Ch\u00f3ir\u00e9 Theas -LocaleNames/ga/KW=Cu\u00e1it -LocaleNames/ga/KY=Oile\u00e1in Cayman -LocaleNames/ga/KZ=an Chasacst\u00e1in -LocaleNames/ga/LB=an Liob\u00e1in -LocaleNames/ga/LI=Lichtinst\u00e9in -LocaleNames/ga/LK=Sr\u00ed Lanca -LocaleNames/ga/LR=An Lib\u00e9ir -LocaleNames/ga/LS=Leos\u00f3ta -LocaleNames/ga/LT=an Liotu\u00e1in +LocaleNames/ga/KM=Oileáin Chomóra +LocaleNames/ga/KN=San Críostóir-Nimheas +LocaleNames/ga/KP=an Chóiré Thuaidh +LocaleNames/ga/KR=an Chóiré Theas +LocaleNames/ga/KW=Cuáit +LocaleNames/ga/KY=Oileáin Cayman +LocaleNames/ga/KZ=an Chasacstáin +LocaleNames/ga/LB=an Liobáin +LocaleNames/ga/LI=Lichtinstéin +LocaleNames/ga/LK=Srí Lanca +LocaleNames/ga/LR=An Libéir +LocaleNames/ga/LS=Leosóta +LocaleNames/ga/LT=an Liotuáin LocaleNames/ga/LU=Lucsamburg LocaleNames/ga/LV=an Laitvia LocaleNames/ga/LY=An Libia -LocaleNames/ga/MA=Marac\u00f3 -LocaleNames/ga/MC=Monac\u00f3 -LocaleNames/ga/MD=an Mhold\u00f3iv -LocaleNames/ga/MH=Oile\u00e1in Marshall -LocaleNames/ga/MK=an Mhacad\u00f3in Thuaidh -LocaleNames/ga/ML=Mail\u00ed +LocaleNames/ga/MA=Maracó +LocaleNames/ga/MC=Monacó +LocaleNames/ga/MD=an Mholdóiv +LocaleNames/ga/MH=Oileáin Marshall +LocaleNames/ga/MK=an Mhacadóin Thuaidh +LocaleNames/ga/ML=Mailí LocaleNames/ga/MM=Maenmar (Burma) -LocaleNames/ga/MN=an Mhong\u00f3il -LocaleNames/ga/MP=Na hOile\u00e1in Mh\u00e1irianacha Thuaidh -LocaleNames/ga/MR=An Mh\u00e1rat\u00e1i +LocaleNames/ga/MN=an Mhongóil +LocaleNames/ga/MP=Na hOileáin Mháirianacha Thuaidh +LocaleNames/ga/MR=An Mháratái LocaleNames/ga/MS=Montsarat -LocaleNames/ga/MT=M\u00e1lta -LocaleNames/ga/MU=Oile\u00e1n Mhuir\u00eds -LocaleNames/ga/MV=Oile\u00e1in Mhaild\u00edve -LocaleNames/ga/MW=an Mhal\u00e1iv +LocaleNames/ga/MT=Málta +LocaleNames/ga/MU=Oileán Mhuirís +LocaleNames/ga/MV=Oileáin Mhaildíve +LocaleNames/ga/MW=an Mhaláiv LocaleNames/ga/MX=Meicsiceo LocaleNames/ga/MY=an Mhalaeisia -LocaleNames/ga/MZ=M\u00f3saimb\u00edc +LocaleNames/ga/MZ=Mósaimbíc LocaleNames/ga/NA=an Namaib -LocaleNames/ga/NC=an Nua-Chalad\u00f3in -LocaleNames/ga/NE=An N\u00edgir -LocaleNames/ga/NF=Oile\u00e1n Norfolk -LocaleNames/ga/NG=An Nig\u00e9ir +LocaleNames/ga/NC=an Nua-Chaladóin +LocaleNames/ga/NE=An Nígir +LocaleNames/ga/NF=Oileán Norfolk +LocaleNames/ga/NG=An Nigéir LocaleNames/ga/NI=Nicearagua -LocaleNames/ga/NL=an \u00cdsilt\u00edr +LocaleNames/ga/NL=an Ísiltír LocaleNames/ga/NO=an Iorua LocaleNames/ga/NP=Neipeal -LocaleNames/ga/NR=N\u00e1r\u00fa -LocaleNames/ga/NZ=an Nua-Sh\u00e9alainn -LocaleNames/ga/PE=Peiri\u00fa -LocaleNames/ga/PF=Polain\u00e9is na Fraince +LocaleNames/ga/NR=Nárú +LocaleNames/ga/NZ=an Nua-Shéalainn +LocaleNames/ga/PE=Peiriú +LocaleNames/ga/PF=Polainéis na Fraince LocaleNames/ga/PG=Nua-Ghuine Phapua -LocaleNames/ga/PH=Na hOile\u00e1in Fhilip\u00edneacha -LocaleNames/ga/PK=an Phacast\u00e1in +LocaleNames/ga/PH=Na hOileáin Fhilipíneacha +LocaleNames/ga/PK=an Phacastáin LocaleNames/ga/PL=an Pholainn LocaleNames/ga/PM=San Pierre agus Miquelon -LocaleNames/ga/PR=P\u00f3rt\u00f3 R\u00edce -LocaleNames/ga/PS=na Cr\u00edocha Palaist\u00edneacha -LocaleNames/ga/PT=an Phortaing\u00e9il +LocaleNames/ga/PR=Pórtó Ríce +LocaleNames/ga/PS=na Críocha Palaistíneacha +LocaleNames/ga/PT=an Phortaingéil LocaleNames/ga/PY=Paragua LocaleNames/ga/QA=Catar -LocaleNames/ga/RE=La R\u00e9union -LocaleNames/ga/RO=an R\u00f3m\u00e1in -LocaleNames/ga/RU=an R\u00fais +LocaleNames/ga/RE=La Réunion +LocaleNames/ga/RO=an Rómáin +LocaleNames/ga/RU=an Rúis LocaleNames/ga/RW=Ruanda -LocaleNames/ga/SA=an Araib Sh\u00e1dach -LocaleNames/ga/SB=Oile\u00e1in Sholaimh -LocaleNames/ga/SC=na S\u00e9is\u00e9il -LocaleNames/ga/SD=An tS\u00fad\u00e1in +LocaleNames/ga/SA=an Araib Shádach +LocaleNames/ga/SB=Oileáin Sholaimh +LocaleNames/ga/SC=na Séiséil +LocaleNames/ga/SD=An tSúdáin LocaleNames/ga/SE=an tSualainn -LocaleNames/ga/SG=Singeap\u00f3r -LocaleNames/ga/SH=San H\u00e9ilin -LocaleNames/ga/SI=an tSl\u00f3iv\u00e9in +LocaleNames/ga/SG=Singeapór +LocaleNames/ga/SH=San Héilin +LocaleNames/ga/SI=an tSlóivéin LocaleNames/ga/SJ=Svalbard agus Jan Mayen -LocaleNames/ga/SK=an tSl\u00f3vaic +LocaleNames/ga/SK=an tSlóvaic LocaleNames/ga/SL=Siarra Leon -LocaleNames/ga/SM=San Mair\u00edne -LocaleNames/ga/SN=An tSeineag\u00e1il -LocaleNames/ga/SO=an tSom\u00e1il +LocaleNames/ga/SM=San Mairíne +LocaleNames/ga/SN=An tSeineagáil +LocaleNames/ga/SO=an tSomáil LocaleNames/ga/SR=Suranam -LocaleNames/ga/ST=S\u00e3o Tom\u00e9 agus Pr\u00edncipe -LocaleNames/ga/SV=An tSalvad\u00f3ir +LocaleNames/ga/ST=São Tomé agus Príncipe +LocaleNames/ga/SV=An tSalvadóir LocaleNames/ga/SY=an tSiria -LocaleNames/ga/SZ=eSuait\u00edn\u00ed -LocaleNames/ga/TC=Oile\u00e1in na dTurcach agus Caicos +LocaleNames/ga/SZ=eSuaitíní +LocaleNames/ga/TC=Oileáin na dTurcach agus Caicos LocaleNames/ga/TD=Sead -LocaleNames/ga/TF=Cr\u00edocha Francacha Dheisceart an Domhain -LocaleNames/ga/TG=T\u00f3ga -LocaleNames/ga/TH=an T\u00e9alainn -LocaleNames/ga/TJ=an T\u00e1ids\u00edceast\u00e1in -LocaleNames/ga/TK=T\u00f3cal\u00e1 -LocaleNames/ga/TL=T\u00edom\u00f3r Thoir -LocaleNames/ga/TM=an Tuircm\u00e9anast\u00e1in -LocaleNames/ga/TN=An Tuin\u00e9is +LocaleNames/ga/TF=Críocha Francacha Dheisceart an Domhain +LocaleNames/ga/TG=Tóga +LocaleNames/ga/TH=an Téalainn +LocaleNames/ga/TJ=an Táidsíceastáin +LocaleNames/ga/TK=Tócalá +LocaleNames/ga/TL=Tíomór Thoir +LocaleNames/ga/TM=an Tuircméanastáin +LocaleNames/ga/TN=An Tuinéis LocaleNames/ga/TR=an Tuirc -LocaleNames/ga/TT=Oile\u00e1n na Tr\u00edon\u00f3ide agus Tob\u00e1ga -LocaleNames/ga/TV=T\u00faval\u00fa -LocaleNames/ga/TW=an T\u00e9av\u00e1in -LocaleNames/ga/TZ=an Tans\u00e1in -LocaleNames/ga/UA=an \u00dacr\u00e1in -LocaleNames/ga/UM=Oile\u00e1in Imeallacha S.A.M. -LocaleNames/ga/US=St\u00e1it Aontaithe Mheirice\u00e1 +LocaleNames/ga/TT=Oileán na Tríonóide agus Tobága +LocaleNames/ga/TV=Túvalú +LocaleNames/ga/TW=an Téaváin +LocaleNames/ga/TZ=an Tansáin +LocaleNames/ga/UA=an Úcráin +LocaleNames/ga/UM=Oileáin Imeallacha S.A.M. +LocaleNames/ga/US=Stáit Aontaithe Mheiriceá LocaleNames/ga/UY=Uragua -LocaleNames/ga/UZ=an \u00daisb\u00e9iceast\u00e1in -LocaleNames/ga/VA=Cathair na Vatac\u00e1ine -LocaleNames/ga/VC=San Uinseann agus na Grean\u00e1id\u00edn\u00ed -LocaleNames/ga/VE=Veinis\u00e9ala -LocaleNames/ga/VG=Oile\u00e1in Bhriotanacha na Maighdean -LocaleNames/ga/VI=Oile\u00e1in Mheirice\u00e1nacha na Maighdean -LocaleNames/ga/VN=V\u00edtneam -LocaleNames/ga/VU=Vanuat\u00fa -LocaleNames/ga/WF=Vail\u00eds agus Fut\u00fana -LocaleNames/ga/WS=Sam\u00f3 -LocaleNames/ga/YE=\u00c9imin +LocaleNames/ga/UZ=an Úisbéiceastáin +LocaleNames/ga/VA=Cathair na Vatacáine +LocaleNames/ga/VC=San Uinseann agus na Greanáidíní +LocaleNames/ga/VE=Veiniséala +LocaleNames/ga/VG=Oileáin Bhriotanacha na Maighdean +LocaleNames/ga/VI=Oileáin Mheiriceánacha na Maighdean +LocaleNames/ga/VN=Vítneam +LocaleNames/ga/VU=Vanuatú +LocaleNames/ga/WF=Vailís agus Futúna +LocaleNames/ga/WS=Samó +LocaleNames/ga/YE=Éimin LocaleNames/ga/ZA=an Afraic Theas LocaleNames/ga/ZM=an tSaimbia # bug #6277696 -FormatData/sr/MonthNames/0=\u0458\u0430\u043d\u0443\u0430\u0440 -FormatData/sr/MonthNames/1=\u0444\u0435\u0431\u0440\u0443\u0430\u0440 -FormatData/sr/MonthNames/2=\u043c\u0430\u0440\u0442 -FormatData/sr/MonthNames/3=\u0430\u043f\u0440\u0438\u043b -FormatData/sr/MonthNames/4=\u043c\u0430\u0458 -FormatData/sr/MonthNames/5=\u0458\u0443\u043d -FormatData/sr/MonthNames/6=\u0458\u0443\u043b -FormatData/sr/MonthNames/7=\u0430\u0432\u0433\u0443\u0441\u0442 -FormatData/sr/MonthNames/8=\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440 -FormatData/sr/MonthNames/9=\u043e\u043a\u0442\u043e\u0431\u0430\u0440 -FormatData/sr/MonthNames/10=\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440 -FormatData/sr/MonthNames/11=\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440 -FormatData/sr/MonthAbbreviations/0=\u0458\u0430\u043d -FormatData/sr/MonthAbbreviations/1=\u0444\u0435\u0431 -FormatData/sr/MonthAbbreviations/2=\u043c\u0430\u0440 -FormatData/sr/MonthAbbreviations/3=\u0430\u043f\u0440 -FormatData/sr/MonthAbbreviations/4=\u043c\u0430\u0458 -FormatData/sr/MonthAbbreviations/5=\u0458\u0443\u043d -FormatData/sr/MonthAbbreviations/6=\u0458\u0443\u043b -FormatData/sr/MonthAbbreviations/7=\u0430\u0432\u0433 -FormatData/sr/MonthAbbreviations/8=\u0441\u0435\u043f -FormatData/sr/MonthAbbreviations/9=\u043e\u043a\u0442 -FormatData/sr/MonthAbbreviations/10=\u043d\u043e\u0432 -FormatData/sr/MonthAbbreviations/11=\u0434\u0435\u0446 -FormatData/sr/DayNames/0=\u043d\u0435\u0434\u0435\u0459\u0430 -FormatData/sr/DayNames/1=\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a -FormatData/sr/DayNames/2=\u0443\u0442\u043e\u0440\u0430\u043a -FormatData/sr/DayNames/3=\u0441\u0440\u0435\u0434\u0430 -FormatData/sr/DayNames/4=\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a -FormatData/sr/DayNames/5=\u043f\u0435\u0442\u0430\u043a -FormatData/sr/DayNames/6=\u0441\u0443\u0431\u043e\u0442\u0430 -FormatData/sr/DayAbbreviations/0=\u043d\u0435\u0434 -FormatData/sr/DayAbbreviations/1=\u043f\u043e\u043d -FormatData/sr/DayAbbreviations/2=\u0443\u0442\u043e -FormatData/sr/DayAbbreviations/3=\u0441\u0440\u0435 -FormatData/sr/DayAbbreviations/4=\u0447\u0435\u0442 -FormatData/sr/DayAbbreviations/5=\u043f\u0435\u0442 -FormatData/sr/DayAbbreviations/6=\u0441\u0443\u0431 -FormatData/sr/Eras/0=\u043f. \u043d. \u0435. -FormatData/sr/Eras/1=\u043d. \u0435. +FormatData/sr/MonthNames/0=јануар +FormatData/sr/MonthNames/1=фебруар +FormatData/sr/MonthNames/2=март +FormatData/sr/MonthNames/3=април +FormatData/sr/MonthNames/4=мај +FormatData/sr/MonthNames/5=јун +FormatData/sr/MonthNames/6=јул +FormatData/sr/MonthNames/7=август +FormatData/sr/MonthNames/8=септембар +FormatData/sr/MonthNames/9=октобар +FormatData/sr/MonthNames/10=новембар +FormatData/sr/MonthNames/11=децембар +FormatData/sr/MonthAbbreviations/0=јан +FormatData/sr/MonthAbbreviations/1=феб +FormatData/sr/MonthAbbreviations/2=мар +FormatData/sr/MonthAbbreviations/3=апр +FormatData/sr/MonthAbbreviations/4=мај +FormatData/sr/MonthAbbreviations/5=јун +FormatData/sr/MonthAbbreviations/6=јул +FormatData/sr/MonthAbbreviations/7=авг +FormatData/sr/MonthAbbreviations/8=сеп +FormatData/sr/MonthAbbreviations/9=окт +FormatData/sr/MonthAbbreviations/10=нов +FormatData/sr/MonthAbbreviations/11=дец +FormatData/sr/DayNames/0=недеља +FormatData/sr/DayNames/1=понедељак +FormatData/sr/DayNames/2=уторак +FormatData/sr/DayNames/3=среда +FormatData/sr/DayNames/4=четвртак +FormatData/sr/DayNames/5=петак +FormatData/sr/DayNames/6=субота +FormatData/sr/DayAbbreviations/0=нед +FormatData/sr/DayAbbreviations/1=пон +FormatData/sr/DayAbbreviations/2=уто +FormatData/sr/DayAbbreviations/3=сре +FormatData/sr/DayAbbreviations/4=чет +FormatData/sr/DayAbbreviations/5=пет +FormatData/sr/DayAbbreviations/6=суб +FormatData/sr/Eras/0=п. н. е. +FormatData/sr/Eras/1=н. е. FormatData/sr/latn.NumberPatterns/0=#,##0.### -FormatData/sr/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 +FormatData/sr/latn.NumberPatterns/1=#,##0.00 ¤ FormatData/sr/latn.NumberPatterns/2=#,##0% FormatData/sr/latn.NumberElements/0=, FormatData/sr/latn.NumberElements/1=. @@ -4089,8 +4089,8 @@ FormatData/sr/latn.NumberElements/4=0 FormatData/sr/latn.NumberElements/5=# FormatData/sr/latn.NumberElements/6=- FormatData/sr/latn.NumberElements/7=E -FormatData/sr/latn.NumberElements/8=\u2030 -FormatData/sr/latn.NumberElements/9=\u221e +FormatData/sr/latn.NumberElements/8=‰ +FormatData/sr/latn.NumberElements/9=∞ FormatData/sr/latn.NumberElements/10=NaN FormatData/sr/TimePatterns/0=HH:mm:ss zzzz FormatData/sr/TimePatterns/1=HH:mm:ss z @@ -4101,610 +4101,610 @@ FormatData/sr/DatePatterns/1=d. MMMM y. FormatData/sr/DatePatterns/2=d. M. y. FormatData/sr/DatePatterns/3=d. M. y. FormatData/sr/DateTimePatterns/0={1} {0} -LocaleNames/sr/af=\u0430\u0444\u0440\u0438\u043a\u0430\u043d\u0441 -LocaleNames/sr/ar=\u0430\u0440\u0430\u043f\u0441\u043a\u0438 -LocaleNames/sr/be=\u0431\u0435\u043b\u043e\u0440\u0443\u0441\u043a\u0438 -LocaleNames/sr/bg=\u0431\u0443\u0433\u0430\u0440\u0441\u043a\u0438 -LocaleNames/sr/br=\u0431\u0440\u0435\u0442\u043e\u043d\u0441\u043a\u0438 -LocaleNames/sr/ca=\u043a\u0430\u0442\u0430\u043b\u043e\u043d\u0441\u043a\u0438 -LocaleNames/sr/co=\u043a\u043e\u0440\u0437\u0438\u043a\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/cs=\u0447\u0435\u0448\u043a\u0438 -LocaleNames/sr/da=\u0434\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/de=\u043d\u0435\u043c\u0430\u0447\u043a\u0438 -LocaleNames/sr/el=\u0433\u0440\u0447\u043a\u0438 -LocaleNames/sr/en=\u0435\u043d\u0433\u043b\u0435\u0441\u043a\u0438 -LocaleNames/sr/eo=\u0435\u0441\u043f\u0435\u0440\u0430\u043d\u0442\u043e -LocaleNames/sr/es=\u0448\u043f\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/et=\u0435\u0441\u0442\u043e\u043d\u0441\u043a\u0438 -LocaleNames/sr/eu=\u0431\u0430\u0441\u043a\u0438\u0458\u0441\u043a\u0438 -LocaleNames/sr/fa=\u043f\u0435\u0440\u0441\u0438\u0458\u0441\u043a\u0438 -LocaleNames/sr/fi=\u0444\u0438\u043d\u0441\u043a\u0438 -LocaleNames/sr/fr=\u0444\u0440\u0430\u043d\u0446\u0443\u0441\u043a\u0438 -LocaleNames/sr/ga=\u0438\u0440\u0441\u043a\u0438 -LocaleNames/sr/he=\u0445\u0435\u0431\u0440\u0435\u0458\u0441\u043a\u0438 -LocaleNames/sr/hi=\u0445\u0438\u043d\u0434\u0438 -LocaleNames/sr/hr=\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438 -LocaleNames/sr/hu=\u043c\u0430\u0452\u0430\u0440\u0441\u043a\u0438 -LocaleNames/sr/hy=\u0458\u0435\u0440\u043c\u0435\u043d\u0441\u043a\u0438 -LocaleNames/sr/id=\u0438\u043d\u0434\u043e\u043d\u0435\u0436\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/is=\u0438\u0441\u043b\u0430\u043d\u0434\u0441\u043a\u0438 -LocaleNames/sr/it=\u0438\u0442\u0430\u043b\u0438\u0458\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/ja=\u0458\u0430\u043f\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/ka=\u0433\u0440\u0443\u0437\u0438\u0458\u0441\u043a\u0438 -LocaleNames/sr/km=\u043a\u043c\u0435\u0440\u0441\u043a\u0438 -LocaleNames/sr/ko=\u043a\u043e\u0440\u0435\u0458\u0441\u043a\u0438 -LocaleNames/sr/ku=\u043a\u0443\u0440\u0434\u0441\u043a\u0438 -LocaleNames/sr/ky=\u043a\u0438\u0440\u0433\u0438\u0441\u043a\u0438 -LocaleNames/sr/la=\u043b\u0430\u0442\u0438\u043d\u0441\u043a\u0438 -LocaleNames/sr/lt=\u043b\u0438\u0442\u0432\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/lv=\u043b\u0435\u0442\u043e\u043d\u0441\u043a\u0438 -LocaleNames/sr/mk=\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438 -LocaleNames/sr/mn=\u043c\u043e\u043d\u0433\u043e\u043b\u0441\u043a\u0438 -LocaleNames/sr/my=\u0431\u0443\u0440\u043c\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/nl=\u0445\u043e\u043b\u0430\u043d\u0434\u0441\u043a\u0438 -LocaleNames/sr/no=\u043d\u043e\u0440\u0432\u0435\u0448\u043a\u0438 -LocaleNames/sr/pl=\u043f\u043e\u0459\u0441\u043a\u0438 -LocaleNames/sr/pt=\u043f\u043e\u0440\u0442\u0443\u0433\u0430\u043b\u0441\u043a\u0438 -LocaleNames/sr/rm=\u0440\u043e\u043c\u0430\u043d\u0448 -LocaleNames/sr/ro=\u0440\u0443\u043c\u0443\u043d\u0441\u043a\u0438 -LocaleNames/sr/ru=\u0440\u0443\u0441\u043a\u0438 -LocaleNames/sr/sa=\u0441\u0430\u043d\u0441\u043a\u0440\u0438\u0442 -LocaleNames/sr/sk=\u0441\u043b\u043e\u0432\u0430\u0447\u043a\u0438 -LocaleNames/sr/sl=\u0441\u043b\u043e\u0432\u0435\u043d\u0430\u0447\u043a\u0438 -LocaleNames/sr/sq=\u0430\u043b\u0431\u0430\u043d\u0441\u043a\u0438 -LocaleNames/sr/sr=\u0441\u0440\u043f\u0441\u043a\u0438 -LocaleNames/sr/sv=\u0448\u0432\u0435\u0434\u0441\u043a\u0438 -LocaleNames/sr/sw=\u0441\u0432\u0430\u0445\u0438\u043b\u0438 -LocaleNames/sr/tr=\u0442\u0443\u0440\u0441\u043a\u0438 -LocaleNames/sr/uk=\u0443\u043a\u0440\u0430\u0458\u0438\u043d\u0441\u043a\u0438 -LocaleNames/sr/vi=\u0432\u0438\u0458\u0435\u0442\u043d\u0430\u043c\u0441\u043a\u0438 -LocaleNames/sr/yi=\u0458\u0438\u0434\u0438\u0448 -LocaleNames/sr/zh=\u043a\u0438\u043d\u0435\u0441\u043a\u0438 -LocaleNames/sr/AD=\u0410\u043d\u0434\u043e\u0440\u0430 -LocaleNames/sr/AE=\u0423\u0458\u0435\u0434\u0438\u045a\u0435\u043d\u0438 \u0410\u0440\u0430\u043f\u0441\u043a\u0438 \u0415\u043c\u0438\u0440\u0430\u0442\u0438 -LocaleNames/sr/AF=\u0410\u0432\u0433\u0430\u043d\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/AL=\u0410\u043b\u0431\u0430\u043d\u0438\u0458\u0430 -LocaleNames/sr/AM=\u0408\u0435\u0440\u043c\u0435\u043d\u0438\u0458\u0430 -LocaleNames/sr/AO=\u0410\u043d\u0433\u043e\u043b\u0430 -LocaleNames/sr/AR=\u0410\u0440\u0433\u0435\u043d\u0442\u0438\u043d\u0430 -LocaleNames/sr/AT=\u0410\u0443\u0441\u0442\u0440\u0438\u0458\u0430 -LocaleNames/sr/AU=\u0410\u0443\u0441\u0442\u0440\u0430\u043b\u0438\u0458\u0430 -LocaleNames/sr/AW=\u0410\u0440\u0443\u0431\u0430 -LocaleNames/sr/AX=\u041e\u043b\u0430\u043d\u0434\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/AZ=\u0410\u0437\u0435\u0440\u0431\u0435\u0458\u045f\u0430\u043d -LocaleNames/sr/BA=\u0411\u043e\u0441\u043d\u0430 \u0438 \u0425\u0435\u0440\u0446\u0435\u0433\u043e\u0432\u0438\u043d\u0430 -LocaleNames/sr/BB=\u0411\u0430\u0440\u0431\u0430\u0434\u043e\u0441 -LocaleNames/sr/BD=\u0411\u0430\u043d\u0433\u043b\u0430\u0434\u0435\u0448 -LocaleNames/sr/BE=\u0411\u0435\u043b\u0433\u0438\u0458\u0430 -LocaleNames/sr/BF=\u0411\u0443\u0440\u043a\u0438\u043d\u0430 \u0424\u0430\u0441\u043e -LocaleNames/sr/BG=\u0411\u0443\u0433\u0430\u0440\u0441\u043a\u0430 -LocaleNames/sr/BH=\u0411\u0430\u0445\u0440\u0435\u0438\u043d -LocaleNames/sr/BI=\u0411\u0443\u0440\u0443\u043d\u0434\u0438 -LocaleNames/sr/BJ=\u0411\u0435\u043d\u0438\u043d -LocaleNames/sr/BM=\u0411\u0435\u0440\u043c\u0443\u0434\u0438 -LocaleNames/sr/BN=\u0411\u0440\u0443\u043d\u0435\u0458 -LocaleNames/sr/BO=\u0411\u043e\u043b\u0438\u0432\u0438\u0458\u0430 -LocaleNames/sr/BR=\u0411\u0440\u0430\u0437\u0438\u043b -LocaleNames/sr/BS=\u0411\u0430\u0445\u0430\u043c\u0438 -LocaleNames/sr/BT=\u0411\u0443\u0442\u0430\u043d -LocaleNames/sr/BV=\u041e\u0441\u0442\u0440\u0432\u043e \u0411\u0443\u0432\u0435 -LocaleNames/sr/BW=\u0411\u043e\u0446\u0432\u0430\u043d\u0430 -LocaleNames/sr/BY=\u0411\u0435\u043b\u043e\u0440\u0443\u0441\u0438\u0458\u0430 -LocaleNames/sr/BZ=\u0411\u0435\u043b\u0438\u0437\u0435 -LocaleNames/sr/CA=\u041a\u0430\u043d\u0430\u0434\u0430 -LocaleNames/sr/CC=\u041a\u043e\u043a\u043e\u0441\u043e\u0432\u0430 (\u041a\u0438\u043b\u0438\u043d\u0433\u043e\u0432\u0430) \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/CD=\u041a\u043e\u043d\u0433\u043e - \u041a\u0438\u043d\u0448\u0430\u0441\u0430 -LocaleNames/sr/CF=\u0426\u0435\u043d\u0442\u0440\u0430\u043b\u043d\u043e\u0430\u0444\u0440\u0438\u0447\u043a\u0430 \u0420\u0435\u043f\u0443\u0431\u043b\u0438\u043a\u0430 -LocaleNames/sr/CG=\u041a\u043e\u043d\u0433\u043e - \u0411\u0440\u0430\u0437\u0430\u0432\u0438\u043b -LocaleNames/sr/CH=\u0428\u0432\u0430\u0458\u0446\u0430\u0440\u0441\u043a\u0430 -LocaleNames/sr/CI=\u041e\u0431\u0430\u043b\u0430 \u0421\u043b\u043e\u043d\u043e\u0432\u0430\u0447\u0435 (\u041a\u043e\u0442 \u0434\u2019\u0418\u0432\u043e\u0430\u0440) -LocaleNames/sr/CL=\u0427\u0438\u043b\u0435 -LocaleNames/sr/CM=\u041a\u0430\u043c\u0435\u0440\u0443\u043d -LocaleNames/sr/CN=\u041a\u0438\u043d\u0430 -LocaleNames/sr/CO=\u041a\u043e\u043b\u0443\u043c\u0431\u0438\u0458\u0430 -LocaleNames/sr/CR=\u041a\u043e\u0441\u0442\u0430\u0440\u0438\u043a\u0430 -LocaleNames/sr/CU=\u041a\u0443\u0431\u0430 -LocaleNames/sr/CV=\u0417\u0435\u043b\u0435\u043d\u043e\u0440\u0442\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/CX=\u0411\u043e\u0436\u0438\u045b\u043d\u043e \u041e\u0441\u0442\u0440\u0432\u043e -LocaleNames/sr/CY=\u041a\u0438\u043f\u0430\u0440 -LocaleNames/sr/CZ=\u0427\u0435\u0448\u043a\u0430 -LocaleNames/sr/DE=\u041d\u0435\u043c\u0430\u0447\u043a\u0430 -LocaleNames/sr/DJ=\u040f\u0438\u0431\u0443\u0442\u0438 -LocaleNames/sr/DK=\u0414\u0430\u043d\u0441\u043a\u0430 -LocaleNames/sr/DM=\u0414\u043e\u043c\u0438\u043d\u0438\u043a\u0430 -LocaleNames/sr/DO=\u0414\u043e\u043c\u0438\u043d\u0438\u043a\u0430\u043d\u0441\u043a\u0430 \u0420\u0435\u043f\u0443\u0431\u043b\u0438\u043a\u0430 -LocaleNames/sr/DZ=\u0410\u043b\u0436\u0438\u0440 -LocaleNames/sr/EC=\u0415\u043a\u0432\u0430\u0434\u043e\u0440 -LocaleNames/sr/EE=\u0415\u0441\u0442\u043e\u043d\u0438\u0458\u0430 -LocaleNames/sr/EG=\u0415\u0433\u0438\u043f\u0430\u0442 -LocaleNames/sr/EH=\u0417\u0430\u043f\u0430\u0434\u043d\u0430 \u0421\u0430\u0445\u0430\u0440\u0430 -LocaleNames/sr/ER=\u0415\u0440\u0438\u0442\u0440\u0435\u0458\u0430 -LocaleNames/sr/ES=\u0428\u043f\u0430\u043d\u0438\u0458\u0430 -LocaleNames/sr/ET=\u0415\u0442\u0438\u043e\u043f\u0438\u0458\u0430 -LocaleNames/sr/FI=\u0424\u0438\u043d\u0441\u043a\u0430 -LocaleNames/sr/FJ=\u0424\u0438\u045f\u0438 -LocaleNames/sr/FK=\u0424\u043e\u043a\u043b\u0430\u043d\u0434\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/FM=\u041c\u0438\u043a\u0440\u043e\u043d\u0435\u0437\u0438\u0458\u0430 -LocaleNames/sr/FO=\u0424\u0430\u0440\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/FR=\u0424\u0440\u0430\u043d\u0446\u0443\u0441\u043a\u0430 -LocaleNames/sr/GA=\u0413\u0430\u0431\u043e\u043d -LocaleNames/sr/GB=\u0423\u0458\u0435\u0434\u0438\u045a\u0435\u043d\u043e \u041a\u0440\u0430\u0459\u0435\u0432\u0441\u0442\u0432\u043e -LocaleNames/sr/GD=\u0413\u0440\u0435\u043d\u0430\u0434\u0430 -LocaleNames/sr/GE=\u0413\u0440\u0443\u0437\u0438\u0458\u0430 -LocaleNames/sr/GF=\u0424\u0440\u0430\u043d\u0446\u0443\u0441\u043a\u0430 \u0413\u0432\u0430\u0458\u0430\u043d\u0430 -LocaleNames/sr/GH=\u0413\u0430\u043d\u0430 -LocaleNames/sr/GI=\u0413\u0438\u0431\u0440\u0430\u043b\u0442\u0430\u0440 -LocaleNames/sr/GL=\u0413\u0440\u0435\u043d\u043b\u0430\u043d\u0434 -LocaleNames/sr/GM=\u0413\u0430\u043c\u0431\u0438\u0458\u0430 -LocaleNames/sr/GN=\u0413\u0432\u0438\u043d\u0435\u0458\u0430 -LocaleNames/sr/GP=\u0413\u0432\u0430\u0434\u0435\u043b\u0443\u043f -LocaleNames/sr/GQ=\u0415\u043a\u0432\u0430\u0442\u043e\u0440\u0438\u0458\u0430\u043b\u043d\u0430 \u0413\u0432\u0438\u043d\u0435\u0458\u0430 -LocaleNames/sr/GR=\u0413\u0440\u0447\u043a\u0430 -LocaleNames/sr/GS=\u0408\u0443\u0436\u043d\u0430 \u040f\u043e\u0440\u045f\u0438\u0458\u0430 \u0438 \u0408\u0443\u0436\u043d\u0430 \u0421\u0435\u043d\u0434\u0432\u0438\u0447\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/GT=\u0413\u0432\u0430\u0442\u0435\u043c\u0430\u043b\u0430 -LocaleNames/sr/GU=\u0413\u0443\u0430\u043c -LocaleNames/sr/GW=\u0413\u0432\u0438\u043d\u0435\u0458\u0430-\u0411\u0438\u0441\u0430\u043e -LocaleNames/sr/GY=\u0413\u0432\u0430\u0458\u0430\u043d\u0430 -LocaleNames/sr/HK=\u0421\u0410\u0420 \u0425\u043e\u043d\u0433\u043a\u043e\u043d\u0433 (\u041a\u0438\u043d\u0430) -LocaleNames/sr/HM=\u041e\u0441\u0442\u0440\u0432\u043e \u0425\u0435\u0440\u0434 \u0438 \u041c\u0435\u043a\u0434\u043e\u043d\u0430\u043b\u0434\u043e\u0432\u0430 \u043e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/HN=\u0425\u043e\u043d\u0434\u0443\u0440\u0430\u0441 -LocaleNames/sr/HR=\u0425\u0440\u0432\u0430\u0442\u0441\u043a\u0430 -LocaleNames/sr/HT=\u0425\u0430\u0438\u0442\u0438 -LocaleNames/sr/HU=\u041c\u0430\u0452\u0430\u0440\u0441\u043a\u0430 -LocaleNames/sr/ID=\u0418\u043d\u0434\u043e\u043d\u0435\u0437\u0438\u0458\u0430 -LocaleNames/sr/IE=\u0418\u0440\u0441\u043a\u0430 -LocaleNames/sr/IL=\u0418\u0437\u0440\u0430\u0435\u043b -LocaleNames/sr/IN=\u0418\u043d\u0434\u0438\u0458\u0430 -LocaleNames/sr/IQ=\u0418\u0440\u0430\u043a -LocaleNames/sr/IR=\u0418\u0440\u0430\u043d -LocaleNames/sr/IS=\u0418\u0441\u043b\u0430\u043d\u0434 -LocaleNames/sr/IT=\u0418\u0442\u0430\u043b\u0438\u0458\u0430 -LocaleNames/sr/JM=\u0408\u0430\u043c\u0430\u0458\u043a\u0430 -LocaleNames/sr/JO=\u0408\u043e\u0440\u0434\u0430\u043d -LocaleNames/sr/JP=\u0408\u0430\u043f\u0430\u043d -LocaleNames/sr/KE=\u041a\u0435\u043d\u0438\u0458\u0430 -LocaleNames/sr/KG=\u041a\u0438\u0440\u0433\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/KH=\u041a\u0430\u043c\u0431\u043e\u045f\u0430 -LocaleNames/sr/KI=\u041a\u0438\u0440\u0438\u0431\u0430\u0442\u0438 -LocaleNames/sr/KM=\u041a\u043e\u043c\u043e\u0440\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/KN=\u0421\u0435\u043d\u0442 \u041a\u0438\u0442\u0441 \u0438 \u041d\u0435\u0432\u0438\u0441 -LocaleNames/sr/KP=\u0421\u0435\u0432\u0435\u0440\u043d\u0430 \u041a\u043e\u0440\u0435\u0458\u0430 -LocaleNames/sr/KR=\u0408\u0443\u0436\u043d\u0430 \u041a\u043e\u0440\u0435\u0458\u0430 -LocaleNames/sr/KW=\u041a\u0443\u0432\u0430\u0458\u0442 -LocaleNames/sr/KY=\u041a\u0430\u0458\u043c\u0430\u043d\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/KZ=\u041a\u0430\u0437\u0430\u0445\u0441\u0442\u0430\u043d -LocaleNames/sr/LA=\u041b\u0430\u043e\u0441 -LocaleNames/sr/LB=\u041b\u0438\u0431\u0430\u043d -LocaleNames/sr/LC=\u0421\u0432\u0435\u0442\u0430 \u041b\u0443\u0446\u0438\u0458\u0430 -LocaleNames/sr/LI=\u041b\u0438\u0445\u0442\u0435\u043d\u0448\u0442\u0430\u0458\u043d -LocaleNames/sr/LK=\u0428\u0440\u0438 \u041b\u0430\u043d\u043a\u0430 -LocaleNames/sr/LR=\u041b\u0438\u0431\u0435\u0440\u0438\u0458\u0430 -LocaleNames/sr/LS=\u041b\u0435\u0441\u043e\u0442\u043e -LocaleNames/sr/LT=\u041b\u0438\u0442\u0432\u0430\u043d\u0438\u0458\u0430 -LocaleNames/sr/LU=\u041b\u0443\u043a\u0441\u0435\u043c\u0431\u0443\u0440\u0433 -LocaleNames/sr/LV=\u041b\u0435\u0442\u043e\u043d\u0438\u0458\u0430 -LocaleNames/sr/LY=\u041b\u0438\u0431\u0438\u0458\u0430 -LocaleNames/sr/MA=\u041c\u0430\u0440\u043e\u043a\u043e -LocaleNames/sr/MC=\u041c\u043e\u043d\u0430\u043a\u043e -LocaleNames/sr/MD=\u041c\u043e\u043b\u0434\u0430\u0432\u0438\u0458\u0430 -LocaleNames/sr/MG=\u041c\u0430\u0434\u0430\u0433\u0430\u0441\u043a\u0430\u0440 -LocaleNames/sr/MH=\u041c\u0430\u0440\u0448\u0430\u043b\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/MK=\u0421\u0435\u0432\u0435\u0440\u043d\u0430 \u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0438\u0458\u0430 -LocaleNames/sr/ML=\u041c\u0430\u043b\u0438 -LocaleNames/sr/MM=\u041c\u0438\u0458\u0430\u043d\u043c\u0430\u0440 (\u0411\u0443\u0440\u043c\u0430) -LocaleNames/sr/MN=\u041c\u043e\u043d\u0433\u043e\u043b\u0438\u0458\u0430 -LocaleNames/sr/MO=\u0421\u0410\u0420 \u041c\u0430\u043a\u0430\u043e (\u041a\u0438\u043d\u0430) -LocaleNames/sr/MP=\u0421\u0435\u0432\u0435\u0440\u043d\u0430 \u041c\u0430\u0440\u0438\u0458\u0430\u043d\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/MQ=\u041c\u0430\u0440\u0442\u0438\u043d\u0438\u043a -LocaleNames/sr/MR=\u041c\u0430\u0443\u0440\u0438\u0442\u0430\u043d\u0438\u0458\u0430 -LocaleNames/sr/MS=\u041c\u043e\u043d\u0441\u0435\u0440\u0430\u0442 -LocaleNames/sr/MT=\u041c\u0430\u043b\u0442\u0430 -LocaleNames/sr/MU=\u041c\u0430\u0443\u0440\u0438\u0446\u0438\u0458\u0443\u0441 -LocaleNames/sr/MV=\u041c\u0430\u043b\u0434\u0438\u0432\u0438 -LocaleNames/sr/MW=\u041c\u0430\u043b\u0430\u0432\u0438 -LocaleNames/sr/MX=\u041c\u0435\u043a\u0441\u0438\u043a\u043e -LocaleNames/sr/MY=\u041c\u0430\u043b\u0435\u0437\u0438\u0458\u0430 -LocaleNames/sr/MZ=\u041c\u043e\u0437\u0430\u043c\u0431\u0438\u043a -LocaleNames/sr/NA=\u041d\u0430\u043c\u0438\u0431\u0438\u0458\u0430 -LocaleNames/sr/NC=\u041d\u043e\u0432\u0430 \u041a\u0430\u043b\u0435\u0434\u043e\u043d\u0438\u0458\u0430 -LocaleNames/sr/NE=\u041d\u0438\u0433\u0435\u0440 -LocaleNames/sr/NF=\u041e\u0441\u0442\u0440\u0432\u043e \u041d\u043e\u0440\u0444\u043e\u043a -LocaleNames/sr/NG=\u041d\u0438\u0433\u0435\u0440\u0438\u0458\u0430 -LocaleNames/sr/NI=\u041d\u0438\u043a\u0430\u0440\u0430\u0433\u0432\u0430 -LocaleNames/sr/NL=\u0425\u043e\u043b\u0430\u043d\u0434\u0438\u0458\u0430 -LocaleNames/sr/NO=\u041d\u043e\u0440\u0432\u0435\u0448\u043a\u0430 -LocaleNames/sr/NP=\u041d\u0435\u043f\u0430\u043b -LocaleNames/sr/NR=\u041d\u0430\u0443\u0440\u0443 -LocaleNames/sr/NU=\u041d\u0438\u0443\u0435 -LocaleNames/sr/NZ=\u041d\u043e\u0432\u0438 \u0417\u0435\u043b\u0430\u043d\u0434 -LocaleNames/sr/OM=\u041e\u043c\u0430\u043d -LocaleNames/sr/PA=\u041f\u0430\u043d\u0430\u043c\u0430 -LocaleNames/sr/PE=\u041f\u0435\u0440\u0443 -LocaleNames/sr/PF=\u0424\u0440\u0430\u043d\u0446\u0443\u0441\u043a\u0430 \u041f\u043e\u043b\u0438\u043d\u0435\u0437\u0438\u0458\u0430 -LocaleNames/sr/PG=\u041f\u0430\u043f\u0443\u0430 \u041d\u043e\u0432\u0430 \u0413\u0432\u0438\u043d\u0435\u0458\u0430 -LocaleNames/sr/PH=\u0424\u0438\u043b\u0438\u043f\u0438\u043d\u0438 -LocaleNames/sr/PK=\u041f\u0430\u043a\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/PL=\u041f\u043e\u0459\u0441\u043a\u0430 -LocaleNames/sr/PM=\u0421\u0435\u043d \u041f\u0458\u0435\u0440 \u0438 \u041c\u0438\u043a\u0435\u043b\u043e\u043d -LocaleNames/sr/PN=\u041f\u0438\u0442\u043a\u0435\u0440\u043d -LocaleNames/sr/PR=\u041f\u043e\u0440\u0442\u043e\u0440\u0438\u043a\u043e -LocaleNames/sr/PS=\u041f\u0430\u043b\u0435\u0441\u0442\u0438\u043d\u0441\u043a\u0435 \u0442\u0435\u0440\u0438\u0442\u043e\u0440\u0438\u0458\u0435 -LocaleNames/sr/PT=\u041f\u043e\u0440\u0442\u0443\u0433\u0430\u043b\u0438\u0458\u0430 -LocaleNames/sr/PW=\u041f\u0430\u043b\u0430\u0443 -LocaleNames/sr/PY=\u041f\u0430\u0440\u0430\u0433\u0432\u0430\u0458 -LocaleNames/sr/QA=\u041a\u0430\u0442\u0430\u0440 -LocaleNames/sr/RE=\u0420\u0435\u0438\u043d\u0438\u043e\u043d -LocaleNames/sr/RO=\u0420\u0443\u043c\u0443\u043d\u0438\u0458\u0430 -LocaleNames/sr/RU=\u0420\u0443\u0441\u0438\u0458\u0430 -LocaleNames/sr/RW=\u0420\u0443\u0430\u043d\u0434\u0430 -LocaleNames/sr/SA=\u0421\u0430\u0443\u0434\u0438\u0458\u0441\u043a\u0430 \u0410\u0440\u0430\u0431\u0438\u0458\u0430 -LocaleNames/sr/SB=\u0421\u043e\u043b\u043e\u043c\u043e\u043d\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/SC=\u0421\u0435\u0458\u0448\u0435\u043b\u0438 -LocaleNames/sr/SD=\u0421\u0443\u0434\u0430\u043d -LocaleNames/sr/SE=\u0428\u0432\u0435\u0434\u0441\u043a\u0430 -LocaleNames/sr/SG=\u0421\u0438\u043d\u0433\u0430\u043f\u0443\u0440 -LocaleNames/sr/SH=\u0421\u0432\u0435\u0442\u0430 \u0408\u0435\u043b\u0435\u043d\u0430 -LocaleNames/sr/SI=\u0421\u043b\u043e\u0432\u0435\u043d\u0438\u0458\u0430 -LocaleNames/sr/SJ=\u0421\u0432\u0430\u043b\u0431\u0430\u0440\u0434 \u0438 \u0408\u0430\u043d \u041c\u0430\u0458\u0435\u043d -LocaleNames/sr/SK=\u0421\u043b\u043e\u0432\u0430\u0447\u043a\u0430 -LocaleNames/sr/SL=\u0421\u0438\u0458\u0435\u0440\u0430 \u041b\u0435\u043e\u043d\u0435 -LocaleNames/sr/SM=\u0421\u0430\u043d \u041c\u0430\u0440\u0438\u043d\u043e -LocaleNames/sr/SN=\u0421\u0435\u043d\u0435\u0433\u0430\u043b -LocaleNames/sr/SO=\u0421\u043e\u043c\u0430\u043b\u0438\u0458\u0430 -LocaleNames/sr/SR=\u0421\u0443\u0440\u0438\u043d\u0430\u043c -LocaleNames/sr/ST=\u0421\u0430\u043e \u0422\u043e\u043c\u0435 \u0438 \u041f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 -LocaleNames/sr/SV=\u0421\u0430\u043b\u0432\u0430\u0434\u043e\u0440 -LocaleNames/sr/SY=\u0421\u0438\u0440\u0438\u0458\u0430 -LocaleNames/sr/SZ=\u0421\u0432\u0430\u0437\u0438\u043b\u0435\u043d\u0434 -LocaleNames/sr/TC=\u041e\u0441\u0442\u0440\u0432\u0430 \u0422\u0443\u0440\u043a\u0441 \u0438 \u041a\u0430\u0438\u043a\u043e\u0441 -LocaleNames/sr/TD=\u0427\u0430\u0434 -LocaleNames/sr/TF=\u0424\u0440\u0430\u043d\u0446\u0443\u0441\u043a\u0435 \u0408\u0443\u0436\u043d\u0435 \u0422\u0435\u0440\u0438\u0442\u043e\u0440\u0438\u0458\u0435 -LocaleNames/sr/TG=\u0422\u043e\u0433\u043e -LocaleNames/sr/TH=\u0422\u0430\u0458\u043b\u0430\u043d\u0434 -LocaleNames/sr/TJ=\u0422\u0430\u045f\u0438\u043a\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/TK=\u0422\u043e\u043a\u0435\u043b\u0430\u0443 -LocaleNames/sr/TL=\u0422\u0438\u043c\u043e\u0440-\u041b\u0435\u0441\u0442\u0435 (\u0418\u0441\u0442\u043e\u0447\u043d\u0438 \u0422\u0438\u043c\u043e\u0440) -LocaleNames/sr/TM=\u0422\u0443\u0440\u043a\u043c\u0435\u043d\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/TN=\u0422\u0443\u043d\u0438\u0441 -LocaleNames/sr/TO=\u0422\u043e\u043d\u0433\u0430 -LocaleNames/sr/TR=\u0422\u0443\u0440\u0441\u043a\u0430 -LocaleNames/sr/TT=\u0422\u0440\u0438\u043d\u0438\u0434\u0430\u0434 \u0438 \u0422\u043e\u0431\u0430\u0433\u043e -LocaleNames/sr/TV=\u0422\u0443\u0432\u0430\u043b\u0443 -LocaleNames/sr/TW=\u0422\u0430\u0458\u0432\u0430\u043d -LocaleNames/sr/TZ=\u0422\u0430\u043d\u0437\u0430\u043d\u0438\u0458\u0430 -LocaleNames/sr/UA=\u0423\u043a\u0440\u0430\u0458\u0438\u043d\u0430 -LocaleNames/sr/UG=\u0423\u0433\u0430\u043d\u0434\u0430 -LocaleNames/sr/UM=\u0423\u0434\u0430\u0459\u0435\u043d\u0430 \u043e\u0441\u0442\u0440\u0432\u0430 \u0421\u0410\u0414 -LocaleNames/sr/US=\u0421\u0458\u0435\u0434\u0438\u045a\u0435\u043d\u0435 \u0414\u0440\u0436\u0430\u0432\u0435 -LocaleNames/sr/UY=\u0423\u0440\u0443\u0433\u0432\u0430\u0458 -LocaleNames/sr/UZ=\u0423\u0437\u0431\u0435\u043a\u0438\u0441\u0442\u0430\u043d -LocaleNames/sr/VA=\u0412\u0430\u0442\u0438\u043a\u0430\u043d -LocaleNames/sr/VC=\u0421\u0435\u043d\u0442 \u0412\u0438\u043d\u0441\u0435\u043d\u0442 \u0438 \u0413\u0440\u0435\u043d\u0430\u0434\u0438\u043d\u0438 -LocaleNames/sr/VE=\u0412\u0435\u043d\u0435\u0446\u0443\u0435\u043b\u0430 -LocaleNames/sr/VG=\u0411\u0440\u0438\u0442\u0430\u043d\u0441\u043a\u0430 \u0414\u0435\u0432\u0438\u0447\u0430\u043d\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/VI=\u0410\u043c\u0435\u0440\u0438\u0447\u043a\u0430 \u0414\u0435\u0432\u0438\u0447\u0430\u043d\u0441\u043a\u0430 \u041e\u0441\u0442\u0440\u0432\u0430 -LocaleNames/sr/VN=\u0412\u0438\u0458\u0435\u0442\u043d\u0430\u043c -LocaleNames/sr/VU=\u0412\u0430\u043d\u0443\u0430\u0442\u0443 -LocaleNames/sr/WF=\u0412\u0430\u043b\u0438\u0441 \u0438 \u0424\u0443\u0442\u0443\u043d\u0430 -LocaleNames/sr/WS=\u0421\u0430\u043c\u043e\u0430 -LocaleNames/sr/YE=\u0408\u0435\u043c\u0435\u043d -LocaleNames/sr/YT=\u041c\u0430\u0458\u043e\u0442 -LocaleNames/sr/ZM=\u0417\u0430\u043c\u0431\u0438\u0458\u0430 -LocaleNames/sr/ZW=\u0417\u0438\u043c\u0431\u0430\u0431\u0432\u0435 -CurrencyNames/sr_CS/EUR=\u20ac +LocaleNames/sr/af=африканс +LocaleNames/sr/ar=арапски +LocaleNames/sr/be=белоруски +LocaleNames/sr/bg=бугарски +LocaleNames/sr/br=бретонски +LocaleNames/sr/ca=каталонски +LocaleNames/sr/co=корзикански +LocaleNames/sr/cs=чешки +LocaleNames/sr/da=дански +LocaleNames/sr/de=немачки +LocaleNames/sr/el=грчки +LocaleNames/sr/en=енглески +LocaleNames/sr/eo=есперанто +LocaleNames/sr/es=шпански +LocaleNames/sr/et=естонски +LocaleNames/sr/eu=баскијски +LocaleNames/sr/fa=персијски +LocaleNames/sr/fi=фински +LocaleNames/sr/fr=француски +LocaleNames/sr/ga=ирски +LocaleNames/sr/he=хебрејски +LocaleNames/sr/hi=хинди +LocaleNames/sr/hr=хрватски +LocaleNames/sr/hu=мађарски +LocaleNames/sr/hy=јерменски +LocaleNames/sr/id=индонежански +LocaleNames/sr/is=исландски +LocaleNames/sr/it=италијански +LocaleNames/sr/ja=јапански +LocaleNames/sr/ka=грузијски +LocaleNames/sr/km=кмерски +LocaleNames/sr/ko=корејски +LocaleNames/sr/ku=курдски +LocaleNames/sr/ky=киргиски +LocaleNames/sr/la=латински +LocaleNames/sr/lt=литвански +LocaleNames/sr/lv=летонски +LocaleNames/sr/mk=македонски +LocaleNames/sr/mn=монголски +LocaleNames/sr/my=бурмански +LocaleNames/sr/nl=холандски +LocaleNames/sr/no=норвешки +LocaleNames/sr/pl=пољски +LocaleNames/sr/pt=португалски +LocaleNames/sr/rm=романш +LocaleNames/sr/ro=румунски +LocaleNames/sr/ru=руски +LocaleNames/sr/sa=санскрит +LocaleNames/sr/sk=словачки +LocaleNames/sr/sl=словеначки +LocaleNames/sr/sq=албански +LocaleNames/sr/sr=српски +LocaleNames/sr/sv=шведски +LocaleNames/sr/sw=свахили +LocaleNames/sr/tr=турски +LocaleNames/sr/uk=украјински +LocaleNames/sr/vi=вијетнамски +LocaleNames/sr/yi=јидиш +LocaleNames/sr/zh=кинески +LocaleNames/sr/AD=Андора +LocaleNames/sr/AE=Уједињени Арапски Емирати +LocaleNames/sr/AF=Авганистан +LocaleNames/sr/AL=Албанија +LocaleNames/sr/AM=Јерменија +LocaleNames/sr/AO=Ангола +LocaleNames/sr/AR=Аргентина +LocaleNames/sr/AT=Аустрија +LocaleNames/sr/AU=Аустралија +LocaleNames/sr/AW=Аруба +LocaleNames/sr/AX=Оландска Острва +LocaleNames/sr/AZ=Азербејџан +LocaleNames/sr/BA=Босна и Херцеговина +LocaleNames/sr/BB=Барбадос +LocaleNames/sr/BD=Бангладеш +LocaleNames/sr/BE=Белгија +LocaleNames/sr/BF=Буркина Фасо +LocaleNames/sr/BG=Бугарска +LocaleNames/sr/BH=Бахреин +LocaleNames/sr/BI=Бурунди +LocaleNames/sr/BJ=Бенин +LocaleNames/sr/BM=Бермуди +LocaleNames/sr/BN=Брунеј +LocaleNames/sr/BO=Боливија +LocaleNames/sr/BR=Бразил +LocaleNames/sr/BS=Бахами +LocaleNames/sr/BT=Бутан +LocaleNames/sr/BV=Острво Буве +LocaleNames/sr/BW=Боцвана +LocaleNames/sr/BY=Белорусија +LocaleNames/sr/BZ=Белизе +LocaleNames/sr/CA=Канада +LocaleNames/sr/CC=Кокосова (Килингова) Острва +LocaleNames/sr/CD=Конго - Киншаса +LocaleNames/sr/CF=Централноафричка Република +LocaleNames/sr/CG=Конго - Бразавил +LocaleNames/sr/CH=Швајцарска +LocaleNames/sr/CI=Обала Слоноваче (Кот д’Ивоар) +LocaleNames/sr/CL=Чиле +LocaleNames/sr/CM=Камерун +LocaleNames/sr/CN=Кина +LocaleNames/sr/CO=Колумбија +LocaleNames/sr/CR=Костарика +LocaleNames/sr/CU=Куба +LocaleNames/sr/CV=Зеленортска Острва +LocaleNames/sr/CX=Божићно Острво +LocaleNames/sr/CY=Кипар +LocaleNames/sr/CZ=Чешка +LocaleNames/sr/DE=Немачка +LocaleNames/sr/DJ=Џибути +LocaleNames/sr/DK=Данска +LocaleNames/sr/DM=Доминика +LocaleNames/sr/DO=Доминиканска Република +LocaleNames/sr/DZ=Алжир +LocaleNames/sr/EC=Еквадор +LocaleNames/sr/EE=Естонија +LocaleNames/sr/EG=Египат +LocaleNames/sr/EH=Западна Сахара +LocaleNames/sr/ER=Еритреја +LocaleNames/sr/ES=Шпанија +LocaleNames/sr/ET=Етиопија +LocaleNames/sr/FI=Финска +LocaleNames/sr/FJ=Фиџи +LocaleNames/sr/FK=Фокландска Острва +LocaleNames/sr/FM=Микронезија +LocaleNames/sr/FO=Фарска Острва +LocaleNames/sr/FR=Француска +LocaleNames/sr/GA=Габон +LocaleNames/sr/GB=Уједињено Краљевство +LocaleNames/sr/GD=Гренада +LocaleNames/sr/GE=Грузија +LocaleNames/sr/GF=Француска Гвајана +LocaleNames/sr/GH=Гана +LocaleNames/sr/GI=Гибралтар +LocaleNames/sr/GL=Гренланд +LocaleNames/sr/GM=Гамбија +LocaleNames/sr/GN=Гвинеја +LocaleNames/sr/GP=Гваделуп +LocaleNames/sr/GQ=Екваторијална Гвинеја +LocaleNames/sr/GR=Грчка +LocaleNames/sr/GS=Јужна Џорџија и Јужна Сендвичка Острва +LocaleNames/sr/GT=Гватемала +LocaleNames/sr/GU=Гуам +LocaleNames/sr/GW=Гвинеја-Бисао +LocaleNames/sr/GY=Гвајана +LocaleNames/sr/HK=САР Хонгконг (Кина) +LocaleNames/sr/HM=Острво Херд и Мекдоналдова острва +LocaleNames/sr/HN=Хондурас +LocaleNames/sr/HR=Хрватска +LocaleNames/sr/HT=Хаити +LocaleNames/sr/HU=Мађарска +LocaleNames/sr/ID=Индонезија +LocaleNames/sr/IE=Ирска +LocaleNames/sr/IL=Израел +LocaleNames/sr/IN=Индија +LocaleNames/sr/IQ=Ирак +LocaleNames/sr/IR=Иран +LocaleNames/sr/IS=Исланд +LocaleNames/sr/IT=Италија +LocaleNames/sr/JM=Јамајка +LocaleNames/sr/JO=Јордан +LocaleNames/sr/JP=Јапан +LocaleNames/sr/KE=Кенија +LocaleNames/sr/KG=Киргистан +LocaleNames/sr/KH=Камбоџа +LocaleNames/sr/KI=Кирибати +LocaleNames/sr/KM=Коморска Острва +LocaleNames/sr/KN=Сент Китс и Невис +LocaleNames/sr/KP=Северна Кореја +LocaleNames/sr/KR=Јужна Кореја +LocaleNames/sr/KW=Кувајт +LocaleNames/sr/KY=Кајманска Острва +LocaleNames/sr/KZ=Казахстан +LocaleNames/sr/LA=Лаос +LocaleNames/sr/LB=Либан +LocaleNames/sr/LC=Света Луција +LocaleNames/sr/LI=Лихтенштајн +LocaleNames/sr/LK=Шри Ланка +LocaleNames/sr/LR=Либерија +LocaleNames/sr/LS=Лесото +LocaleNames/sr/LT=Литванија +LocaleNames/sr/LU=Луксембург +LocaleNames/sr/LV=Летонија +LocaleNames/sr/LY=Либија +LocaleNames/sr/MA=Мароко +LocaleNames/sr/MC=Монако +LocaleNames/sr/MD=Молдавија +LocaleNames/sr/MG=Мадагаскар +LocaleNames/sr/MH=Маршалска Острва +LocaleNames/sr/MK=Северна Македонија +LocaleNames/sr/ML=Мали +LocaleNames/sr/MM=Мијанмар (Бурма) +LocaleNames/sr/MN=Монголија +LocaleNames/sr/MO=САР Макао (Кина) +LocaleNames/sr/MP=Северна Маријанска Острва +LocaleNames/sr/MQ=Мартиник +LocaleNames/sr/MR=Мауританија +LocaleNames/sr/MS=Монсерат +LocaleNames/sr/MT=Малта +LocaleNames/sr/MU=Маурицијус +LocaleNames/sr/MV=Малдиви +LocaleNames/sr/MW=Малави +LocaleNames/sr/MX=Мексико +LocaleNames/sr/MY=Малезија +LocaleNames/sr/MZ=Мозамбик +LocaleNames/sr/NA=Намибија +LocaleNames/sr/NC=Нова Каледонија +LocaleNames/sr/NE=Нигер +LocaleNames/sr/NF=Острво Норфок +LocaleNames/sr/NG=Нигерија +LocaleNames/sr/NI=Никарагва +LocaleNames/sr/NL=Холандија +LocaleNames/sr/NO=Норвешка +LocaleNames/sr/NP=Непал +LocaleNames/sr/NR=Науру +LocaleNames/sr/NU=Ниуе +LocaleNames/sr/NZ=Нови Зеланд +LocaleNames/sr/OM=Оман +LocaleNames/sr/PA=Панама +LocaleNames/sr/PE=Перу +LocaleNames/sr/PF=Француска Полинезија +LocaleNames/sr/PG=Папуа Нова Гвинеја +LocaleNames/sr/PH=Филипини +LocaleNames/sr/PK=Пакистан +LocaleNames/sr/PL=Пољска +LocaleNames/sr/PM=Сен Пјер и Микелон +LocaleNames/sr/PN=Питкерн +LocaleNames/sr/PR=Порторико +LocaleNames/sr/PS=Палестинске територије +LocaleNames/sr/PT=Португалија +LocaleNames/sr/PW=Палау +LocaleNames/sr/PY=Парагвај +LocaleNames/sr/QA=Катар +LocaleNames/sr/RE=Реинион +LocaleNames/sr/RO=Румунија +LocaleNames/sr/RU=Русија +LocaleNames/sr/RW=Руанда +LocaleNames/sr/SA=Саудијска Арабија +LocaleNames/sr/SB=Соломонска Острва +LocaleNames/sr/SC=Сејшели +LocaleNames/sr/SD=Судан +LocaleNames/sr/SE=Шведска +LocaleNames/sr/SG=Сингапур +LocaleNames/sr/SH=Света Јелена +LocaleNames/sr/SI=Словенија +LocaleNames/sr/SJ=Свалбард и Јан Мајен +LocaleNames/sr/SK=Словачка +LocaleNames/sr/SL=Сијера Леоне +LocaleNames/sr/SM=Сан Марино +LocaleNames/sr/SN=Сенегал +LocaleNames/sr/SO=Сомалија +LocaleNames/sr/SR=Суринам +LocaleNames/sr/ST=Сао Томе и Принципе +LocaleNames/sr/SV=Салвадор +LocaleNames/sr/SY=Сирија +LocaleNames/sr/SZ=Свазиленд +LocaleNames/sr/TC=Острва Туркс и Каикос +LocaleNames/sr/TD=Чад +LocaleNames/sr/TF=Француске Јужне Територије +LocaleNames/sr/TG=Того +LocaleNames/sr/TH=Тајланд +LocaleNames/sr/TJ=Таџикистан +LocaleNames/sr/TK=Токелау +LocaleNames/sr/TL=Тимор-Лесте (Источни Тимор) +LocaleNames/sr/TM=Туркменистан +LocaleNames/sr/TN=Тунис +LocaleNames/sr/TO=Тонга +LocaleNames/sr/TR=Турска +LocaleNames/sr/TT=Тринидад и Тобаго +LocaleNames/sr/TV=Тувалу +LocaleNames/sr/TW=Тајван +LocaleNames/sr/TZ=Танзанија +LocaleNames/sr/UA=Украјина +LocaleNames/sr/UG=Уганда +LocaleNames/sr/UM=Удаљена острва САД +LocaleNames/sr/US=Сједињене Државе +LocaleNames/sr/UY=Уругвај +LocaleNames/sr/UZ=Узбекистан +LocaleNames/sr/VA=Ватикан +LocaleNames/sr/VC=Сент Винсент и Гренадини +LocaleNames/sr/VE=Венецуела +LocaleNames/sr/VG=Британска Девичанска Острва +LocaleNames/sr/VI=Америчка Девичанска Острва +LocaleNames/sr/VN=Вијетнам +LocaleNames/sr/VU=Вануату +LocaleNames/sr/WF=Валис и Футуна +LocaleNames/sr/WS=Самоа +LocaleNames/sr/YE=Јемен +LocaleNames/sr/YT=Мајот +LocaleNames/sr/ZM=Замбија +LocaleNames/sr/ZW=Зимбабве +CurrencyNames/sr_CS/EUR=€ # bug 6498742: data is changed -CurrencyNames/sr_BA/BAM=\u041a\u041c +CurrencyNames/sr_BA/BAM=КМ -CurrencyNames/sr_BA/EUR=\u20ac +CurrencyNames/sr_BA/EUR=€ # bug #6351682 Country name for Korean is wrong in Simplified Chinese -LocaleNames/zh/KP=\u671d\u9c9c -LocaleNames/zh/KR=\u97e9\u56fd +LocaleNames/zh/KP=朝鲜 +LocaleNames/zh/KR=韩国 # bug 6379382: Finnish time of day should be formatted as "H.mm.ss", not "hh:mm:ss" FormatData/fi/TimePatterns/0=H.mm.ss zzzz FormatData/fi/TimePatterns/1=H.mm.ss z # bug 6498742: data for IR & ZW changed -LocaleNames/pt_PT/IR=Ir\u00e3o -LocaleNames/pt_PT/ZW=Zimbabu\u00e9 +LocaleNames/pt_PT/IR=Irão +LocaleNames/pt_PT/ZW=Zimbabué -LocaleNames/el/ar=\u0391\u03c1\u03b1\u03b2\u03b9\u03ba\u03ac -LocaleNames/el/be=\u039b\u03b5\u03c5\u03ba\u03bf\u03c1\u03c9\u03c3\u03b9\u03ba\u03ac -LocaleNames/el/bg=\u0392\u03bf\u03c5\u03bb\u03b3\u03b1\u03c1\u03b9\u03ba\u03ac -LocaleNames/el/bn=\u0392\u03b5\u03b3\u03b3\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/bo=\u0398\u03b9\u03b2\u03b5\u03c4\u03b9\u03b1\u03bd\u03ac -LocaleNames/el/bs=\u0392\u03bf\u03c3\u03bd\u03b9\u03b1\u03ba\u03ac -LocaleNames/el/ca=\u039a\u03b1\u03c4\u03b1\u03bb\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/co=\u039a\u03bf\u03c1\u03c3\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/cs=\u03a4\u03c3\u03b5\u03c7\u03b9\u03ba\u03ac -LocaleNames/el/cy=\u039f\u03c5\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/da=\u0394\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/de=\u0393\u03b5\u03c1\u03bc\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/el=\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/en=\u0391\u03b3\u03b3\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/es=\u0399\u03c3\u03c0\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/et=\u0395\u03c3\u03b8\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/eu=\u0392\u03b1\u03c3\u03ba\u03b9\u03ba\u03ac -LocaleNames/el/fa=\u03a0\u03b5\u03c1\u03c3\u03b9\u03ba\u03ac -LocaleNames/el/fi=\u03a6\u03b9\u03bd\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el/fr=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/ga=\u0399\u03c1\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el/gd=\u03a3\u03ba\u03c9\u03c4\u03b9\u03ba\u03ac \u039a\u03b5\u03bb\u03c4\u03b9\u03ba\u03ac -LocaleNames/el/he=\u0395\u03b2\u03c1\u03b1\u03ca\u03ba\u03ac -LocaleNames/el/hi=\u03a7\u03af\u03bd\u03c4\u03b9 -LocaleNames/el/hr=\u039a\u03c1\u03bf\u03b1\u03c4\u03b9\u03ba\u03ac -LocaleNames/el/hu=\u039f\u03c5\u03b3\u03b3\u03c1\u03b9\u03ba\u03ac -LocaleNames/el/hy=\u0391\u03c1\u03bc\u03b5\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/id=\u0399\u03bd\u03b4\u03bf\u03bd\u03b7\u03c3\u03b9\u03b1\u03ba\u03ac -LocaleNames/el/is=\u0399\u03c3\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el/it=\u0399\u03c4\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/ja=\u0399\u03b1\u03c0\u03c9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/ka=\u0393\u03b5\u03c9\u03c1\u03b3\u03b9\u03b1\u03bd\u03ac -LocaleNames/el/ko=\u039a\u03bf\u03c1\u03b5\u03b1\u03c4\u03b9\u03ba\u03ac -LocaleNames/el/la=\u039b\u03b1\u03c4\u03b9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/lt=\u039b\u03b9\u03b8\u03bf\u03c5\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/lv=\u039b\u03b5\u03c4\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/mk=\u03a3\u03bb\u03b1\u03b2\u03bf\u03bc\u03b1\u03ba\u03b5\u03b4\u03bf\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/mn=\u039c\u03bf\u03b3\u03b3\u03bf\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/mt=\u039c\u03b1\u03bb\u03c4\u03b5\u03b6\u03b9\u03ba\u03ac -LocaleNames/el/no=\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03b9\u03ba\u03ac -LocaleNames/el/pl=\u03a0\u03bf\u03bb\u03c9\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/pt=\u03a0\u03bf\u03c1\u03c4\u03bf\u03b3\u03b1\u03bb\u03b9\u03ba\u03ac -LocaleNames/el/ro=\u03a1\u03bf\u03c5\u03bc\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/ru=\u03a1\u03c9\u03c3\u03b9\u03ba\u03ac -LocaleNames/el/sk=\u03a3\u03bb\u03bf\u03b2\u03b1\u03ba\u03b9\u03ba\u03ac -LocaleNames/el/sl=\u03a3\u03bb\u03bf\u03b2\u03b5\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/sq=\u0391\u03bb\u03b2\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/sr=\u03a3\u03b5\u03c1\u03b2\u03b9\u03ba\u03ac -LocaleNames/el/sv=\u03a3\u03bf\u03c5\u03b7\u03b4\u03b9\u03ba\u03ac -LocaleNames/el/th=\u03a4\u03b1\u03ca\u03bb\u03b1\u03bd\u03b4\u03b9\u03ba\u03ac -LocaleNames/el/tr=\u03a4\u03bf\u03c5\u03c1\u03ba\u03b9\u03ba\u03ac -LocaleNames/el/uk=\u039f\u03c5\u03ba\u03c1\u03b1\u03bd\u03b9\u03ba\u03ac -LocaleNames/el/vi=\u0392\u03b9\u03b5\u03c4\u03bd\u03b1\u03bc\u03b9\u03ba\u03ac -LocaleNames/el/yi=\u0393\u03af\u03bd\u03c4\u03b9\u03c2 -LocaleNames/el/zh=\u039a\u03b9\u03bd\u03b5\u03b6\u03b9\u03ba\u03ac -LocaleNames/el/AD=\u0391\u03bd\u03b4\u03cc\u03c1\u03b1 -LocaleNames/el/AE=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b1 \u0391\u03c1\u03b1\u03b2\u03b9\u03ba\u03ac \u0395\u03bc\u03b9\u03c1\u03ac\u03c4\u03b1 -LocaleNames/el/AF=\u0391\u03c6\u03b3\u03b1\u03bd\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/AG=\u0391\u03bd\u03c4\u03af\u03b3\u03ba\u03bf\u03c5\u03b1 \u03ba\u03b1\u03b9 \u039c\u03c0\u03b1\u03c1\u03bc\u03c0\u03bf\u03cd\u03bd\u03c4\u03b1 -LocaleNames/el/AI=\u0391\u03bd\u03b3\u03ba\u03bf\u03c5\u03af\u03bb\u03b1 -LocaleNames/el/AL=\u0391\u03bb\u03b2\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/AM=\u0391\u03c1\u03bc\u03b5\u03bd\u03af\u03b1 -LocaleNames/el/AO=\u0391\u03b3\u03ba\u03cc\u03bb\u03b1 -LocaleNames/el/AQ=\u0391\u03bd\u03c4\u03b1\u03c1\u03ba\u03c4\u03b9\u03ba\u03ae -LocaleNames/el/AR=\u0391\u03c1\u03b3\u03b5\u03bd\u03c4\u03b9\u03bd\u03ae -LocaleNames/el/AS=\u0391\u03bc\u03b5\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ae \u03a3\u03b1\u03bc\u03cc\u03b1 -LocaleNames/el/AT=\u0391\u03c5\u03c3\u03c4\u03c1\u03af\u03b1 -LocaleNames/el/AU=\u0391\u03c5\u03c3\u03c4\u03c1\u03b1\u03bb\u03af\u03b1 -LocaleNames/el/AW=\u0391\u03c1\u03bf\u03cd\u03bc\u03c0\u03b1 -LocaleNames/el/AX=\u039d\u03ae\u03c3\u03bf\u03b9 \u038c\u03bb\u03b1\u03bd\u03c4 -LocaleNames/el/AZ=\u0391\u03b6\u03b5\u03c1\u03bc\u03c0\u03b1\u03ca\u03c4\u03b6\u03ac\u03bd -LocaleNames/el/BA=\u0392\u03bf\u03c3\u03bd\u03af\u03b1 - \u0395\u03c1\u03b6\u03b5\u03b3\u03bf\u03b2\u03af\u03bd\u03b7 -LocaleNames/el/BB=\u039c\u03c0\u03b1\u03c1\u03bc\u03c0\u03ad\u03b9\u03bd\u03c4\u03bf\u03c2 -LocaleNames/el/BD=\u039c\u03c0\u03b1\u03bd\u03b3\u03ba\u03bb\u03b1\u03bd\u03c4\u03ad\u03c2 -LocaleNames/el/BE=\u0392\u03ad\u03bb\u03b3\u03b9\u03bf -LocaleNames/el/BF=\u039c\u03c0\u03bf\u03c5\u03c1\u03ba\u03af\u03bd\u03b1 \u03a6\u03ac\u03c3\u03bf -LocaleNames/el/BG=\u0392\u03bf\u03c5\u03bb\u03b3\u03b1\u03c1\u03af\u03b1 -LocaleNames/el/BH=\u039c\u03c0\u03b1\u03c7\u03c1\u03ad\u03b9\u03bd -LocaleNames/el/BI=\u039c\u03c0\u03bf\u03c5\u03c1\u03bf\u03cd\u03bd\u03c4\u03b9 -LocaleNames/el/BJ=\u039c\u03c0\u03b5\u03bd\u03af\u03bd -LocaleNames/el/BM=\u0392\u03b5\u03c1\u03bc\u03bf\u03cd\u03b4\u03b5\u03c2 -LocaleNames/el/BN=\u039c\u03c0\u03c1\u03bf\u03c5\u03bd\u03ad\u03b9 -LocaleNames/el/BO=\u0392\u03bf\u03bb\u03b9\u03b2\u03af\u03b1 -LocaleNames/el/BR=\u0392\u03c1\u03b1\u03b6\u03b9\u03bb\u03af\u03b1 -LocaleNames/el/BS=\u039c\u03c0\u03b1\u03c7\u03ac\u03bc\u03b5\u03c2 -LocaleNames/el/BT=\u039c\u03c0\u03bf\u03c5\u03c4\u03ac\u03bd -LocaleNames/el/BV=\u039d\u03ae\u03c3\u03bf\u03c2 \u039c\u03c0\u03bf\u03c5\u03b2\u03ad -LocaleNames/el/BW=\u039c\u03c0\u03bf\u03c4\u03c3\u03bf\u03c5\u03ac\u03bd\u03b1 -LocaleNames/el/BY=\u039b\u03b5\u03c5\u03ba\u03bf\u03c1\u03c9\u03c3\u03af\u03b1 -LocaleNames/el/BZ=\u039c\u03c0\u03b5\u03bb\u03af\u03b6 -LocaleNames/el/CA=\u039a\u03b1\u03bd\u03b1\u03b4\u03ac\u03c2 -LocaleNames/el/CC=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03cc\u03ba\u03bf\u03c2 (\u039a\u03af\u03bb\u03b9\u03bd\u03b3\u03ba) -LocaleNames/el/CD=\u039a\u03bf\u03bd\u03b3\u03ba\u03cc - \u039a\u03b9\u03bd\u03c3\u03ac\u03c3\u03b1 -LocaleNames/el/CF=\u039a\u03b5\u03bd\u03c4\u03c1\u03bf\u03b1\u03c6\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ae \u0394\u03b7\u03bc\u03bf\u03ba\u03c1\u03b1\u03c4\u03af\u03b1 -LocaleNames/el/CG=\u039a\u03bf\u03bd\u03b3\u03ba\u03cc - \u039c\u03c0\u03c1\u03b1\u03b6\u03b1\u03b2\u03af\u03bb -LocaleNames/el/CH=\u0395\u03bb\u03b2\u03b5\u03c4\u03af\u03b1 -LocaleNames/el/CI=\u0391\u03ba\u03c4\u03ae \u0395\u03bb\u03b5\u03c6\u03b1\u03bd\u03c4\u03bf\u03c3\u03c4\u03bf\u03cd -LocaleNames/el/CK=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03bf\u03c5\u03ba -LocaleNames/el/CL=\u03a7\u03b9\u03bb\u03ae -LocaleNames/el/CM=\u039a\u03b1\u03bc\u03b5\u03c1\u03bf\u03cd\u03bd -LocaleNames/el/CN=\u039a\u03af\u03bd\u03b1 -LocaleNames/el/CO=\u039a\u03bf\u03bb\u03bf\u03bc\u03b2\u03af\u03b1 -LocaleNames/el/CR=\u039a\u03cc\u03c3\u03c4\u03b1 \u03a1\u03af\u03ba\u03b1 -LocaleNames/el/CU=\u039a\u03bf\u03cd\u03b2\u03b1 -LocaleNames/el/CV=\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf \u0391\u03ba\u03c1\u03c9\u03c4\u03ae\u03c1\u03b9\u03bf -LocaleNames/el/CX=\u039d\u03ae\u03c3\u03bf\u03c2 \u03c4\u03c9\u03bd \u03a7\u03c1\u03b9\u03c3\u03c4\u03bf\u03c5\u03b3\u03ad\u03bd\u03bd\u03c9\u03bd -LocaleNames/el/CY=\u039a\u03cd\u03c0\u03c1\u03bf\u03c2 -LocaleNames/el/CZ=\u03a4\u03c3\u03b5\u03c7\u03af\u03b1 -LocaleNames/el/DE=\u0393\u03b5\u03c1\u03bc\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/DJ=\u03a4\u03b6\u03b9\u03bc\u03c0\u03bf\u03c5\u03c4\u03af -LocaleNames/el/DK=\u0394\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/DM=\u039d\u03c4\u03bf\u03bc\u03af\u03bd\u03b9\u03ba\u03b1 -LocaleNames/el/DO=\u0394\u03bf\u03bc\u03b9\u03bd\u03b9\u03ba\u03b1\u03bd\u03ae \u0394\u03b7\u03bc\u03bf\u03ba\u03c1\u03b1\u03c4\u03af\u03b1 -LocaleNames/el/DZ=\u0391\u03bb\u03b3\u03b5\u03c1\u03af\u03b1 -LocaleNames/el/EC=\u0399\u03c3\u03b7\u03bc\u03b5\u03c1\u03b9\u03bd\u03cc\u03c2 -LocaleNames/el/EE=\u0395\u03c3\u03b8\u03bf\u03bd\u03af\u03b1 -LocaleNames/el/EG=\u0391\u03af\u03b3\u03c5\u03c0\u03c4\u03bf\u03c2 -LocaleNames/el/EH=\u0394\u03c5\u03c4\u03b9\u03ba\u03ae \u03a3\u03b1\u03c7\u03ac\u03c1\u03b1 -LocaleNames/el/ER=\u0395\u03c1\u03c5\u03b8\u03c1\u03b1\u03af\u03b1 -LocaleNames/el/ES=\u0399\u03c3\u03c0\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/ET=\u0391\u03b9\u03b8\u03b9\u03bf\u03c0\u03af\u03b1 -LocaleNames/el/FI=\u03a6\u03b9\u03bd\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/FJ=\u03a6\u03af\u03c4\u03b6\u03b9 -LocaleNames/el/FK=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a6\u03cc\u03ba\u03bb\u03b1\u03bd\u03c4 -LocaleNames/el/FM=\u039c\u03b9\u03ba\u03c1\u03bf\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el/FO=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a6\u03b5\u03c1\u03cc\u03b5\u03c2 -LocaleNames/el/FR=\u0393\u03b1\u03bb\u03bb\u03af\u03b1 -LocaleNames/el/GA=\u0393\u03ba\u03b1\u03bc\u03c0\u03cc\u03bd -LocaleNames/el/GB=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03bf \u0392\u03b1\u03c3\u03af\u03bb\u03b5\u03b9\u03bf -LocaleNames/el/GD=\u0393\u03c1\u03b5\u03bd\u03ac\u03b4\u03b1 -LocaleNames/el/GE=\u0393\u03b5\u03c9\u03c1\u03b3\u03af\u03b1 -LocaleNames/el/GF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ae \u0393\u03bf\u03c5\u03b9\u03ac\u03bd\u03b1 -LocaleNames/el/GH=\u0393\u03ba\u03ac\u03bd\u03b1 -LocaleNames/el/GI=\u0393\u03b9\u03b2\u03c1\u03b1\u03bb\u03c4\u03ac\u03c1 -LocaleNames/el/GL=\u0393\u03c1\u03bf\u03b9\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/GM=\u0393\u03ba\u03ac\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el/GN=\u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el/GP=\u0393\u03bf\u03c5\u03b1\u03b4\u03b5\u03bb\u03bf\u03cd\u03c0\u03b7 -LocaleNames/el/GQ=\u0399\u03c3\u03b7\u03bc\u03b5\u03c1\u03b9\u03bd\u03ae \u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el/GS=\u039d\u03ae\u03c3\u03bf\u03b9 \u039d\u03cc\u03c4\u03b9\u03b1 \u0393\u03b5\u03c9\u03c1\u03b3\u03af\u03b1 \u03ba\u03b1\u03b9 \u039d\u03cc\u03c4\u03b9\u03b5\u03c2 \u03a3\u03ac\u03bd\u03c4\u03bf\u03c5\u03b9\u03c4\u03c2 -LocaleNames/el/GT=\u0393\u03bf\u03c5\u03b1\u03c4\u03b5\u03bc\u03ac\u03bb\u03b1 -LocaleNames/el/GU=\u0393\u03ba\u03bf\u03c5\u03ac\u03bc -LocaleNames/el/GW=\u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 \u039c\u03c0\u03b9\u03c3\u03ac\u03bf\u03c5 -LocaleNames/el/GY=\u0393\u03bf\u03c5\u03b9\u03ac\u03bd\u03b1 -LocaleNames/el/HK=\u03a7\u03bf\u03bd\u03b3\u03ba \u039a\u03bf\u03bd\u03b3\u03ba \u0395\u0394\u03a0 \u039a\u03af\u03bd\u03b1\u03c2 -LocaleNames/el/HM=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a7\u03b5\u03c1\u03bd\u03c4 \u03ba\u03b1\u03b9 \u039c\u03b1\u03ba\u03bd\u03c4\u03cc\u03bd\u03b1\u03bb\u03bd\u03c4 -LocaleNames/el/HN=\u039f\u03bd\u03b4\u03bf\u03cd\u03c1\u03b1 -LocaleNames/el/HR=\u039a\u03c1\u03bf\u03b1\u03c4\u03af\u03b1 -LocaleNames/el/HT=\u0391\u03ca\u03c4\u03ae -LocaleNames/el/HU=\u039f\u03c5\u03b3\u03b3\u03b1\u03c1\u03af\u03b1 -LocaleNames/el/ID=\u0399\u03bd\u03b4\u03bf\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el/IE=\u0399\u03c1\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/IL=\u0399\u03c3\u03c1\u03b1\u03ae\u03bb -LocaleNames/el/IN=\u0399\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/IO=\u0392\u03c1\u03b5\u03c4\u03b1\u03bd\u03b9\u03ba\u03ac \u0395\u03b4\u03ac\u03c6\u03b7 \u0399\u03bd\u03b4\u03b9\u03ba\u03bf\u03cd \u03a9\u03ba\u03b5\u03b1\u03bd\u03bf\u03cd -LocaleNames/el/IQ=\u0399\u03c1\u03ac\u03ba -LocaleNames/el/IR=\u0399\u03c1\u03ac\u03bd -LocaleNames/el/IS=\u0399\u03c3\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/IT=\u0399\u03c4\u03b1\u03bb\u03af\u03b1 -LocaleNames/el/JM=\u03a4\u03b6\u03b1\u03bc\u03ac\u03b9\u03ba\u03b1 -LocaleNames/el/JO=\u0399\u03bf\u03c1\u03b4\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/JP=\u0399\u03b1\u03c0\u03c9\u03bd\u03af\u03b1 -LocaleNames/el/KE=\u039a\u03ad\u03bd\u03c5\u03b1 -LocaleNames/el/KG=\u039a\u03b9\u03c1\u03b3\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/KH=\u039a\u03b1\u03bc\u03c0\u03cc\u03c4\u03b6\u03b7 -LocaleNames/el/KI=\u039a\u03b9\u03c1\u03b9\u03bc\u03c0\u03ac\u03c4\u03b9 -LocaleNames/el/KM=\u039a\u03bf\u03bc\u03cc\u03c1\u03b5\u03c2 -LocaleNames/el/KN=\u03a3\u03b5\u03bd \u039a\u03b9\u03c4\u03c2 \u03ba\u03b1\u03b9 \u039d\u03ad\u03b2\u03b9\u03c2 -LocaleNames/el/KP=\u0392\u03cc\u03c1\u03b5\u03b9\u03b1 \u039a\u03bf\u03c1\u03ad\u03b1 -LocaleNames/el/KR=\u039d\u03cc\u03c4\u03b9\u03b1 \u039a\u03bf\u03c1\u03ad\u03b1 -LocaleNames/el/KW=\u039a\u03bf\u03c5\u03b2\u03ad\u03b9\u03c4 -LocaleNames/el/KY=\u039d\u03ae\u03c3\u03bf\u03b9 \u039a\u03ad\u03b9\u03bc\u03b1\u03bd -LocaleNames/el/KZ=\u039a\u03b1\u03b6\u03b1\u03ba\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/LA=\u039b\u03ac\u03bf\u03c2 -LocaleNames/el/LB=\u039b\u03af\u03b2\u03b1\u03bd\u03bf\u03c2 -LocaleNames/el/LC=\u0391\u03b3\u03af\u03b1 \u039b\u03bf\u03c5\u03ba\u03af\u03b1 -LocaleNames/el/LI=\u039b\u03b9\u03c7\u03c4\u03b5\u03bd\u03c3\u03c4\u03ac\u03b9\u03bd -LocaleNames/el/LK=\u03a3\u03c1\u03b9 \u039b\u03ac\u03bd\u03ba\u03b1 -LocaleNames/el/LR=\u039b\u03b9\u03b2\u03b5\u03c1\u03af\u03b1 -LocaleNames/el/LS=\u039b\u03b5\u03c3\u03cc\u03c4\u03bf -LocaleNames/el/LT=\u039b\u03b9\u03b8\u03bf\u03c5\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/LU=\u039b\u03bf\u03c5\u03be\u03b5\u03bc\u03b2\u03bf\u03cd\u03c1\u03b3\u03bf -LocaleNames/el/LV=\u039b\u03b5\u03c4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el/LY=\u039b\u03b9\u03b2\u03cd\u03b7 -LocaleNames/el/MA=\u039c\u03b1\u03c1\u03cc\u03ba\u03bf -LocaleNames/el/MC=\u039c\u03bf\u03bd\u03b1\u03ba\u03cc -LocaleNames/el/MD=\u039c\u03bf\u03bb\u03b4\u03b1\u03b2\u03af\u03b1 -LocaleNames/el/MG=\u039c\u03b1\u03b4\u03b1\u03b3\u03b1\u03c3\u03ba\u03ac\u03c1\u03b7 -LocaleNames/el/MH=\u039d\u03ae\u03c3\u03bf\u03b9 \u039c\u03ac\u03c1\u03c3\u03b1\u03bb -LocaleNames/el/MK=\u0392\u03cc\u03c1\u03b5\u03b9\u03b1 \u039c\u03b1\u03ba\u03b5\u03b4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el/ML=\u039c\u03ac\u03bb\u03b9 -LocaleNames/el/MM=\u039c\u03b9\u03b1\u03bd\u03bc\u03ac\u03c1 (\u0392\u03b9\u03c1\u03bc\u03b1\u03bd\u03af\u03b1) -LocaleNames/el/MN=\u039c\u03bf\u03b3\u03b3\u03bf\u03bb\u03af\u03b1 -LocaleNames/el/MO=\u039c\u03b1\u03ba\u03ac\u03bf \u0395\u0394\u03a0 \u039a\u03af\u03bd\u03b1\u03c2 -LocaleNames/el/MP=\u039d\u03ae\u03c3\u03bf\u03b9 \u0392\u03cc\u03c1\u03b5\u03b9\u03b5\u03c2 \u039c\u03b1\u03c1\u03b9\u03ac\u03bd\u03b5\u03c2 -LocaleNames/el/MQ=\u039c\u03b1\u03c1\u03c4\u03b9\u03bd\u03af\u03ba\u03b1 -LocaleNames/el/MR=\u039c\u03b1\u03c5\u03c1\u03b9\u03c4\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/MS=\u039c\u03bf\u03bd\u03c3\u03b5\u03c1\u03ac\u03c4 -LocaleNames/el/MT=\u039c\u03ac\u03bb\u03c4\u03b1 -LocaleNames/el/MU=\u039c\u03b1\u03c5\u03c1\u03af\u03ba\u03b9\u03bf\u03c2 -LocaleNames/el/MV=\u039c\u03b1\u03bb\u03b4\u03af\u03b2\u03b5\u03c2 -LocaleNames/el/MW=\u039c\u03b1\u03bb\u03ac\u03bf\u03c5\u03b9 -LocaleNames/el/MX=\u039c\u03b5\u03be\u03b9\u03ba\u03cc -LocaleNames/el/MY=\u039c\u03b1\u03bb\u03b1\u03b9\u03c3\u03af\u03b1 -LocaleNames/el/MZ=\u039c\u03bf\u03b6\u03b1\u03bc\u03b2\u03af\u03ba\u03b7 -LocaleNames/el/NA=\u039d\u03b1\u03bc\u03af\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el/NC=\u039d\u03ad\u03b1 \u039a\u03b1\u03bb\u03b7\u03b4\u03bf\u03bd\u03af\u03b1 -LocaleNames/el/NE=\u039d\u03af\u03b3\u03b7\u03c1\u03b1\u03c2 -LocaleNames/el/NF=\u039d\u03ae\u03c3\u03bf\u03c2 \u039d\u03cc\u03c1\u03c6\u03bf\u03bb\u03ba -LocaleNames/el/NG=\u039d\u03b9\u03b3\u03b7\u03c1\u03af\u03b1 -LocaleNames/el/NI=\u039d\u03b9\u03ba\u03b1\u03c1\u03ac\u03b3\u03bf\u03c5\u03b1 -LocaleNames/el/NL=\u039a\u03ac\u03c4\u03c9 \u03a7\u03ce\u03c1\u03b5\u03c2 -LocaleNames/el/NO=\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03af\u03b1 -LocaleNames/el/NP=\u039d\u03b5\u03c0\u03ac\u03bb -LocaleNames/el/NR=\u039d\u03b1\u03bf\u03c5\u03c1\u03bf\u03cd -LocaleNames/el/NU=\u039d\u03b9\u03bf\u03cd\u03b5 -LocaleNames/el/NZ=\u039d\u03ad\u03b1 \u0396\u03b7\u03bb\u03b1\u03bd\u03b4\u03af\u03b1 -LocaleNames/el/OM=\u039f\u03bc\u03ac\u03bd -LocaleNames/el/PA=\u03a0\u03b1\u03bd\u03b1\u03bc\u03ac\u03c2 -LocaleNames/el/PE=\u03a0\u03b5\u03c1\u03bf\u03cd -LocaleNames/el/PF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ae \u03a0\u03bf\u03bb\u03c5\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el/PG=\u03a0\u03b1\u03c0\u03bf\u03cd\u03b1 \u039d\u03ad\u03b1 \u0393\u03bf\u03c5\u03b9\u03bd\u03ad\u03b1 -LocaleNames/el/PH=\u03a6\u03b9\u03bb\u03b9\u03c0\u03c0\u03af\u03bd\u03b5\u03c2 -LocaleNames/el/PK=\u03a0\u03b1\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/PL=\u03a0\u03bf\u03bb\u03c9\u03bd\u03af\u03b1 -LocaleNames/el/PM=\u03a3\u03b5\u03bd \u03a0\u03b9\u03b5\u03c1 \u03ba\u03b1\u03b9 \u039c\u03b9\u03ba\u03b5\u03bb\u03cc\u03bd -LocaleNames/el/PN=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a0\u03af\u03c4\u03ba\u03b5\u03c1\u03bd -LocaleNames/el/PR=\u03a0\u03bf\u03c5\u03ad\u03c1\u03c4\u03bf \u03a1\u03af\u03ba\u03bf -LocaleNames/el/PS=\u03a0\u03b1\u03bb\u03b1\u03b9\u03c3\u03c4\u03b9\u03bd\u03b9\u03b1\u03ba\u03ac \u0395\u03b4\u03ac\u03c6\u03b7 -LocaleNames/el/PT=\u03a0\u03bf\u03c1\u03c4\u03bf\u03b3\u03b1\u03bb\u03af\u03b1 -LocaleNames/el/PW=\u03a0\u03b1\u03bb\u03ac\u03bf\u03c5 -LocaleNames/el/PY=\u03a0\u03b1\u03c1\u03b1\u03b3\u03bf\u03c5\u03ac\u03b7 -LocaleNames/el/QA=\u039a\u03b1\u03c4\u03ac\u03c1 -LocaleNames/el/RE=\u03a1\u03b5\u03ca\u03bd\u03b9\u03cc\u03bd -LocaleNames/el/RO=\u03a1\u03bf\u03c5\u03bc\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/RU=\u03a1\u03c9\u03c3\u03af\u03b1 -LocaleNames/el/RW=\u03a1\u03bf\u03c5\u03ac\u03bd\u03c4\u03b1 -LocaleNames/el/SA=\u03a3\u03b1\u03bf\u03c5\u03b4\u03b9\u03ba\u03ae \u0391\u03c1\u03b1\u03b2\u03af\u03b1 -LocaleNames/el/SB=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a3\u03bf\u03bb\u03bf\u03bc\u03ce\u03bd\u03c4\u03bf\u03c2 -LocaleNames/el/SC=\u03a3\u03b5\u03cb\u03c7\u03ad\u03bb\u03bb\u03b5\u03c2 -LocaleNames/el/SD=\u03a3\u03bf\u03c5\u03b4\u03ac\u03bd -LocaleNames/el/SE=\u03a3\u03bf\u03c5\u03b7\u03b4\u03af\u03b1 -LocaleNames/el/SG=\u03a3\u03b9\u03b3\u03ba\u03b1\u03c0\u03bf\u03cd\u03c1\u03b7 -LocaleNames/el/SH=\u0391\u03b3\u03af\u03b1 \u0395\u03bb\u03ad\u03bd\u03b7 -LocaleNames/el/SI=\u03a3\u03bb\u03bf\u03b2\u03b5\u03bd\u03af\u03b1 -LocaleNames/el/SJ=\u03a3\u03b2\u03ac\u03bb\u03bc\u03c0\u03b1\u03c1\u03bd\u03c4 \u03ba\u03b1\u03b9 \u0393\u03b9\u03b1\u03bd \u039c\u03b1\u03b3\u03b9\u03ad\u03bd -LocaleNames/el/SK=\u03a3\u03bb\u03bf\u03b2\u03b1\u03ba\u03af\u03b1 -LocaleNames/el/SL=\u03a3\u03b9\u03ad\u03c1\u03b1 \u039b\u03b5\u03cc\u03bd\u03b5 -LocaleNames/el/SM=\u0386\u03b3\u03b9\u03bf\u03c2 \u039c\u03b1\u03c1\u03af\u03bd\u03bf\u03c2 -LocaleNames/el/SN=\u03a3\u03b5\u03bd\u03b5\u03b3\u03ac\u03bb\u03b7 -LocaleNames/el/SO=\u03a3\u03bf\u03bc\u03b1\u03bb\u03af\u03b1 -LocaleNames/el/SR=\u03a3\u03bf\u03c5\u03c1\u03b9\u03bd\u03ac\u03bc -LocaleNames/el/ST=\u03a3\u03ac\u03bf \u03a4\u03bf\u03bc\u03ad \u03ba\u03b1\u03b9 \u03a0\u03c1\u03af\u03bd\u03c3\u03b9\u03c0\u03b5 -LocaleNames/el/SV=\u0395\u03bb \u03a3\u03b1\u03bb\u03b2\u03b1\u03b4\u03cc\u03c1 -LocaleNames/el/SY=\u03a3\u03c5\u03c1\u03af\u03b1 -LocaleNames/el/SZ=\u0395\u03c3\u03bf\u03c5\u03b1\u03c4\u03af\u03bd\u03b9 -LocaleNames/el/TC=\u039d\u03ae\u03c3\u03bf\u03b9 \u03a4\u03b5\u03c1\u03ba\u03c2 \u03ba\u03b1\u03b9 \u039a\u03ac\u03b9\u03ba\u03bf\u03c2 -LocaleNames/el/TD=\u03a4\u03c3\u03b1\u03bd\u03c4 -LocaleNames/el/TF=\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac \u039d\u03cc\u03c4\u03b9\u03b1 \u0395\u03b4\u03ac\u03c6\u03b7 -LocaleNames/el/TG=\u03a4\u03cc\u03b3\u03ba\u03bf -LocaleNames/el/TH=\u03a4\u03b1\u03ca\u03bb\u03ac\u03bd\u03b4\u03b7 -LocaleNames/el/TJ=\u03a4\u03b1\u03c4\u03b6\u03b9\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/TK=\u03a4\u03bf\u03ba\u03b5\u03bb\u03ac\u03bf\u03c5 -LocaleNames/el/TL=\u03a4\u03b9\u03bc\u03cc\u03c1-\u039b\u03ad\u03c3\u03c4\u03b5 -LocaleNames/el/TM=\u03a4\u03bf\u03c5\u03c1\u03ba\u03bc\u03b5\u03bd\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/TN=\u03a4\u03c5\u03bd\u03b7\u03c3\u03af\u03b1 -LocaleNames/el/TO=\u03a4\u03cc\u03bd\u03b3\u03ba\u03b1 -LocaleNames/el/TR=\u03a4\u03bf\u03c5\u03c1\u03ba\u03af\u03b1 -LocaleNames/el/TT=\u03a4\u03c1\u03b9\u03bd\u03b9\u03bd\u03c4\u03ac\u03bd\u03c4 \u03ba\u03b1\u03b9 \u03a4\u03bf\u03bc\u03c0\u03ac\u03b3\u03ba\u03bf -LocaleNames/el/TV=\u03a4\u03bf\u03c5\u03b2\u03b1\u03bb\u03bf\u03cd -LocaleNames/el/TW=\u03a4\u03b1\u03ca\u03b2\u03ac\u03bd -LocaleNames/el/TZ=\u03a4\u03b1\u03bd\u03b6\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/UA=\u039f\u03c5\u03ba\u03c1\u03b1\u03bd\u03af\u03b1 -LocaleNames/el/UG=\u039f\u03c5\u03b3\u03ba\u03ac\u03bd\u03c4\u03b1 -LocaleNames/el/UM=\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03b5\u03c2 \u039d\u03b7\u03c3\u03af\u03b4\u03b5\u03c2 \u0397\u03a0\u0391 -LocaleNames/el/US=\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a0\u03bf\u03bb\u03b9\u03c4\u03b5\u03af\u03b5\u03c2 -LocaleNames/el/UY=\u039f\u03c5\u03c1\u03bf\u03c5\u03b3\u03bf\u03c5\u03ac\u03b7 -LocaleNames/el/UZ=\u039f\u03c5\u03b6\u03bc\u03c0\u03b5\u03ba\u03b9\u03c3\u03c4\u03ac\u03bd -LocaleNames/el/VA=\u0392\u03b1\u03c4\u03b9\u03ba\u03b1\u03bd\u03cc -LocaleNames/el/VC=\u0386\u03b3\u03b9\u03bf\u03c2 \u0392\u03b9\u03ba\u03ad\u03bd\u03c4\u03b9\u03bf\u03c2 \u03ba\u03b1\u03b9 \u0393\u03c1\u03b5\u03bd\u03b1\u03b4\u03af\u03bd\u03b5\u03c2 -LocaleNames/el/VE=\u0392\u03b5\u03bd\u03b5\u03b6\u03bf\u03c5\u03ad\u03bb\u03b1 -LocaleNames/el/VG=\u0392\u03c1\u03b5\u03c4\u03b1\u03bd\u03b9\u03ba\u03ad\u03c2 \u03a0\u03b1\u03c1\u03b8\u03ad\u03bd\u03b5\u03c2 \u039d\u03ae\u03c3\u03bf\u03b9 -LocaleNames/el/VI=\u0391\u03bc\u03b5\u03c1\u03b9\u03ba\u03b1\u03bd\u03b9\u03ba\u03ad\u03c2 \u03a0\u03b1\u03c1\u03b8\u03ad\u03bd\u03b5\u03c2 \u039d\u03ae\u03c3\u03bf\u03b9 -LocaleNames/el/VN=\u0392\u03b9\u03b5\u03c4\u03bd\u03ac\u03bc -LocaleNames/el/VU=\u0392\u03b1\u03bd\u03bf\u03c5\u03ac\u03c4\u03bf\u03c5 -LocaleNames/el/WF=\u0393\u03bf\u03c5\u03ac\u03bb\u03b9\u03c2 \u03ba\u03b1\u03b9 \u03a6\u03bf\u03c5\u03c4\u03bf\u03cd\u03bd\u03b1 -LocaleNames/el/WS=\u03a3\u03b1\u03bc\u03cc\u03b1 -LocaleNames/el/YE=\u03a5\u03b5\u03bc\u03ad\u03bd\u03b7 -LocaleNames/el/YT=\u039c\u03b1\u03b3\u03b9\u03cc\u03c4 -LocaleNames/el/ZA=\u039d\u03cc\u03c4\u03b9\u03b1 \u0391\u03c6\u03c1\u03b9\u03ba\u03ae -LocaleNames/el/ZM=\u0396\u03ac\u03bc\u03c0\u03b9\u03b1 -LocaleNames/el/ZW=\u0396\u03b9\u03bc\u03c0\u03ac\u03bc\u03c0\u03bf\u03c5\u03b5 +LocaleNames/el/ar=Αραβικά +LocaleNames/el/be=Λευκορωσικά +LocaleNames/el/bg=Βουλγαρικά +LocaleNames/el/bn=Βεγγαλικά +LocaleNames/el/bo=Θιβετιανά +LocaleNames/el/bs=Βοσνιακά +LocaleNames/el/ca=Καταλανικά +LocaleNames/el/co=Κορσικανικά +LocaleNames/el/cs=Τσεχικά +LocaleNames/el/cy=Ουαλικά +LocaleNames/el/da=Δανικά +LocaleNames/el/de=Γερμανικά +LocaleNames/el/el=Ελληνικά +LocaleNames/el/en=Αγγλικά +LocaleNames/el/es=Ισπανικά +LocaleNames/el/et=Εσθονικά +LocaleNames/el/eu=Βασκικά +LocaleNames/el/fa=Περσικά +LocaleNames/el/fi=Φινλανδικά +LocaleNames/el/fr=Γαλλικά +LocaleNames/el/ga=Ιρλανδικά +LocaleNames/el/gd=Σκωτικά Κελτικά +LocaleNames/el/he=Εβραϊκά +LocaleNames/el/hi=Χίντι +LocaleNames/el/hr=Κροατικά +LocaleNames/el/hu=Ουγγρικά +LocaleNames/el/hy=Αρμενικά +LocaleNames/el/id=Ινδονησιακά +LocaleNames/el/is=Ισλανδικά +LocaleNames/el/it=Ιταλικά +LocaleNames/el/ja=Ιαπωνικά +LocaleNames/el/ka=Γεωργιανά +LocaleNames/el/ko=Κορεατικά +LocaleNames/el/la=Λατινικά +LocaleNames/el/lt=Λιθουανικά +LocaleNames/el/lv=Λετονικά +LocaleNames/el/mk=Σλαβομακεδονικά +LocaleNames/el/mn=Μογγολικά +LocaleNames/el/mt=Μαλτεζικά +LocaleNames/el/no=Νορβηγικά +LocaleNames/el/pl=Πολωνικά +LocaleNames/el/pt=Πορτογαλικά +LocaleNames/el/ro=Ρουμανικά +LocaleNames/el/ru=Ρωσικά +LocaleNames/el/sk=Σλοβακικά +LocaleNames/el/sl=Σλοβενικά +LocaleNames/el/sq=Αλβανικά +LocaleNames/el/sr=Σερβικά +LocaleNames/el/sv=Σουηδικά +LocaleNames/el/th=Ταϊλανδικά +LocaleNames/el/tr=Τουρκικά +LocaleNames/el/uk=Ουκρανικά +LocaleNames/el/vi=Βιετναμικά +LocaleNames/el/yi=Γίντις +LocaleNames/el/zh=Κινεζικά +LocaleNames/el/AD=Ανδόρα +LocaleNames/el/AE=Ηνωμένα Αραβικά Εμιράτα +LocaleNames/el/AF=Αφγανιστάν +LocaleNames/el/AG=Αντίγκουα και Μπαρμπούντα +LocaleNames/el/AI=Ανγκουίλα +LocaleNames/el/AL=Αλβανία +LocaleNames/el/AM=Αρμενία +LocaleNames/el/AO=Αγκόλα +LocaleNames/el/AQ=Ανταρκτική +LocaleNames/el/AR=Αργεντινή +LocaleNames/el/AS=Αμερικανική Σαμόα +LocaleNames/el/AT=Αυστρία +LocaleNames/el/AU=Αυστραλία +LocaleNames/el/AW=Αρούμπα +LocaleNames/el/AX=Νήσοι Όλαντ +LocaleNames/el/AZ=Αζερμπαϊτζάν +LocaleNames/el/BA=Βοσνία - Ερζεγοβίνη +LocaleNames/el/BB=Μπαρμπέιντος +LocaleNames/el/BD=Μπανγκλαντές +LocaleNames/el/BE=Βέλγιο +LocaleNames/el/BF=Μπουρκίνα Φάσο +LocaleNames/el/BG=Βουλγαρία +LocaleNames/el/BH=Μπαχρέιν +LocaleNames/el/BI=Μπουρούντι +LocaleNames/el/BJ=Μπενίν +LocaleNames/el/BM=Βερμούδες +LocaleNames/el/BN=Μπρουνέι +LocaleNames/el/BO=Βολιβία +LocaleNames/el/BR=Βραζιλία +LocaleNames/el/BS=Μπαχάμες +LocaleNames/el/BT=Μπουτάν +LocaleNames/el/BV=Νήσος Μπουβέ +LocaleNames/el/BW=Μποτσουάνα +LocaleNames/el/BY=Λευκορωσία +LocaleNames/el/BZ=Μπελίζ +LocaleNames/el/CA=Καναδάς +LocaleNames/el/CC=Νήσοι Κόκος (Κίλινγκ) +LocaleNames/el/CD=Κονγκό - Κινσάσα +LocaleNames/el/CF=Κεντροαφρικανική Δημοκρατία +LocaleNames/el/CG=Κονγκό - Μπραζαβίλ +LocaleNames/el/CH=Ελβετία +LocaleNames/el/CI=Ακτή Ελεφαντοστού +LocaleNames/el/CK=Νήσοι Κουκ +LocaleNames/el/CL=Χιλή +LocaleNames/el/CM=Καμερούν +LocaleNames/el/CN=Κίνα +LocaleNames/el/CO=Κολομβία +LocaleNames/el/CR=Κόστα Ρίκα +LocaleNames/el/CU=Κούβα +LocaleNames/el/CV=Πράσινο Ακρωτήριο +LocaleNames/el/CX=Νήσος των Χριστουγέννων +LocaleNames/el/CY=Κύπρος +LocaleNames/el/CZ=Τσεχία +LocaleNames/el/DE=Γερμανία +LocaleNames/el/DJ=Τζιμπουτί +LocaleNames/el/DK=Δανία +LocaleNames/el/DM=Ντομίνικα +LocaleNames/el/DO=Δομινικανή Δημοκρατία +LocaleNames/el/DZ=Αλγερία +LocaleNames/el/EC=Ισημερινός +LocaleNames/el/EE=Εσθονία +LocaleNames/el/EG=Αίγυπτος +LocaleNames/el/EH=Δυτική Σαχάρα +LocaleNames/el/ER=Ερυθραία +LocaleNames/el/ES=Ισπανία +LocaleNames/el/ET=Αιθιοπία +LocaleNames/el/FI=Φινλανδία +LocaleNames/el/FJ=Φίτζι +LocaleNames/el/FK=Νήσοι Φόκλαντ +LocaleNames/el/FM=Μικρονησία +LocaleNames/el/FO=Νήσοι Φερόες +LocaleNames/el/FR=Γαλλία +LocaleNames/el/GA=Γκαμπόν +LocaleNames/el/GB=Ηνωμένο Βασίλειο +LocaleNames/el/GD=Γρενάδα +LocaleNames/el/GE=Γεωργία +LocaleNames/el/GF=Γαλλική Γουιάνα +LocaleNames/el/GH=Γκάνα +LocaleNames/el/GI=Γιβραλτάρ +LocaleNames/el/GL=Γροιλανδία +LocaleNames/el/GM=Γκάμπια +LocaleNames/el/GN=Γουινέα +LocaleNames/el/GP=Γουαδελούπη +LocaleNames/el/GQ=Ισημερινή Γουινέα +LocaleNames/el/GS=Νήσοι Νότια Γεωργία και Νότιες Σάντουιτς +LocaleNames/el/GT=Γουατεμάλα +LocaleNames/el/GU=Γκουάμ +LocaleNames/el/GW=Γουινέα Μπισάου +LocaleNames/el/GY=Γουιάνα +LocaleNames/el/HK=Χονγκ Κονγκ ΕΔΠ Κίνας +LocaleNames/el/HM=Νήσοι Χερντ και Μακντόναλντ +LocaleNames/el/HN=Ονδούρα +LocaleNames/el/HR=Κροατία +LocaleNames/el/HT=Αϊτή +LocaleNames/el/HU=Ουγγαρία +LocaleNames/el/ID=Ινδονησία +LocaleNames/el/IE=Ιρλανδία +LocaleNames/el/IL=Ισραήλ +LocaleNames/el/IN=Ινδία +LocaleNames/el/IO=Βρετανικά Εδάφη Ινδικού Ωκεανού +LocaleNames/el/IQ=Ιράκ +LocaleNames/el/IR=Ιράν +LocaleNames/el/IS=Ισλανδία +LocaleNames/el/IT=Ιταλία +LocaleNames/el/JM=Τζαμάικα +LocaleNames/el/JO=Ιορδανία +LocaleNames/el/JP=Ιαπωνία +LocaleNames/el/KE=Κένυα +LocaleNames/el/KG=Κιργιστάν +LocaleNames/el/KH=Καμπότζη +LocaleNames/el/KI=Κιριμπάτι +LocaleNames/el/KM=Κομόρες +LocaleNames/el/KN=Σεν Κιτς και Νέβις +LocaleNames/el/KP=Βόρεια Κορέα +LocaleNames/el/KR=Νότια Κορέα +LocaleNames/el/KW=Κουβέιτ +LocaleNames/el/KY=Νήσοι Κέιμαν +LocaleNames/el/KZ=Καζακστάν +LocaleNames/el/LA=Λάος +LocaleNames/el/LB=Λίβανος +LocaleNames/el/LC=Αγία Λουκία +LocaleNames/el/LI=Λιχτενστάιν +LocaleNames/el/LK=Σρι Λάνκα +LocaleNames/el/LR=Λιβερία +LocaleNames/el/LS=Λεσότο +LocaleNames/el/LT=Λιθουανία +LocaleNames/el/LU=Λουξεμβούργο +LocaleNames/el/LV=Λετονία +LocaleNames/el/LY=Λιβύη +LocaleNames/el/MA=Μαρόκο +LocaleNames/el/MC=Μονακό +LocaleNames/el/MD=Μολδαβία +LocaleNames/el/MG=Μαδαγασκάρη +LocaleNames/el/MH=Νήσοι Μάρσαλ +LocaleNames/el/MK=Βόρεια Μακεδονία +LocaleNames/el/ML=Μάλι +LocaleNames/el/MM=Μιανμάρ (Βιρμανία) +LocaleNames/el/MN=Μογγολία +LocaleNames/el/MO=Μακάο ΕΔΠ Κίνας +LocaleNames/el/MP=Νήσοι Βόρειες Μαριάνες +LocaleNames/el/MQ=Μαρτινίκα +LocaleNames/el/MR=Μαυριτανία +LocaleNames/el/MS=Μονσεράτ +LocaleNames/el/MT=Μάλτα +LocaleNames/el/MU=Μαυρίκιος +LocaleNames/el/MV=Μαλδίβες +LocaleNames/el/MW=Μαλάουι +LocaleNames/el/MX=Μεξικό +LocaleNames/el/MY=Μαλαισία +LocaleNames/el/MZ=Μοζαμβίκη +LocaleNames/el/NA=Ναμίμπια +LocaleNames/el/NC=Νέα Καληδονία +LocaleNames/el/NE=Νίγηρας +LocaleNames/el/NF=Νήσος Νόρφολκ +LocaleNames/el/NG=Νιγηρία +LocaleNames/el/NI=Νικαράγουα +LocaleNames/el/NL=Κάτω Χώρες +LocaleNames/el/NO=Νορβηγία +LocaleNames/el/NP=Νεπάλ +LocaleNames/el/NR=Ναουρού +LocaleNames/el/NU=Νιούε +LocaleNames/el/NZ=Νέα Ζηλανδία +LocaleNames/el/OM=Ομάν +LocaleNames/el/PA=Παναμάς +LocaleNames/el/PE=Περού +LocaleNames/el/PF=Γαλλική Πολυνησία +LocaleNames/el/PG=Παπούα Νέα Γουινέα +LocaleNames/el/PH=Φιλιππίνες +LocaleNames/el/PK=Πακιστάν +LocaleNames/el/PL=Πολωνία +LocaleNames/el/PM=Σεν Πιερ και Μικελόν +LocaleNames/el/PN=Νήσοι Πίτκερν +LocaleNames/el/PR=Πουέρτο Ρίκο +LocaleNames/el/PS=Παλαιστινιακά Εδάφη +LocaleNames/el/PT=Πορτογαλία +LocaleNames/el/PW=Παλάου +LocaleNames/el/PY=Παραγουάη +LocaleNames/el/QA=Κατάρ +LocaleNames/el/RE=Ρεϊνιόν +LocaleNames/el/RO=Ρουμανία +LocaleNames/el/RU=Ρωσία +LocaleNames/el/RW=Ρουάντα +LocaleNames/el/SA=Σαουδική Αραβία +LocaleNames/el/SB=Νήσοι Σολομώντος +LocaleNames/el/SC=Σεϋχέλλες +LocaleNames/el/SD=Σουδάν +LocaleNames/el/SE=Σουηδία +LocaleNames/el/SG=Σιγκαπούρη +LocaleNames/el/SH=Αγία Ελένη +LocaleNames/el/SI=Σλοβενία +LocaleNames/el/SJ=Σβάλμπαρντ και Γιαν Μαγιέν +LocaleNames/el/SK=Σλοβακία +LocaleNames/el/SL=Σιέρα Λεόνε +LocaleNames/el/SM=Άγιος Μαρίνος +LocaleNames/el/SN=Σενεγάλη +LocaleNames/el/SO=Σομαλία +LocaleNames/el/SR=Σουρινάμ +LocaleNames/el/ST=Σάο Τομέ και Πρίνσιπε +LocaleNames/el/SV=Ελ Σαλβαδόρ +LocaleNames/el/SY=Συρία +LocaleNames/el/SZ=Εσουατίνι +LocaleNames/el/TC=Νήσοι Τερκς και Κάικος +LocaleNames/el/TD=Τσαντ +LocaleNames/el/TF=Γαλλικά Νότια Εδάφη +LocaleNames/el/TG=Τόγκο +LocaleNames/el/TH=Ταϊλάνδη +LocaleNames/el/TJ=Τατζικιστάν +LocaleNames/el/TK=Τοκελάου +LocaleNames/el/TL=Τιμόρ-Λέστε +LocaleNames/el/TM=Τουρκμενιστάν +LocaleNames/el/TN=Τυνησία +LocaleNames/el/TO=Τόνγκα +LocaleNames/el/TR=Τουρκία +LocaleNames/el/TT=Τρινιντάντ και Τομπάγκο +LocaleNames/el/TV=Τουβαλού +LocaleNames/el/TW=Ταϊβάν +LocaleNames/el/TZ=Τανζανία +LocaleNames/el/UA=Ουκρανία +LocaleNames/el/UG=Ουγκάντα +LocaleNames/el/UM=Απομακρυσμένες Νησίδες ΗΠΑ +LocaleNames/el/US=Ηνωμένες Πολιτείες +LocaleNames/el/UY=Ουρουγουάη +LocaleNames/el/UZ=Ουζμπεκιστάν +LocaleNames/el/VA=Βατικανό +LocaleNames/el/VC=Άγιος Βικέντιος και Γρεναδίνες +LocaleNames/el/VE=Βενεζουέλα +LocaleNames/el/VG=Βρετανικές Παρθένες Νήσοι +LocaleNames/el/VI=Αμερικανικές Παρθένες Νήσοι +LocaleNames/el/VN=Βιετνάμ +LocaleNames/el/VU=Βανουάτου +LocaleNames/el/WF=Γουάλις και Φουτούνα +LocaleNames/el/WS=Σαμόα +LocaleNames/el/YE=Υεμένη +LocaleNames/el/YT=Μαγιότ +LocaleNames/el/ZA=Νότια Αφρική +LocaleNames/el/ZM=Ζάμπια +LocaleNames/el/ZW=Ζιμπάμπουε LocaleNames/en_MT/fy=Western Frisian LocaleNames/en_MT/gl=Galician LocaleNames/en_MT/ps=Pashto -LocaleNames/en_MT/AX=\u00c5land Islands +LocaleNames/en_MT/AX=Åland Islands LocaleNames/en_MT/CD=Congo - Kinshasa LocaleNames/en_MT/CG=Congo - Brazzaville LocaleNames/en_MT/HK=Hong Kong SAR China @@ -4712,7 +4712,7 @@ LocaleNames/en_MT/MO=Macao SAR China LocaleNames/en_PH/fy=Western Frisian LocaleNames/en_PH/gl=Galician LocaleNames/en_PH/ps=Pashto -LocaleNames/en_PH/AX=\u00c5land Islands +LocaleNames/en_PH/AX=Åland Islands LocaleNames/en_PH/CD=Congo - Kinshasa LocaleNames/en_PH/CG=Congo - Brazzaville LocaleNames/en_PH/HK=Hong Kong SAR China @@ -4721,7 +4721,7 @@ LocaleNames/en_PH/MO=Macao SAR China LocaleNames/en_SG/fy=Western Frisian LocaleNames/en_SG/gl=Galician LocaleNames/en_SG/ps=Pashto -LocaleNames/en_SG/AX=\u00c5land Islands +LocaleNames/en_SG/AX=Åland Islands LocaleNames/en_SG/CD=Congo - Kinshasa LocaleNames/en_SG/CG=Congo - Brazzaville LocaleNames/en_SG/HK=Hong Kong SAR China @@ -4729,53 +4729,53 @@ LocaleNames/en_SG/MO=Macao SAR China LocaleNames/es_US/ab=abjasio LocaleNames/es_US/dz=dzongkha LocaleNames/es_US/fj=fiyiano -LocaleNames/es_US/si=cingal\u00e9s -LocaleNames/es_US/ti=tigri\u00f1a -LocaleNames/es_US/vo=volap\u00fck -LocaleNames/es_US/AX=Islas \u00c5land -LocaleNames/es_US/BH=Bar\u00e9in -LocaleNames/es_US/KG=Kirguist\u00e1n -LocaleNames/mt/ab=Abka\u017cjan +LocaleNames/es_US/si=cingalés +LocaleNames/es_US/ti=tigriña +LocaleNames/es_US/vo=volapük +LocaleNames/es_US/AX=Islas Åland +LocaleNames/es_US/BH=Baréin +LocaleNames/es_US/KG=Kirguistán +LocaleNames/mt/ab=Abkażjan LocaleNames/mt/af=Afrikans LocaleNames/mt/am=Amhariku -LocaleNames/mt/ar=G\u0127arbi +LocaleNames/mt/ar=Għarbi LocaleNames/mt/av=Avarik LocaleNames/mt/ay=Aymara -LocaleNames/mt/az=A\u017cerbaj\u0121ani +LocaleNames/mt/az=Ażerbajġani LocaleNames/mt/ba=Bashkir LocaleNames/mt/be=Belarussu LocaleNames/mt/bg=Bulgaru LocaleNames/mt/bo=Tibetjan LocaleNames/mt/br=Breton -LocaleNames/mt/bs=Bo\u017cnijaku +LocaleNames/mt/bs=Bożnijaku LocaleNames/mt/ca=Katalan LocaleNames/mt/ce=Chechen LocaleNames/mt/ch=Chamorro LocaleNames/mt/co=Korsiku LocaleNames/mt/cr=Cree -LocaleNames/mt/cs=\u010aek +LocaleNames/mt/cs=Ċek LocaleNames/mt/cu=Slaviku tal-Knisja LocaleNames/mt/cv=Chuvash LocaleNames/mt/cy=Welsh -LocaleNames/mt/da=Dani\u017c -LocaleNames/mt/de=\u0120ermani\u017c +LocaleNames/mt/da=Daniż +LocaleNames/mt/de=Ġermaniż LocaleNames/mt/dv=Divehi LocaleNames/mt/dz=Dzongkha LocaleNames/mt/el=Grieg -LocaleNames/mt/en=Ingli\u017c +LocaleNames/mt/en=Ingliż LocaleNames/mt/es=Spanjol LocaleNames/mt/et=Estonjan LocaleNames/mt/eu=Bask LocaleNames/mt/fa=Persjan LocaleNames/mt/ff=Fulah -LocaleNames/mt/fi=Finlandi\u017c -LocaleNames/mt/fj=Fi\u0121jan +LocaleNames/mt/fi=Finlandiż +LocaleNames/mt/fj=Fiġjan LocaleNames/mt/fo=Faroese -LocaleNames/mt/fr=Fran\u010bi\u017c +LocaleNames/mt/fr=Franċiż LocaleNames/mt/fy=Frisian tal-Punent -LocaleNames/mt/ga=Irlandi\u017c -LocaleNames/mt/gd=Galliku Sko\u010b\u010bi\u017c -LocaleNames/mt/gl=Gali\u010bjan +LocaleNames/mt/ga=Irlandiż +LocaleNames/mt/gd=Galliku Skoċċiż +LocaleNames/mt/gl=Galiċjan LocaleNames/mt/gn=Guarani LocaleNames/mt/gu=Gujarati LocaleNames/mt/gv=Manx @@ -4784,59 +4784,59 @@ LocaleNames/mt/he=Ebrajk LocaleNames/mt/hi=Hindi LocaleNames/mt/ho=Hiri Motu LocaleNames/mt/hr=Kroat -LocaleNames/mt/hu=Ungeri\u017c +LocaleNames/mt/hu=Ungeriż LocaleNames/mt/hy=Armen LocaleNames/mt/hz=Herero -LocaleNames/mt/id=Indone\u017cjan +LocaleNames/mt/id=Indoneżjan LocaleNames/mt/ik=Inupjak -LocaleNames/mt/is=I\u017clandi\u017c +LocaleNames/mt/is=Iżlandiż LocaleNames/mt/it=Taljan LocaleNames/mt/iu=Inuktitut -LocaleNames/mt/ja=\u0120appuni\u017c -LocaleNames/mt/jv=\u0120avani\u017c -LocaleNames/mt/ka=\u0120or\u0121jan +LocaleNames/mt/ja=Ġappuniż +LocaleNames/mt/jv=Ġavaniż +LocaleNames/mt/ka=Ġorġjan LocaleNames/mt/ki=Kikuju LocaleNames/mt/kj=Kuanyama -LocaleNames/mt/kk=Ka\u017cak +LocaleNames/mt/kk=Każak LocaleNames/mt/kl=Kalallisut LocaleNames/mt/km=Khmer LocaleNames/mt/ko=Korean LocaleNames/mt/ks=Kashmiri LocaleNames/mt/ku=Kurd LocaleNames/mt/kw=Korniku -LocaleNames/mt/ky=Kirgi\u017c -LocaleNames/mt/lb=Lussemburgi\u017c +LocaleNames/mt/ky=Kirgiż +LocaleNames/mt/lb=Lussemburgiż LocaleNames/mt/ln=Lingaljan LocaleNames/mt/lt=Litwan LocaleNames/mt/lv=Latvjan LocaleNames/mt/mg=Malagasy -LocaleNames/mt/mh=Marshalljani\u017c -LocaleNames/mt/mk=Ma\u010bedonjan +LocaleNames/mt/mh=Marshalljaniż +LocaleNames/mt/mk=Maċedonjan LocaleNames/mt/ml=Malayalam LocaleNames/mt/mn=Mongoljan LocaleNames/mt/mr=Marathi LocaleNames/mt/ms=Malay LocaleNames/mt/mt=Malti -LocaleNames/mt/my=Burmi\u017c +LocaleNames/mt/my=Burmiż LocaleNames/mt/na=Naurujan -LocaleNames/mt/nb=Bokmal Norve\u0121i\u017c +LocaleNames/mt/nb=Bokmal Norveġiż LocaleNames/mt/nd=Ndebeli tat-Tramuntana -LocaleNames/mt/ne=Nepali\u017c -LocaleNames/mt/nl=Olandi\u017c -LocaleNames/mt/nn=Ninorsk Norve\u0121i\u017c -LocaleNames/mt/no=Norve\u0121i\u017c +LocaleNames/mt/ne=Nepaliż +LocaleNames/mt/nl=Olandiż +LocaleNames/mt/nn=Ninorsk Norveġiż +LocaleNames/mt/no=Norveġiż LocaleNames/mt/nr=Ndebele tan-Nofsinhar LocaleNames/mt/nv=Navajo LocaleNames/mt/ny=Nyanja -LocaleNames/mt/oc=O\u010b\u010bitan -LocaleNames/mt/oj=O\u0121ibwa +LocaleNames/mt/oc=Oċċitan +LocaleNames/mt/oj=Oġibwa LocaleNames/mt/om=Oromo LocaleNames/mt/or=Odia LocaleNames/mt/os=Ossettiku LocaleNames/mt/pa=Punjabi LocaleNames/mt/pl=Pollakk LocaleNames/mt/ps=Pashto -LocaleNames/mt/pt=Portugi\u017c +LocaleNames/mt/pt=Portugiż LocaleNames/mt/qu=Quechua LocaleNames/mt/rm=Romanz LocaleNames/mt/ro=Rumen @@ -4850,127 +4850,127 @@ LocaleNames/mt/sk=Slovakk LocaleNames/mt/sl=Sloven LocaleNames/mt/sm=Samoan LocaleNames/mt/sn=Shona -LocaleNames/mt/sq=Albani\u017c +LocaleNames/mt/sq=Albaniż LocaleNames/mt/sr=Serb LocaleNames/mt/st=Soto tan-Nofsinhar -LocaleNames/mt/su=Sundani\u017c -LocaleNames/mt/sv=\u017bvedi\u017c +LocaleNames/mt/su=Sundaniż +LocaleNames/mt/sv=Żvediż LocaleNames/mt/sw=Swahili -LocaleNames/mt/tg=Ta\u0121ik -LocaleNames/mt/th=Tajlandi\u017c +LocaleNames/mt/tg=Taġik +LocaleNames/mt/th=Tajlandiż LocaleNames/mt/ti=Tigrinya LocaleNames/mt/tk=Turkmeni LocaleNames/mt/tn=Tswana LocaleNames/mt/to=Tongan LocaleNames/mt/tr=Tork -LocaleNames/mt/ty=Ta\u0127itjan +LocaleNames/mt/ty=Taħitjan LocaleNames/mt/ug=Uyghur LocaleNames/mt/uk=Ukren LocaleNames/mt/uz=Uzbek -LocaleNames/mt/vi=Vjetnami\u017c +LocaleNames/mt/vi=Vjetnamiż LocaleNames/mt/vo=Volapuk LocaleNames/mt/xh=Xhosa LocaleNames/mt/yi=Yiddish LocaleNames/mt/yo=Yoruba LocaleNames/mt/za=Zhuang -LocaleNames/mt/zh=\u010aini\u017c +LocaleNames/mt/zh=Ċiniż LocaleNames/mt/zu=Zulu -LocaleNames/mt/AE=l-Emirati G\u0127arab Mag\u0127quda +LocaleNames/mt/AE=l-Emirati Għarab Magħquda LocaleNames/mt/AF=l-Afganistan LocaleNames/mt/AI=Anguilla LocaleNames/mt/AL=l-Albanija LocaleNames/mt/AM=l-Armenja LocaleNames/mt/AQ=l-Antartika -LocaleNames/mt/AR=l-Ar\u0121entina +LocaleNames/mt/AR=l-Arġentina LocaleNames/mt/AS=is-Samoa Amerikana LocaleNames/mt/AT=l-Awstrija LocaleNames/mt/AU=l-Awstralja -LocaleNames/mt/AZ=l-A\u017cerbaj\u0121an -LocaleNames/mt/BA=il-Bo\u017cnija-\u0126erzegovina +LocaleNames/mt/AZ=l-Ażerbajġan +LocaleNames/mt/BA=il-Bożnija-Ħerzegovina LocaleNames/mt/BD=il-Bangladesh -LocaleNames/mt/BE=il-Bel\u0121ju +LocaleNames/mt/BE=il-Belġju LocaleNames/mt/BG=il-Bulgarija LocaleNames/mt/BH=il-Bahrain LocaleNames/mt/BN=il-Brunei LocaleNames/mt/BO=il-Bolivja -LocaleNames/mt/BR=Il-Bra\u017cil +LocaleNames/mt/BR=Il-Brażil LocaleNames/mt/BS=il-Bahamas LocaleNames/mt/BT=il-Bhutan LocaleNames/mt/BY=il-Belarussja LocaleNames/mt/BZ=il-Belize LocaleNames/mt/CA=il-Kanada -LocaleNames/mt/CC=G\u017cejjer Cocos (Keeling) +LocaleNames/mt/CC=Gżejjer Cocos (Keeling) LocaleNames/mt/CD=ir-Repubblika Demokratika tal-Kongo -LocaleNames/mt/CF=ir-Repubblika \u010aentru-Afrikana +LocaleNames/mt/CF=ir-Repubblika Ċentru-Afrikana LocaleNames/mt/CG=il-Kongo - Brazzaville -LocaleNames/mt/CH=l-I\u017cvizzera +LocaleNames/mt/CH=l-Iżvizzera LocaleNames/mt/CI=il-Kosta tal-Avorju -LocaleNames/mt/CL=i\u010b-\u010aili +LocaleNames/mt/CL=iċ-Ċili LocaleNames/mt/CM=il-Kamerun -LocaleNames/mt/CN=i\u010b-\u010aina +LocaleNames/mt/CN=iċ-Ċina LocaleNames/mt/CO=il-Kolombja LocaleNames/mt/CR=il-Costa Rica LocaleNames/mt/CU=Kuba LocaleNames/mt/CV=Cape Verde -LocaleNames/mt/CY=\u010aipru -LocaleNames/mt/CZ=ir-Repubblika \u010aeka -LocaleNames/mt/DE=il-\u0120ermanja +LocaleNames/mt/CY=Ċipru +LocaleNames/mt/CZ=ir-Repubblika Ċeka +LocaleNames/mt/DE=il-Ġermanja LocaleNames/mt/DJ=il-Djibouti LocaleNames/mt/DK=id-Danimarka LocaleNames/mt/DM=Dominica LocaleNames/mt/DO=ir-Repubblika Dominicana -LocaleNames/mt/DZ=l-Al\u0121erija +LocaleNames/mt/DZ=l-Alġerija LocaleNames/mt/EC=l-Ekwador LocaleNames/mt/EE=l-Estonja -LocaleNames/mt/EG=l-E\u0121ittu -LocaleNames/mt/EH=is-Sa\u0127ara tal-Punent +LocaleNames/mt/EG=l-Eġittu +LocaleNames/mt/EH=is-Saħara tal-Punent LocaleNames/mt/ER=l-Eritrea LocaleNames/mt/ES=Spanja LocaleNames/mt/ET=l-Etjopja LocaleNames/mt/FI=il-Finlandja -LocaleNames/mt/FJ=Fi\u0121i -LocaleNames/mt/FM=il-Mikrone\u017cja -LocaleNames/mt/FO=il-G\u017cejjer Faeroe +LocaleNames/mt/FJ=Fiġi +LocaleNames/mt/FM=il-Mikroneżja +LocaleNames/mt/FO=il-Gżejjer Faeroe LocaleNames/mt/FR=Franza LocaleNames/mt/GB=ir-Renju Unit LocaleNames/mt/GE=il-Georgia -LocaleNames/mt/GF=il-Guyana Fran\u010bi\u017ca +LocaleNames/mt/GF=il-Guyana Franċiża LocaleNames/mt/GH=il-Ghana LocaleNames/mt/GL=Greenland LocaleNames/mt/GM=il-Gambja LocaleNames/mt/GN=il-Guinea LocaleNames/mt/GP=Guadeloupe LocaleNames/mt/GQ=il-Guinea Ekwatorjali -LocaleNames/mt/GR=il-Gre\u010bja -LocaleNames/mt/GS=il-Georgia tan-Nofsinhar u l-G\u017cejjer Sandwich tan-Nofsinhar +LocaleNames/mt/GR=il-Greċja +LocaleNames/mt/GS=il-Georgia tan-Nofsinhar u l-Gżejjer Sandwich tan-Nofsinhar LocaleNames/mt/GT=il-Gwatemala LocaleNames/mt/GU=Guam LocaleNames/mt/GW=il-Guinea-Bissau LocaleNames/mt/GY=il-Guyana -LocaleNames/mt/HK=ir-Re\u0121jun Amministrattiv Spe\u010bjali ta\u2019 Hong Kong tar-Repubblika tal-Poplu ta\u010b-\u010aina -LocaleNames/mt/HM=il-G\u017cejjer Heard u l-G\u017cejjer McDonald +LocaleNames/mt/HK=ir-Reġjun Amministrattiv Speċjali ta’ Hong Kong tar-Repubblika tal-Poplu taċ-Ċina +LocaleNames/mt/HM=il-Gżejjer Heard u l-Gżejjer McDonald LocaleNames/mt/HN=il-Honduras LocaleNames/mt/HR=il-Kroazja LocaleNames/mt/HT=il-Haiti LocaleNames/mt/HU=l-Ungerija -LocaleNames/mt/ID=l-Indone\u017cja +LocaleNames/mt/ID=l-Indoneżja LocaleNames/mt/IE=l-Irlanda -LocaleNames/mt/IL=I\u017crael +LocaleNames/mt/IL=Iżrael LocaleNames/mt/IN=l-Indja -LocaleNames/mt/IS=l-I\u017clanda +LocaleNames/mt/IS=l-Iżlanda LocaleNames/mt/IT=l-Italja -LocaleNames/mt/JM=il-\u0120amajka -LocaleNames/mt/JO=il-\u0120ordan -LocaleNames/mt/JP=il-\u0120appun +LocaleNames/mt/JM=il-Ġamajka +LocaleNames/mt/JO=il-Ġordan +LocaleNames/mt/JP=il-Ġappun LocaleNames/mt/KE=il-Kenja -LocaleNames/mt/KG=il-Kirgi\u017cistan +LocaleNames/mt/KG=il-Kirgiżistan LocaleNames/mt/KH=il-Kambodja LocaleNames/mt/KM=Comoros LocaleNames/mt/KN=Saint Kitts u Nevis -LocaleNames/mt/KP=il-Korea ta\u2019 Fuq -LocaleNames/mt/KR=il-Korea t\u2019Isfel +LocaleNames/mt/KP=il-Korea ta’ Fuq +LocaleNames/mt/KR=il-Korea t’Isfel LocaleNames/mt/KW=il-Kuwajt -LocaleNames/mt/KZ=il-Ka\u017cakistan +LocaleNames/mt/KZ=il-Każakistan LocaleNames/mt/LB=il-Libanu LocaleNames/mt/LC=Saint Lucia LocaleNames/mt/LR=il-Liberja @@ -4983,12 +4983,12 @@ LocaleNames/mt/MA=il-Marokk LocaleNames/mt/MC=Monaco LocaleNames/mt/MD=il-Moldova LocaleNames/mt/MG=Madagascar -LocaleNames/mt/MH=G\u017cejjer Marshall -LocaleNames/mt/MK=il-Ma\u010bedonja ta\u2019 Fuq +LocaleNames/mt/MH=Gżejjer Marshall +LocaleNames/mt/MK=il-Maċedonja ta’ Fuq LocaleNames/mt/MM=il-Myanmar/Burma LocaleNames/mt/MN=il-Mongolja -LocaleNames/mt/MO=ir-Re\u0121jun Amministrattiv Spe\u010bjali tal-Macao tar-Repubblika tal-Poplu ta\u010b-\u010aina -LocaleNames/mt/MP=\u0120\u017cejjer Mariana tat-Tramuntana +LocaleNames/mt/MO=ir-Reġjun Amministrattiv Speċjali tal-Macao tar-Repubblika tal-Poplu taċ-Ċina +LocaleNames/mt/MP=Ġżejjer Mariana tat-Tramuntana LocaleNames/mt/MQ=Martinique LocaleNames/mt/MR=il-Mauritania LocaleNames/mt/MU=Mauritius @@ -4996,12 +4996,12 @@ LocaleNames/mt/MX=il-Messiku LocaleNames/mt/MY=il-Malasja LocaleNames/mt/MZ=il-Mozambique LocaleNames/mt/NA=in-Namibja -LocaleNames/mt/NE=in-Ni\u0121er -LocaleNames/mt/NG=in-Ni\u0121erja +LocaleNames/mt/NE=in-Niġer +LocaleNames/mt/NG=in-Niġerja LocaleNames/mt/NI=in-Nikaragwa LocaleNames/mt/NL=in-Netherlands -LocaleNames/mt/NO=in-Norve\u0121ja -LocaleNames/mt/PF=Poline\u017cja Fran\u010bi\u017ca +LocaleNames/mt/NO=in-Norveġja +LocaleNames/mt/PF=Polineżja Franċiża LocaleNames/mt/PG=Papua New Guinea LocaleNames/mt/PH=il-Filippini LocaleNames/mt/PL=il-Polonja @@ -5009,28 +5009,28 @@ LocaleNames/mt/PM=Saint Pierre u Miquelon LocaleNames/mt/PS=it-Territorji Palestinjani LocaleNames/mt/PT=il-Portugall LocaleNames/mt/PY=il-Paragwaj -LocaleNames/mt/RE=R\u00e9union +LocaleNames/mt/RE=Réunion LocaleNames/mt/RO=ir-Rumanija LocaleNames/mt/RU=ir-Russja LocaleNames/mt/SA=l-Arabja Sawdija -LocaleNames/mt/SE=l-I\u017cvezja +LocaleNames/mt/SE=l-Iżvezja LocaleNames/mt/SG=Singapore LocaleNames/mt/SI=is-Slovenja LocaleNames/mt/SJ=Svalbard u Jan Mayen LocaleNames/mt/SK=is-Slovakkja LocaleNames/mt/SO=is-Somalja LocaleNames/mt/SR=is-Suriname -LocaleNames/mt/ST=S\u00e3o Tom\u00e9 u Pr\u00edncipe +LocaleNames/mt/ST=São Tomé u Príncipe LocaleNames/mt/SY=is-Sirja LocaleNames/mt/SZ=l-Eswatini -LocaleNames/mt/TC=il-G\u017cejjer Turks u Caicos -LocaleNames/mt/TD=i\u010b-Chad -LocaleNames/mt/TF=It-Territorji Fran\u010bi\u017ci tan-Nofsinhar +LocaleNames/mt/TC=il-Gżejjer Turks u Caicos +LocaleNames/mt/TD=iċ-Chad +LocaleNames/mt/TF=It-Territorji Franċiżi tan-Nofsinhar LocaleNames/mt/TH=it-Tajlandja -LocaleNames/mt/TJ=it-Ta\u0121ikistan +LocaleNames/mt/TJ=it-Taġikistan LocaleNames/mt/TK=it-Tokelau LocaleNames/mt/TL=Timor Leste -LocaleNames/mt/TN=it-Tune\u017cija +LocaleNames/mt/TN=it-Tuneżija LocaleNames/mt/TR=it-Turkija LocaleNames/mt/TT=Trinidad u Tobago LocaleNames/mt/TW=it-Tajwan @@ -5038,7 +5038,7 @@ LocaleNames/mt/TZ=it-Tanzanija LocaleNames/mt/UA=l-Ukrajna LocaleNames/mt/US=l-Istati Uniti LocaleNames/mt/UY=l-Urugwaj -LocaleNames/mt/UZ=l-U\u017cbekistan +LocaleNames/mt/UZ=l-Użbekistan LocaleNames/mt/VA=l-Istat tal-Belt tal-Vatikan LocaleNames/mt/VC=Saint Vincent u l-Grenadini LocaleNames/mt/VE=il-Venezwela @@ -5047,48 +5047,48 @@ LocaleNames/mt/VU=Vanuatu LocaleNames/mt/WF=Wallis u Futuna LocaleNames/mt/YE=il-Jemen LocaleNames/mt/YT=Mayotte -LocaleNames/mt/ZA=l-Afrika t\u2019Isfel -LocaleNames/mt/ZM=i\u017c-\u017bambja -LocaleNames/mt/ZW=i\u017c-\u017bimbabwe -LocaleNames/sr/ZA=\u0408\u0443\u0436\u043d\u043e\u0430\u0444\u0440\u0438\u0447\u043a\u0430 \u0420\u0435\u043f\u0443\u0431\u043b\u0438\u043a\u0430 -LocaleNames/zh_SG/bo=\u85cf\u8bed -LocaleNames/zh_SG/gd=\u82cf\u683c\u5170\u76d6\u5c14\u8bed -LocaleNames/zh_SG/ho=\u5e0c\u91cc\u83ab\u56fe\u8bed -LocaleNames/zh_SG/ia=\u56fd\u9645\u8bed -LocaleNames/zh_SG/ie=\u56fd\u9645\u6587\u5b57\uff08E\uff09 -LocaleNames/zh_SG/iu=\u56e0\u7ebd\u7279\u8bed -LocaleNames/zh_SG/kj=\u5bbd\u4e9a\u739b\u8bed -LocaleNames/zh_SG/kn=\u5361\u7eb3\u8fbe\u8bed -LocaleNames/zh_SG/lv=\u62c9\u8131\u7ef4\u4e9a\u8bed -LocaleNames/zh_SG/ny=\u9f50\u5207\u74e6\u8bed -LocaleNames/zh_SG/oc=\u5965\u514b\u8bed -LocaleNames/zh_SG/om=\u5965\u7f57\u83ab\u8bed -LocaleNames/zh_SG/rm=\u7f57\u66fc\u4ec0\u8bed -LocaleNames/zh_SG/sd=\u4fe1\u5fb7\u8bed -LocaleNames/zh_SG/se=\u5317\u65b9\u8428\u7c73\u8bed -LocaleNames/zh_SG/sn=\u7ecd\u7eb3\u8bed -LocaleNames/zh_SG/ss=\u65af\u74e6\u8482\u8bed -LocaleNames/zh_SG/su=\u5dfd\u4ed6\u8bed -LocaleNames/zh_SG/tl=\u4ed6\u52a0\u7984\u8bed -LocaleNames/zh_SG/tn=\u8328\u74e6\u7eb3\u8bed -LocaleNames/zh_SG/ts=\u806a\u52a0\u8bed -LocaleNames/zh_SG/tt=\u9791\u977c\u8bed -LocaleNames/zh_SG/tw=\u5951\u7ef4\u8bed -LocaleNames/zh_SG/wa=\u74e6\u9686\u8bed -LocaleNames/zh_SG/wo=\u6c83\u6d1b\u592b\u8bed -LocaleNames/zh_SG/xh=\u79d1\u8428\u8bed -LocaleNames/zh_SG/za=\u58ee\u8bed -LocaleNames/zh_SG/BA=\u6ce2\u65af\u5c3c\u4e9a\u548c\u9ed1\u585e\u54e5\u7ef4\u90a3 -LocaleNames/zh_SG/CC=\u79d1\u79d1\u65af\uff08\u57fa\u6797\uff09\u7fa4\u5c9b -LocaleNames/zh_SG/CD=\u521a\u679c\uff08\u91d1\uff09 -LocaleNames/zh_SG/CG=\u521a\u679c\uff08\u5e03\uff09 -LocaleNames/zh_SG/DM=\u591a\u7c73\u5c3c\u514b -LocaleNames/zh_SG/KG=\u5409\u5c14\u5409\u65af\u65af\u5766 -LocaleNames/zh_SG/KP=\u671d\u9c9c -LocaleNames/zh_SG/MQ=\u9a6c\u63d0\u5c3c\u514b -LocaleNames/zh_SG/MQ=\u9a6c\u63d0\u5c3c\u514b -LocaleNames/zh_SG/NC=\u65b0\u5580\u91cc\u591a\u5c3c\u4e9a -LocaleNames/zh_SG/TF=\u6cd5\u5c5e\u5357\u90e8\u9886\u5730 +LocaleNames/mt/ZA=l-Afrika t’Isfel +LocaleNames/mt/ZM=iż-Żambja +LocaleNames/mt/ZW=iż-Żimbabwe +LocaleNames/sr/ZA=Јужноафричка Република +LocaleNames/zh_SG/bo=藏语 +LocaleNames/zh_SG/gd=苏格兰盖尔语 +LocaleNames/zh_SG/ho=希里莫图语 +LocaleNames/zh_SG/ia=国际语 +LocaleNames/zh_SG/ie=国际文字(E) +LocaleNames/zh_SG/iu=因纽特语 +LocaleNames/zh_SG/kj=宽亚玛语 +LocaleNames/zh_SG/kn=卡纳达语 +LocaleNames/zh_SG/lv=拉脱维亚语 +LocaleNames/zh_SG/ny=齐切瓦语 +LocaleNames/zh_SG/oc=奥克语 +LocaleNames/zh_SG/om=奥罗莫语 +LocaleNames/zh_SG/rm=罗曼什语 +LocaleNames/zh_SG/sd=信德语 +LocaleNames/zh_SG/se=北方萨米语 +LocaleNames/zh_SG/sn=绍纳语 +LocaleNames/zh_SG/ss=斯瓦蒂语 +LocaleNames/zh_SG/su=巽他语 +LocaleNames/zh_SG/tl=他加禄语 +LocaleNames/zh_SG/tn=茨瓦纳语 +LocaleNames/zh_SG/ts=聪加语 +LocaleNames/zh_SG/tt=鞑靼语 +LocaleNames/zh_SG/tw=契维语 +LocaleNames/zh_SG/wa=瓦隆语 +LocaleNames/zh_SG/wo=沃洛夫语 +LocaleNames/zh_SG/xh=科萨语 +LocaleNames/zh_SG/za=壮语 +LocaleNames/zh_SG/BA=波斯尼亚和黑塞哥维那 +LocaleNames/zh_SG/CC=科科斯(基林)群岛 +LocaleNames/zh_SG/CD=刚果(金) +LocaleNames/zh_SG/CG=刚果(布) +LocaleNames/zh_SG/DM=多米尼克 +LocaleNames/zh_SG/KG=吉尔吉斯斯坦 +LocaleNames/zh_SG/KP=朝鲜 +LocaleNames/zh_SG/MQ=马提尼克 +LocaleNames/zh_SG/MQ=马提尼克 +LocaleNames/zh_SG/NC=新喀里多尼亚 +LocaleNames/zh_SG/TF=法属南部领地 FormatData/es_US/AmPmMarkers/0=a.m. FormatData/es_US/AmPmMarkers/1=p.m. FormatData/es_US/latn.NumberElements/0=. @@ -5099,18 +5099,18 @@ FormatData/es_US/latn.NumberElements/4=0 FormatData/es_US/latn.NumberElements/5=# FormatData/es_US/latn.NumberElements/6=- FormatData/es_US/latn.NumberElements/7=E -FormatData/es_US/latn.NumberElements/8=\u2030 -FormatData/es_US/latn.NumberElements/9=\u221e +FormatData/es_US/latn.NumberElements/8=‰ +FormatData/es_US/latn.NumberElements/9=∞ FormatData/es_US/latn.NumberElements/10=NaN FormatData/mt/AmPmMarkers/0=AM FormatData/mt/AmPmMarkers/1=PM -FormatData/mt/DatePatterns/0=EEEE, d 'ta'\u2019 MMMM y +FormatData/mt/DatePatterns/0=EEEE, d 'ta'’ MMMM y # bug# 6498742 # make sure that the default en data is used for en_SG : CLDR1.4.1 demoted these data -FormatData/en_SG/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/en_SG/TimePatterns/1=h:mm:ss\u202fa z -FormatData/en_SG/TimePatterns/2=h:mm:ss\u202fa -FormatData/en_SG/TimePatterns/3=h:mm\u202fa +FormatData/en_SG/TimePatterns/0=h:mm:ss a zzzz +FormatData/en_SG/TimePatterns/1=h:mm:ss a z +FormatData/en_SG/TimePatterns/2=h:mm:ss a +FormatData/en_SG/TimePatterns/3=h:mm a FormatData/en_SG/DatePatterns/0=EEEE, d MMMM y FormatData/en_SG/DatePatterns/1=d MMMM y FormatData/en_SG/DatePatterns/2=d MMM y @@ -5119,10 +5119,10 @@ FormatData/en_SG/DateTimePatterns/0={1}, {0} # Use approved data FormatData/ms/Eras/0=S.M. FormatData/ms/Eras/1=TM -FormatData/sr_BA/MonthNames/5=\u0458\u0443\u043d -FormatData/sr_BA/MonthNames/6=\u0458\u0443\u043b -FormatData/sr_BA/DayNames/3=\u0441\u0440\u0435\u0434\u0430 -FormatData/sr_BA/DayAbbreviations/3=\u0441\u0440\u0435 +FormatData/sr_BA/MonthNames/5=јун +FormatData/sr_BA/MonthNames/6=јул +FormatData/sr_BA/DayNames/3=среда +FormatData/sr_BA/DayAbbreviations/3=сре FormatData/sr_BA/TimePatterns/0=HH:mm:ss zzzz FormatData/sr_BA/TimePatterns/1=HH:mm:ss z FormatData/sr_BA/TimePatterns/2=HH:mm:ss @@ -5134,31 +5134,31 @@ FormatData/sr_BA/DatePatterns/3=d. M. y. FormatData/sr_BA/DateTimePatterns/0={1} {0} LocaleNames/pt_BR/ce=checheno LocaleNames/pt_BR/ik=inupiaque -LocaleNames/pt_BR/jv=javan\u00eas +LocaleNames/pt_BR/jv=javanês LocaleNames/pt_BR/nd=ndebele do norte LocaleNames/pt_BR/nr=ndebele do sul LocaleNames/pt_BR/st=soto do sul LocaleNames/pt_BR/AX=Ilhas Aland -LocaleNames/pt_BR/BA=B\u00f3snia e Herzegovina +LocaleNames/pt_BR/BA=Bósnia e Herzegovina LocaleNames/pt_BR/BH=Barein LocaleNames/pt_BR/KP=Coreia do Norte -LocaleNames/pt_BR/MK=Maced\u00f4nia do Norte -LocaleNames/pt_BR/ZW=Zimb\u00e1bue +LocaleNames/pt_BR/MK=Macedônia do Norte +LocaleNames/pt_BR/ZW=Zimbábue LocaleNames/pt_PT/ee=ewe -LocaleNames/pt_PT/fo=fero\u00eas +LocaleNames/pt_PT/fo=feroês LocaleNames/pt_PT/gl=galego -LocaleNames/pt_PT/ha=ha\u00fa\u00e7a -LocaleNames/pt_PT/hy=arm\u00e9nio +LocaleNames/pt_PT/ha=haúça +LocaleNames/pt_PT/hy=arménio LocaleNames/pt_PT/ig=igbo LocaleNames/pt_PT/ki=quicuio -LocaleNames/pt_PT/kl=groneland\u00eas +LocaleNames/pt_PT/kl=gronelandês LocaleNames/pt_PT/km=khmer -LocaleNames/pt_PT/mh=marshal\u00eas -LocaleNames/pt_PT/mk=maced\u00f3nio +LocaleNames/pt_PT/mh=marshalês +LocaleNames/pt_PT/mk=macedónio LocaleNames/pt_PT/nr=ndebele do sul -LocaleNames/pt_PT/os=oss\u00e9tico +LocaleNames/pt_PT/os=ossético LocaleNames/pt_PT/st=sesoto -LocaleNames/pt_PT/ta=t\u00e2mil +LocaleNames/pt_PT/ta=tâmil LocaleNames/pt_PT/AI=Anguila LocaleNames/pt_PT/AX=Alanda @@ -5176,7 +5176,7 @@ FormatData/nl/Eras/1=n.Chr. LocaleNames/da/da=dansk # bug 6485516 -LocaleNames/fr/GF=Guyane fran\u00e7aise +LocaleNames/fr/GF=Guyane française # bug 6486607 LocaleNames/fr/GY=Guyana @@ -5190,9 +5190,9 @@ FormatData/fr_FR/DateTimePatternChars=GyMdkHmsSEDFwWahKzZ FormatData/fr_LU/DateTimePatternChars=GyMdkHmsSEDFwWahKzZ # bug 6547501 -FormatData/fr/latn.NumberPatterns/2=#,##0\u00a0% +FormatData/fr/latn.NumberPatterns/2=#,##0 % # following two lines are also for bug 4494727 -FormatData/fr_CA/latn.NumberPatterns/2=#,##0\u00a0% +FormatData/fr_CA/latn.NumberPatterns/2=#,##0 % FormatData/fr_CH/latn.NumberPatterns/2=#,##0% # bug 4494727 @@ -5206,27 +5206,27 @@ LocaleNames/de/ME=Montenegro LocaleNames/de/RS=Serbien LocaleNames/es/ME=Montenegro LocaleNames/es/RS=Serbia -LocaleNames/fr/ME=Mont\u00e9n\u00e9gro +LocaleNames/fr/ME=Monténégro LocaleNames/fr/RS=Serbie LocaleNames/it/ME=Montenegro LocaleNames/it/RS=Serbia -LocaleNames/ja/ME=\u30e2\u30f3\u30c6\u30cd\u30b0\u30ed -LocaleNames/ja/RS=\u30bb\u30eb\u30d3\u30a2 -LocaleNames/ko/ME=\ubaac\ud14c\ub124\uadf8\ub85c -LocaleNames/ko/RS=\uc138\ub974\ube44\uc544 +LocaleNames/ja/ME=モンテネグロ +LocaleNames/ja/RS=セルビア +LocaleNames/ko/ME=몬테네그로 +LocaleNames/ko/RS=세르비아 LocaleNames/sv/ME=Montenegro LocaleNames/sv/RS=Serbien -LocaleNames/zh/ME=\u9ed1\u5c71 -LocaleNames/zh/RS=\u585e\u5c14\u7ef4\u4e9a -LocaleNames/zh_TW/ME=\u8499\u7279\u5167\u54e5\u7f85 -LocaleNames/zh_TW/RS=\u585e\u723e\u7dad\u4e9e +LocaleNames/zh/ME=黑山 +LocaleNames/zh/RS=塞尔维亚 +LocaleNames/zh_TW/ME=蒙特內哥羅 +LocaleNames/zh_TW/RS=塞爾維亞 # bug 6531591 -CurrencyNames/ar_SD/SDD=\u062f.\u0633.\u200f -CurrencyNames/ar_SD/SDG=\u062c.\u0633. +CurrencyNames/ar_SD/SDD=د.س.‏ +CurrencyNames/ar_SD/SDG=ج.س. # bug 6531593 -FormatData/is_IS/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 +FormatData/is_IS/latn.NumberPatterns/1=#,##0.00 ¤ # bug 6509039 FormatData/sv/AmPmMarkers/0=fm @@ -5240,7 +5240,7 @@ FormatData/fi/AmPmMarkers/0=ap. FormatData/fi/AmPmMarkers/1=ip. # bug 6507067 8317979 -TimeZoneNames/zh_TW/Asia\/Taipei/1=\u53f0\u5317\u6a19\u6e96\u6642\u9593 +TimeZoneNames/zh_TW/Asia\/Taipei/1=台北標準時間 TimeZoneNames/zh_TW/Asia\/Taipei/2=CST # bug 6645271 @@ -5248,10 +5248,10 @@ FormatData/hr_HR/DatePatterns/2=d. MMM y. FormatData/hr_HR/DatePatterns/3=dd. MM. y. # bug 6873931 -CurrencyNames/tr_TR/TRY=\u20ba +CurrencyNames/tr_TR/TRY=₺ #bug 6450945 -FormatData/ro/DayNames/6=s\u00e2mb\u0103t\u0103 +FormatData/ro/DayNames/6=sâmbătă #bug 6645268 LocaleNames/fi/fr=ranska @@ -5260,14 +5260,14 @@ LocaleNames/fi_FI/fr=ranska LocaleNames/fi_FI/FR=Ranska # bug 6646611, 6914413 -FormatData/be_BY/MonthNames/10=\u043b\u0456\u0441\u0442\u0430\u043f\u0430\u0434\u0430 -FormatData/be_BY/MonthAbbreviations/10=\u043b\u0456\u0441 +FormatData/be_BY/MonthNames/10=лістапада +FormatData/be_BY/MonthAbbreviations/10=ліс # bug 6645405 -FormatData/hu_HU/latn.NumberPatterns/1=#,##0.00\u00a0\u00a4 +FormatData/hu_HU/latn.NumberPatterns/1=#,##0.00 ¤ # bug 6650730 -FormatData/lt/latn.NumberElements/1=\u00a0 +FormatData/lt/latn.NumberElements/1=  FormatData/lt/DatePatterns/2=y-MM-dd # bug 6573250 @@ -5276,7 +5276,7 @@ CurrencyNames/en_CA/USD=US$ # bug 6870908 FormatData/et/MonthNames/0=jaanuar FormatData/et/MonthNames/1=veebruar -FormatData/et/MonthNames/2=m\u00e4rts +FormatData/et/MonthNames/2=märts FormatData/et/MonthNames/3=aprill FormatData/et/MonthNames/4=mai FormatData/et/MonthNames/5=juuni @@ -5288,7 +5288,7 @@ FormatData/et/MonthNames/10=november FormatData/et/MonthNames/11=detsember FormatData/et/MonthAbbreviations/0=jaan FormatData/et/MonthAbbreviations/1=veebr -FormatData/et/MonthAbbreviations/2=m\u00e4rts +FormatData/et/MonthAbbreviations/2=märts FormatData/et/MonthAbbreviations/3=apr FormatData/et/MonthAbbreviations/4=mai FormatData/et/MonthAbbreviations/5=juuni @@ -5304,39 +5304,39 @@ LocaleNames/es/aa=afar LocaleNames/es/av=avar LocaleNames/es/az=azerbaiyano LocaleNames/es/ba=baskir -LocaleNames/es/bn=bengal\u00ed -LocaleNames/es/cu=eslavo eclesi\u00e1stico +LocaleNames/es/bn=bengalí +LocaleNames/es/cu=eslavo eclesiástico LocaleNames/es/dz=dzongkha LocaleNames/es/eu=euskera LocaleNames/es/fa=persa LocaleNames/es/ff=fula LocaleNames/es/fj=fiyiano -LocaleNames/es/fo=fero\u00e9s -LocaleNames/es/fy=fris\u00f3n occidental -LocaleNames/es/gu=guyarat\u00ed -LocaleNames/es/gv=man\u00e9s +LocaleNames/es/fo=feroés +LocaleNames/es/fy=frisón occidental +LocaleNames/es/gu=guyaratí +LocaleNames/es/gv=manés LocaleNames/es/hi=hindi LocaleNames/es/ho=hiri motu LocaleNames/es/ie=interlingue LocaleNames/es/ig=igbo -LocaleNames/es/ii=yi de Sichu\u00e1n +LocaleNames/es/ii=yi de Sichuán LocaleNames/es/ik=inupiaq LocaleNames/es/kg=kongo LocaleNames/es/ki=kikuyu LocaleNames/es/kj=kuanyama LocaleNames/es/kk=kazajo LocaleNames/es/km=jemer -LocaleNames/es/kn=canar\u00e9s +LocaleNames/es/kn=canarés LocaleNames/es/ks=cachemir LocaleNames/es/ku=kurdo -LocaleNames/es/ky=kirgu\u00eds +LocaleNames/es/ky=kirguís LocaleNames/es/lu=luba-katanga -LocaleNames/es/mr=marat\u00ed +LocaleNames/es/mr=maratí LocaleNames/es/nb=noruego bokmal LocaleNames/es/nd=ndebele septentrional LocaleNames/es/nn=noruego nynorsk LocaleNames/es/nr=ndebele meridional -LocaleNames/es/os=os\u00e9tico +LocaleNames/es/os=osético LocaleNames/es/rm=romanche LocaleNames/es/rn=kirundi LocaleNames/es/rw=kinyarwanda @@ -5346,10 +5346,10 @@ LocaleNames/es/sl=esloveno LocaleNames/es/sn=shona LocaleNames/es/ss=suazi LocaleNames/es/st=sotho meridional -LocaleNames/es/su=sundan\u00e9s +LocaleNames/es/su=sundanés LocaleNames/es/sw=suajili LocaleNames/es/tg=tayiko -LocaleNames/es/ti=tigri\u00f1a +LocaleNames/es/ti=tigriña LocaleNames/es/tn=setsuana LocaleNames/es/to=tongano LocaleNames/es/tw=twi @@ -5357,7 +5357,7 @@ LocaleNames/es/ty=tahitiano LocaleNames/es/ug=uigur LocaleNames/es/uk=ucraniano LocaleNames/es/uz=uzbeko -LocaleNames/es/vo=volap\u00fck +LocaleNames/es/vo=volapük LocaleNames/es/za=zhuang # bug 6716626 - language @@ -5406,13 +5406,13 @@ LocaleNames/nl/fa=Perzisch LocaleNames/nl/ff=Fulah LocaleNames/nl/fi=Fins LocaleNames/nl/fj=Fijisch -LocaleNames/nl/fo=Faer\u00f6ers +LocaleNames/nl/fo=Faeröers LocaleNames/nl/fr=Frans LocaleNames/nl/fy=Fries LocaleNames/nl/ga=Iers LocaleNames/nl/gd=Schots-Gaelisch LocaleNames/nl/gl=Galicisch -LocaleNames/nl/gn=Guaran\u00ed +LocaleNames/nl/gn=Guaraní LocaleNames/nl/gu=Gujarati LocaleNames/nl/gv=Manx LocaleNames/nl/ha=Hausa @@ -5420,7 +5420,7 @@ LocaleNames/nl/he=Hebreeuws LocaleNames/nl/hi=Hindi LocaleNames/nl/ho=Hiri Motu LocaleNames/nl/hr=Kroatisch -LocaleNames/nl/ht=Ha\u00eftiaans Creools +LocaleNames/nl/ht=Haïtiaans Creools LocaleNames/nl/hu=Hongaars LocaleNames/nl/hy=Armeens LocaleNames/nl/hz=Herero @@ -5471,7 +5471,7 @@ LocaleNames/nl/ms=Maleis LocaleNames/nl/mt=Maltees LocaleNames/nl/my=Birmaans LocaleNames/nl/na=Nauruaans -LocaleNames/nl/nb=Noors - Bokm\u00e5l +LocaleNames/nl/nb=Noors - Bokmål LocaleNames/nl/nd=Noord-Ndebele LocaleNames/nl/ne=Nepalees LocaleNames/nl/ng=Ndonga @@ -5530,12 +5530,12 @@ LocaleNames/nl/tt=Tataars LocaleNames/nl/tw=Twi LocaleNames/nl/ty=Tahitiaans LocaleNames/nl/ug=Oeigoers -LocaleNames/nl/uk=Oekra\u00efens +LocaleNames/nl/uk=Oekraïens LocaleNames/nl/ur=Urdu LocaleNames/nl/uz=Oezbeeks LocaleNames/nl/ve=Venda LocaleNames/nl/vi=Vietnamees -LocaleNames/nl/vo=Volap\u00fck +LocaleNames/nl/vo=Volapük LocaleNames/nl/wa=Waals LocaleNames/nl/wo=Wolof LocaleNames/nl/xh=Xhosa @@ -5551,21 +5551,21 @@ LocaleNames/nl/AE=Verenigde Arabische Emiraten LocaleNames/nl/AF=Afghanistan LocaleNames/nl/AG=Antigua en Barbuda LocaleNames/nl/AI=Anguilla -LocaleNames/nl/AL=Albani\u00eb -LocaleNames/nl/AM=Armeni\u00eb +LocaleNames/nl/AL=Albanië +LocaleNames/nl/AM=Armenië LocaleNames/nl/AO=Angola LocaleNames/nl/AQ=Antarctica -LocaleNames/nl/AR=Argentini\u00eb +LocaleNames/nl/AR=Argentinië LocaleNames/nl/AS=Amerikaans-Samoa LocaleNames/nl/AT=Oostenrijk -LocaleNames/nl/AU=Australi\u00eb +LocaleNames/nl/AU=Australië LocaleNames/nl/AW=Aruba -LocaleNames/nl/AX=\u00c5land +LocaleNames/nl/AX=Åland LocaleNames/nl/AZ=Azerbeidzjan -LocaleNames/nl/BA=Bosni\u00eb en Herzegovina +LocaleNames/nl/BA=Bosnië en Herzegovina LocaleNames/nl/BB=Barbados LocaleNames/nl/BD=Bangladesh -LocaleNames/nl/BE=Belgi\u00eb +LocaleNames/nl/BE=België LocaleNames/nl/BF=Burkina Faso LocaleNames/nl/BG=Bulgarije LocaleNames/nl/BH=Bahrein @@ -5574,8 +5574,8 @@ LocaleNames/nl/BJ=Benin LocaleNames/nl/BM=Bermuda LocaleNames/nl/BN=Brunei LocaleNames/nl/BO=Bolivia -LocaleNames/nl/BR=Brazili\u00eb -LocaleNames/nl/BS=Bahama\u2019s +LocaleNames/nl/BR=Brazilië +LocaleNames/nl/BS=Bahama’s LocaleNames/nl/BT=Bhutan LocaleNames/nl/BV=Bouveteiland LocaleNames/nl/BW=Botswana @@ -5595,10 +5595,10 @@ LocaleNames/nl/CN=China LocaleNames/nl/CO=Colombia LocaleNames/nl/CR=Costa Rica LocaleNames/nl/CU=Cuba -LocaleNames/nl/CV=Kaapverdi\u00eb +LocaleNames/nl/CV=Kaapverdië LocaleNames/nl/CX=Christmaseiland LocaleNames/nl/CY=Cyprus -LocaleNames/nl/CZ=Tsjechi\u00eb +LocaleNames/nl/CZ=Tsjechië LocaleNames/nl/DE=Duitsland LocaleNames/nl/DJ=Djibouti LocaleNames/nl/DK=Denemarken @@ -5611,17 +5611,17 @@ LocaleNames/nl/EG=Egypte LocaleNames/nl/EH=Westelijke Sahara LocaleNames/nl/ER=Eritrea LocaleNames/nl/ES=Spanje -LocaleNames/nl/ET=Ethiopi\u00eb +LocaleNames/nl/ET=Ethiopië LocaleNames/nl/FI=Finland LocaleNames/nl/FJ=Fiji LocaleNames/nl/FK=Falklandeilanden LocaleNames/nl/FM=Micronesia -LocaleNames/nl/FO=Faer\u00f6er +LocaleNames/nl/FO=Faeröer LocaleNames/nl/FR=Frankrijk LocaleNames/nl/GA=Gabon LocaleNames/nl/GB=Verenigd Koninkrijk LocaleNames/nl/GD=Grenada -LocaleNames/nl/GE=Georgi\u00eb +LocaleNames/nl/GE=Georgië LocaleNames/nl/GF=Frans-Guyana LocaleNames/nl/GH=Ghana LocaleNames/nl/GI=Gibraltar @@ -5639,23 +5639,23 @@ LocaleNames/nl/GY=Guyana LocaleNames/nl/HK=Hongkong SAR van China LocaleNames/nl/HM=Heard en McDonaldeilanden LocaleNames/nl/HN=Honduras -LocaleNames/nl/HR=Kroati\u00eb -LocaleNames/nl/HT=Ha\u00efti +LocaleNames/nl/HR=Kroatië +LocaleNames/nl/HT=Haïti LocaleNames/nl/HU=Hongarije -LocaleNames/nl/ID=Indonesi\u00eb +LocaleNames/nl/ID=Indonesië LocaleNames/nl/IE=Ierland -LocaleNames/nl/IL=Isra\u00ebl +LocaleNames/nl/IL=Israël LocaleNames/nl/IN=India LocaleNames/nl/IO=Brits Indische Oceaanterritorium LocaleNames/nl/IQ=Irak LocaleNames/nl/IR=Iran LocaleNames/nl/IS=IJsland -LocaleNames/nl/IT=Itali\u00eb +LocaleNames/nl/IT=Italië LocaleNames/nl/JM=Jamaica -LocaleNames/nl/JO=Jordani\u00eb +LocaleNames/nl/JO=Jordanië LocaleNames/nl/JP=Japan LocaleNames/nl/KE=Kenia -LocaleNames/nl/KG=Kirgizi\u00eb +LocaleNames/nl/KG=Kirgizië LocaleNames/nl/KH=Cambodja LocaleNames/nl/KI=Kiribati LocaleNames/nl/KM=Comoren @@ -5675,31 +5675,31 @@ LocaleNames/nl/LS=Lesotho LocaleNames/nl/LT=Litouwen LocaleNames/nl/LU=Luxemburg LocaleNames/nl/LV=Letland -LocaleNames/nl/LY=Libi\u00eb +LocaleNames/nl/LY=Libië LocaleNames/nl/MA=Marokko LocaleNames/nl/MC=Monaco -LocaleNames/nl/MD=Moldavi\u00eb +LocaleNames/nl/MD=Moldavië LocaleNames/nl/ME=Montenegro LocaleNames/nl/MG=Madagaskar LocaleNames/nl/MH=Marshalleilanden -LocaleNames/nl/MK=Noord-Macedoni\u00eb +LocaleNames/nl/MK=Noord-Macedonië LocaleNames/nl/ML=Mali LocaleNames/nl/MM=Myanmar (Birma) -LocaleNames/nl/MN=Mongoli\u00eb +LocaleNames/nl/MN=Mongolië LocaleNames/nl/MO=Macau SAR van China LocaleNames/nl/MP=Noordelijke Marianen LocaleNames/nl/MQ=Martinique -LocaleNames/nl/MR=Mauritani\u00eb +LocaleNames/nl/MR=Mauritanië LocaleNames/nl/MS=Montserrat LocaleNames/nl/MT=Malta LocaleNames/nl/MU=Mauritius LocaleNames/nl/MV=Maldiven LocaleNames/nl/MW=Malawi LocaleNames/nl/MX=Mexico -LocaleNames/nl/MY=Maleisi\u00eb +LocaleNames/nl/MY=Maleisië LocaleNames/nl/MZ=Mozambique -LocaleNames/nl/NA=Namibi\u00eb -LocaleNames/nl/NC=Nieuw-Caledoni\u00eb +LocaleNames/nl/NA=Namibië +LocaleNames/nl/NC=Nieuw-Caledonië LocaleNames/nl/NE=Niger LocaleNames/nl/NF=Norfolk LocaleNames/nl/NG=Nigeria @@ -5713,7 +5713,7 @@ LocaleNames/nl/NZ=Nieuw-Zeeland LocaleNames/nl/OM=Oman LocaleNames/nl/PA=Panama LocaleNames/nl/PE=Peru -LocaleNames/nl/PF=Frans-Polynesi\u00eb +LocaleNames/nl/PF=Frans-Polynesië LocaleNames/nl/PG=Papoea-Nieuw-Guinea LocaleNames/nl/PH=Filipijnen LocaleNames/nl/PK=Pakistan @@ -5726,29 +5726,29 @@ LocaleNames/nl/PT=Portugal LocaleNames/nl/PW=Palau LocaleNames/nl/PY=Paraguay LocaleNames/nl/QA=Qatar -LocaleNames/nl/RE=R\u00e9union -LocaleNames/nl/RO=Roemeni\u00eb -LocaleNames/nl/RS=Servi\u00eb +LocaleNames/nl/RE=Réunion +LocaleNames/nl/RO=Roemenië +LocaleNames/nl/RS=Servië LocaleNames/nl/RU=Rusland LocaleNames/nl/RW=Rwanda -LocaleNames/nl/SA=Saoedi-Arabi\u00eb +LocaleNames/nl/SA=Saoedi-Arabië LocaleNames/nl/SB=Salomonseilanden LocaleNames/nl/SC=Seychellen LocaleNames/nl/SD=Soedan LocaleNames/nl/SE=Zweden LocaleNames/nl/SG=Singapore LocaleNames/nl/SH=Sint-Helena -LocaleNames/nl/SI=Sloveni\u00eb +LocaleNames/nl/SI=Slovenië LocaleNames/nl/SJ=Spitsbergen en Jan Mayen LocaleNames/nl/SK=Slowakije LocaleNames/nl/SL=Sierra Leone LocaleNames/nl/SM=San Marino LocaleNames/nl/SN=Senegal -LocaleNames/nl/SO=Somali\u00eb +LocaleNames/nl/SO=Somalië LocaleNames/nl/SR=Suriname -LocaleNames/nl/ST=Sao Tom\u00e9 en Principe +LocaleNames/nl/ST=Sao Tomé en Principe LocaleNames/nl/SV=El Salvador -LocaleNames/nl/SY=Syri\u00eb +LocaleNames/nl/SY=Syrië LocaleNames/nl/SZ=Eswatini LocaleNames/nl/TC=Turks- en Caicoseilanden LocaleNames/nl/TD=Tsjaad @@ -5759,14 +5759,14 @@ LocaleNames/nl/TJ=Tadzjikistan LocaleNames/nl/TK=Tokelau LocaleNames/nl/TL=Oost-Timor LocaleNames/nl/TM=Turkmenistan -LocaleNames/nl/TN=Tunesi\u00eb +LocaleNames/nl/TN=Tunesië LocaleNames/nl/TO=Tonga LocaleNames/nl/TR=Turkije LocaleNames/nl/TT=Trinidad en Tobago LocaleNames/nl/TV=Tuvalu LocaleNames/nl/TW=Taiwan LocaleNames/nl/TZ=Tanzania -LocaleNames/nl/UA=Oekra\u00efne +LocaleNames/nl/UA=Oekraïne LocaleNames/nl/UG=Oeganda LocaleNames/nl/UM=Kleine afgelegen eilanden van de Verenigde Staten LocaleNames/nl/US=Verenigde Staten @@ -5800,18 +5800,18 @@ FormatData/sr-Latn-RS/MonthNames/8=septembar FormatData/sr-Latn/DayNames/1=ponedeljak FormatData/sr-Latn-BA/DayNames/2=utorak FormatData/sr-Latn-ME/DayNames/3=srijeda -FormatData/sr-Latn-RS/DayNames/4=\u010detvrtak +FormatData/sr-Latn-RS/DayNames/4=četvrtak # FormatData/sr-Latn/DayAbbreviations/1=pon FormatData/sr-Latn-BA/DayAbbreviations/2=uto FormatData/sr-Latn-ME/DayAbbreviations/3=srijeda -FormatData/sr-Latn-RS/DayAbbreviations/4=\u010det +FormatData/sr-Latn-RS/DayAbbreviations/4=čet # -CurrencyNames/sr-Latn/EUR=\u20ac -CurrencyNames/sr-Latn-BA/EUR=\u20ac +CurrencyNames/sr-Latn/EUR=€ +CurrencyNames/sr-Latn-BA/EUR=€ CurrencyNames/sr-Latn-BA/BAM=KM -CurrencyNames/sr-Latn-ME/EUR=\u20ac -CurrencyNames/sr-Latn-RS/EUR=\u20ac +CurrencyNames/sr-Latn-ME/EUR=€ +CurrencyNames/sr-Latn-RS/EUR=€ # FormatData/sr-Latn/TimePatterns/1=HH:mm:ss z FormatData/sr-Latn-BA/TimePatterns/2=HH:mm:ss @@ -5820,81 +5820,81 @@ FormatData/sr-Latn-RS/DatePatterns/1=d. MMMM y. # bug 7019267 CurrencyNames/pt/adp=Peseta de Andorra -CurrencyNames/pt/aed=Dirham dos Emirados \u00c1rabes Unidos -CurrencyNames/pt/afa=Afegane (1927\u20132002) -CurrencyNames/pt/afn=Afegane afeg\u00e3o -CurrencyNames/pt/all=Lek alban\u00eas -CurrencyNames/pt/amd=Dram arm\u00eanio +CurrencyNames/pt/aed=Dirham dos Emirados Árabes Unidos +CurrencyNames/pt/afa=Afegane (1927–2002) +CurrencyNames/pt/afn=Afegane afegão +CurrencyNames/pt/all=Lek albanês +CurrencyNames/pt/amd=Dram armênio CurrencyNames/pt/ang=Florim das Antilhas Holandesas CurrencyNames/pt/aoa=Kwanza angolano CurrencyNames/pt/ars=Peso argentino -CurrencyNames/pt/ats=Xelim austr\u00edaco -CurrencyNames/pt/aud=D\u00f3lar australiano +CurrencyNames/pt/ats=Xelim austríaco +CurrencyNames/pt/aud=Dólar australiano CurrencyNames/pt/awg=Florim arubano -CurrencyNames/pt/azm=Manat azerbaijano (1993\u20132006) +CurrencyNames/pt/azm=Manat azerbaijano (1993–2006) CurrencyNames/pt/azn=Manat azeri -CurrencyNames/pt/bam=Marco convers\u00edvel da B\u00f3snia e Herzegovina -CurrencyNames/pt/bbd=D\u00f3lar barbadense +CurrencyNames/pt/bam=Marco conversível da Bósnia e Herzegovina +CurrencyNames/pt/bbd=Dólar barbadense CurrencyNames/pt/bdt=Taka bengali CurrencyNames/pt/bef=Franco belga -CurrencyNames/pt/bgl=Lev forte b\u00falgaro -CurrencyNames/pt/bgn=Lev b\u00falgaro +CurrencyNames/pt/bgl=Lev forte búlgaro +CurrencyNames/pt/bgn=Lev búlgaro CurrencyNames/pt/bhd=Dinar bareinita CurrencyNames/pt/bif=Franco burundiano -CurrencyNames/pt/bmd=D\u00f3lar bermudense -CurrencyNames/pt/bnd=D\u00f3lar bruneano +CurrencyNames/pt/bmd=Dólar bermudense +CurrencyNames/pt/bnd=Dólar bruneano CurrencyNames/pt/bov=Mvdol boliviano CurrencyNames/pt/brl=Real brasileiro -CurrencyNames/pt/bsd=D\u00f3lar bahamense -CurrencyNames/pt/btn=Ngultrum butan\u00eas +CurrencyNames/pt/bsd=Dólar bahamense +CurrencyNames/pt/btn=Ngultrum butanês CurrencyNames/pt/bwp=Pula botsuanesa -CurrencyNames/pt/byb=Rublo novo bielo-russo (1994\u20131999) -CurrencyNames/pt/byr=Rublo bielorrusso (2000\u20132016) -CurrencyNames/pt/bzd=D\u00f3lar belizenho -CurrencyNames/pt/cad=D\u00f3lar canadense -CurrencyNames/pt/cdf=Franco congol\u00eas -CurrencyNames/pt/chf=Franco su\u00ed\u00e7o +CurrencyNames/pt/byb=Rublo novo bielo-russo (1994–1999) +CurrencyNames/pt/byr=Rublo bielorrusso (2000–2016) +CurrencyNames/pt/bzd=Dólar belizenho +CurrencyNames/pt/cad=Dólar canadense +CurrencyNames/pt/cdf=Franco congolês +CurrencyNames/pt/chf=Franco suíço CurrencyNames/pt/clf=Unidades de Fomento chilenas CurrencyNames/pt/clp=Peso chileno -CurrencyNames/pt/cny=Yuan chin\u00eas +CurrencyNames/pt/cny=Yuan chinês CurrencyNames/pt/cop=Peso colombiano -CurrencyNames/pt/crc=Col\u00f3n costarriquenho -CurrencyNames/pt/csd=Dinar s\u00e9rvio (2002\u20132006) +CurrencyNames/pt/crc=Colón costarriquenho +CurrencyNames/pt/csd=Dinar sérvio (2002–2006) CurrencyNames/pt/cup=Peso cubano CurrencyNames/pt/cve=Escudo cabo-verdiano CurrencyNames/pt/cyp=Libra cipriota CurrencyNames/pt/czk=Coroa tcheca -CurrencyNames/pt/dem=Marco alem\u00e3o +CurrencyNames/pt/dem=Marco alemão CurrencyNames/pt/djf=Franco djiboutiano CurrencyNames/pt/dkk=Coroa dinamarquesa CurrencyNames/pt/dop=Peso dominicano CurrencyNames/pt/dzd=Dinar argelino CurrencyNames/pt/eek=Coroa estoniana -CurrencyNames/pt/egp=Libra eg\u00edpcia +CurrencyNames/pt/egp=Libra egípcia CurrencyNames/pt/ern=Nakfa da Eritreia CurrencyNames/pt/esp=Peseta espanhola -CurrencyNames/pt/etb=Birr et\u00edope +CurrencyNames/pt/etb=Birr etíope CurrencyNames/pt/fim=Marca finlandesa -CurrencyNames/pt/fjd=D\u00f3lar fijiano +CurrencyNames/pt/fjd=Dólar fijiano CurrencyNames/pt/fkp=Libra malvinense -CurrencyNames/pt/frf=Franco franc\u00eas +CurrencyNames/pt/frf=Franco francês CurrencyNames/pt/gbp=Libra esterlina CurrencyNames/pt/gel=Lari georgiano -CurrencyNames/pt/ghc=Cedi de Gana (1979\u20132007) -CurrencyNames/pt/ghs=Cedi gan\u00eas +CurrencyNames/pt/ghc=Cedi de Gana (1979–2007) +CurrencyNames/pt/ghs=Cedi ganês CurrencyNames/pt/gip=Libra de Gibraltar CurrencyNames/pt/gmd=Dalasi gambiano CurrencyNames/pt/gnf=Franco guineano CurrencyNames/pt/grd=Dracma grego CurrencyNames/pt/gtq=Quetzal guatemalteco -CurrencyNames/pt/gwp=Peso da Guin\u00e9-Bissau -CurrencyNames/pt/gyd=D\u00f3lar guianense -CurrencyNames/pt/hkd=D\u00f3lar de Hong Kong +CurrencyNames/pt/gwp=Peso da Guiné-Bissau +CurrencyNames/pt/gyd=Dólar guianense +CurrencyNames/pt/hkd=Dólar de Hong Kong CurrencyNames/pt/hnl=Lempira hondurenha CurrencyNames/pt/hrk=Kuna croata CurrencyNames/pt/htg=Gourde haitiano -CurrencyNames/pt/huf=Florim h\u00fangaro -CurrencyNames/pt/idr=Rupia indon\u00e9sia +CurrencyNames/pt/huf=Florim húngaro +CurrencyNames/pt/idr=Rupia indonésia CurrencyNames/pt/iep=Libra irlandesa CurrencyNames/pt/ils=Novo shekel israelense CurrencyNames/pt/inr=Rupia indiana @@ -5902,9 +5902,9 @@ CurrencyNames/pt/iqd=Dinar iraquiano CurrencyNames/pt/irr=Rial iraniano CurrencyNames/pt/isk=Coroa islandesa CurrencyNames/pt/itl=Lira italiana -CurrencyNames/pt/jmd=D\u00f3lar jamaicano +CurrencyNames/pt/jmd=Dólar jamaicano CurrencyNames/pt/jod=Dinar jordaniano -CurrencyNames/pt/jpy=Iene japon\u00eas +CurrencyNames/pt/jpy=Iene japonês CurrencyNames/pt/kes=Xelim queniano CurrencyNames/pt/kgs=Som quirguiz CurrencyNames/pt/khr=Riel cambojano @@ -5912,26 +5912,26 @@ CurrencyNames/pt/kmf=Franco comoriano CurrencyNames/pt/kpw=Won norte-coreano CurrencyNames/pt/krw=Won sul-coreano CurrencyNames/pt/kwd=Dinar kuwaitiano -CurrencyNames/pt/kyd=D\u00f3lar das Ilhas Cayman +CurrencyNames/pt/kyd=Dólar das Ilhas Cayman CurrencyNames/pt/kzt=Tenge cazaque CurrencyNames/pt/lak=Kip laosiano CurrencyNames/pt/lbp=Libra libanesa CurrencyNames/pt/lkr=Rupia cingalesa -CurrencyNames/pt/lrd=D\u00f3lar liberiano +CurrencyNames/pt/lrd=Dólar liberiano CurrencyNames/pt/lsl=Loti lesotiano CurrencyNames/pt/ltl=Litas lituano -CurrencyNames/pt/luf=Franco luxemburgu\u00eas -CurrencyNames/pt/lvl=Lats let\u00e3o -CurrencyNames/pt/lyd=Dinar l\u00edbio +CurrencyNames/pt/luf=Franco luxemburguês +CurrencyNames/pt/lvl=Lats letão +CurrencyNames/pt/lyd=Dinar líbio CurrencyNames/pt/mad=Dirham marroquino -CurrencyNames/pt/mdl=Leu mold\u00e1vio +CurrencyNames/pt/mdl=Leu moldávio CurrencyNames/pt/mga=Ariary malgaxe CurrencyNames/pt/mgf=Franco de Madagascar -CurrencyNames/pt/mkd=Dinar maced\u00f4nio +CurrencyNames/pt/mkd=Dinar macedônio CurrencyNames/pt/mmk=Quiate mianmarense CurrencyNames/pt/mnt=Tugrik mongol CurrencyNames/pt/mop=Pataca macaense -CurrencyNames/pt/mro=Ouguiya mauritana (1973\u20132017) +CurrencyNames/pt/mro=Ouguiya mauritana (1973–2017) CurrencyNames/pt/mtl=Lira maltesa CurrencyNames/pt/mur=Rupia mauriciana CurrencyNames/pt/mvr=Rupia maldivana @@ -5939,69 +5939,69 @@ CurrencyNames/pt/mwk=Kwacha malauiana CurrencyNames/pt/mxn=Peso mexicano CurrencyNames/pt/mxv=Unidade Mexicana de Investimento (UDI) CurrencyNames/pt/myr=Ringgit malaio -CurrencyNames/pt/mzm=Metical de Mo\u00e7ambique (1980\u20132006) -CurrencyNames/pt/mzn=Metical mo\u00e7ambicano -CurrencyNames/pt/nad=D\u00f3lar namibiano +CurrencyNames/pt/mzm=Metical de Moçambique (1980–2006) +CurrencyNames/pt/mzn=Metical moçambicano +CurrencyNames/pt/nad=Dólar namibiano CurrencyNames/pt/ngn=Naira nigeriana -CurrencyNames/pt/nio=C\u00f3rdoba nicaraguense -CurrencyNames/pt/nlg=Florim holand\u00eas +CurrencyNames/pt/nio=Córdoba nicaraguense +CurrencyNames/pt/nlg=Florim holandês CurrencyNames/pt/nok=Coroa norueguesa CurrencyNames/pt/npr=Rupia nepalesa -CurrencyNames/pt/nzd=D\u00f3lar neozeland\u00eas +CurrencyNames/pt/nzd=Dólar neozelandês CurrencyNames/pt/omr=Rial omanense CurrencyNames/pt/pab=Balboa panamenho CurrencyNames/pt/pen=Novo sol peruano -CurrencyNames/pt/pgk=Kina papu\u00e1sia +CurrencyNames/pt/pgk=Kina papuásia CurrencyNames/pt/php=Peso filipino CurrencyNames/pt/pkr=Rupia paquistanesa -CurrencyNames/pt/pln=Zloty polon\u00eas -CurrencyNames/pt/pte=Escudo portugu\u00eas +CurrencyNames/pt/pln=Zloty polonês +CurrencyNames/pt/pte=Escudo português CurrencyNames/pt/pyg=Guarani paraguaio CurrencyNames/pt/qar=Rial catariano -CurrencyNames/pt/rol=Leu romeno (1952\u20132006) +CurrencyNames/pt/rol=Leu romeno (1952–2006) CurrencyNames/pt/ron=Leu romeno -CurrencyNames/pt/rsd=Dinar s\u00e9rvio +CurrencyNames/pt/rsd=Dinar sérvio CurrencyNames/pt/rub=Rublo russo -CurrencyNames/pt/rur=Rublo russo (1991\u20131998) -CurrencyNames/pt/rwf=Franco ruand\u00eas +CurrencyNames/pt/rur=Rublo russo (1991–1998) +CurrencyNames/pt/rwf=Franco ruandês CurrencyNames/pt/sar=Riyal saudita -CurrencyNames/pt/sbd=D\u00f3lar das Ilhas Salom\u00e3o +CurrencyNames/pt/sbd=Dólar das Ilhas Salomão CurrencyNames/pt/scr=Rupia seichelense -CurrencyNames/pt/sdd=Dinar sudan\u00eas (1992\u20132007) +CurrencyNames/pt/sdd=Dinar sudanês (1992–2007) CurrencyNames/pt/sdg=Libra sudanesa CurrencyNames/pt/sek=Coroa sueca -CurrencyNames/pt/sgd=D\u00f3lar singapuriano +CurrencyNames/pt/sgd=Dólar singapuriano CurrencyNames/pt/shp=Libra de Santa Helena CurrencyNames/pt/sit=Tolar Bons esloveno CurrencyNames/pt/skk=Coroa eslovaca -CurrencyNames/pt/sll=Leone de Serra Leoa (1964\u20142022) +CurrencyNames/pt/sll=Leone de Serra Leoa (1964—2022) CurrencyNames/pt/sos=Xelim somali -CurrencyNames/pt/srd=D\u00f3lar surinam\u00eas +CurrencyNames/pt/srd=Dólar surinamês CurrencyNames/pt/srg=Florim do Suriname -CurrencyNames/pt/std=Dobra de S\u00e3o Tom\u00e9 e Pr\u00edncipe (1977\u20132017) +CurrencyNames/pt/std=Dobra de São Tomé e Príncipe (1977–2017) CurrencyNames/pt/svc=Colom salvadorenho -CurrencyNames/pt/syp=Libra s\u00edria +CurrencyNames/pt/syp=Libra síria CurrencyNames/pt/szl=Lilangeni suazi -CurrencyNames/pt/thb=Baht tailand\u00eas +CurrencyNames/pt/thb=Baht tailandês CurrencyNames/pt/tjs=Somoni tadjique -CurrencyNames/pt/tmm=Manat do Turcomenist\u00e3o (1993\u20132009) +CurrencyNames/pt/tmm=Manat do Turcomenistão (1993–2009) CurrencyNames/pt/tnd=Dinar tunisiano -CurrencyNames/pt/top=Pa\u02bbanga tonganesa +CurrencyNames/pt/top=Paʻanga tonganesa CurrencyNames/pt/tpe=Escudo timorense -CurrencyNames/pt/trl=Lira turca (1922\u20132005) +CurrencyNames/pt/trl=Lira turca (1922–2005) CurrencyNames/pt/try=Lira turca -CurrencyNames/pt/ttd=D\u00f3lar de Trinidad e Tobago -CurrencyNames/pt/twd=Novo d\u00f3lar taiwan\u00eas +CurrencyNames/pt/ttd=Dólar de Trinidad e Tobago +CurrencyNames/pt/twd=Novo dólar taiwanês CurrencyNames/pt/tzs=Xelim tanzaniano CurrencyNames/pt/uah=Hryvnia ucraniano CurrencyNames/pt/ugx=Xelim ugandense -CurrencyNames/pt/usd=D\u00f3lar americano -CurrencyNames/pt/usn=D\u00f3lar norte-americano (Dia seguinte) -CurrencyNames/pt/uss=D\u00f3lar norte-americano (Mesmo dia) +CurrencyNames/pt/usd=Dólar americano +CurrencyNames/pt/usn=Dólar norte-americano (Dia seguinte) +CurrencyNames/pt/uss=Dólar norte-americano (Mesmo dia) CurrencyNames/pt/uyu=Peso uruguaio CurrencyNames/pt/uzs=Som uzbeque -CurrencyNames/pt/veb=Bol\u00edvar venezuelano (1871\u20132008) -CurrencyNames/pt/vef=Bol\u00edvar venezuelano (2008\u20132018) +CurrencyNames/pt/veb=Bolívar venezuelano (1871–2008) +CurrencyNames/pt/vef=Bolívar venezuelano (2008–2018) CurrencyNames/pt/vnd=Dong vietnamita CurrencyNames/pt/vuv=Vatu de Vanuatu CurrencyNames/pt/wst=Tala samoano @@ -6009,35 +6009,35 @@ CurrencyNames/pt/xaf=Franco CFA de BEAC CurrencyNames/pt/xag=Prata CurrencyNames/pt/xau=Ouro CurrencyNames/pt/xba=Unidade Composta Europeia -CurrencyNames/pt/xbb=Unidade Monet\u00e1ria Europeia +CurrencyNames/pt/xbb=Unidade Monetária Europeia CurrencyNames/pt/xbc=Unidade de Conta Europeia (XBC) CurrencyNames/pt/xbd=Unidade de Conta Europeia (XBD) -CurrencyNames/pt/xcd=D\u00f3lar do Caribe Oriental +CurrencyNames/pt/xcd=Dólar do Caribe Oriental CurrencyNames/pt/xdr=Direitos Especiais de Giro -CurrencyNames/pt/xfo=Franco-ouro franc\u00eas -CurrencyNames/pt/xfu=Franco UIC franc\u00eas +CurrencyNames/pt/xfo=Franco-ouro francês +CurrencyNames/pt/xfu=Franco UIC francês CurrencyNames/pt/xof=Franco CFA de BCEAO -CurrencyNames/pt/xpd=Pal\u00e1dio +CurrencyNames/pt/xpd=Paládio CurrencyNames/pt/xpf=Franco CFP CurrencyNames/pt/xpt=Platina -CurrencyNames/pt/xts=C\u00f3digo de Moeda de Teste +CurrencyNames/pt/xts=Código de Moeda de Teste CurrencyNames/pt/xxx=Moeda desconhecida CurrencyNames/pt/yer=Rial iemenita -CurrencyNames/pt/yum=Dinar noviy iugoslavo (1994\u20132002) +CurrencyNames/pt/yum=Dinar noviy iugoslavo (1994–2002) CurrencyNames/pt/zar=Rand sul-africano -CurrencyNames/pt/zmk=Cuacha zambiano (1968\u20132012) -CurrencyNames/pt/zwd=D\u00f3lar do Zimb\u00e1bue (1980\u20132008) +CurrencyNames/pt/zmk=Cuacha zambiano (1968–2012) +CurrencyNames/pt/zwd=Dólar do Zimbábue (1980–2008) # bug 7025837 -CurrencyNames/sr-Latn-BA/bam=Bosanskohercegova\u010dka konvertibilna marka +CurrencyNames/sr-Latn-BA/bam=Bosanskohercegovačka konvertibilna marka CurrencyNames/sr-Latn-BA/eur=evro CurrencyNames/sr-Latn-ME/eur=evro CurrencyNames/sr-Latn-RS/rsd=srpski dinar # bug 7020583 -CurrencyNames/de/azm=Aserbaidschan-Manat (1993\u20132006) +CurrencyNames/de/azm=Aserbaidschan-Manat (1993–2006) CurrencyNames/de/azn=Aserbaidschan-Manat -CurrencyNames/de/csd=Serbischer Dinar (2002\u20132006) +CurrencyNames/de/csd=Serbischer Dinar (2002–2006) CurrencyNames/de/cyp=Zypern-Pfund CurrencyNames/de/esp=Spanische Peseta CurrencyNames/de/fjd=Fidschi-Dollar @@ -6052,11 +6052,11 @@ CurrencyNames/de/jmd=Jamaika-Dollar CurrencyNames/de/kes=Kenia-Schilling CurrencyNames/de/mgf=Madagaskar-Franc CurrencyNames/de/mur=Mauritius-Rupie -CurrencyNames/de/mzm=Mosambikanischer Metical (1980\u20132006) +CurrencyNames/de/mzm=Mosambikanischer Metical (1980–2006) CurrencyNames/de/mzn=Mosambikanischer Metical CurrencyNames/de/nad=Namibia-Dollar CurrencyNames/de/nzd=Neuseeland-Dollar -CurrencyNames/de/ron=Rum\u00e4nischer Leu +CurrencyNames/de/ron=Rumänischer Leu CurrencyNames/de/rsd=Serbischer Dinar CurrencyNames/de/rwf=Ruanda-Franc CurrencyNames/de/sbd=Salomonen-Dollar @@ -6066,226 +6066,226 @@ CurrencyNames/de/sgd=Singapur-Dollar CurrencyNames/de/sos=Somalia-Schilling CurrencyNames/de/srd=Suriname-Dollar CurrencyNames/de/tpe=Timor-Escudo -CurrencyNames/de/trl=T\u00fcrkische Lira (1922\u20132005) -CurrencyNames/de/try=T\u00fcrkische Lira +CurrencyNames/de/trl=Türkische Lira (1922–2005) +CurrencyNames/de/try=Türkische Lira CurrencyNames/de/ttd=Trinidad-und-Tobago-Dollar CurrencyNames/de/twd=Neuer Taiwan-Dollar CurrencyNames/de/tzs=Tansania-Schilling CurrencyNames/de/ugx=Uganda-Schilling CurrencyNames/de/usd=US-Dollar -CurrencyNames/de/vef=Venezolanischer Bol\u00edvar (2008\u20132018) +CurrencyNames/de/vef=Venezolanischer Bolívar (2008–2018) CurrencyNames/de/xag=Unze Silber CurrencyNames/de/xau=Unze Gold -CurrencyNames/de/xbb=Europ\u00e4ische W\u00e4hrungseinheit (XBB) +CurrencyNames/de/xbb=Europäische Währungseinheit (XBB) CurrencyNames/de/xpd=Unze Palladium CurrencyNames/de/xpt=Unze Platin -CurrencyNames/de/xts=Testw\u00e4hrung -CurrencyNames/de/xxx=Unbekannte W\u00e4hrung +CurrencyNames/de/xts=Testwährung +CurrencyNames/de/xxx=Unbekannte Währung CurrencyNames/de/yer=Jemen-Rial -CurrencyNames/de/zar=S\u00fcdafrikanischer Rand -CurrencyNames/de/zwd=Simbabwe-Dollar (1980\u20132008) +CurrencyNames/de/zar=Südafrikanischer Rand +CurrencyNames/de/zwd=Simbabwe-Dollar (1980–2008) -CurrencyNames/es/aed=d\u00edrham de los Emiratos \u00c1rabes Unidos -CurrencyNames/es/azm=manat azer\u00ed (1993\u20132006) +CurrencyNames/es/aed=dírham de los Emiratos Árabes Unidos +CurrencyNames/es/azm=manat azerí (1993–2006) CurrencyNames/es/azn=manat azerbaiyano CurrencyNames/es/csd=antiguo dinar serbio -CurrencyNames/es/ghc=cedi ghan\u00e9s (1979\u20132007) -CurrencyNames/es/ghs=cedi ghan\u00e9s -CurrencyNames/es/mzm=antiguo metical mozambique\u00f1o -CurrencyNames/es/mzn=metical mozambique\u00f1o +CurrencyNames/es/ghc=cedi ghanés (1979–2007) +CurrencyNames/es/ghs=cedi ghanés +CurrencyNames/es/mzm=antiguo metical mozambiqueño +CurrencyNames/es/mzn=metical mozambiqueño CurrencyNames/es/rsd=dinar serbio CurrencyNames/es/sdg=libra sudanesa -CurrencyNames/es/trl=lira turca (1922\u20132005) -CurrencyNames/es/vef=bol\u00edvar venezolano (2008\u20132018) +CurrencyNames/es/trl=lira turca (1922–2005) +CurrencyNames/es/vef=bolívar venezolano (2008–2018) -CurrencyNames/fr/afa=afghani (1927\u20132002) +CurrencyNames/fr/afa=afghani (1927–2002) CurrencyNames/fr/all=lek albanais CurrencyNames/fr/ang=florin antillais CurrencyNames/fr/awg=florin arubais -CurrencyNames/fr/azm=manat az\u00e9ri (1993\u20132006) -CurrencyNames/fr/azn=manat az\u00e9ri +CurrencyNames/fr/azm=manat azéri (1993–2006) +CurrencyNames/fr/azn=manat azéri CurrencyNames/fr/bam=mark convertible bosniaque CurrencyNames/fr/bbd=dollar barbadien CurrencyNames/fr/bdt=taka bangladeshi -CurrencyNames/fr/bgl=lev bulgare (1962\u20131999) +CurrencyNames/fr/bgl=lev bulgare (1962–1999) CurrencyNames/fr/bgn=lev bulgare -CurrencyNames/fr/bhd=dinar bahre\u00efni +CurrencyNames/fr/bhd=dinar bahreïni CurrencyNames/fr/bif=franc burundais CurrencyNames/fr/bmd=dollar bermudien -CurrencyNames/fr/bnd=dollar brun\u00e9ien +CurrencyNames/fr/bnd=dollar brunéien CurrencyNames/fr/bov=mvdol bolivien -CurrencyNames/fr/brl=r\u00e9al br\u00e9silien -CurrencyNames/fr/bsd=dollar baham\u00e9en +CurrencyNames/fr/brl=réal brésilien +CurrencyNames/fr/bsd=dollar bahaméen CurrencyNames/fr/btn=ngultrum bouthanais CurrencyNames/fr/bwp=pula botswanais -CurrencyNames/fr/bzd=dollar b\u00e9liz\u00e9en +CurrencyNames/fr/bzd=dollar bélizéen CurrencyNames/fr/cny=yuan renminbi chinois -CurrencyNames/fr/crc=col\u00f3n costaricain -CurrencyNames/fr/csd=dinar serbo-mont\u00e9n\u00e9grin +CurrencyNames/fr/crc=colón costaricain +CurrencyNames/fr/csd=dinar serbo-monténégrin CurrencyNames/fr/cve=escudo capverdien CurrencyNames/fr/cyp=livre chypriote CurrencyNames/fr/dem=mark allemand CurrencyNames/fr/djf=franc djiboutien -CurrencyNames/fr/ern=nafka \u00e9rythr\u00e9en -CurrencyNames/fr/etb=birr \u00e9thiopien +CurrencyNames/fr/ern=nafka érythréen +CurrencyNames/fr/etb=birr éthiopien CurrencyNames/fr/fjd=dollar fidjien -CurrencyNames/fr/fkp=livre des \u00eeles Malouines -CurrencyNames/fr/gel=lari g\u00e9orgien -CurrencyNames/fr/ghs=c\u00e9di ghan\u00e9en +CurrencyNames/fr/fkp=livre des îles Malouines +CurrencyNames/fr/gel=lari géorgien +CurrencyNames/fr/ghs=cédi ghanéen CurrencyNames/fr/gmd=dalasi gambien CurrencyNames/fr/grd=drachme grecque -CurrencyNames/fr/gtq=quetzal guat\u00e9malt\u00e8que -CurrencyNames/fr/gwp=peso bissau-guin\u00e9en +CurrencyNames/fr/gtq=quetzal guatémaltèque +CurrencyNames/fr/gwp=peso bissau-guinéen CurrencyNames/fr/hnl=lempira hondurien CurrencyNames/fr/hrk=kuna croate -CurrencyNames/fr/htg=gourde ha\u00eftienne +CurrencyNames/fr/htg=gourde haïtienne CurrencyNames/fr/huf=forint hongrois -CurrencyNames/fr/idr=roupie indon\u00e9sienne -CurrencyNames/fr/ils=nouveau shekel isra\u00e9lien +CurrencyNames/fr/idr=roupie indonésienne +CurrencyNames/fr/ils=nouveau shekel israélien CurrencyNames/fr/iqd=dinar irakien CurrencyNames/fr/jpy=yen japonais -CurrencyNames/fr/kes=shilling k\u00e9nyan +CurrencyNames/fr/kes=shilling kényan CurrencyNames/fr/kgs=som kirghize CurrencyNames/fr/khr=riel cambodgien CurrencyNames/fr/kmf=franc comorien -CurrencyNames/fr/kwd=dinar kowe\u00eftien +CurrencyNames/fr/kwd=dinar koweïtien CurrencyNames/fr/kzt=tenge kazakh CurrencyNames/fr/lak=kip laotien CurrencyNames/fr/lkr=roupie srilankaise CurrencyNames/fr/lsl=loti lesothan CurrencyNames/fr/mga=ariary malgache -CurrencyNames/fr/mkd=denar mac\u00e9donien +CurrencyNames/fr/mkd=denar macédonien CurrencyNames/fr/mmk=kyat myanmarais CurrencyNames/fr/mnt=tugrik mongol CurrencyNames/fr/mop=pataca macanaise -CurrencyNames/fr/mro=ouguiya mauritanien (1973\u20132017) +CurrencyNames/fr/mro=ouguiya mauritanien (1973–2017) CurrencyNames/fr/mvr=rufiyaa maldivienne CurrencyNames/fr/mwk=kwacha malawite CurrencyNames/fr/myr=ringgit malais CurrencyNames/fr/mzn=metical mozambicain -CurrencyNames/fr/ngn=naira nig\u00e9rian -CurrencyNames/fr/nio=c\u00f3rdoba oro nicaraguayen -CurrencyNames/fr/npr=roupie n\u00e9palaise -CurrencyNames/fr/pab=balboa panam\u00e9en -CurrencyNames/fr/pgk=kina papouan-n\u00e9o-guin\u00e9en +CurrencyNames/fr/ngn=naira nigérian +CurrencyNames/fr/nio=córdoba oro nicaraguayen +CurrencyNames/fr/npr=roupie népalaise +CurrencyNames/fr/pab=balboa panaméen +CurrencyNames/fr/pgk=kina papouan-néo-guinéen CurrencyNames/fr/pkr=roupie pakistanaise CurrencyNames/fr/pln=zloty polonais -CurrencyNames/fr/pyg=guaran\u00ed paraguayen +CurrencyNames/fr/pyg=guaraní paraguayen CurrencyNames/fr/qar=riyal qatari CurrencyNames/fr/ron=leu roumain CurrencyNames/fr/rsd=dinar serbe CurrencyNames/fr/rub=rouble russe -CurrencyNames/fr/rur=rouble russe (1991\u20131998) -CurrencyNames/fr/sbd=dollar des \u00eeles Salomon +CurrencyNames/fr/rur=rouble russe (1991–1998) +CurrencyNames/fr/sbd=dollar des îles Salomon CurrencyNames/fr/sdg=livre soudanaise -CurrencyNames/fr/sit=tolar slov\u00e8ne -CurrencyNames/fr/sll=leone sierra-l\u00e9onais (1964\u20142022) +CurrencyNames/fr/sit=tolar slovène +CurrencyNames/fr/sll=leone sierra-léonais (1964—2022) CurrencyNames/fr/sos=shilling somalien CurrencyNames/fr/srg=florin surinamais -CurrencyNames/fr/std=dobra santom\u00e9en (1977\u20132017) -CurrencyNames/fr/svc=col\u00f3n salvadorien +CurrencyNames/fr/std=dobra santoméen (1977–2017) +CurrencyNames/fr/svc=colón salvadorien CurrencyNames/fr/szl=lilangeni swazi -CurrencyNames/fr/thb=baht tha\u00eflandais +CurrencyNames/fr/thb=baht thaïlandais CurrencyNames/fr/tjs=somoni tadjik -CurrencyNames/fr/tmm=manat turkm\u00e8ne -CurrencyNames/fr/top=pa\u2019anga tongan +CurrencyNames/fr/tmm=manat turkmène +CurrencyNames/fr/top=pa’anga tongan CurrencyNames/fr/tpe=escudo timorais -CurrencyNames/fr/ttd=dollar de Trinit\u00e9-et-Tobago -CurrencyNames/fr/twd=nouveau dollar ta\u00efwanais +CurrencyNames/fr/ttd=dollar de Trinité-et-Tobago +CurrencyNames/fr/twd=nouveau dollar taïwanais CurrencyNames/fr/tzs=shilling tanzanien CurrencyNames/fr/uah=hryvnia ukrainienne CurrencyNames/fr/uzs=sum ouzbek -CurrencyNames/fr/vef=bolivar v\u00e9n\u00e9zu\u00e9lien (2008\u20132018) -CurrencyNames/fr/vnd=d\u00f4ng vietnamien +CurrencyNames/fr/vef=bolivar vénézuélien (2008–2018) +CurrencyNames/fr/vnd=dông vietnamien CurrencyNames/fr/vuv=vatu vanuatuan CurrencyNames/fr/wst=tala samoan CurrencyNames/fr/xts=(devise de test) CurrencyNames/fr/xxx=devise inconnue ou non valide -CurrencyNames/fr/yer=riyal y\u00e9m\u00e9nite +CurrencyNames/fr/yer=riyal yéménite CurrencyNames/fr/zar=rand sud-africain -CurrencyNames/fr/zmk=kwacha zambien (1968\u20132012) -CurrencyNames/fr/zwd=dollar zimbabw\u00e9en +CurrencyNames/fr/zmk=kwacha zambien (1968–2012) +CurrencyNames/fr/zwd=dollar zimbabwéen -CurrencyNames/it/azm=manat azero (1993\u20132006) +CurrencyNames/it/azm=manat azero (1993–2006) CurrencyNames/it/ghs=cedi ghanese CurrencyNames/it/iep=sterlina irlandese CurrencyNames/it/mzn=metical mozambicano CurrencyNames/it/rsd=dinaro serbo CurrencyNames/it/sdg=sterlina sudanese CurrencyNames/it/srd=dollaro del Suriname -CurrencyNames/it/vef=bol\u00edvar venezuelano (2008\u20132018) +CurrencyNames/it/vef=bolívar venezuelano (2008–2018) CurrencyNames/it/xag=argento CurrencyNames/it/xpd=palladio -CurrencyNames/ja/azm=\u30a2\u30bc\u30eb\u30d0\u30a4\u30b8\u30e3\u30f3 \u30de\u30ca\u30c8 (1993\u20132006) -CurrencyNames/ja/azn=\u30a2\u30bc\u30eb\u30d0\u30a4\u30b8\u30e3\u30f3 \u30de\u30ca\u30c8 -CurrencyNames/ja/ghc=\u30ac\u30fc\u30ca \u30bb\u30c7\u30a3 (1979\u20132007) -CurrencyNames/ja/ghs=\u30ac\u30fc\u30ca \u30bb\u30c7\u30a3 -CurrencyNames/ja/mzn=\u30e2\u30b6\u30f3\u30d3\u30fc\u30af \u30e1\u30c6\u30a3\u30ab\u30eb -CurrencyNames/ja/rol=\u30eb\u30fc\u30de\u30cb\u30a2 \u30ec\u30a4 (1952\u20132006) -CurrencyNames/ja/ron=\u30eb\u30fc\u30de\u30cb\u30a2 \u30ec\u30a4 -CurrencyNames/ja/rsd=\u30bb\u30eb\u30d3\u30a2 \u30c7\u30a3\u30ca\u30fc\u30eb -CurrencyNames/ja/sdg=\u30b9\u30fc\u30c0\u30f3 \u30dd\u30f3\u30c9 -CurrencyNames/ja/srd=\u30b9\u30ea\u30ca\u30e0 \u30c9\u30eb -CurrencyNames/ja/vef=\u30d9\u30cd\u30ba\u30a8\u30e9 \u30dc\u30ea\u30d0\u30eb (2008\u20132018) -CurrencyNames/ja/xag=\u9280 -CurrencyNames/ja/xpd=\u30d1\u30e9\u30b8\u30a6\u30e0 -CurrencyNames/ja/xpt=\u30d7\u30e9\u30c1\u30ca -CurrencyNames/ja/xts=\u30c6\u30b9\u30c8\u7528\u901a\u8ca8\u30b3\u30fc\u30c9 -CurrencyNames/ja/xxx=\u4e0d\u660e\u307e\u305f\u306f\u7121\u52b9\u306a\u901a\u8ca8 -CurrencyNames/ja/zmk=\u30b6\u30f3\u30d3\u30a2 \u30af\u30ef\u30c1\u30e3 (1968\u20132012) +CurrencyNames/ja/azm=アゼルバイジャン マナト (1993–2006) +CurrencyNames/ja/azn=アゼルバイジャン マナト +CurrencyNames/ja/ghc=ガーナ セディ (1979–2007) +CurrencyNames/ja/ghs=ガーナ セディ +CurrencyNames/ja/mzn=モザンビーク メティカル +CurrencyNames/ja/rol=ルーマニア レイ (1952–2006) +CurrencyNames/ja/ron=ルーマニア レイ +CurrencyNames/ja/rsd=セルビア ディナール +CurrencyNames/ja/sdg=スーダン ポンド +CurrencyNames/ja/srd=スリナム ドル +CurrencyNames/ja/vef=ベネズエラ ボリバル (2008–2018) +CurrencyNames/ja/xag=銀 +CurrencyNames/ja/xpd=パラジウム +CurrencyNames/ja/xpt=プラチナ +CurrencyNames/ja/xts=テスト用通貨コード +CurrencyNames/ja/xxx=不明または無効な通貨 +CurrencyNames/ja/zmk=ザンビア クワチャ (1968–2012) -CurrencyNames/ko/aed=\uc544\ub78d\uc5d0\ubbf8\ub9ac\ud2b8 \ub514\ub974\ud568 -CurrencyNames/ko/ang=\ub124\ub35c\ub780\ub4dc\ub839 \uc548\ud2f8\ub808\uc2a4 \uae38\ub354 -CurrencyNames/ko/azm=\uc544\uc81c\ub974\ubc14\uc774\uc820 \ub9c8\ub098\ud2b8(1993\u20132006) -CurrencyNames/ko/azn=\uc544\uc81c\ub974\ubc14\uc774\uc794 \ub9c8\ub098\ud2b8 -CurrencyNames/ko/bov=\ubcfc\ub9ac\ube44\uc544\ub178 Mvdol(\uae30\uae08) -CurrencyNames/ko/chf=\uc2a4\uc704\uc2a4 \ud504\ub791 -CurrencyNames/ko/clf=\uce60\ub808 (UF) -CurrencyNames/ko/csd=\uace0 \uc138\ub974\ube44\uc544 \ub514\ub098\ub974 -CurrencyNames/ko/ghc=\uac00\ub098 \uc2dc\ub514 (1979\u20132007) -CurrencyNames/ko/ghs=\uac00\ub098 \uc138\ub514 -CurrencyNames/ko/mxv=\uba55\uc2dc\ucf54 (UDI) -CurrencyNames/ko/myr=\ub9d0\ub808\uc774\uc2dc\uc544 \ub9c1\uae43 -CurrencyNames/ko/mzm=\uace0 \ubaa8\uc7a0\ube44\ud06c \uba54\ud2f0\uce7c -CurrencyNames/ko/mzn=\ubaa8\uc7a0\ube44\ud06c \uba54\ud2f0\uce7c -CurrencyNames/ko/ron=\ub8e8\ub9c8\ub2c8\uc544 \ub808\uc6b0 -CurrencyNames/ko/rsd=\uc138\ub974\ube44\uc544 \ub514\ub098\ub974 -CurrencyNames/ko/sdg=\uc218\ub2e8 \ud30c\uc6b4\ub4dc -CurrencyNames/ko/srd=\uc218\ub9ac\ub0a8 \ub2ec\ub7ec -CurrencyNames/ko/top=\ud1b5\uac00 \ud30c\uc559\uac00 -CurrencyNames/ko/trl=\ud130\ud0a4 \ub9ac\ub77c(1922~2005) -CurrencyNames/ko/try=\ud280\ub974\ud0a4\uc608 \ub9ac\ub77c -CurrencyNames/ko/usn=\ubbf8\uad6d \ub2ec\ub7ec(\ub2e4\uc74c\ub0a0) -CurrencyNames/ko/uss=\ubbf8\uad6d \ub2ec\ub7ec(\ub2f9\uc77c) -CurrencyNames/ko/vef=\ubca0\ub124\uc218\uc5d8\ub77c \ubcfc\ub9ac\ubc14\ub974 (2008\u20132018) -CurrencyNames/ko/xaf=\uc911\uc559\uc544\ud504\ub9ac\uce74 CFA \ud504\ub791 -CurrencyNames/ko/xag=\uc740\ud654 -CurrencyNames/ko/xba=\uc720\ub974\ucf54 (\uc720\ub7fd \ud68c\uacc4 \ub2e8\uc704) -CurrencyNames/ko/xbb=\uc720\ub7fd \ud1b5\ud654 \ub3d9\ub9f9 -CurrencyNames/ko/xbc=\uc720\ub7fd \uacc4\uc0b0 \ub2e8\uc704 (XBC) -CurrencyNames/ko/xbd=\uc720\ub7fd \uacc4\uc0b0 \ub2e8\uc704 (XBD) -CurrencyNames/ko/xof=\uc11c\uc544\ud504\ub9ac\uce74 CFA \ud504\ub791 -CurrencyNames/ko/xpd=\ud314\ub77c\ub4d0 -CurrencyNames/ko/xpf=CFP \ud504\ub791 -CurrencyNames/ko/xpt=\ubc31\uae08 -CurrencyNames/ko/xts=\ud14c\uc2a4\ud2b8 \ud1b5\ud654 \ucf54\ub4dc -CurrencyNames/ko/xxx=\uc54c \uc218 \uc5c6\ub294 \ud1b5\ud654 \ub2e8\uc704 -CurrencyNames/ko/zwd=\uc9d0\ubc14\ube0c\uc6e8 \ub2ec\ub7ec +CurrencyNames/ko/aed=아랍에미리트 디르함 +CurrencyNames/ko/ang=네덜란드령 안틸레스 길더 +CurrencyNames/ko/azm=아제르바이젠 마나트(1993–2006) +CurrencyNames/ko/azn=아제르바이잔 마나트 +CurrencyNames/ko/bov=볼리비아노 Mvdol(기금) +CurrencyNames/ko/chf=스위스 프랑 +CurrencyNames/ko/clf=칠레 (UF) +CurrencyNames/ko/csd=고 세르비아 디나르 +CurrencyNames/ko/ghc=가나 시디 (1979–2007) +CurrencyNames/ko/ghs=가나 세디 +CurrencyNames/ko/mxv=멕시코 (UDI) +CurrencyNames/ko/myr=말레이시아 링깃 +CurrencyNames/ko/mzm=고 모잠비크 메티칼 +CurrencyNames/ko/mzn=모잠비크 메티칼 +CurrencyNames/ko/ron=루마니아 레우 +CurrencyNames/ko/rsd=세르비아 디나르 +CurrencyNames/ko/sdg=수단 파운드 +CurrencyNames/ko/srd=수리남 달러 +CurrencyNames/ko/top=통가 파앙가 +CurrencyNames/ko/trl=터키 리라(1922~2005) +CurrencyNames/ko/try=튀르키예 리라 +CurrencyNames/ko/usn=미국 달러(다음날) +CurrencyNames/ko/uss=미국 달러(당일) +CurrencyNames/ko/vef=베네수엘라 볼리바르 (2008–2018) +CurrencyNames/ko/xaf=중앙아프리카 CFA 프랑 +CurrencyNames/ko/xag=은화 +CurrencyNames/ko/xba=유르코 (유럽 회계 단위) +CurrencyNames/ko/xbb=유럽 통화 동맹 +CurrencyNames/ko/xbc=유럽 계산 단위 (XBC) +CurrencyNames/ko/xbd=유럽 계산 단위 (XBD) +CurrencyNames/ko/xof=서아프리카 CFA 프랑 +CurrencyNames/ko/xpd=팔라듐 +CurrencyNames/ko/xpf=CFP 프랑 +CurrencyNames/ko/xpt=백금 +CurrencyNames/ko/xts=테스트 통화 코드 +CurrencyNames/ko/xxx=알 수 없는 통화 단위 +CurrencyNames/ko/zwd=짐바브웨 달러 CurrencyNames/sv/adp=andorransk peseta CurrencyNames/sv/aed=emiratisk dirham -CurrencyNames/sv/afa=afghani (1927\u20132002) +CurrencyNames/sv/afa=afghani (1927–2002) CurrencyNames/sv/afn=afghansk afghani CurrencyNames/sv/all=albansk lek CurrencyNames/sv/amd=armenisk dram CurrencyNames/sv/ang=antillergulden CurrencyNames/sv/aoa=angolansk kwanza CurrencyNames/sv/ars=argentinsk peso -CurrencyNames/sv/ats=\u00f6sterrikisk schilling +CurrencyNames/sv/ats=österrikisk schilling CurrencyNames/sv/aud=australisk dollar CurrencyNames/sv/awg=arubansk florin -CurrencyNames/sv/azm=azerbajdzjansk manat (1993\u20132006) +CurrencyNames/sv/azm=azerbajdzjansk manat (1993–2006) CurrencyNames/sv/azn=azerbajdzjansk manat CurrencyNames/sv/bam=bosnisk-hercegovinsk mark (konvertibel) CurrencyNames/sv/bbd=barbadisk dollar @@ -6301,8 +6301,8 @@ CurrencyNames/sv/brl=brasiliansk real CurrencyNames/sv/bsd=bahamansk dollar CurrencyNames/sv/btn=bhutanesisk ngultrum CurrencyNames/sv/bwp=botswansk pula -CurrencyNames/sv/byb=belarusisk ny rubel (1994\u20131999) -CurrencyNames/sv/byr=belarusisk rubel (2000\u20132016) +CurrencyNames/sv/byb=belarusisk ny rubel (1994–1999) +CurrencyNames/sv/byr=belarusisk rubel (2000–2016) CurrencyNames/sv/bzd=belizisk dollar CurrencyNames/sv/cad=kanadensisk dollar CurrencyNames/sv/cdf=kongolesisk franc @@ -6311,8 +6311,8 @@ CurrencyNames/sv/clf=chilensk unidad de fomento CurrencyNames/sv/clp=chilensk peso CurrencyNames/sv/cny=kinesisk yuan CurrencyNames/sv/cop=colombiansk peso -CurrencyNames/sv/crc=costarikansk col\u00f3n -CurrencyNames/sv/csd=serbisk dinar (2002\u20132006) +CurrencyNames/sv/crc=costarikansk colón +CurrencyNames/sv/csd=serbisk dinar (2002–2006) CurrencyNames/sv/cup=kubansk peso CurrencyNames/sv/cve=kapverdisk escudo CurrencyNames/sv/cyp=cypriotiskt pund @@ -6333,7 +6333,7 @@ CurrencyNames/sv/fjd=Fijidollar CurrencyNames/sv/frf=fransk franc CurrencyNames/sv/gbp=brittiskt pund CurrencyNames/sv/gel=georgisk lari -CurrencyNames/sv/ghc=ghanansk cedi (1979\u20132007) +CurrencyNames/sv/ghc=ghanansk cedi (1979–2007) CurrencyNames/sv/ghs=ghanansk cedi CurrencyNames/sv/gip=gibraltiskt pund CurrencyNames/sv/gmd=gambisk dalasi @@ -6346,12 +6346,12 @@ CurrencyNames/sv/hrk=kroatisk kuna CurrencyNames/sv/htg=haitisk gourde CurrencyNames/sv/huf=ungersk forint CurrencyNames/sv/idr=indonesisk rupie -CurrencyNames/sv/iep=irl\u00e4ndskt pund +CurrencyNames/sv/iep=irländskt pund CurrencyNames/sv/ils=israelisk ny shekel CurrencyNames/sv/inr=indisk rupie CurrencyNames/sv/iqd=irakisk dinar CurrencyNames/sv/irr=iransk rial -CurrencyNames/sv/isk=isl\u00e4ndsk krona +CurrencyNames/sv/isk=isländsk krona CurrencyNames/sv/itl=italiensk lire CurrencyNames/sv/jmd=jamaicansk dollar CurrencyNames/sv/jod=jordansk dinar @@ -6379,9 +6379,9 @@ CurrencyNames/sv/mga=madagaskisk ariary CurrencyNames/sv/mgf=madagaskisk franc CurrencyNames/sv/mkd=makedonisk denar CurrencyNames/sv/mmk=myanmarisk kyat -CurrencyNames/sv/mnt=mongolisk t\u00f6gr\u00f6g +CurrencyNames/sv/mnt=mongolisk tögrög CurrencyNames/sv/mop=makanesisk pataca -CurrencyNames/sv/mro=mauretansk ouguiya (1973\u20132017) +CurrencyNames/sv/mro=mauretansk ouguiya (1973–2017) CurrencyNames/sv/mtl=maltesisk lire CurrencyNames/sv/mur=mauritisk rupie CurrencyNames/sv/mvr=maldivisk rufiyaa @@ -6389,15 +6389,15 @@ CurrencyNames/sv/mwk=malawisk kwacha CurrencyNames/sv/mxn=mexikansk peso CurrencyNames/sv/mxv=mexikansk unidad de inversion CurrencyNames/sv/myr=malaysisk ringgit -CurrencyNames/sv/mzm=gammal mo\u00e7ambikisk metical -CurrencyNames/sv/mzn=mo\u00e7ambikisk metical +CurrencyNames/sv/mzm=gammal moçambikisk metical +CurrencyNames/sv/mzn=moçambikisk metical CurrencyNames/sv/nad=namibisk dollar CurrencyNames/sv/ngn=nigeriansk naira -CurrencyNames/sv/nio=nicaraguansk c\u00f3rdoba -CurrencyNames/sv/nlg=nederl\u00e4ndsk gulden +CurrencyNames/sv/nio=nicaraguansk córdoba +CurrencyNames/sv/nlg=nederländsk gulden CurrencyNames/sv/nok=norsk krona CurrencyNames/sv/npr=nepalesisk rupie -CurrencyNames/sv/nzd=nyzeel\u00e4ndsk dollar +CurrencyNames/sv/nzd=nyzeeländsk dollar CurrencyNames/sv/omr=omansk rial CurrencyNames/sv/pab=panamansk balboa CurrencyNames/sv/pen=peruansk sol @@ -6408,34 +6408,34 @@ CurrencyNames/sv/pln=polsk zloty CurrencyNames/sv/pte=portugisisk escudo CurrencyNames/sv/pyg=paraguayansk guarani CurrencyNames/sv/qar=qatarisk rial -CurrencyNames/sv/rol=rum\u00e4nsk leu (1952\u20132005) -CurrencyNames/sv/ron=rum\u00e4nsk leu +CurrencyNames/sv/rol=rumänsk leu (1952–2005) +CurrencyNames/sv/ron=rumänsk leu CurrencyNames/sv/rsd=serbisk dinar CurrencyNames/sv/rub=rysk rubel -CurrencyNames/sv/rur=rysk rubel (1991\u20131998) +CurrencyNames/sv/rur=rysk rubel (1991–1998) CurrencyNames/sv/rwf=rwandisk franc CurrencyNames/sv/sar=saudisk riyal CurrencyNames/sv/scr=seychellisk rupie -CurrencyNames/sv/sdd=sudansk dinar (1992\u20132007) +CurrencyNames/sv/sdd=sudansk dinar (1992–2007) CurrencyNames/sv/sdg=sudanesiskt pund CurrencyNames/sv/sek=svensk krona CurrencyNames/sv/sgd=singaporiansk dollar CurrencyNames/sv/sit=slovensk tolar CurrencyNames/sv/skk=slovakisk koruna -CurrencyNames/sv/sll=sierraleonsk leone (1964\u20142022) +CurrencyNames/sv/sll=sierraleonsk leone (1964—2022) CurrencyNames/sv/sos=somalisk shilling CurrencyNames/sv/srd=surinamesisk dollar CurrencyNames/sv/srg=surinamesisk gulden -CurrencyNames/sv/svc=salvadoransk col\u00f3n +CurrencyNames/sv/svc=salvadoransk colón CurrencyNames/sv/syp=syriskt pund -CurrencyNames/sv/szl=swazil\u00e4ndsk lilangeni -CurrencyNames/sv/thb=thail\u00e4ndsk baht +CurrencyNames/sv/szl=swaziländsk lilangeni +CurrencyNames/sv/thb=thailändsk baht CurrencyNames/sv/tjs=tadzjikisk somoni -CurrencyNames/sv/tmm=turkmenistansk manat (1993\u20132009) +CurrencyNames/sv/tmm=turkmenistansk manat (1993–2009) CurrencyNames/sv/tnd=tunisisk dinar -CurrencyNames/sv/top=tongansk pa\u02bbanga -CurrencyNames/sv/tpe=\u00f6sttimoresisk escudo -CurrencyNames/sv/trl=turkisk lire (1922\u20132005) +CurrencyNames/sv/top=tongansk paʻanga +CurrencyNames/sv/tpe=östtimoresisk escudo +CurrencyNames/sv/trl=turkisk lire (1922–2005) CurrencyNames/sv/try=turkisk lira CurrencyNames/sv/ttd=Trinidaddollar CurrencyNames/sv/twd=taiwanesisk dollar @@ -6444,94 +6444,94 @@ CurrencyNames/sv/uah=ukrainsk hryvnia CurrencyNames/sv/ugx=ugandisk shilling CurrencyNames/sv/uyu=uruguayansk peso CurrencyNames/sv/uzs=uzbekisk sum -CurrencyNames/sv/veb=venezuelansk bolivar (1871\u20132008) -CurrencyNames/sv/vef=venezuelansk bol\u00edvar (2008\u20132018) +CurrencyNames/sv/veb=venezuelansk bolivar (1871–2008) +CurrencyNames/sv/vef=venezuelansk bolívar (2008–2018) CurrencyNames/sv/vnd=vietnamesisk dong CurrencyNames/sv/vuv=vanuatisk vatu -CurrencyNames/sv/wst=v\u00e4stsamoansk tala +CurrencyNames/sv/wst=västsamoansk tala CurrencyNames/sv/xag=silver CurrencyNames/sv/xau=guld CurrencyNames/sv/xba=europeisk kompositenhet -CurrencyNames/sv/xbb=europeisk monet\u00e4r enhet +CurrencyNames/sv/xbb=europeisk monetär enhet CurrencyNames/sv/xbc=europeisk kontoenhet (XBC) CurrencyNames/sv/xbd=europeisk kontoenhet (XBD) -CurrencyNames/sv/xcd=\u00f6stkaribisk dollar -CurrencyNames/sv/xdr=IMF s\u00e4rskild dragningsr\u00e4tt +CurrencyNames/sv/xcd=östkaribisk dollar +CurrencyNames/sv/xdr=IMF särskild dragningsrätt CurrencyNames/sv/xfo=fransk guldfranc CurrencyNames/sv/xpd=palladium CurrencyNames/sv/xpt=platina CurrencyNames/sv/xts=testvalutaenhet -CurrencyNames/sv/xxx=ok\u00e4nd valuta +CurrencyNames/sv/xxx=okänd valuta CurrencyNames/sv/yer=jemenitisk rial -CurrencyNames/sv/yum=jugoslavisk dinar (1994\u20132002) +CurrencyNames/sv/yum=jugoslavisk dinar (1994–2002) CurrencyNames/sv/zar=sydafrikansk rand -CurrencyNames/sv/zmk=zambisk kwacha (1968\u20132012) +CurrencyNames/sv/zmk=zambisk kwacha (1968–2012) CurrencyNames/sv/zwd=Zimbabwe-dollar -CurrencyNames/zh_CN/ang=\u8377\u5c5e\u5b89\u7684\u5217\u65af\u76fe -CurrencyNames/zh_CN/azm=\u963f\u585e\u62dc\u7586\u9a6c\u7eb3\u7279 (1993\u20132006) -CurrencyNames/zh_CN/azn=\u963f\u585e\u62dc\u7586\u9a6c\u7eb3\u7279 -CurrencyNames/zh_CN/csd=\u65e7\u585e\u5c14\u7ef4\u4e9a\u7b2c\u7eb3\u5c14 -CurrencyNames/zh_CN/ghs=\u52a0\u7eb3\u585e\u5730 -CurrencyNames/zh_CN/mzm=\u65e7\u83ab\u6851\u6bd4\u514b\u7f8e\u63d0\u5361 -CurrencyNames/zh_CN/mzn=\u83ab\u6851\u6bd4\u514b\u7f8e\u63d0\u5361 -CurrencyNames/zh_CN/ron=\u7f57\u9a6c\u5c3c\u4e9a\u5217\u4f0a -CurrencyNames/zh_CN/rsd=\u585e\u5c14\u7ef4\u4e9a\u7b2c\u7eb3\u5c14 -CurrencyNames/zh_CN/shp=\u5723\u8d6b\u52d2\u62ff\u7fa4\u5c9b\u78c5 -CurrencyNames/zh_CN/twd=\u65b0\u53f0\u5e01 -CurrencyNames/zh_CN/vef=\u59d4\u5185\u745e\u62c9\u73bb\u5229\u74e6\u5c14 (2008\u20132018) -CurrencyNames/zh_CN/xxx=\u672a\u77e5\u8d27\u5e01 +CurrencyNames/zh_CN/ang=荷属安的列斯盾 +CurrencyNames/zh_CN/azm=阿塞拜疆马纳特 (1993–2006) +CurrencyNames/zh_CN/azn=阿塞拜疆马纳特 +CurrencyNames/zh_CN/csd=旧塞尔维亚第纳尔 +CurrencyNames/zh_CN/ghs=加纳塞地 +CurrencyNames/zh_CN/mzm=旧莫桑比克美提卡 +CurrencyNames/zh_CN/mzn=莫桑比克美提卡 +CurrencyNames/zh_CN/ron=罗马尼亚列伊 +CurrencyNames/zh_CN/rsd=塞尔维亚第纳尔 +CurrencyNames/zh_CN/shp=圣赫勒拿群岛磅 +CurrencyNames/zh_CN/twd=新台币 +CurrencyNames/zh_CN/vef=委内瑞拉玻利瓦尔 (2008–2018) +CurrencyNames/zh_CN/xxx=未知货币 -CurrencyNames/zh_TW/afa=\u963f\u5bcc\u6c57\u5c3c (1927\u20132002) -CurrencyNames/zh_TW/ang=\u8377\u5c6c\u5b89\u5730\u5217\u65af\u76fe -CurrencyNames/zh_TW/azm=\u4e9e\u585e\u62dc\u7136\u99ac\u7d0d\u7279 (1993\u20132006) -CurrencyNames/zh_TW/azn=\u4e9e\u585e\u62dc\u7136\u99ac\u7d0d\u7279 -CurrencyNames/zh_TW/bwp=\u6ce2\u672d\u90a3\u666e\u62c9 -CurrencyNames/zh_TW/bzd=\u8c9d\u91cc\u65af\u5143 -CurrencyNames/zh_TW/csd=\u820a\u585e\u723e\u7dad\u4e9e\u7b2c\u7d0d\u723e -CurrencyNames/zh_TW/cyp=\u8cfd\u666e\u52d2\u65af\u938a -CurrencyNames/zh_TW/ghc=\u8fe6\u7d0d\u8cfd\u5730 (1979\u20132007) -CurrencyNames/zh_TW/ghs=\u8fe6\u7d0d\u585e\u5730 -CurrencyNames/zh_TW/gwp=\u5e7e\u5167\u4e9e\u6bd4\u7d22\u62ab\u7d22 -CurrencyNames/zh_TW/huf=\u5308\u7259\u5229\u798f\u6797 -CurrencyNames/zh_TW/idr=\u5370\u5c3c\u76fe -CurrencyNames/zh_TW/inr=\u5370\u5ea6\u76e7\u6bd4 -CurrencyNames/zh_TW/kpw=\u5317\u97d3\u5143 -CurrencyNames/zh_TW/krw=\u97d3\u5143 -CurrencyNames/zh_TW/lak=\u5bee\u570b\u57fa\u666e -CurrencyNames/zh_TW/mad=\u6469\u6d1b\u54e5\u8fea\u62c9\u59c6 -CurrencyNames/zh_TW/mxn=\u58a8\u897f\u54e5\u62ab\u7d22 -CurrencyNames/zh_TW/mxv=\u58a8\u897f\u54e5\u8f49\u63db\u55ae\u4f4d (UDI) -CurrencyNames/zh_TW/myr=\u99ac\u4f86\u897f\u4e9e\u4ee4\u5409 -CurrencyNames/zh_TW/mzn=\u83ab\u4e09\u6bd4\u514b\u6885\u8482\u5361\u723e -CurrencyNames/zh_TW/nio=\u5c3c\u52a0\u62c9\u74dc\u91d1\u79d1\u591a\u5df4 -CurrencyNames/zh_TW/rol=\u820a\u7f85\u99ac\u5c3c\u4e9e\u5217\u4f0a -CurrencyNames/zh_TW/ron=\u7f85\u99ac\u5c3c\u4e9e\u5217\u4f0a -CurrencyNames/zh_TW/rsd=\u585e\u723e\u7dad\u4e9e\u6234\u7d0d -CurrencyNames/zh_TW/scr=\u585e\u5e2d\u723e\u76e7\u6bd4 -CurrencyNames/zh_TW/sdg=\u8607\u4e39\u938a -CurrencyNames/zh_TW/shp=\u8056\u8d6b\u52d2\u62ff\u938a -CurrencyNames/zh_TW/srd=\u8607\u5229\u5357\u5143 -CurrencyNames/zh_TW/srg=\u8607\u5229\u5357\u57fa\u723e -CurrencyNames/zh_TW/svc=\u85a9\u723e\u74e6\u591a\u79d1\u90ce -CurrencyNames/zh_TW/szl=\u53f2\u74e6\u5e1d\u5c3c\u6717\u5409\u5c3c -CurrencyNames/zh_TW/tpe=\u5e1d\u6c76\u57c3\u65af\u5eab\u591a -CurrencyNames/zh_TW/ttd=\u5343\u91cc\u9054\u53ca\u6258\u5df4\u54e5\u5143 -CurrencyNames/zh_TW/tzs=\u5766\u5c1a\u5c3c\u4e9e\u5148\u4ee4 -CurrencyNames/zh_TW/uzs=\u70cf\u8332\u5225\u514b\u7d22\u59c6 -CurrencyNames/zh_TW/veb=\u59d4\u5167\u745e\u62c9\u73bb\u5229\u74e6 (1871\u20132008) -CurrencyNames/zh_TW/vef=\u59d4\u5167\u745e\u62c9\u73bb\u5229\u74e6 (2008\u20132018) -CurrencyNames/zh_TW/xaf=\u6cd5\u90ce (CFA\u2013BEAC) -CurrencyNames/zh_TW/xag=\u767d\u9280 -CurrencyNames/zh_TW/xof=\u6cd5\u90ce (CFA\u2013BCEAO) -CurrencyNames/zh_TW/xpd=\u5e15\u62c9\u72c4\u6602 -CurrencyNames/zh_TW/xpt=\u767d\u91d1 -CurrencyNames/zh_TW/xts=\u6e2c\u8a66\u7528\u8ca8\u5e63\u4ee3\u78bc -CurrencyNames/zh_TW/xxx=\u672a\u77e5\u8ca8\u5e63 -CurrencyNames/zh_TW/yer=\u8449\u9580\u91cc\u4e9e\u723e +CurrencyNames/zh_TW/afa=阿富汗尼 (1927–2002) +CurrencyNames/zh_TW/ang=荷屬安地列斯盾 +CurrencyNames/zh_TW/azm=亞塞拜然馬納特 (1993–2006) +CurrencyNames/zh_TW/azn=亞塞拜然馬納特 +CurrencyNames/zh_TW/bwp=波札那普拉 +CurrencyNames/zh_TW/bzd=貝里斯元 +CurrencyNames/zh_TW/csd=舊塞爾維亞第納爾 +CurrencyNames/zh_TW/cyp=賽普勒斯鎊 +CurrencyNames/zh_TW/ghc=迦納賽地 (1979–2007) +CurrencyNames/zh_TW/ghs=迦納塞地 +CurrencyNames/zh_TW/gwp=幾內亞比索披索 +CurrencyNames/zh_TW/huf=匈牙利福林 +CurrencyNames/zh_TW/idr=印尼盾 +CurrencyNames/zh_TW/inr=印度盧比 +CurrencyNames/zh_TW/kpw=北韓元 +CurrencyNames/zh_TW/krw=韓元 +CurrencyNames/zh_TW/lak=寮國基普 +CurrencyNames/zh_TW/mad=摩洛哥迪拉姆 +CurrencyNames/zh_TW/mxn=墨西哥披索 +CurrencyNames/zh_TW/mxv=墨西哥轉換單位 (UDI) +CurrencyNames/zh_TW/myr=馬來西亞令吉 +CurrencyNames/zh_TW/mzn=莫三比克梅蒂卡爾 +CurrencyNames/zh_TW/nio=尼加拉瓜金科多巴 +CurrencyNames/zh_TW/rol=舊羅馬尼亞列伊 +CurrencyNames/zh_TW/ron=羅馬尼亞列伊 +CurrencyNames/zh_TW/rsd=塞爾維亞戴納 +CurrencyNames/zh_TW/scr=塞席爾盧比 +CurrencyNames/zh_TW/sdg=蘇丹鎊 +CurrencyNames/zh_TW/shp=聖赫勒拿鎊 +CurrencyNames/zh_TW/srd=蘇利南元 +CurrencyNames/zh_TW/srg=蘇利南基爾 +CurrencyNames/zh_TW/svc=薩爾瓦多科郎 +CurrencyNames/zh_TW/szl=史瓦帝尼朗吉尼 +CurrencyNames/zh_TW/tpe=帝汶埃斯庫多 +CurrencyNames/zh_TW/ttd=千里達及托巴哥元 +CurrencyNames/zh_TW/tzs=坦尚尼亞先令 +CurrencyNames/zh_TW/uzs=烏茲別克索姆 +CurrencyNames/zh_TW/veb=委內瑞拉玻利瓦 (1871–2008) +CurrencyNames/zh_TW/vef=委內瑞拉玻利瓦 (2008–2018) +CurrencyNames/zh_TW/xaf=法郎 (CFA–BEAC) +CurrencyNames/zh_TW/xag=白銀 +CurrencyNames/zh_TW/xof=法郎 (CFA–BCEAO) +CurrencyNames/zh_TW/xpd=帕拉狄昂 +CurrencyNames/zh_TW/xpt=白金 +CurrencyNames/zh_TW/xts=測試用貨幣代碼 +CurrencyNames/zh_TW/xxx=未知貨幣 +CurrencyNames/zh_TW/yer=葉門里亞爾 # bug 7036905 -CurrencyNames/de/afa=Afghanische Afghani (1927\u20132002) +CurrencyNames/de/afa=Afghanische Afghani (1927–2002) CurrencyNames/de/afn=Afghanischer Afghani CurrencyNames/de/bob=Bolivianischer Boliviano CurrencyNames/de/dem=Deutsche Mark @@ -6547,48 +6547,48 @@ CurrencyNames/de/zwl=Simbabwe-Dollar (2009) CurrencyNames/es/cuc=peso cubano convertible CurrencyNames/es/tmt=manat turcomano -CurrencyNames/es/zwl=d\u00f3lar zimbabuense +CurrencyNames/es/zwl=dólar zimbabuense CurrencyNames/es_CU/CUP=$ CurrencyNames/et_EE/eek=Eesti kroon -CurrencyNames/et_EE/EUR=\u20ac +CurrencyNames/et_EE/EUR=€ CurrencyNames/et_EE/eur=euro CurrencyNames/fr/cuc=peso cubain convertible -CurrencyNames/fr/tmt=nouveau manat turkm\u00e8ne +CurrencyNames/fr/tmt=nouveau manat turkmène -CurrencyNames/ja/cuc=\u30ad\u30e5\u30fc\u30d0 \u514c\u63db\u30da\u30bd -CurrencyNames/ja/tmt=\u30c8\u30eb\u30af\u30e1\u30cb\u30b9\u30bf\u30f3 \u30de\u30ca\u30c8 -CurrencyNames/ja/zwl=\u30b8\u30f3\u30d0\u30d6\u30a8 \u30c9\u30eb (2009) +CurrencyNames/ja/cuc=キューバ 兌換ペソ +CurrencyNames/ja/tmt=トルクメニスタン マナト +CurrencyNames/ja/zwl=ジンバブエ ドル (2009) -CurrencyNames/ko/cuc=\ucfe0\ubc14 \ud0dc\ud658 \ud398\uc18c +CurrencyNames/ko/cuc=쿠바 태환 페소 -CurrencyNames/pt/bob=Boliviano da Bol\u00edvia -CurrencyNames/pt/cuc=Peso cubano convers\u00edvel +CurrencyNames/pt/bob=Boliviano da Bolívia +CurrencyNames/pt/cuc=Peso cubano conversível CurrencyNames/pt/tmt=Manat turcomeno -CurrencyNames/pt/zwl=D\u00f3lar do Zimb\u00e1bue (2009) -CurrencyNames/pt/zwr=D\u00f3lar do Zimb\u00e1bue (2008) +CurrencyNames/pt/zwl=Dólar do Zimbábue (2009) +CurrencyNames/pt/zwr=Dólar do Zimbábue (2008) -CurrencyNames/sk_SK/skk=slovensk\u00e1 koruna -CurrencyNames/sk_SK/EUR=\u20ac +CurrencyNames/sk_SK/skk=slovenská koruna +CurrencyNames/sk_SK/EUR=€ -CurrencyNames/zh_CN/cuc=\u53e4\u5df4\u53ef\u5151\u6362\u6bd4\u7d22 -CurrencyNames/zh_CN/tmt=\u571f\u5e93\u66fc\u65af\u5766\u9a6c\u7eb3\u7279 -CurrencyNames/zh_CN/zwl=\u6d25\u5df4\u5e03\u97e6\u5143 (2009) +CurrencyNames/zh_CN/cuc=古巴可兑换比索 +CurrencyNames/zh_CN/tmt=土库曼斯坦马纳特 +CurrencyNames/zh_CN/zwl=津巴布韦元 (2009) -CurrencyNames/zh_TW/cuc=\u53e4\u5df4\u53ef\u8f49\u63db\u62ab\u7d22 -CurrencyNames/zh_TW/tmt=\u571f\u5eab\u66fc\u99ac\u7d0d\u7279 -CurrencyNames/zh_TW/zwl=\u8f9b\u5df4\u5a01\u5143 (2009) +CurrencyNames/zh_TW/cuc=古巴可轉換披索 +CurrencyNames/zh_TW/tmt=土庫曼馬納特 +CurrencyNames/zh_TW/zwl=辛巴威元 (2009) # bug 7003124 -FormatData/bg/TimePatterns/0=H:mm:ss '\u0447'. zzzz +FormatData/bg/TimePatterns/0=H:mm:ss 'ч'. zzzz FormatData/bg/TimePatterns/2=H:mm:ss FormatData/bg/TimePatterns/3=H:mm -FormatData/bg/DatePatterns/0=EEEE, d MMMM y\u202f'\u0433'. -FormatData/bg/DatePatterns/1=d MMMM y\u202f'\u0433'. -FormatData/bg/DatePatterns/2=d.MM.y\u202f'\u0433'. -FormatData/bg/DatePatterns/3=d.MM.yy\u202f'\u0433'. +FormatData/bg/DatePatterns/0=EEEE, d MMMM y 'г'. +FormatData/bg/DatePatterns/1=d MMMM y 'г'. +FormatData/bg/DatePatterns/2=d.MM.y 'г'. +FormatData/bg/DatePatterns/3=d.MM.yy 'г'. # bug 7085757 LocaleNames/en/SS=South Sudan @@ -6623,46 +6623,46 @@ FormatData//japanese.narrow.Eras/2=T FormatData//japanese.narrow.Eras/3=S FormatData//japanese.narrow.Eras/4=H -FormatData/ar/DayNarrows/0=\u062d -FormatData/ar/DayNarrows/1=\u0646 -FormatData/ar/DayNarrows/2=\u062b -FormatData/ar/DayNarrows/3=\u0631 -FormatData/ar/DayNarrows/4=\u062e -FormatData/ar/DayNarrows/5=\u062c -FormatData/ar/DayNarrows/6=\u0633 +FormatData/ar/DayNarrows/0=ح +FormatData/ar/DayNarrows/1=ن +FormatData/ar/DayNarrows/2=ث +FormatData/ar/DayNarrows/3=ر +FormatData/ar/DayNarrows/4=خ +FormatData/ar/DayNarrows/5=ج +FormatData/ar/DayNarrows/6=س -FormatData/be/standalone.MonthNarrows/0=\u0441 -FormatData/be/standalone.MonthNarrows/1=\u043b -FormatData/be/standalone.MonthNarrows/2=\u0441 -FormatData/be/standalone.MonthNarrows/3=\u043a -FormatData/be/standalone.MonthNarrows/4=\u043c -FormatData/be/standalone.MonthNarrows/5=\u0447 -FormatData/be/standalone.MonthNarrows/6=\u043b -FormatData/be/standalone.MonthNarrows/7=\u0436 -FormatData/be/standalone.MonthNarrows/8=\u0432 -FormatData/be/standalone.MonthNarrows/9=\u043a -FormatData/be/standalone.MonthNarrows/10=\u043b -FormatData/be/standalone.MonthNarrows/11=\u0441 +FormatData/be/standalone.MonthNarrows/0=с +FormatData/be/standalone.MonthNarrows/1=л +FormatData/be/standalone.MonthNarrows/2=с +FormatData/be/standalone.MonthNarrows/3=к +FormatData/be/standalone.MonthNarrows/4=м +FormatData/be/standalone.MonthNarrows/5=ч +FormatData/be/standalone.MonthNarrows/6=л +FormatData/be/standalone.MonthNarrows/7=ж +FormatData/be/standalone.MonthNarrows/8=в +FormatData/be/standalone.MonthNarrows/9=к +FormatData/be/standalone.MonthNarrows/10=л +FormatData/be/standalone.MonthNarrows/11=с FormatData/be/standalone.MonthNarrows/12= -FormatData/be/DayNarrows/0=\u043d -FormatData/be/DayNarrows/1=\u043f -FormatData/be/DayNarrows/2=\u0430 -FormatData/be/DayNarrows/3=\u0441 -FormatData/be/DayNarrows/4=\u0447 -FormatData/be/DayNarrows/5=\u043f -FormatData/be/DayNarrows/6=\u0441 +FormatData/be/DayNarrows/0=н +FormatData/be/DayNarrows/1=п +FormatData/be/DayNarrows/2=а +FormatData/be/DayNarrows/3=с +FormatData/be/DayNarrows/4=ч +FormatData/be/DayNarrows/5=п +FormatData/be/DayNarrows/6=с -FormatData/bg/DayNarrows/0=\u043d -FormatData/bg/DayNarrows/1=\u043f -FormatData/bg/DayNarrows/2=\u0432 -FormatData/bg/DayNarrows/3=\u0441 -FormatData/bg/DayNarrows/4=\u0447 -FormatData/bg/DayNarrows/5=\u043f -FormatData/bg/DayNarrows/6=\u0441 +FormatData/bg/DayNarrows/0=н +FormatData/bg/DayNarrows/1=п +FormatData/bg/DayNarrows/2=в +FormatData/bg/DayNarrows/3=с +FormatData/bg/DayNarrows/4=ч +FormatData/bg/DayNarrows/5=п +FormatData/bg/DayNarrows/6=с FormatData/ca/standalone.MonthNarrows/0=GN FormatData/ca/standalone.MonthNarrows/1=FB -FormatData/ca/standalone.MonthNarrows/2=M\u00c7 +FormatData/ca/standalone.MonthNarrows/2=MÇ FormatData/ca/standalone.MonthNarrows/3=AB FormatData/ca/standalone.MonthNarrows/4=MG FormatData/ca/standalone.MonthNarrows/5=JN @@ -6691,9 +6691,9 @@ FormatData/ca/standalone.DayNarrows/6=ds. FormatData/cs/DayNarrows/0=N FormatData/cs/DayNarrows/1=P -FormatData/cs/DayNarrows/2=\u00da +FormatData/cs/DayNarrows/2=Ú FormatData/cs/DayNarrows/3=S -FormatData/cs/DayNarrows/4=\u010c +FormatData/cs/DayNarrows/4=Č FormatData/cs/DayNarrows/5=P FormatData/cs/DayNarrows/6=S @@ -6713,13 +6713,13 @@ FormatData/de/DayNarrows/4=D FormatData/de/DayNarrows/5=F FormatData/de/DayNarrows/6=S -FormatData/el/DayNarrows/0=\u039a -FormatData/el/DayNarrows/1=\u0394 -FormatData/el/DayNarrows/2=\u03a4 -FormatData/el/DayNarrows/3=\u03a4 -FormatData/el/DayNarrows/4=\u03a0 -FormatData/el/DayNarrows/5=\u03a0 -FormatData/el/DayNarrows/6=\u03a3 +FormatData/el/DayNarrows/0=Κ +FormatData/el/DayNarrows/1=Δ +FormatData/el/DayNarrows/2=Τ +FormatData/el/DayNarrows/3=Τ +FormatData/el/DayNarrows/4=Π +FormatData/el/DayNarrows/5=Π +FormatData/el/DayNarrows/6=Σ FormatData/es/DayNarrows/0=D FormatData/es/DayNarrows/1=L @@ -6775,13 +6775,13 @@ FormatData/fr/DayNarrows/4=J FormatData/fr/DayNarrows/5=V FormatData/fr/DayNarrows/6=S -FormatData/hi_IN/DayNarrows/0=\u0930 -FormatData/hi_IN/DayNarrows/1=\u0938\u094b -FormatData/hi_IN/DayNarrows/2=\u092e\u0902 -FormatData/hi_IN/DayNarrows/3=\u092c\u0941 -FormatData/hi_IN/DayNarrows/4=\u0917\u0941 -FormatData/hi_IN/DayNarrows/5=\u0936\u0941 -FormatData/hi_IN/DayNarrows/6=\u0936 +FormatData/hi_IN/DayNarrows/0=र +FormatData/hi_IN/DayNarrows/1=सो +FormatData/hi_IN/DayNarrows/2=मं +FormatData/hi_IN/DayNarrows/3=बु +FormatData/hi_IN/DayNarrows/4=गु +FormatData/hi_IN/DayNarrows/5=शु +FormatData/hi_IN/DayNarrows/6=श FormatData/hr/standalone.MonthNarrows/0=1. FormatData/hr/standalone.MonthNarrows/1=2. @@ -6800,14 +6800,14 @@ FormatData/hr/DayNarrows/0=N FormatData/hr/DayNarrows/1=P FormatData/hr/DayNarrows/2=U FormatData/hr/DayNarrows/3=S -FormatData/hr/DayNarrows/4=\u010c +FormatData/hr/DayNarrows/4=Č FormatData/hr/DayNarrows/5=P FormatData/hr/DayNarrows/6=S FormatData/hr/standalone.DayNarrows/0=n FormatData/hr/standalone.DayNarrows/1=p FormatData/hr/standalone.DayNarrows/2=u FormatData/hr/standalone.DayNarrows/3=s -FormatData/hr/standalone.DayNarrows/4=\u010d +FormatData/hr/standalone.DayNarrows/4=č FormatData/hr/standalone.DayNarrows/5=p FormatData/hr/standalone.DayNarrows/6=s @@ -6826,7 +6826,7 @@ FormatData/is/standalone.MonthNarrows/3=A FormatData/is/standalone.MonthNarrows/4=M FormatData/is/standalone.MonthNarrows/5=J FormatData/is/standalone.MonthNarrows/6=J -FormatData/is/standalone.MonthNarrows/7=\u00c1 +FormatData/is/standalone.MonthNarrows/7=Á FormatData/is/standalone.MonthNarrows/8=S FormatData/is/standalone.MonthNarrows/9=O FormatData/is/standalone.MonthNarrows/10=N @@ -6834,14 +6834,14 @@ FormatData/is/standalone.MonthNarrows/11=D FormatData/is/standalone.MonthNarrows/12= FormatData/is/DayNarrows/0=S FormatData/is/DayNarrows/1=M -FormatData/is/DayNarrows/2=\u00de +FormatData/is/DayNarrows/2=Þ FormatData/is/DayNarrows/3=M FormatData/is/DayNarrows/4=F FormatData/is/DayNarrows/5=F FormatData/is/DayNarrows/6=L FormatData/is/standalone.DayNarrows/0=S FormatData/is/standalone.DayNarrows/1=M -FormatData/is/standalone.DayNarrows/2=\u00de +FormatData/is/standalone.DayNarrows/2=Þ FormatData/is/standalone.DayNarrows/3=M FormatData/is/standalone.DayNarrows/4=F FormatData/is/standalone.DayNarrows/5=F @@ -6855,36 +6855,36 @@ FormatData/it/DayNarrows/4=G FormatData/it/DayNarrows/5=V FormatData/it/DayNarrows/6=S -FormatData/iw/DayNarrows/0=\u05d0\u05f3 -FormatData/iw/DayNarrows/1=\u05d1\u05f3 -FormatData/iw/DayNarrows/2=\u05d2\u05f3 -FormatData/iw/DayNarrows/3=\u05d3\u05f3 -FormatData/iw/DayNarrows/4=\u05d4\u05f3 -FormatData/iw/DayNarrows/5=\u05d5\u05f3 -FormatData/iw/DayNarrows/6=\u05e9\u05f3 -FormatData/iw/standalone.DayNarrows/0=\u05d0\u05f3 -FormatData/iw/standalone.DayNarrows/1=\u05d1\u05f3 -FormatData/iw/standalone.DayNarrows/2=\u05d2\u05f3 -FormatData/iw/standalone.DayNarrows/3=\u05d3\u05f3 -FormatData/iw/standalone.DayNarrows/4=\u05d4\u05f3 -FormatData/iw/standalone.DayNarrows/5=\u05d5\u05f3 -FormatData/iw/standalone.DayNarrows/6=\u05e9\u05f3 +FormatData/iw/DayNarrows/0=א׳ +FormatData/iw/DayNarrows/1=ב׳ +FormatData/iw/DayNarrows/2=ג׳ +FormatData/iw/DayNarrows/3=ד׳ +FormatData/iw/DayNarrows/4=ה׳ +FormatData/iw/DayNarrows/5=ו׳ +FormatData/iw/DayNarrows/6=ש׳ +FormatData/iw/standalone.DayNarrows/0=א׳ +FormatData/iw/standalone.DayNarrows/1=ב׳ +FormatData/iw/standalone.DayNarrows/2=ג׳ +FormatData/iw/standalone.DayNarrows/3=ד׳ +FormatData/iw/standalone.DayNarrows/4=ה׳ +FormatData/iw/standalone.DayNarrows/5=ו׳ +FormatData/iw/standalone.DayNarrows/6=ש׳ -FormatData/ja/DayNarrows/0=\u65e5 -FormatData/ja/DayNarrows/1=\u6708 -FormatData/ja/DayNarrows/2=\u706b -FormatData/ja/DayNarrows/3=\u6c34 -FormatData/ja/DayNarrows/4=\u6728 -FormatData/ja/DayNarrows/5=\u91d1 -FormatData/ja/DayNarrows/6=\u571f +FormatData/ja/DayNarrows/0=日 +FormatData/ja/DayNarrows/1=月 +FormatData/ja/DayNarrows/2=火 +FormatData/ja/DayNarrows/3=水 +FormatData/ja/DayNarrows/4=木 +FormatData/ja/DayNarrows/5=金 +FormatData/ja/DayNarrows/6=土 -FormatData/ko/DayNarrows/0=\uc77c -FormatData/ko/DayNarrows/1=\uc6d4 -FormatData/ko/DayNarrows/2=\ud654 -FormatData/ko/DayNarrows/3=\uc218 -FormatData/ko/DayNarrows/4=\ubaa9 -FormatData/ko/DayNarrows/5=\uae08 -FormatData/ko/DayNarrows/6=\ud1a0 +FormatData/ko/DayNarrows/0=일 +FormatData/ko/DayNarrows/1=월 +FormatData/ko/DayNarrows/2=화 +FormatData/ko/DayNarrows/3=수 +FormatData/ko/DayNarrows/4=목 +FormatData/ko/DayNarrows/5=금 +FormatData/ko/DayNarrows/6=토 FormatData/lt/standalone.MonthNarrows/0=S FormatData/lt/standalone.MonthNarrows/1=V @@ -6906,14 +6906,14 @@ FormatData/lt/DayNarrows/2=A FormatData/lt/DayNarrows/3=T FormatData/lt/DayNarrows/4=K FormatData/lt/DayNarrows/5=P -FormatData/lt/DayNarrows/6=\u0160 +FormatData/lt/DayNarrows/6=Š FormatData/lt/standalone.DayNarrows/0=S FormatData/lt/standalone.DayNarrows/1=P FormatData/lt/standalone.DayNarrows/2=A FormatData/lt/standalone.DayNarrows/3=T FormatData/lt/standalone.DayNarrows/4=K FormatData/lt/standalone.DayNarrows/5=P -FormatData/lt/standalone.DayNarrows/6=\u0160 +FormatData/lt/standalone.DayNarrows/6=Š FormatData/lv/DayNarrows/0=S FormatData/lv/DayNarrows/1=P @@ -6923,13 +6923,13 @@ FormatData/lv/DayNarrows/4=C FormatData/lv/DayNarrows/5=P FormatData/lv/DayNarrows/6=S -FormatData/mk/DayNarrows/0=\u043d -FormatData/mk/DayNarrows/1=\u043f -FormatData/mk/DayNarrows/2=\u0432 -FormatData/mk/DayNarrows/3=\u0441 -FormatData/mk/DayNarrows/4=\u0447 -FormatData/mk/DayNarrows/5=\u043f -FormatData/mk/DayNarrows/6=\u0441 +FormatData/mk/DayNarrows/0=н +FormatData/mk/DayNarrows/1=п +FormatData/mk/DayNarrows/2=в +FormatData/mk/DayNarrows/3=с +FormatData/mk/DayNarrows/4=ч +FormatData/mk/DayNarrows/5=п +FormatData/mk/DayNarrows/6=с FormatData/ms/standalone.MonthNarrows/0=J FormatData/ms/standalone.MonthNarrows/1=F @@ -6959,12 +6959,12 @@ FormatData/ms/standalone.DayNarrows/4=K FormatData/ms/standalone.DayNarrows/5=J FormatData/ms/standalone.DayNarrows/6=S -FormatData/mt/DayNarrows/0=\u0126d +FormatData/mt/DayNarrows/0=Ħd FormatData/mt/DayNarrows/1=T FormatData/mt/DayNarrows/2=Tl FormatData/mt/DayNarrows/3=Er -FormatData/mt/DayNarrows/4=\u0126m -FormatData/mt/DayNarrows/5=\u0120m +FormatData/mt/DayNarrows/4=Ħm +FormatData/mt/DayNarrows/5=Ġm FormatData/mt/DayNarrows/6=Sb FormatData/nl/DayNarrows/0=Z @@ -6978,7 +6978,7 @@ FormatData/nl/DayNarrows/6=Z FormatData/pl/DayNarrows/0=n FormatData/pl/DayNarrows/1=p FormatData/pl/DayNarrows/2=w -FormatData/pl/DayNarrows/3=\u015b +FormatData/pl/DayNarrows/3=ś FormatData/pl/DayNarrows/4=c FormatData/pl/DayNarrows/5=p FormatData/pl/DayNarrows/6=s @@ -7020,28 +7020,28 @@ FormatData/ro/standalone.DayNarrows/4=J FormatData/ro/standalone.DayNarrows/5=V FormatData/ro/standalone.DayNarrows/6=S -FormatData/ru/DayNarrows/0=\u0412 -FormatData/ru/DayNarrows/1=\u041f -FormatData/ru/DayNarrows/2=\u0412 -FormatData/ru/DayNarrows/3=\u0421 -FormatData/ru/DayNarrows/4=\u0427 -FormatData/ru/DayNarrows/5=\u041f +FormatData/ru/DayNarrows/0=В +FormatData/ru/DayNarrows/1=П +FormatData/ru/DayNarrows/2=В +FormatData/ru/DayNarrows/3=С +FormatData/ru/DayNarrows/4=Ч +FormatData/ru/DayNarrows/5=П # Note: "sat" is an contributed item in CLDR. -FormatData/ru/DayNarrows/6=\u0421 +FormatData/ru/DayNarrows/6=С -FormatData/ru/standalone.DayNarrows/0=\u0412 -FormatData/ru/standalone.DayNarrows/1=\u041f -FormatData/ru/standalone.DayNarrows/2=\u0412 -FormatData/ru/standalone.DayNarrows/3=\u0421 -FormatData/ru/standalone.DayNarrows/4=\u0427 -FormatData/ru/standalone.DayNarrows/5=\u041f -FormatData/ru/standalone.DayNarrows/6=\u0421 +FormatData/ru/standalone.DayNarrows/0=В +FormatData/ru/standalone.DayNarrows/1=П +FormatData/ru/standalone.DayNarrows/2=В +FormatData/ru/standalone.DayNarrows/3=С +FormatData/ru/standalone.DayNarrows/4=Ч +FormatData/ru/standalone.DayNarrows/5=П +FormatData/ru/standalone.DayNarrows/6=С FormatData/sk/DayNarrows/0=n FormatData/sk/DayNarrows/1=p FormatData/sk/DayNarrows/2=u FormatData/sk/DayNarrows/3=s -FormatData/sk/DayNarrows/4=\u0161 +FormatData/sk/DayNarrows/4=š FormatData/sk/DayNarrows/5=p FormatData/sk/DayNarrows/6=s @@ -7049,7 +7049,7 @@ FormatData/sl/DayNarrows/0=n FormatData/sl/DayNarrows/1=p FormatData/sl/DayNarrows/2=t FormatData/sl/DayNarrows/3=s -FormatData/sl/DayNarrows/4=\u010d +FormatData/sl/DayNarrows/4=č FormatData/sl/DayNarrows/5=p FormatData/sl/DayNarrows/6=s @@ -7061,15 +7061,15 @@ FormatData/sq/DayNarrows/4=e FormatData/sq/DayNarrows/5=p FormatData/sq/DayNarrows/6=sh -FormatData/sr/DayNarrows/0=\u043d -FormatData/sr/DayNarrows/1=\u043f -FormatData/sr/DayNarrows/2=\u0443 -FormatData/sr/DayNarrows/3=\u0441 -FormatData/sr/DayNarrows/4=\u0447 -FormatData/sr/DayNarrows/5=\u043f -FormatData/sr/DayNarrows/6=\u0441 -FormatData/sr/narrow.Eras/0=\u043f.\u043d.\u0435. -FormatData/sr/narrow.Eras/1=\u043d.\u0435. +FormatData/sr/DayNarrows/0=н +FormatData/sr/DayNarrows/1=п +FormatData/sr/DayNarrows/2=у +FormatData/sr/DayNarrows/3=с +FormatData/sr/DayNarrows/4=ч +FormatData/sr/DayNarrows/5=п +FormatData/sr/DayNarrows/6=с +FormatData/sr/narrow.Eras/0=п.н.е. +FormatData/sr/narrow.Eras/1=н.е. FormatData/sv/standalone.MonthNarrows/0=J FormatData/sv/standalone.MonthNarrows/1=F @@ -7103,31 +7103,31 @@ FormatData/sv/narrow.Eras/1=e.Kr. FormatData/sv/narrow.AmPmMarkers/0=fm FormatData/sv/narrow.AmPmMarkers/1=em -FormatData/th/standalone.MonthNarrows/0=\u0e21.\u0e04. -FormatData/th/standalone.MonthNarrows/1=\u0e01.\u0e1e. -FormatData/th/standalone.MonthNarrows/2=\u0e21\u0e35.\u0e04. -FormatData/th/standalone.MonthNarrows/3=\u0e40\u0e21.\u0e22. -FormatData/th/standalone.MonthNarrows/4=\u0e1e.\u0e04. -FormatData/th/standalone.MonthNarrows/5=\u0e21\u0e34.\u0e22. -FormatData/th/standalone.MonthNarrows/6=\u0e01.\u0e04. -FormatData/th/standalone.MonthNarrows/7=\u0e2a.\u0e04. -FormatData/th/standalone.MonthNarrows/8=\u0e01.\u0e22. -FormatData/th/standalone.MonthNarrows/9=\u0e15.\u0e04. -FormatData/th/standalone.MonthNarrows/10=\u0e1e.\u0e22. -FormatData/th/standalone.MonthNarrows/11=\u0e18.\u0e04. +FormatData/th/standalone.MonthNarrows/0=ม.ค. +FormatData/th/standalone.MonthNarrows/1=ก.พ. +FormatData/th/standalone.MonthNarrows/2=มี.ค. +FormatData/th/standalone.MonthNarrows/3=เม.ย. +FormatData/th/standalone.MonthNarrows/4=พ.ค. +FormatData/th/standalone.MonthNarrows/5=มิ.ย. +FormatData/th/standalone.MonthNarrows/6=ก.ค. +FormatData/th/standalone.MonthNarrows/7=ส.ค. +FormatData/th/standalone.MonthNarrows/8=ก.ย. +FormatData/th/standalone.MonthNarrows/9=ต.ค. +FormatData/th/standalone.MonthNarrows/10=พ.ย. +FormatData/th/standalone.MonthNarrows/11=ธ.ค. FormatData/th/standalone.MonthNarrows/12= -FormatData/th/DayNarrows/0=\u0e2d\u0e32 -FormatData/th/DayNarrows/1=\u0e08 -FormatData/th/DayNarrows/2=\u0e2d -FormatData/th/DayNarrows/3=\u0e1e -FormatData/th/DayNarrows/4=\u0e1e\u0e24 -FormatData/th/DayNarrows/5=\u0e28 -FormatData/th/DayNarrows/6=\u0e2a -FormatData/th/narrow.Eras/0=\u0e01\u0e48\u0e2d\u0e19 \u0e04.\u0e28. -FormatData/th/narrow.Eras/1=\u0e04.\u0e28. +FormatData/th/DayNarrows/0=อา +FormatData/th/DayNarrows/1=จ +FormatData/th/DayNarrows/2=อ +FormatData/th/DayNarrows/3=พ +FormatData/th/DayNarrows/4=พฤ +FormatData/th/DayNarrows/5=ศ +FormatData/th/DayNarrows/6=ส +FormatData/th/narrow.Eras/0=ก่อน ค.ศ. +FormatData/th/narrow.Eras/1=ค.ศ. FormatData/tr/standalone.MonthNarrows/0=O -FormatData/tr/standalone.MonthNarrows/1=\u015e +FormatData/tr/standalone.MonthNarrows/1=Ş FormatData/tr/standalone.MonthNarrows/2=M FormatData/tr/standalone.MonthNarrows/3=N FormatData/tr/standalone.MonthNarrows/4=M @@ -7142,18 +7142,18 @@ FormatData/tr/standalone.MonthNarrows/12= FormatData/tr/DayNarrows/0=P FormatData/tr/DayNarrows/1=P FormatData/tr/DayNarrows/2=S -FormatData/tr/DayNarrows/3=\u00c7 +FormatData/tr/DayNarrows/3=Ç FormatData/tr/DayNarrows/4=P FormatData/tr/DayNarrows/5=C FormatData/tr/DayNarrows/6=C -FormatData/uk/DayNarrows/0=\u041d -FormatData/uk/DayNarrows/1=\u041f -FormatData/uk/DayNarrows/2=\u0412 -FormatData/uk/DayNarrows/3=\u0421 -FormatData/uk/DayNarrows/4=\u0427 -FormatData/uk/DayNarrows/5=\u041f -FormatData/uk/DayNarrows/6=\u0421 +FormatData/uk/DayNarrows/0=Н +FormatData/uk/DayNarrows/1=П +FormatData/uk/DayNarrows/2=В +FormatData/uk/DayNarrows/3=С +FormatData/uk/DayNarrows/4=Ч +FormatData/uk/DayNarrows/5=П +FormatData/uk/DayNarrows/6=С FormatData/vi/DayNarrows/0=CN FormatData/vi/DayNarrows/1=T2 @@ -7176,13 +7176,13 @@ FormatData/zh/standalone.MonthNarrows/9=10 FormatData/zh/standalone.MonthNarrows/10=11 FormatData/zh/standalone.MonthNarrows/11=12 FormatData/zh/standalone.MonthNarrows/12= -FormatData/zh/DayNarrows/0=\u65e5 -FormatData/zh/DayNarrows/1=\u4e00 -FormatData/zh/DayNarrows/2=\u4e8c -FormatData/zh/DayNarrows/3=\u4e09 -FormatData/zh/DayNarrows/4=\u56db -FormatData/zh/DayNarrows/5=\u4e94 -FormatData/zh/DayNarrows/6=\u516d +FormatData/zh/DayNarrows/0=日 +FormatData/zh/DayNarrows/1=一 +FormatData/zh/DayNarrows/2=二 +FormatData/zh/DayNarrows/3=三 +FormatData/zh/DayNarrows/4=四 +FormatData/zh/DayNarrows/5=五 +FormatData/zh/DayNarrows/6=六 # bug 7114053 LocaleNames/sq/sq=shqip @@ -7206,33 +7206,33 @@ FormatData/pt/MonthAbbreviations/10=nov. FormatData/pt/MonthAbbreviations/11=dez. # bug 8021121 -CurrencyNames/lv_LV/EUR=\u20ac +CurrencyNames/lv_LV/EUR=€ # bug # 6192407 -LocaleNames/ko/PT=\ud3ec\ub974\ud22c\uac08 +LocaleNames/ko/PT=포르투갈 # bug 6931564 LocaleNames/sv/ZA=Sydafrika # bug 8027695 -FormatData/sv_SE/latn.NumberPatterns/2=#,##0\u00a0% +FormatData/sv_SE/latn.NumberPatterns/2=#,##0 % # bug 8017142 -FormatData/es_CL/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_CL/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_CL/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_CL/TimePatterns/3=h:mm\u202fa -FormatData/es_EC/TimePatterns/0=h:mm:ss\u202fa zzzz -FormatData/es_EC/TimePatterns/1=h:mm:ss\u202fa z -FormatData/es_EC/TimePatterns/2=h:mm:ss\u202fa -FormatData/es_EC/TimePatterns/3=h:mm\u202fa +FormatData/es_CL/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_CL/TimePatterns/1=h:mm:ss a z +FormatData/es_CL/TimePatterns/2=h:mm:ss a +FormatData/es_CL/TimePatterns/3=h:mm a +FormatData/es_EC/TimePatterns/0=h:mm:ss a zzzz +FormatData/es_EC/TimePatterns/1=h:mm:ss a z +FormatData/es_EC/TimePatterns/2=h:mm:ss a +FormatData/es_EC/TimePatterns/3=h:mm a # bug 8037343 FormatData/es_DO/DatePatterns/2=d MMM y FormatData/es_DO/DatePatterns/3=d/M/yy # bug 8055222 -CurrencyNames/lt_LT/EUR=\u20ac +CurrencyNames/lt_LT/EUR=€ # bug 8042126 + missing MonthNarrows data FormatData//MonthNarrows/0=1 @@ -7248,18 +7248,18 @@ FormatData//MonthNarrows/9=10 FormatData//MonthNarrows/10=11 FormatData//MonthNarrows/11=12 FormatData//MonthNarrows/12= -FormatData/bg/MonthNarrows/0=\u044f -FormatData/bg/MonthNarrows/1=\u0444 -FormatData/bg/MonthNarrows/2=\u043c -FormatData/bg/MonthNarrows/3=\u0430 -FormatData/bg/MonthNarrows/4=\u043c -FormatData/bg/MonthNarrows/5=\u044e -FormatData/bg/MonthNarrows/6=\u044e -FormatData/bg/MonthNarrows/7=\u0430 -FormatData/bg/MonthNarrows/8=\u0441 -FormatData/bg/MonthNarrows/9=\u043e -FormatData/bg/MonthNarrows/10=\u043d -FormatData/bg/MonthNarrows/11=\u0434 +FormatData/bg/MonthNarrows/0=я +FormatData/bg/MonthNarrows/1=ф +FormatData/bg/MonthNarrows/2=м +FormatData/bg/MonthNarrows/3=а +FormatData/bg/MonthNarrows/4=м +FormatData/bg/MonthNarrows/5=ю +FormatData/bg/MonthNarrows/6=ю +FormatData/bg/MonthNarrows/7=а +FormatData/bg/MonthNarrows/8=с +FormatData/bg/MonthNarrows/9=о +FormatData/bg/MonthNarrows/10=н +FormatData/bg/MonthNarrows/11=д FormatData/bg/MonthNarrows/12= FormatData/zh_TW/MonthNarrows/0=1 FormatData/zh_TW/MonthNarrows/1=2 @@ -7287,31 +7287,31 @@ FormatData/it/MonthNarrows/9=O FormatData/it/MonthNarrows/10=N FormatData/it/MonthNarrows/11=D FormatData/it/MonthNarrows/12= -FormatData/ko/MonthNarrows/0=1\uc6d4 -FormatData/ko/MonthNarrows/1=2\uc6d4 -FormatData/ko/MonthNarrows/2=3\uc6d4 -FormatData/ko/MonthNarrows/3=4\uc6d4 -FormatData/ko/MonthNarrows/4=5\uc6d4 -FormatData/ko/MonthNarrows/5=6\uc6d4 -FormatData/ko/MonthNarrows/6=7\uc6d4 -FormatData/ko/MonthNarrows/7=8\uc6d4 -FormatData/ko/MonthNarrows/8=9\uc6d4 -FormatData/ko/MonthNarrows/9=10\uc6d4 -FormatData/ko/MonthNarrows/10=11\uc6d4 -FormatData/ko/MonthNarrows/11=12\uc6d4 +FormatData/ko/MonthNarrows/0=1월 +FormatData/ko/MonthNarrows/1=2월 +FormatData/ko/MonthNarrows/2=3월 +FormatData/ko/MonthNarrows/3=4월 +FormatData/ko/MonthNarrows/4=5월 +FormatData/ko/MonthNarrows/5=6월 +FormatData/ko/MonthNarrows/6=7월 +FormatData/ko/MonthNarrows/7=8월 +FormatData/ko/MonthNarrows/8=9월 +FormatData/ko/MonthNarrows/9=10월 +FormatData/ko/MonthNarrows/10=11월 +FormatData/ko/MonthNarrows/11=12월 FormatData/ko/MonthNarrows/12= -FormatData/uk/MonthNarrows/0=\u0441 -FormatData/uk/MonthNarrows/1=\u043b -FormatData/uk/MonthNarrows/2=\u0431 -FormatData/uk/MonthNarrows/3=\u043a -FormatData/uk/MonthNarrows/4=\u0442 -FormatData/uk/MonthNarrows/5=\u0447 -FormatData/uk/MonthNarrows/6=\u043b -FormatData/uk/MonthNarrows/7=\u0441 -FormatData/uk/MonthNarrows/8=\u0432 -FormatData/uk/MonthNarrows/9=\u0436 -FormatData/uk/MonthNarrows/10=\u043b -FormatData/uk/MonthNarrows/11=\u0433 +FormatData/uk/MonthNarrows/0=с +FormatData/uk/MonthNarrows/1=л +FormatData/uk/MonthNarrows/2=б +FormatData/uk/MonthNarrows/3=к +FormatData/uk/MonthNarrows/4=т +FormatData/uk/MonthNarrows/5=ч +FormatData/uk/MonthNarrows/6=л +FormatData/uk/MonthNarrows/7=с +FormatData/uk/MonthNarrows/8=в +FormatData/uk/MonthNarrows/9=ж +FormatData/uk/MonthNarrows/10=л +FormatData/uk/MonthNarrows/11=г FormatData/uk/MonthNarrows/12= FormatData/lv/MonthNarrows/0=J FormatData/lv/MonthNarrows/1=F @@ -7352,18 +7352,18 @@ FormatData/sk/MonthNarrows/9=o FormatData/sk/MonthNarrows/10=n FormatData/sk/MonthNarrows/11=d FormatData/sk/MonthNarrows/12= -FormatData/hi_IN/MonthNarrows/0=\u091c -FormatData/hi_IN/MonthNarrows/1=\u092b\u093c -FormatData/hi_IN/MonthNarrows/2=\u092e\u093e -FormatData/hi_IN/MonthNarrows/3=\u0905 -FormatData/hi_IN/MonthNarrows/4=\u092e -FormatData/hi_IN/MonthNarrows/5=\u091c\u0942 -FormatData/hi_IN/MonthNarrows/6=\u091c\u0941 -FormatData/hi_IN/MonthNarrows/7=\u0905 -FormatData/hi_IN/MonthNarrows/8=\u0938\u093f -FormatData/hi_IN/MonthNarrows/9=\u0905 -FormatData/hi_IN/MonthNarrows/10=\u0928 -FormatData/hi_IN/MonthNarrows/11=\u0926\u093f +FormatData/hi_IN/MonthNarrows/0=ज +FormatData/hi_IN/MonthNarrows/1=फ़ +FormatData/hi_IN/MonthNarrows/2=मा +FormatData/hi_IN/MonthNarrows/3=अ +FormatData/hi_IN/MonthNarrows/4=म +FormatData/hi_IN/MonthNarrows/5=जू +FormatData/hi_IN/MonthNarrows/6=जु +FormatData/hi_IN/MonthNarrows/7=अ +FormatData/hi_IN/MonthNarrows/8=सि +FormatData/hi_IN/MonthNarrows/9=अ +FormatData/hi_IN/MonthNarrows/10=न +FormatData/hi_IN/MonthNarrows/11=दि FormatData/hi_IN/MonthNarrows/12= FormatData/ga/MonthNarrows/0=E FormatData/ga/MonthNarrows/1=F @@ -7417,23 +7417,23 @@ FormatData/cs/MonthNarrows/9=10 FormatData/cs/MonthNarrows/10=11 FormatData/cs/MonthNarrows/11=12 FormatData/cs/MonthNarrows/12= -FormatData/el/MonthNarrows/0=\u0399 -FormatData/el/MonthNarrows/1=\u03a6 -FormatData/el/MonthNarrows/2=\u039c -FormatData/el/MonthNarrows/3=\u0391 -FormatData/el/MonthNarrows/4=\u039c -FormatData/el/MonthNarrows/5=\u0399 -FormatData/el/MonthNarrows/6=\u0399 -FormatData/el/MonthNarrows/7=\u0391 -FormatData/el/MonthNarrows/8=\u03a3 -FormatData/el/MonthNarrows/9=\u039f -FormatData/el/MonthNarrows/10=\u039d -FormatData/el/MonthNarrows/11=\u0394 +FormatData/el/MonthNarrows/0=Ι +FormatData/el/MonthNarrows/1=Φ +FormatData/el/MonthNarrows/2=Μ +FormatData/el/MonthNarrows/3=Α +FormatData/el/MonthNarrows/4=Μ +FormatData/el/MonthNarrows/5=Ι +FormatData/el/MonthNarrows/6=Ι +FormatData/el/MonthNarrows/7=Α +FormatData/el/MonthNarrows/8=Σ +FormatData/el/MonthNarrows/9=Ο +FormatData/el/MonthNarrows/10=Ν +FormatData/el/MonthNarrows/11=Δ FormatData/el/MonthNarrows/12= FormatData/hu/MonthNarrows/0=J FormatData/hu/MonthNarrows/1=F FormatData/hu/MonthNarrows/2=M -FormatData/hu/MonthNarrows/3=\u00c1 +FormatData/hu/MonthNarrows/3=Á FormatData/hu/MonthNarrows/4=M FormatData/hu/MonthNarrows/5=J FormatData/hu/MonthNarrows/6=J @@ -7457,7 +7457,7 @@ FormatData/es/MonthNarrows/10=N FormatData/es/MonthNarrows/11=D FormatData/es/MonthNarrows/12= FormatData/tr/MonthNarrows/0=O -FormatData/tr/MonthNarrows/1=\u015e +FormatData/tr/MonthNarrows/1=Ş FormatData/tr/MonthNarrows/2=M FormatData/tr/MonthNarrows/3=N FormatData/tr/MonthNarrows/4=M @@ -7528,7 +7528,7 @@ FormatData/is/MonthNarrows/3=A FormatData/is/MonthNarrows/4=M FormatData/is/MonthNarrows/5=J FormatData/is/MonthNarrows/6=J -FormatData/is/MonthNarrows/7=\u00c1 +FormatData/is/MonthNarrows/7=Á FormatData/is/MonthNarrows/8=S FormatData/is/MonthNarrows/9=O FormatData/is/MonthNarrows/10=N @@ -7562,7 +7562,7 @@ FormatData/en/MonthNarrows/11=D FormatData/en/MonthNarrows/12= FormatData/ca/MonthNarrows/0=GN FormatData/ca/MonthNarrows/1=FB -FormatData/ca/MonthNarrows/2=M\u00c7 +FormatData/ca/MonthNarrows/2=MÇ FormatData/ca/MonthNarrows/3=AB FormatData/ca/MonthNarrows/4=MG FormatData/ca/MonthNarrows/5=JN @@ -7599,18 +7599,18 @@ FormatData/fi/MonthNarrows/9=L FormatData/fi/MonthNarrows/10=M FormatData/fi/MonthNarrows/11=J FormatData/fi/MonthNarrows/12= -FormatData/mk/MonthNarrows/0=\u0458 -FormatData/mk/MonthNarrows/1=\u0444 -FormatData/mk/MonthNarrows/2=\u043c -FormatData/mk/MonthNarrows/3=\u0430 -FormatData/mk/MonthNarrows/4=\u043c -FormatData/mk/MonthNarrows/5=\u0458 -FormatData/mk/MonthNarrows/6=\u0458 -FormatData/mk/MonthNarrows/7=\u0430 -FormatData/mk/MonthNarrows/8=\u0441 -FormatData/mk/MonthNarrows/9=\u043e -FormatData/mk/MonthNarrows/10=\u043d -FormatData/mk/MonthNarrows/11=\u0434 +FormatData/mk/MonthNarrows/0=ј +FormatData/mk/MonthNarrows/1=ф +FormatData/mk/MonthNarrows/2=м +FormatData/mk/MonthNarrows/3=а +FormatData/mk/MonthNarrows/4=м +FormatData/mk/MonthNarrows/5=ј +FormatData/mk/MonthNarrows/6=ј +FormatData/mk/MonthNarrows/7=а +FormatData/mk/MonthNarrows/8=с +FormatData/mk/MonthNarrows/9=о +FormatData/mk/MonthNarrows/10=н +FormatData/mk/MonthNarrows/11=д FormatData/mk/MonthNarrows/12= FormatData/sr-Latn/MonthNarrows/0=j FormatData/sr-Latn/MonthNarrows/1=f @@ -7625,44 +7625,44 @@ FormatData/sr-Latn/MonthNarrows/9=o FormatData/sr-Latn/MonthNarrows/10=n FormatData/sr-Latn/MonthNarrows/11=d FormatData/sr-Latn/MonthNarrows/12= -FormatData/th/MonthNarrows/0=\u0e21.\u0e04. -FormatData/th/MonthNarrows/1=\u0e01.\u0e1e. -FormatData/th/MonthNarrows/2=\u0e21\u0e35.\u0e04. -FormatData/th/MonthNarrows/3=\u0e40\u0e21.\u0e22. -FormatData/th/MonthNarrows/4=\u0e1e.\u0e04. -FormatData/th/MonthNarrows/5=\u0e21\u0e34.\u0e22. -FormatData/th/MonthNarrows/6=\u0e01.\u0e04. -FormatData/th/MonthNarrows/7=\u0e2a.\u0e04. -FormatData/th/MonthNarrows/8=\u0e01.\u0e22. -FormatData/th/MonthNarrows/9=\u0e15.\u0e04. -FormatData/th/MonthNarrows/10=\u0e1e.\u0e22. -FormatData/th/MonthNarrows/11=\u0e18.\u0e04. +FormatData/th/MonthNarrows/0=ม.ค. +FormatData/th/MonthNarrows/1=ก.พ. +FormatData/th/MonthNarrows/2=มี.ค. +FormatData/th/MonthNarrows/3=เม.ย. +FormatData/th/MonthNarrows/4=พ.ค. +FormatData/th/MonthNarrows/5=มิ.ย. +FormatData/th/MonthNarrows/6=ก.ค. +FormatData/th/MonthNarrows/7=ส.ค. +FormatData/th/MonthNarrows/8=ก.ย. +FormatData/th/MonthNarrows/9=ต.ค. +FormatData/th/MonthNarrows/10=พ.ย. +FormatData/th/MonthNarrows/11=ธ.ค. FormatData/th/MonthNarrows/12= -FormatData/ar/MonthNarrows/0=\u064a -FormatData/ar/MonthNarrows/1=\u0641 -FormatData/ar/MonthNarrows/2=\u0645 -FormatData/ar/MonthNarrows/3=\u0623 -FormatData/ar/MonthNarrows/4=\u0648 -FormatData/ar/MonthNarrows/5=\u0646 -FormatData/ar/MonthNarrows/6=\u0644 -FormatData/ar/MonthNarrows/7=\u063a -FormatData/ar/MonthNarrows/8=\u0633 -FormatData/ar/MonthNarrows/9=\u0643 -FormatData/ar/MonthNarrows/10=\u0628 -FormatData/ar/MonthNarrows/11=\u062f +FormatData/ar/MonthNarrows/0=ي +FormatData/ar/MonthNarrows/1=ف +FormatData/ar/MonthNarrows/2=م +FormatData/ar/MonthNarrows/3=أ +FormatData/ar/MonthNarrows/4=و +FormatData/ar/MonthNarrows/5=ن +FormatData/ar/MonthNarrows/6=ل +FormatData/ar/MonthNarrows/7=غ +FormatData/ar/MonthNarrows/8=س +FormatData/ar/MonthNarrows/9=ك +FormatData/ar/MonthNarrows/10=ب +FormatData/ar/MonthNarrows/11=د FormatData/ar/MonthNarrows/12= -FormatData/ru/MonthNarrows/0=\u042f -FormatData/ru/MonthNarrows/1=\u0424 -FormatData/ru/MonthNarrows/2=\u041c -FormatData/ru/MonthNarrows/3=\u0410 -FormatData/ru/MonthNarrows/4=\u041c -FormatData/ru/MonthNarrows/5=\u0418 -FormatData/ru/MonthNarrows/6=\u0418 -FormatData/ru/MonthNarrows/7=\u0410 -FormatData/ru/MonthNarrows/8=\u0421 -FormatData/ru/MonthNarrows/9=\u041e -FormatData/ru/MonthNarrows/10=\u041d -FormatData/ru/MonthNarrows/11=\u0414 +FormatData/ru/MonthNarrows/0=Я +FormatData/ru/MonthNarrows/1=Ф +FormatData/ru/MonthNarrows/2=М +FormatData/ru/MonthNarrows/3=А +FormatData/ru/MonthNarrows/4=М +FormatData/ru/MonthNarrows/5=И +FormatData/ru/MonthNarrows/6=И +FormatData/ru/MonthNarrows/7=А +FormatData/ru/MonthNarrows/8=С +FormatData/ru/MonthNarrows/9=О +FormatData/ru/MonthNarrows/10=Н +FormatData/ru/MonthNarrows/11=Д FormatData/ru/MonthNarrows/12= FormatData/ms/MonthNarrows/0=J FormatData/ms/MonthNarrows/1=F @@ -7703,25 +7703,25 @@ FormatData/vi/MonthNarrows/9=10 FormatData/vi/MonthNarrows/10=11 FormatData/vi/MonthNarrows/11=12 FormatData/vi/MonthNarrows/12= -FormatData/sr/MonthNarrows/0=\u0458 -FormatData/sr/MonthNarrows/1=\u0444 -FormatData/sr/MonthNarrows/2=\u043c -FormatData/sr/MonthNarrows/3=\u0430 -FormatData/sr/MonthNarrows/4=\u043c -FormatData/sr/MonthNarrows/5=\u0458 -FormatData/sr/MonthNarrows/6=\u0458 -FormatData/sr/MonthNarrows/7=\u0430 -FormatData/sr/MonthNarrows/8=\u0441 -FormatData/sr/MonthNarrows/9=\u043e -FormatData/sr/MonthNarrows/10=\u043d -FormatData/sr/MonthNarrows/11=\u0434 +FormatData/sr/MonthNarrows/0=ј +FormatData/sr/MonthNarrows/1=ф +FormatData/sr/MonthNarrows/2=м +FormatData/sr/MonthNarrows/3=а +FormatData/sr/MonthNarrows/4=м +FormatData/sr/MonthNarrows/5=ј +FormatData/sr/MonthNarrows/6=ј +FormatData/sr/MonthNarrows/7=а +FormatData/sr/MonthNarrows/8=с +FormatData/sr/MonthNarrows/9=о +FormatData/sr/MonthNarrows/10=н +FormatData/sr/MonthNarrows/11=д FormatData/sr/MonthNarrows/12= FormatData/mt/MonthNarrows/0=J FormatData/mt/MonthNarrows/1=F FormatData/mt/MonthNarrows/2=M FormatData/mt/MonthNarrows/3=A FormatData/mt/MonthNarrows/4=M -FormatData/mt/MonthNarrows/5=\u0120 +FormatData/mt/MonthNarrows/5=Ġ FormatData/mt/MonthNarrows/6=L FormatData/mt/MonthNarrows/7=A FormatData/mt/MonthNarrows/8=S @@ -7815,33 +7815,33 @@ FormatData/fi/DatePatterns/2=d.M.y FormatData/fi/DatePatterns/3=d.M.y # bug #8075173 -FormatData/de/standalone.MonthAbbreviations/2=M\u00e4r +FormatData/de/standalone.MonthAbbreviations/2=Mär # bug #8178872 FormatData/pt_PT/latn.NumberElements/0=, -FormatData/pt_PT/latn.NumberElements/1=\u00a0 +FormatData/pt_PT/latn.NumberElements/1=  FormatData/pt_AO/latn.NumberElements/0=, -FormatData/pt_AO/latn.NumberElements/1=\u00a0 +FormatData/pt_AO/latn.NumberElements/1=  FormatData/pt_CH/latn.NumberElements/0=, -FormatData/pt_CH/latn.NumberElements/1=\u00a0 +FormatData/pt_CH/latn.NumberElements/1=  FormatData/pt_CV/latn.NumberElements/0=, -FormatData/pt_CV/latn.NumberElements/1=\u00a0 +FormatData/pt_CV/latn.NumberElements/1=  FormatData/pt_GQ/latn.NumberElements/0=, -FormatData/pt_GQ/latn.NumberElements/1=\u00a0 +FormatData/pt_GQ/latn.NumberElements/1=  FormatData/pt_MO/latn.NumberElements/0=, -FormatData/pt_MO/latn.NumberElements/1=\u00a0 +FormatData/pt_MO/latn.NumberElements/1=  FormatData/pt_LU/latn.NumberElements/0=, -FormatData/pt_LU/latn.NumberElements/1=\u00a0 +FormatData/pt_LU/latn.NumberElements/1=  FormatData/pt_MZ/latn.NumberElements/0=, -FormatData/pt_MZ/latn.NumberElements/1=\u00a0 +FormatData/pt_MZ/latn.NumberElements/1=  FormatData/pt_ST/latn.NumberElements/0=, -FormatData/pt_ST/latn.NumberElements/1=\u00a0 +FormatData/pt_ST/latn.NumberElements/1=  FormatData/pt_TL/latn.NumberElements/0=, -FormatData/pt_TL/latn.NumberElements/1=\u00a0 +FormatData/pt_TL/latn.NumberElements/1=  FormatData/kea/latn.NumberElements/0=, -FormatData/kea/latn.NumberElements/1=\u00a0 +FormatData/kea/latn.NumberElements/1=  FormatData/kea_CV/latn.NumberElements/0=, -FormatData/kea_CV/latn.NumberElements/1=\u00a0 +FormatData/kea_CV/latn.NumberElements/1=  # bug #8202537 FormatData/ccp_IN/cakm.NumberElements/4=0 @@ -7860,11 +7860,11 @@ FormatData/fr_CH/latn.NumberElements/11=. # bug # 8295564 FormatData/nb/latn.NumberElements/0=, -FormatData/nb/latn.NumberElements/1=\u00a0 +FormatData/nb/latn.NumberElements/1=  FormatData/no/latn.NumberElements/0=, -FormatData/no/latn.NumberElements/1=\u00a0 +FormatData/no/latn.NumberElements/1=  FormatData/nn/latn.NumberElements/0=, -FormatData/nn/latn.NumberElements/1=\u00a0 +FormatData/nn/latn.NumberElements/1=  # CalendarData consolidated to root CalendarData//firstDayOfWeek=1: AG AS BD BR BS BT BW BZ CA CO DM DO ET GT GU HK HN ID IL IN JM JP KE KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PT PY SA SG SV TH TT TW UM US VE VI WS YE ZA ZW;2: 001 AD AE AI AL AM AN AR AT AU AX AZ BA BE BG BM BN BY CH CL CM CN CR CY CZ DE DK EC EE ES FI FJ FO FR GB GE GF GP GR HR HU IE IS IT KG KZ LB LI LK LT LU LV MC MD ME MK MN MQ MY NL NO NZ PL RE RO RS RU SE SI SK SM TJ TM TR UA UY UZ VA VN XK;6: MV;7: AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY @@ -7875,4 +7875,4 @@ TimeZoneNames/en/America\/Ojinaga/1=Central Standard Time TimeZoneNames/en/America\/Chihuahua/1=Central Standard Time # bug 8303472 -LocaleNames/en/TR=T\u00fcrkiye +LocaleNames/en/TR=Türkiye diff --git a/test/jdk/sun/text/resources/LocaleDataTest.java b/test/jdk/sun/text/resources/LocaleDataTest.java index 40c97d93169..009ba718de5 100644 --- a/test/jdk/sun/text/resources/LocaleDataTest.java +++ b/test/jdk/sun/text/resources/LocaleDataTest.java @@ -41,7 +41,7 @@ * 8187946 8195478 8181157 8179071 8193552 8202026 8204269 8202537 8208746 * 8209775 8221432 8227127 8230284 8231273 8233579 8234288 8250665 8255086 * 8251317 8274658 8283277 8283805 8265315 8287868 8295564 8284840 8296715 - * 8301206 8303472 8317979 8306116 8174269 8333582 8357075 + * 8301206 8303472 8317979 8306116 8174269 8333582 8357075 8357882 * @summary Verify locale data * @modules java.base/sun.util.resources * @modules jdk.localedata @@ -91,9 +91,8 @@ * pairs delimited by newline characters, with the keys separated from the values * by = signs. The keys are similar in syntax to a Unix pathname, with keys at * successive levels of containment in the resource-data hierarchy separated by - * slashes. The file is in ISO 8859-1 encoding, with control characters and - * non-ASCII characters denoted with backslash-u escape sequences. The program also allows - * blank lines and comment lines to be interspersed with the data. Comment lines + * slashes. The file is in UTF-8 encoding. The program also allows blank lines + * and comment lines to be interspersed with the data. Comment lines * begin with '#'. * * A data file for this test would look something like this:

      @@ -102,8 +101,8 @@
        *        LocaleNames//US=United States
        *        LocaleNames//FR=France
        *        FormatData/fr_FR/MonthNames/0=janvier
      - *        FormatData/fr_FR/MonthNames/1=f\u00e9vrier
      - *        LocaleNames/fr_FR/US=\u00c9tats-Unis
      + *        FormatData/fr_FR/MonthNames/1=février
      + *        LocaleNames/fr_FR/US=États-Unis
        *        LocaleNames/fr_FR/FR=France
      * * Second field which designates locale is in the form of: @@ -144,7 +143,7 @@ * date/time format of SimpleDateFormat by making sure that the full date and time * patterns include sufficient data. The test of this is not whether changes were * made to the locale data; it's whether using this data gives round-trip integrity. - * Likewise, changing the currency patterns to use \u00a4 instead of local currency + * Likewise, changing the currency patterns to use ¤ instead of local currency * symbols isn't something that can be tested by this test; instead, you want to * actually format currency values and make sure the proper currency symbol was used. * @@ -160,14 +159,10 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FilterReader; -import java.io.FilterWriter; -import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; -import java.io.Reader; -import java.io.Writer; +import java.nio.charset.StandardCharsets; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; @@ -199,19 +194,17 @@ public class LocaleDataTest doThrow = false; else if (args[i].equals("-s") && in == null) - in = new BufferedReader(new EscapeReader(new InputStreamReader(System.in, - "ISO8859_1"))); + in = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); else if (!args[i].startsWith("-") && in == null) - in = new BufferedReader(new EscapeReader(new InputStreamReader(new - FileInputStream(args[i]), "ISO8859_1"))); + in = new BufferedReader(new InputStreamReader(new + FileInputStream(args[i]), StandardCharsets.UTF_8)); } if (in == null) { File localeData = new File(System.getProperty("test.src", "."), DEFAULT_DATAFILE); - in = new BufferedReader(new EscapeReader(new InputStreamReader(new - FileInputStream(localeData), "ISO8859_1"))); + in = new BufferedReader(new InputStreamReader(new + FileInputStream(localeData), StandardCharsets.UTF_8)); } - out = new PrintWriter(new EscapeWriter(new OutputStreamWriter(System.out, - "ISO8859_1")), true); + out = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8)); // perform the actual test int errorCount = doTest(in, out, writeNewFile); @@ -394,97 +387,3 @@ public class LocaleDataTest return true; } } - -class EscapeReader extends FilterReader { - public EscapeReader(Reader in) { - super(in); - } - - public int read() throws IOException { - if (buffer != null) { - String b = buffer.toString(); - int result = b.charAt(0); - if (b.length() > 1) - buffer = new StringBuffer(b.substring(1)); - else - buffer = null; - return result; - } - else { - int result = super.read(); - if (result != '\\') - return result; - else { - buffer = new StringBuffer(); - result = super.read(); - buffer.append((char)result); - if (result == 'u') { - for (int i = 0; i < 4; i++) { - result = super.read(); - if (result == -1) - break; - buffer.append((char)result); - } - String number = buffer.toString().substring(1); - result = Integer.parseInt(number, 16); - buffer = null; - return result; - } - return '\\'; - } - } - } - - public int read(char[] cbuf, int start, int len) throws IOException { - int p = start; - int end = start + len; - int c = 0; - while (c != -1 && p < end) { - c = read(); - if (c != -1) - cbuf[p++] = (char)c; - } - if (c == -1 && p == start) - return -1; - else - return p - start; - } - - private StringBuffer buffer = null; -} - -class EscapeWriter extends FilterWriter { - public EscapeWriter(Writer out) { - super(out); - } - - public void write(int c) throws IOException { - if ((c >= ' ' && c <= '\u007e') || c == '\r' || c == '\n') - super.write(c); - else { - super.write('\\'); - super.write('u'); - String number = Integer.toHexString(c); - if (number.length() < 4) - number = zeros.substring(0, 4 - number.length()) + number; - super.write(number.charAt(0)); - super.write(number.charAt(1)); - super.write(number.charAt(2)); - super.write(number.charAt(3)); - } - } - - public void write(char[] cbuf, int off, int len) throws IOException { - int end = off + len; - while (off < end) - write(cbuf[off++]); - } - - public void write(String str, int off, int len) throws IOException { - int end = off + len; - while (off < end) - write(str.charAt(off++)); - } - - private static String zeros = "0000"; -} From 3cc630985d47be6ba4cf991698e999f17dbde203 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Fri, 30 May 2025 17:36:03 +0000 Subject: [PATCH 027/216] 8353955: nsk/jdi tests should be fixed to not always require includevirtualthreads=y Reviewed-by: sspitsyn, amenkov, lmesnik --- .../thread/thread001/TestDescription.java | 3 +- .../invokemethod011/TestDescription.java | 3 +- .../invokemethod012/TestDescription.java | 3 +- .../invokemethod013/TestDescription.java | 3 +- .../request/request001/TestDescription.java | 3 +- .../nextevent001/TestDescription.java | 3 +- .../crstepreq005/TestDescription.java | 3 +- .../crstepreq006/TestDescription.java | 3 +- .../crstepreq007/TestDescription.java | 3 +- .../crstepreq008/TestDescription.java | 3 +- .../crstepreq009/TestDescription.java | 3 +- .../crstepreq010/TestDescription.java | 3 +- .../stepreq001/TestDescription.java | 3 +- .../thread/thread001/TestDescription.java | 3 +- .../invokemethod010/TestDescription.java | 3 +- .../invokemethod011/TestDescription.java | 3 +- .../invokemethod012/TestDescription.java | 3 +- .../invokemethod013/TestDescription.java | 3 +- .../waitingthreads002/TestDescription.java | 3 +- .../thread/thread001/TestDescription.java | 3 +- .../allthreads001/TestDescription.java | 3 +- .../vmTestbase/nsk/share/ArgumentParser.java | 4 +-- .../vmTestbase/nsk/share/jdi/Binder.java | 6 ++-- .../share/jdi/SerialExecutionDebugger.java | 5 ++-- .../share/jpda/DebugeeArgumentHandler.java | 29 ++++++++++++++----- 25 files changed, 72 insertions(+), 35 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareEvent/thread/thread001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareEvent/thread/thread001/TestDescription.java index cea844bba80..b6c9c93c485 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareEvent/thread/thread001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassPrepareEvent/thread/thread001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -81,6 +81,7 @@ * @run driver * nsk.jdi.ClassPrepareEvent.thread.thread001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod011/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod011/TestDescription.java index adb7b99567c..4c72804bc41 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod011/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod011/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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,6 +56,7 @@ * @run driver * nsk.jdi.ClassType.invokeMethod.invokemethod011 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod012/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod012/TestDescription.java index e675bf3c3fc..2bea9cc5209 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod012/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod012/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -54,6 +54,7 @@ * @run driver * nsk.jdi.ClassType.invokeMethod.invokemethod012 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod013/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod013/TestDescription.java index ed341632008..5224d9350da 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod013/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod013/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -54,6 +54,7 @@ * @run driver * nsk.jdi.ClassType.invokeMethod.invokemethod013 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001/TestDescription.java index 37f3750bee4..87f7d9f57aa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/request/request001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.Event.request.request001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001/TestDescription.java index 237158dd6fc..01d425015bf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventIterator/nextEvent/nextevent001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.EventIterator.nextEvent.nextevent001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq005/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq005/TestDescription.java index e8c1809dec5..1d3ac400931 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq005/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq005/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -71,6 +71,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq005 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq006/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq006/TestDescription.java index 00f5b29388b..810483e0740 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq006/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq006/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -71,6 +71,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq006 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq007/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq007/TestDescription.java index 561e3fd5580..f1897446525 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq007/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq007/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -69,6 +69,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq007 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq008/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq008/TestDescription.java index 66f744debf8..47fa4bbb940 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq008/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq008/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -71,6 +71,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq008 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq009/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq009/TestDescription.java index 92a997a0b3d..bc059e87c86 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq009/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq009/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -71,6 +71,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq009 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq010/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq010/TestDescription.java index 793141637a1..9117c5dc640 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq010/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/createStepRequest/crstepreq010/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -70,6 +70,7 @@ * @run driver * nsk.jdi.EventRequestManager.createStepRequest.crstepreq010 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq001/TestDescription.java index a95b34f511d..62362a737a8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventRequestManager/stepRequests/stepreq001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -51,6 +51,7 @@ * @run driver * nsk.jdi.EventRequestManager.stepRequests.stepreq001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001/TestDescription.java index ff8bed293ad..e885341a1b7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/LocatableEvent/thread/thread001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.LocatableEvent.thread.thread001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod010/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod010/TestDescription.java index 951028bb112..da2c2d31fc6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod010/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod010/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -61,6 +61,7 @@ * @run driver * nsk.jdi.ObjectReference.invokeMethod.invokemethod010 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod011/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod011/TestDescription.java index d152338e488..3cda0572ff6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod011/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod011/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.ObjectReference.invokeMethod.invokemethod011 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod012/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod012/TestDescription.java index b39a8723c9f..fb0d9cb0345 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod012/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod012/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -58,6 +58,7 @@ * @run driver * nsk.jdi.ObjectReference.invokeMethod.invokemethod012 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod013/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod013/TestDescription.java index b18bc0a9fb1..94d7bf4f473 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod013/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod013/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -58,6 +58,7 @@ * @run driver * nsk.jdi.ObjectReference.invokeMethod.invokemethod013 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002/TestDescription.java index 0edb28dd0e1..ac1e9e49672 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -62,6 +62,7 @@ * @run driver * nsk.jdi.ObjectReference.waitingThreads.waitingthreads002 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001/TestDescription.java index abcc5e8a18a..0b6ae5920c6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartEvent/thread/thread001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -88,6 +88,7 @@ * @run driver * nsk.jdi.ThreadStartEvent.thread.thread001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/allThreads/allthreads001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/allThreads/allthreads001/TestDescription.java index 0156e863a31..fe5f9b09b00 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/allThreads/allthreads001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/allThreads/allthreads001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -73,6 +73,7 @@ * @run driver * nsk.jdi.VirtualMachine.allThreads.allthreads001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/ArgumentParser.java b/test/hotspot/jtreg/vmTestbase/nsk/share/ArgumentParser.java index be92244b417..4c5ffe97e7b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/ArgumentParser.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/ArgumentParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -476,7 +476,7 @@ public class ArgumentParser { if (option.equals("verbose") || option.equals("vbs") || option.equals("trace.time")) { - if (!(value == null || value.length() <= 0)) { + if (!(value == null || value.length() == 0)) { throw new BadOption(option + ": no value must be specified"); } return true; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java index 9879b68775f..646d6e9e39e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -518,7 +518,7 @@ public class Binder extends DebugeeBinder { // This flag is needed so VirtualMachine.allThreads() includes known vthreads. arg = (Connector.StringArgument) arguments.get("includevirtualthreads"); - arg.setValue("y"); + arg.setValue(argumentHandler.isIncludeVirtualThreads() ? "y" : "n"); String vmArgs = ""; @@ -750,4 +750,4 @@ public class Binder extends DebugeeBinder { return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); } -} \ No newline at end of file +} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/SerialExecutionDebugger.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/SerialExecutionDebugger.java index 48546cc6a63..52add61cdf6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/SerialExecutionDebugger.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/SerialExecutionDebugger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -111,8 +111,9 @@ public class SerialExecutionDebugger extends TestDebuggerType2 { if (args[i].equals("-configFile") && (i < args.length - 1)) { configFileName = args[i + 1]; i++; - } else + } else { standardArgs.add(args[i]); + } } if (configFileName == null) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java index 72461a52309..72b8076f927 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/DebugeeArgumentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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,9 +83,9 @@ import java.net.ServerSocket; */ public class DebugeeArgumentHandler extends ArgumentParser { - public static final String DEFAULT_PIPE_PORT = "7123"; - public static final String DEFAULT_TRANSPORT_PORT = "8123"; - public static final String DEFAULT_BIND_PORT = "9123"; + public static final String DEFAULT_PIPE_PORT = "7123"; + public static final String DEFAULT_TRANSPORT_PORT = "8123"; + public static final String DEFAULT_BIND_PORT = "9123"; /** @@ -103,6 +103,16 @@ public class DebugeeArgumentHandler extends ArgumentParser { super(args); } + /** + * Return true if -includevirtualthreads command line option + * is specified. + * + * @see #setRawArguments(String[]) + */ + public boolean isIncludeVirtualThreads() { + return options.getProperty("includevirtualthreads") != null; + } + /** * Return name of the host where test executes, specified by * -test.host command line option or @@ -471,7 +481,7 @@ public class DebugeeArgumentHandler extends ArgumentParser { } /** - * Return true if JVMDI strict mode for launching debugeeVM is used^ + * Return true if JVMDI strict mode for launching debugeeVM is used * either by specifying in command line or by default. * * @see #getJVMDIStrictMode() @@ -648,8 +658,13 @@ public class DebugeeArgumentHandler extends ArgumentParser { */ protected boolean checkOption(String option, String value) { - if(option.equals("traceAll")) - return true; + if (option.equals("traceAll") + || option.equals("includevirtualthreads")) { + if (!(value == null || value.length() == 0)) { + throw new BadOption(option + ": no value must be specified"); + } + return true; + } // option with any string value if (option.equals("debugee.vmkeys")) { From 82807d43f8d18b186428be88a80ebe28892517cc Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Fri, 30 May 2025 17:58:46 +0000 Subject: [PATCH 028/216] 8357184: Test vmTestbase/nsk/jdi/ExceptionEvent/_itself_/exevent008/TestDescription.java fails with unreported exception Reviewed-by: lmesnik, sspitsyn --- .../ExceptionEvent/_itself_/exevent008.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionEvent/_itself_/exevent008.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionEvent/_itself_/exevent008.java index ffd217b31bc..4efbd53c66a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionEvent/_itself_/exevent008.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ExceptionEvent/_itself_/exevent008.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -80,7 +80,7 @@ public class exevent008 { private ExceptionRequest eRequest; private ReferenceType rType, rTypeEx; private String cmd; - private int counter1 = 0, counter2 = 0; + private volatile boolean exception1Received = false, exception2Received = false; private volatile int tot_res = PASSED; public static void main (String argv[]) { @@ -134,7 +134,6 @@ public class exevent008 { elThread.start(); log.display("Forcing debuggee to generate caught exception"); - counter1 = 0; pipe.println(COMMAND_TEST1); if (!cmd.equals(COMMAND_READY)) { @@ -145,7 +144,6 @@ public class exevent008 { log.display("Exception caught"); log.display("Forcing debuggee to generate uncaught exception"); - counter1 = 0; pipe.println(COMMAND_TEST2); log.display("Waiting for debuggee exits due to uncaught exception"); @@ -161,12 +159,12 @@ public class exevent008 { return quitDebuggee(); } - if (counter1 == 0) { + if (!exception1Received) { log.complain("TEST FAILED: caught exception " + DEBUGGEE_EXCEPTION1 + " was not reported by the debugger"); tot_res = FAILED; } - if (counter2 == 0) { + if (!exception2Received) { log.complain("TEST FAILED: uncaught exception " + DEBUGGEE_EXCEPTION2 + " was not reported by the debugger"); tot_res = FAILED; @@ -243,13 +241,13 @@ public class exevent008 { if (exEvent.exception().referenceType().name().equals(DEBUGGEE_EXCEPTION1)) { log.display("CException event equals to expected for caught exception\n\t" + exEvent.exception().referenceType().name()); - counter1++; - log.display("\t" + "counter1 = " + counter1); + exception1Received = true; + log.display("\t" + "exception1Received = " + exception1Received); } else if (exEvent.exception().referenceType().name().equals(DEBUGGEE_EXCEPTION2)) { log.display("Exception event equals to expected for uncaught exception\n\t" + exEvent.exception().referenceType().name()); - counter2++; - log.display("\t" + "counter2 = " + counter2); + exception2Received = true; + log.display("\t" + "exception2Received = " + exception2Received); } } } else { From b7ca672d5c5f11f472110154868f08299f6e8796 Mon Sep 17 00:00:00 2001 From: Ashutosh Mehra Date: Fri, 30 May 2025 18:26:19 +0000 Subject: [PATCH 029/216] 8357047: [ubsan] AdapterFingerPrint::AdapterFingerPrint runtime error: index 3 out of bounds Reviewed-by: kvn, adinn --- src/hotspot/share/runtime/sharedRuntime.cpp | 53 ++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index a3546e0f5a2..edb33b3500a 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2177,7 +2177,6 @@ static int _lookups; // number of calls to lookup static int _equals; // number of buckets checked with matching hash static int _archived_hits; // number of successful lookups in archived table static int _runtime_hits; // number of successful lookups in runtime table -static int _compact; // number of equals calls with compact signature #endif // A simple wrapper class around the calling convention information @@ -2188,18 +2187,22 @@ class AdapterFingerPrint : public MetaspaceObj { _basic_type_bits = 4, _basic_type_mask = right_n_bits(_basic_type_bits), _basic_types_per_int = BitsPerInt / _basic_type_bits, - _compact_int_count = 3 }; // TO DO: Consider integrating this with a more global scheme for compressing signatures. // For now, 4 bits per components (plus T_VOID gaps after double/long) is not excessive. int _length; - int _value[_compact_int_count]; + + static int data_offset() { return sizeof(AdapterFingerPrint); } + int* data_pointer() { + return (int*)((address)this + data_offset()); + } // Private construtor. Use allocate() to get an instance. AdapterFingerPrint(int total_args_passed, BasicType* sig_bt) { + int* data = data_pointer(); // Pack the BasicTypes with 8 per int - _length = (total_args_passed + (_basic_types_per_int-1)) / _basic_types_per_int; + _length = length(total_args_passed); int sig_index = 0; for (int index = 0; index < _length; index++) { int value = 0; @@ -2208,7 +2211,7 @@ class AdapterFingerPrint : public MetaspaceObj { assert((bt & _basic_type_mask) == bt, "must fit in 4 bits"); value = (value << _basic_type_bits) | bt; } - _value[index] = value; + data[index] = value; } } @@ -2217,6 +2220,15 @@ class AdapterFingerPrint : public MetaspaceObj { FreeHeap(this); } + static int length(int total_args) { + return (total_args + (_basic_types_per_int-1)) / _basic_types_per_int; + } + + static int compute_size(int total_args_passed, BasicType* sig_bt) { + int len = length(total_args_passed); + return sizeof(AdapterFingerPrint) + (len * sizeof(int)); + } + // Remap BasicTypes that are handled equivalently by the adapters. // These are correct for the current system but someday it might be // necessary to make this mapping platform dependent. @@ -2276,13 +2288,8 @@ class AdapterFingerPrint : public MetaspaceObj { } public: - static int allocation_size(int total_args_passed, BasicType* sig_bt) { - int len = (total_args_passed + (_basic_types_per_int-1)) / _basic_types_per_int; - return sizeof(AdapterFingerPrint) + (len > _compact_int_count ? (len - _compact_int_count) * sizeof(int) : 0); - } - static AdapterFingerPrint* allocate(int total_args_passed, BasicType* sig_bt) { - int size_in_bytes = allocation_size(total_args_passed, sig_bt); + int size_in_bytes = compute_size(total_args_passed, sig_bt); return new (size_in_bytes) AdapterFingerPrint(total_args_passed, sig_bt); } @@ -2291,18 +2298,14 @@ class AdapterFingerPrint : public MetaspaceObj { } int value(int index) { - return _value[index]; + int* data = data_pointer(); + return data[index]; } int length() { - if (_length < 0) return -_length; return _length; } - bool is_compact() { - return _length <= _compact_int_count; - } - unsigned int compute_hash() { int hash = 0; for (int i = 0; i < length(); i++) { @@ -2405,7 +2408,7 @@ class AdapterFingerPrint : public MetaspaceObj { return false; } else { for (int i = 0; i < _length; i++) { - if (_value[i] != other->_value[i]) { + if (value(i) != other->value(i)) { return false; } } @@ -2415,7 +2418,7 @@ class AdapterFingerPrint : public MetaspaceObj { // methods required by virtue of being a MetaspaceObj void metaspace_pointers_do(MetaspaceClosure* it) { return; /* nothing to do here */ } - int size() const { return (int)heap_word_size(sizeof(AdapterFingerPrint) + (_length > _compact_int_count ? (_length - _compact_int_count) * sizeof(int) : 0)); } + int size() const { return (int)heap_word_size(sizeof(AdapterFingerPrint) + (_length * sizeof(int))); } MetaspaceObj::Type type() const { return AdapterFingerPrintType; } static bool equals(AdapterFingerPrint* const& fp1, AdapterFingerPrint* const& fp2) { @@ -2459,14 +2462,11 @@ AdapterHandlerEntry* AdapterHandlerLibrary::lookup(int total_args_passed, BasicT if (AOTCodeCache::is_using_adapter()) { // Search archived table first. It is read-only table so can be searched without lock entry = _aot_adapter_handler_table.lookup(fp, fp->compute_hash(), 0 /* unused */); - if (entry != nullptr) { #ifndef PRODUCT - if (fp->is_compact()) { - _compact++; - } + if (entry != nullptr) { _archived_hits++; -#endif } +#endif } #endif // INCLUDE_CDS if (entry == nullptr) { @@ -2478,7 +2478,6 @@ AdapterHandlerEntry* AdapterHandlerLibrary::lookup(int total_args_passed, BasicT entry->fingerprint()->as_basic_args_string(), entry->fingerprint()->as_string(), entry->fingerprint()->compute_hash(), fp->as_basic_args_string(), fp->as_string(), fp->compute_hash()); #ifndef PRODUCT - if (fp->is_compact()) _compact++; _runtime_hits++; #endif } @@ -2497,8 +2496,8 @@ static void print_table_statistics() { tty->print_cr("AdapterHandlerTable (table_size=%d, entries=%d)", _adapter_handler_table->table_size(), _adapter_handler_table->number_of_entries()); int total_hits = _archived_hits + _runtime_hits; - tty->print_cr("AdapterHandlerTable: lookups %d equals %d hits %d (archived=%d+runtime=%d) compact %d", - _lookups, _equals, total_hits, _archived_hits, _runtime_hits, _compact); + tty->print_cr("AdapterHandlerTable: lookups %d equals %d hits %d (archived=%d+runtime=%d)", + _lookups, _equals, total_hits, _archived_hits, _runtime_hits); } #endif From 94039e22bbe943888e858d8ae278145e2668526a Mon Sep 17 00:00:00 2001 From: Daniel Gredler Date: Fri, 30 May 2025 19:16:17 +0000 Subject: [PATCH 030/216] 8353230: Emoji rendering regression after JDK-8208377 Reviewed-by: prr, honkar --- .../classes/sun/font/CCharToGlyphMapper.java | 60 ++++--- .../share/classes/sun/font/CMap.java | 44 +---- .../classes/sun/font/CharToGlyphMapper.java | 9 +- .../sun/font/CompositeGlyphMapper.java | 58 +++---- .../share/classes/sun/font/Font2D.java | 10 +- .../share/classes/sun/font/FontUtilities.java | 14 ++ .../share/classes/sun/font/HBShaper.java | 6 +- .../classes/sun/font/TrueTypeGlyphMapper.java | 38 ++-- .../classes/sun/font/Type1GlyphMapper.java | 24 ++- .../classes/sun/print/RasterPrinterJob.java | 6 +- .../share/native/libfontmanager/sunFont.c | 6 +- .../classes/sun/font/NativeGlyphMapper.java | 6 +- .../font/GlyphVector/GlyphVectorGsubTest.java | 164 ++++++++++++++++++ 13 files changed, 318 insertions(+), 127 deletions(-) create mode 100644 test/jdk/java/awt/font/GlyphVector/GlyphVectorGsubTest.java diff --git a/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java b/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java index 5eb05a9f93e..7ce12b7d4f7 100644 --- a/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java +++ b/src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java @@ -27,6 +27,9 @@ package sun.font; import java.util.HashMap; +import static sun.font.FontUtilities.isDefaultIgnorable; +import static sun.font.FontUtilities.isIgnorableWhitespace; + public class CCharToGlyphMapper extends CharToGlyphMapper { private static native int countGlyphs(final long nativeFontPtr); @@ -47,12 +50,12 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { } public boolean canDisplay(char ch) { - int glyph = charToGlyph(ch); + int glyph = charToGlyph(ch, false); return glyph != missingGlyph; } public boolean canDisplay(int cp) { - int glyph = charToGlyph(cp); + int glyph = charToGlyph(cp, false); return glyph != missingGlyph; } @@ -89,17 +92,17 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { } public synchronized int charToGlyph(char unicode) { - int glyph = cache.get(unicode); + return charToGlyph(unicode, false); + } + + private int charToGlyph(char unicode, boolean raw) { + int glyph = cache.get(unicode, raw); if (glyph != 0) return glyph; - if (FontUtilities.isDefaultIgnorable(unicode) || isIgnorableWhitespace(unicode)) { - glyph = INVISIBLE_GLYPH_ID; - } else { - final char[] unicodeArray = new char[] { unicode }; - final int[] glyphArray = new int[1]; - nativeCharsToGlyphs(fFont.getNativeFontPtr(), 1, unicodeArray, glyphArray); - glyph = glyphArray[0]; - } + final char[] unicodeArray = new char[] { unicode }; + final int[] glyphArray = new int[1]; + nativeCharsToGlyphs(fFont.getNativeFontPtr(), 1, unicodeArray, glyphArray); + glyph = glyphArray[0]; cache.put(unicode, glyph); @@ -107,35 +110,37 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { } public synchronized int charToGlyph(int unicode) { + return charToGlyph(unicode, false); + } + + public synchronized int charToGlyphRaw(int unicode) { + return charToGlyph(unicode, true); + } + + private int charToGlyph(int unicode, boolean raw) { if (unicode >= 0x10000) { int[] glyphs = new int[2]; char[] surrogates = new char[2]; int base = unicode - 0x10000; surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START); surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START); - charsToGlyphs(2, surrogates, glyphs); + cache.get(2, surrogates, glyphs, raw); return glyphs[0]; } else { - return charToGlyph((char)unicode); + return charToGlyph((char) unicode, raw); } } public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { - cache.get(count, unicodes, glyphs); + cache.get(count, unicodes, glyphs, false); } public synchronized void charsToGlyphs(int count, int[] unicodes, int[] glyphs) { for (int i = 0; i < count; i++) { - glyphs[i] = charToGlyph(unicodes[i]); + glyphs[i] = charToGlyph(unicodes[i], false); } } - // Matches behavior in e.g. CMap.getControlCodeGlyph(int, boolean) - // and RasterPrinterJob.removeControlChars(String) - private static boolean isIgnorableWhitespace(int code) { - return code == 0x0009 || code == 0x000a || code == 0x000d; - } - // This mapper returns either the glyph code, or if the character can be // replaced on-the-fly using CoreText substitution; the negative unicode // value. If this "glyph code int" is treated as an opaque code, it will @@ -159,7 +164,11 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { firstLayerCache[1] = 1; } - public synchronized int get(final int index) { + public synchronized int get(final int index, final boolean raw) { + if (isIgnorableWhitespace(index) || (isDefaultIgnorable(index) && !raw)) { + return INVISIBLE_GLYPH_ID; + } + if (index < FIRST_LAYER_SIZE) { // catch common glyphcodes return firstLayerCache[index]; @@ -230,7 +239,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { } } - public synchronized void get(int count, char[] indices, int[] values) + public synchronized void get(int count, char[] indices, int[] values, boolean raw) { // "missed" is the count of 'char' that are not mapped. // Surrogates count for 2. @@ -252,16 +261,13 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { } } - final int value = get(code); + final int value = get(code, raw); if (value != 0 && value != -1) { values[i] = value; if (code >= 0x10000) { values[i+1] = INVISIBLE_GLYPH_ID; i++; } - } else if (FontUtilities.isDefaultIgnorable(code) || isIgnorableWhitespace(code)) { - values[i] = INVISIBLE_GLYPH_ID; - put(code, INVISIBLE_GLYPH_ID); } else { values[i] = 0; put(code, -1); diff --git a/src/java.desktop/share/classes/sun/font/CMap.java b/src/java.desktop/share/classes/sun/font/CMap.java index 3cb1ad57751..2bb582a8a9a 100644 --- a/src/java.desktop/share/classes/sun/font/CMap.java +++ b/src/java.desktop/share/classes/sun/font/CMap.java @@ -546,9 +546,8 @@ abstract class CMap { int index = 0; char glyphCode = 0; - int controlGlyph = getControlCodeGlyph(charCode, true); - if (controlGlyph >= 0) { - return (char)controlGlyph; + if (isSurrogate(charCode)) { + return 0; } /* presence of translation array indicates that this @@ -633,13 +632,6 @@ abstract class CMap { char getGlyph(int charCode) { if (charCode < 256) { - if (charCode < 0x0010) { - switch (charCode) { - case 0x0009: - case 0x000a: - case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID; - } - } return (char)(0xff & cmap[charCode]); } else { return 0; @@ -778,10 +770,8 @@ abstract class CMap { } char getGlyph(int charCode) { - final int origCharCode = charCode; - int controlGlyph = getControlCodeGlyph(charCode, true); - if (controlGlyph >= 0) { - return (char)controlGlyph; + if (isSurrogate(charCode)) { + return 0; } if (xlat != null) { @@ -858,11 +848,9 @@ abstract class CMap { } char getGlyph(int charCode) { - final int origCharCode = charCode; - int controlGlyph = getControlCodeGlyph(charCode, true); - if (controlGlyph >= 0) { - return (char)controlGlyph; - } + if (isSurrogate(charCode)) { + return 0; + } if (xlat != null) { charCode = xlat[charCode]; @@ -1020,11 +1008,6 @@ abstract class CMap { } char getGlyph(int charCode) { - final int origCharCode = charCode; - int controlGlyph = getControlCodeGlyph(charCode, false); - if (controlGlyph >= 0) { - return (char)controlGlyph; - } int probe = power; int range = 0; @@ -1060,17 +1043,8 @@ abstract class CMap { public static final NullCMapClass theNullCmap = new NullCMapClass(); - final int getControlCodeGlyph(int charCode, boolean noSurrogates) { - if (charCode < 0x0010) { - switch (charCode) { - case 0x0009: - case 0x000a: - case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID; - } - } else if (noSurrogates && charCode >= 0xFFFF) { - return 0; - } - return -1; + private static boolean isSurrogate(int charCode) { + return charCode >= 0xFFFF; } static class UVS { diff --git a/src/java.desktop/share/classes/sun/font/CharToGlyphMapper.java b/src/java.desktop/share/classes/sun/font/CharToGlyphMapper.java index bac385d81db..3b50b0e8876 100644 --- a/src/java.desktop/share/classes/sun/font/CharToGlyphMapper.java +++ b/src/java.desktop/share/classes/sun/font/CharToGlyphMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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 @@ -86,6 +86,13 @@ public abstract class CharToGlyphMapper { return charToGlyph(unicode); } + public int charToVariationGlyphRaw(int unicode, int variationSelector) { + // Override this if variation selector is supported. + return charToGlyphRaw(unicode); + } + + public abstract int charToGlyphRaw(int unicode); + public abstract int getNumGlyphs(); public abstract void charsToGlyphs(int count, diff --git a/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java b/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java index cd53d96d0f4..673e2eb0d9f 100644 --- a/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java +++ b/src/java.desktop/share/classes/sun/font/CompositeGlyphMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -42,6 +42,9 @@ package sun.font; * this appears to cause problems. */ +import static sun.font.FontUtilities.isDefaultIgnorable; +import static sun.font.FontUtilities.isIgnorableWhitespace; + public class CompositeGlyphMapper extends CharToGlyphMapper { public static final int SLOTMASK = 0xff000000; @@ -51,7 +54,6 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { public static final int BLOCKSZ = 256; public static final int MAXUNICODE = NBLOCKS*BLOCKSZ; - CompositeFont font; CharToGlyphMapper[] slotMappers; int[][] glyphMaps; @@ -96,7 +98,7 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { private void setCachedGlyphCode(int unicode, int glyphCode) { if (unicode >= MAXUNICODE) { - return; // don't cache surrogates + return; // don't cache surrogates } int index0 = unicode >> 8; if (glyphMaps[index0] == null) { @@ -117,12 +119,18 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { return mapper; } - private int convertToGlyph(int unicode) { - + private int getGlyph(int unicode, boolean raw) { + if (isIgnorableWhitespace(unicode) || (isDefaultIgnorable(unicode) && !raw)) { + return INVISIBLE_GLYPH_ID; + } + int glyphCode = getCachedGlyphCode(unicode); + if (glyphCode != UNINITIALIZED_GLYPH) { + return glyphCode; + } for (int slot = 0; slot < font.numSlots; slot++) { if (!hasExcludes || !font.isExcludedChar(slot, unicode)) { CharToGlyphMapper mapper = getSlotMapper(slot); - int glyphCode = mapper.charToGlyph(unicode); + glyphCode = mapper.charToGlyphRaw(unicode); if (glyphCode != mapper.getMissingGlyphCode()) { glyphCode = compositeGlyphCode(slot, glyphCode); setCachedGlyphCode(unicode, glyphCode); @@ -155,12 +163,13 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { return numGlyphs; } - public int charToGlyph(int unicode) { + public int charToGlyphRaw(int unicode) { + int glyphCode = getGlyph(unicode, true); + return glyphCode; + } - int glyphCode = getCachedGlyphCode(unicode); - if (glyphCode == UNINITIALIZED_GLYPH) { - glyphCode = convertToGlyph(unicode); - } + public int charToGlyph(int unicode) { + int glyphCode = getGlyph(unicode, false); return glyphCode; } @@ -176,11 +185,7 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { } public int charToGlyph(char unicode) { - - int glyphCode = getCachedGlyphCode(unicode); - if (glyphCode == UNINITIALIZED_GLYPH) { - glyphCode = convertToGlyph(unicode); - } + int glyphCode = getGlyph(unicode, false); return glyphCode; } @@ -206,10 +211,7 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { } } - int gc = glyphs[i] = getCachedGlyphCode(code); - if (gc == UNINITIALIZED_GLYPH) { - glyphs[i] = convertToGlyph(code); - } + glyphs[i] = getGlyph(code, false); if (code < FontUtilities.MIN_LAYOUT_CHARCODE) { continue; @@ -243,31 +245,21 @@ public class CompositeGlyphMapper extends CharToGlyphMapper { code = (code - HI_SURROGATE_START) * 0x400 + low - LO_SURROGATE_START + 0x10000; - int gc = glyphs[i] = getCachedGlyphCode(code); - if (gc == UNINITIALIZED_GLYPH) { - glyphs[i] = convertToGlyph(code); - } + glyphs[i] = getGlyph(code, false); i += 1; // Empty glyph slot after surrogate glyphs[i] = INVISIBLE_GLYPH_ID; continue; } } - int gc = glyphs[i] = getCachedGlyphCode(code); - if (gc == UNINITIALIZED_GLYPH) { - glyphs[i] = convertToGlyph(code); - } + glyphs[i] = getGlyph(code, false); } } public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) { for (int i=0; i 0xffff) { return missingGlyph; } else { - if (FontUtilities.isDefaultIgnorable(ch) || isIgnorableWhitespace(ch)) { + if (isIgnorableWhitespace(ch) || (isDefaultIgnorable(ch) && !raw)) { return INVISIBLE_GLYPH_ID; } try { @@ -105,13 +118,6 @@ public final class Type1GlyphMapper extends CharToGlyphMapper { } } - // Matches behavior in e.g. CMap.getControlCodeGlyph(int, boolean) - // and RasterPrinterJob.removeControlChars(String) - // and CCharToGlyphMapper.isIgnorableWhitespace(int) - private static boolean isIgnorableWhitespace(int code) { - return code == 0x0009 || code == 0x000a || code == 0x000d; - } - public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { /* The conversion into surrogates is misleading. * The Type1 glyph mapper only accepts 16 bit unsigned shorts. diff --git a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index dbd7999fdc0..2a6d45e2ba8 100644 --- a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -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 @@ -90,6 +90,8 @@ import javax.print.attribute.standard.RequestingUserName; import javax.print.attribute.standard.SheetCollate; import javax.print.attribute.standard.Sides; +import static sun.font.FontUtilities.isIgnorableWhitespace; + /** * A class which rasterizes a printer job. * @@ -2482,7 +2484,7 @@ public abstract class RasterPrinterJob extends PrinterJob { for (int i = 0; i < len; i++) { char c = in_chars[i]; - if (c > '\r' || c < '\t' || c == '\u000b' || c == '\u000c') { + if (!isIgnorableWhitespace(c)) { out_chars[pos++] = c; } } diff --git a/src/java.desktop/share/native/libfontmanager/sunFont.c b/src/java.desktop/share/native/libfontmanager/sunFont.c index e6082b69416..1fe4cc7dfd7 100644 --- a/src/java.desktop/share/native/libfontmanager/sunFont.c +++ b/src/java.desktop/share/native/libfontmanager/sunFont.c @@ -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 @@ -143,9 +143,9 @@ static void initFontIDs(JNIEnv *env) { CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/Font2D")); CHECK_NULL(sunFontIDs.f2dCharToGlyphMID = - (*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I")); + (*env)->GetMethodID(env, tmpClass, "charToGlyphRaw", "(I)I")); CHECK_NULL(sunFontIDs.f2dCharToVariationGlyphMID = - (*env)->GetMethodID(env, tmpClass, "charToVariationGlyph", "(II)I")); + (*env)->GetMethodID(env, tmpClass, "charToVariationGlyphRaw", "(II)I")); CHECK_NULL(sunFontIDs.getMapperMID = (*env)->GetMethodID(env, tmpClass, "getMapper", "()Lsun/font/CharToGlyphMapper;")); diff --git a/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java b/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java index aecb2494f24..cec455e2e83 100644 --- a/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java +++ b/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -75,6 +75,10 @@ public class NativeGlyphMapper extends CharToGlyphMapper { } } + public int charToGlyphRaw(int unicode) { + return charToGlyph(unicode); + } + public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { for (int i=0; iFont created for this test which contains two GSUB substitutions: a + * "liga" ligature for "a" + "b" which requires that the ligature support + * be enabled, and a "ccmp" ligature for an emoji sequence which does not + * require that ligatures be explicitly enabled. + * + *

      The following FontForge Python script was used to generate this font: + * + *

      +     * import fontforge
      +     * import base64
      +     *
      +     * def draw(glyph, width, height):
      +     *   pen = glyph.glyphPen()
      +     *   pen.moveTo((100, 100))
      +     *   pen.lineTo((100, 100 + height))
      +     *   pen.lineTo((100 + width, 100 + height))
      +     *   pen.lineTo((100 + width, 100))
      +     *   pen.closePath()
      +     *   glyph.draw(pen)
      +     *   pen = None
      +     *
      +     * font = fontforge.font()
      +     * font.encoding = 'UnicodeFull'
      +     * font.design_size = 16
      +     * font.em = 2048
      +     * font.ascent = 1638
      +     * font.descent = 410
      +     * font.familyname = 'Test'
      +     * font.fontname = 'Test'
      +     * font.fullname = 'Test'
      +     * font.copyright = ''
      +     * font.autoWidth(0, 0, 2048)
      +     *
      +     * font.addLookup('ligatures', 'gsub_ligature', (), (('liga',(('latn',('dflt')),)),))
      +     * font.addLookupSubtable('ligatures', 'sub1')
      +     *
      +     * font.addLookup('sequences', 'gsub_ligature', (), (('ccmp',(('latn',('dflt')),)),))
      +     * font.addLookupSubtable('sequences', 'sub2')
      +     *
      +     * space = font.createChar(0x20)
      +     * space.width = 600
      +     *
      +     * # create glyphs: a, b, ab
      +     *
      +     * for char in list('ab'):
      +     *   glyph = font.createChar(ord(char))
      +     *   draw(glyph, 400, 100)
      +     *   glyph.width = 600
      +     *
      +     * ab = font.createChar(-1, 'ab')
      +     * ab.addPosSub('sub1', ('a', 'b'))
      +     * draw(ab, 400, 400)
      +     * ab.width = 600
      +     *
      +     * # create glyphs for "woman" emoji sequence
      +     *
      +     * components = []
      +     * woman = '\U0001F471\U0001F3FD\u200D\u2640\uFE0F'
      +     * for char in list(woman):
      +     *   glyph = font.createChar(ord(char))
      +     *   draw(glyph, 400, 800)
      +     *   glyph.width = 600
      +     *   components.append(glyph.glyphname)
      +     *
      +     * del components[-1] # remove last
      +     * seq = font.createChar(-1, 'seq')
      +     * seq.addPosSub('sub2', components)
      +     * draw(seq, 400, 1200)
      +     * seq.width = 600
      +     *
      +     * # save font to file
      +     *
      +     * ttf = 'test.ttf'     # TrueType
      +     * t64 = 'test.ttf.txt' # TrueType Base64
      +     *
      +     * font.generate(ttf)
      +     *
      +     * with open(ttf, 'rb') as f1:
      +     *   encoded = base64.b64encode(f1.read())
      +     *   with open(t64, 'wb') as f2:
      +     *     f2.write(encoded)
      +     * 
      + */ + private static final String TTF_BYTES = "AAEAAAAQAQAABAAARkZUTaomGsgAAAiUAAAAHEdERUYAQQAZAAAHtAAAACRHUE9T4BjvnAAACFwAAAA2R1NVQkbjQAkAAAfYAAAAhE9TLzKik/GeAAABiAAAAGBjbWFwK+OB7AAAAgwAAAHWY3Z0IABEBREAAAPkAAAABGdhc3D//wADAAAHrAAAAAhnbHlmyBUElgAABAQAAAG4aGVhZCnqeTIAAAEMAAAANmhoZWEIcgJdAAABRAAAACRobXR4CPwB1AAAAegAAAAibG9jYQKIAxYAAAPoAAAAHG1heHAAUQA5AAABaAAAACBuYW1lQcPFIwAABbwAAAGGcG9zdIAWZOAAAAdEAAAAaAABAAAAAQAA7g5Qb18PPPUACwgAAAAAAOQSF3AAAAAA5BIXcABEAAACZAVVAAAACAACAAAAAAAAAAEAAAVVAAAAuAJYAAAAAAJkAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAANAAgAAgAAAAAAAgAAAAEAAQAAAEAALgAAAAAABAJYAZAABQAABTMFmQAAAR4FMwWZAAAD1wBmAhIAAAIABQkAAAAAAACAAAABAgBAAAgAAAAAAAAAUGZFZACAACD//wZm/mYAuAVVAAAAAAABAAAAAADIAAAAAAAgAAQCWABEAAAAAAJYAAACWAAAAGQAZABkAGQAZABkAGQAZABkAAAAAAAFAAAAAwAAACwAAAAEAAAAbAABAAAAAADQAAMAAQAAACwAAwAKAAAAbAAEAEAAAAAMAAgAAgAEACAAYiANJkD+D///AAAAIABhIA0mQP4P////4/+j3/nZxwH5AAEAAAAAAAAAAAAAAAAADAAAAAAAZAAAAAAAAAAHAAAAIAAAACAAAAADAAAAYQAAAGIAAAAEAAAgDQAAIA0AAAAGAAAmQAAAJkAAAAAHAAD+DwAA/g8AAAAIAAHz/QAB8/0AAAAJAAH0cQAB9HEAAAAKAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQFEQAAACwALAAsACwAPgBQAGQAeACMAKAAtADIANwAAgBEAAACZAVVAAMABwAusQEALzyyBwQA7TKxBgXcPLIDAgDtMgCxAwAvPLIFBADtMrIHBgH8PLIBAgDtMjMRIRElIREhRAIg/iQBmP5oBVX6q0QEzQAAAAIAZABkAfQAyAADAAcAADc1IRUhNSEVZAGQ/nABkGRkZGRkAAIAZABkAfQAyAADAAcAADc1IRUhNSEVZAGQ/nABkGRkZGRkAAIAZABkAfQDhAADAAcAADcRIREhESERZAGQ/nABkGQDIPzgAyD84AACAGQAZAH0A4QAAwAHAAA3ESERIREhEWQBkP5wAZBkAyD84AMg/OAAAgBkAGQB9AOEAAMABwAANxEhESERIRFkAZD+cAGQZAMg/OADIPzgAAIAZABkAfQDhAADAAcAADcRIREhESERZAGQ/nABkGQDIPzgAyD84AACAGQAZAH0A4QAAwAHAAA3ESERIREhEWQBkP5wAZBkAyD84AMg/OAAAgBkAGQB9AH0AAMABwAANxEhESERIRFkAZD+cAGQZAGQ/nABkP5wAAIAZABkAfQFFAADAAcAADcRIREhESERZAGQ/nABkGQEsPtQBLD7UAAAAA4ArgABAAAAAAAAAAAAAgABAAAAAAABAAQADQABAAAAAAACAAcAIgABAAAAAAADAB8AagABAAAAAAAEAAQAlAABAAAAAAAFAA8AuQABAAAAAAAGAAQA0wADAAEECQAAAAAAAAADAAEECQABAAgAAwADAAEECQACAA4AEgADAAEECQADAD4AKgADAAEECQAEAAgAigADAAEECQAFAB4AmQADAAEECQAGAAgAyQAAAABUAGUAcwB0AABUZXN0AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABGAG8AbgB0AEYAbwByAGcAZQAgADIALgAwACAAOgAgAFQAZQBzAHQAIAA6ACAAMQAtADQALQAyADAAMgA1AABGb250Rm9yZ2UgMi4wIDogVGVzdCA6IDEtNC0yMDI1AABUAGUAcwB0AABUZXN0AABWAGUAcgBzAGkAbwBuACAAMAAwADEALgAwADAAMAAAVmVyc2lvbiAwMDEuMDAwAABUAGUAcwB0AABUZXN0AAAAAAIAAAAAAAD/ZwBmAAAAAQAAAAAAAAAAAAAAAAAAAAAADQAAAAEAAgADAEQARQECAQMBBAEFAQYBBwEIB3VuaTIwMEQGZmVtYWxlB3VuaUZFMEYGdTFGM0ZEBnUxRjQ3MQJhYgNzZXEAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwAKAAEACwAMAAIABAAAAAIAAAABAAAACgAgADoAAWxhdG4ACAAEAAAAAP//AAIAAAABAAJjY21wAA5saWdhABQAAAABAAAAAAABAAEAAgAGAA4ABAAAAAEAEAAEAAAAAQAkAAEAFgABAAgAAQAEAAwABAAJAAYABwABAAEACgABABIAAQAIAAEABAALAAIABQABAAEABAABAAAACgAeADQAAWxhdG4ACAAEAAAAAP//AAEAAAABc2l6ZQAIAAQAAACgAAAAAAAAAAAAAAAAAAAAAQAAAADiAevnAAAAAOQSF3AAAAAA5BIXcA=="; + + public static void main(String[] args) throws Exception { + + byte[] ttfBytes = Base64.getDecoder().decode(TTF_BYTES); + ByteArrayInputStream ttfStream = new ByteArrayInputStream(ttfBytes); + Font f1 = Font.createFont(Font.TRUETYPE_FONT, ttfStream).deriveFont(80f); + + // Test emoji sequence, using "ccmp" feature and ZWJ (zero-width joiner): + // - person with blonde hair + // - emoji modifier fitzpatrick type 4 + // - zero-width joiner + // - female sign + // - variation selector 16 + // Does not require the use of the TextAttribute.LIGATURES_ON attribute. + char[] text1 = "\ud83d\udc71\ud83c\udffd\u200d\u2640\ufe0f".toCharArray(); + FontRenderContext frc = new FontRenderContext(null, true, true); + GlyphVector gv1 = f1.layoutGlyphVector(frc, text1, 0, text1.length, 0); + checkOneGlyph(gv1, text1, 12); + + // Test regular ligature, using "liga" feature: "ab" -> replacement + // Requires the use of the TextAttribute.LIGATURES_ON attribute. + char[] text2 = "ab".toCharArray(); + Font f2 = f1.deriveFont(Map.of(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON)); + GlyphVector gv2 = f2.layoutGlyphVector(frc, text2, 0, text2.length, 0); + checkOneGlyph(gv2, text2, 11); + } + + private static void checkOneGlyph(GlyphVector gv, char[] text, int expectedCode) { + int glyphs = gv.getNumGlyphs(); + if (glyphs != 1) { + throw new RuntimeException("Unexpected number of glyphs for text " + + new String(text) + ": " + glyphs); + } + int code = gv.getGlyphCode(0); + if (code != expectedCode) { + throw new RuntimeException("Unexpected glyph code for text " + + new String(text) + ": " + expectedCode + " != " + code); + } + } +} From c9d6e01233fbc9f3a95a4879feff906748649c54 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Fri, 30 May 2025 20:13:00 +0000 Subject: [PATCH 031/216] 8358076: KeyFactory.getInstance("EdDSA").generatePublic(null) throws NPE Reviewed-by: weijun --- .../classes/sun/security/ec/ECKeyFactory.java | 4 + .../sun/security/ec/XDHKeyFactory.java | 106 ++++++++------- .../sun/security/ec/ed/EdDSAKeyFactory.java | 97 +++++++------- .../sun/security/rsa/RSAKeyFactory.java | 122 ++++++++++-------- 4 files changed, 180 insertions(+), 149 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ec/ECKeyFactory.java b/src/java.base/share/classes/sun/security/ec/ECKeyFactory.java index cd84fd4dec3..2530425fbd4 100644 --- a/src/java.base/share/classes/sun/security/ec/ECKeyFactory.java +++ b/src/java.base/share/classes/sun/security/ec/ECKeyFactory.java @@ -219,6 +219,8 @@ public final class ECKeyFactory extends KeyFactorySpi { } yield new ECPublicKeyImpl(p8key.getPubKeyEncoded()); } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); default -> throw new InvalidKeySpecException(keySpec.getClass().getName() + " not supported."); @@ -239,6 +241,8 @@ public final class ECKeyFactory extends KeyFactorySpi { } case ECPrivateKeySpec e -> new ECPrivateKeyImpl(e.getS(), e.getParams()); + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); default -> throw new InvalidKeySpecException(keySpec.getClass().getName() + " not supported."); diff --git a/src/java.base/share/classes/sun/security/ec/XDHKeyFactory.java b/src/java.base/share/classes/sun/security/ec/XDHKeyFactory.java index 00eb5b4353d..c8fb6c0c11b 100644 --- a/src/java.base/share/classes/sun/security/ec/XDHKeyFactory.java +++ b/src/java.base/share/classes/sun/security/ec/XDHKeyFactory.java @@ -144,64 +144,72 @@ public class XDHKeyFactory extends KeyFactorySpi { private PublicKey generatePublicImpl(KeySpec keySpec) throws InvalidKeyException, InvalidKeySpecException { - if (keySpec instanceof X509EncodedKeySpec) { - X509EncodedKeySpec x509Spec = (X509EncodedKeySpec) keySpec; - XDHPublicKeyImpl result = - new XDHPublicKeyImpl(x509Spec.getEncoded()); - checkLockedParams(InvalidKeySpecException::new, - result.getParams()); - return result; - } else if (keySpec instanceof XECPublicKeySpec) { - XECPublicKeySpec publicKeySpec = (XECPublicKeySpec) keySpec; - XECParameters params = XECParameters.get( - InvalidKeySpecException::new, publicKeySpec.getParams()); - checkLockedParams(InvalidKeySpecException::new, params); - return new XDHPublicKeyImpl(params, publicKeySpec.getU()); - } else if (keySpec instanceof PKCS8EncodedKeySpec p8) { - PKCS8Key p8key = new XDHPrivateKeyImpl(p8.getEncoded()); - if (!p8key.hasPublicKey()) { - throw new InvalidKeySpecException("No public key found."); + return switch (keySpec) { + case X509EncodedKeySpec x509Spec -> { + XDHPublicKeyImpl result = + new XDHPublicKeyImpl(x509Spec.getEncoded()); + checkLockedParams(InvalidKeySpecException::new, + result.getParams()); + yield result; } - XDHPublicKeyImpl result = - new XDHPublicKeyImpl(p8key.getPubKeyEncoded()); - checkLockedParams(InvalidKeySpecException::new, - result.getParams()); - return result; - } else { - throw new InvalidKeySpecException(keySpec.getClass().getName() + - " not supported."); - } + case XECPublicKeySpec publicKeySpec -> { + XECParameters params = XECParameters.get( + InvalidKeySpecException::new, publicKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + yield new XDHPublicKeyImpl(params, publicKeySpec.getU()); + } + case PKCS8EncodedKeySpec p8 -> { + PKCS8Key p8key = new XDHPrivateKeyImpl(p8.getEncoded()); + if (!p8key.hasPublicKey()) { + throw new InvalidKeySpecException("No public key found."); + } + XDHPublicKeyImpl result = + new XDHPublicKeyImpl(p8key.getPubKeyEncoded()); + checkLockedParams(InvalidKeySpecException::new, + result.getParams()); + yield result; + } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } private PrivateKey generatePrivateImpl(KeySpec keySpec) throws InvalidKeyException, InvalidKeySpecException { - if (keySpec instanceof PKCS8EncodedKeySpec) { - PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec) keySpec; - byte[] encoded = pkcsSpec.getEncoded(); - try { - XDHPrivateKeyImpl result = new XDHPrivateKeyImpl(encoded); - checkLockedParams(InvalidKeySpecException::new, + return switch (keySpec) { + case PKCS8EncodedKeySpec pkcsSpec -> { + byte[] encoded = pkcsSpec.getEncoded(); + try { + XDHPrivateKeyImpl result = new XDHPrivateKeyImpl(encoded); + checkLockedParams(InvalidKeySpecException::new, result.getParams()); - return result; - } finally { - Arrays.fill(encoded, (byte) 0); + yield result; + } finally { + Arrays.fill(encoded, (byte) 0); + } } - } else if (keySpec instanceof XECPrivateKeySpec) { - XECPrivateKeySpec privateKeySpec = (XECPrivateKeySpec) keySpec; - XECParameters params = XECParameters.get( - InvalidKeySpecException::new, privateKeySpec.getParams()); - checkLockedParams(InvalidKeySpecException::new, params); - byte[] scalar = privateKeySpec.getScalar(); - try { - return new XDHPrivateKeyImpl(params, scalar); - } finally { - Arrays.fill(scalar, (byte)0); + case XECPrivateKeySpec privateKeySpec -> { + XECParameters params = XECParameters.get( + InvalidKeySpecException::new, privateKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + + byte[] scalar = privateKeySpec.getScalar(); + try { + yield new XDHPrivateKeyImpl(params, scalar); + } finally { + Arrays.fill(scalar, (byte) 0); + } } - } else { - throw new InvalidKeySpecException( - "Only PKCS8EncodedKeySpec and XECPrivateKeySpec supported"); - } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } protected T engineGetKeySpec(Key key, Class keySpec) diff --git a/src/java.base/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java b/src/java.base/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java index b3316f5ffe0..71ec14ba06f 100644 --- a/src/java.base/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java +++ b/src/java.base/share/classes/sun/security/ec/ed/EdDSAKeyFactory.java @@ -137,61 +137,68 @@ public class EdDSAKeyFactory extends KeyFactorySpi { private PublicKey generatePublicImpl(KeySpec keySpec) throws InvalidKeyException, InvalidKeySpecException { - if (keySpec instanceof X509EncodedKeySpec) { - X509EncodedKeySpec x509Spec = (X509EncodedKeySpec) keySpec; - EdDSAPublicKeyImpl result = - new EdDSAPublicKeyImpl(x509Spec.getEncoded()); - checkLockedParams(InvalidKeySpecException::new, - result.getParams()); - return result; - } else if (keySpec instanceof EdECPublicKeySpec) { - EdECPublicKeySpec publicKeySpec = (EdECPublicKeySpec) keySpec; - EdDSAParameters params = EdDSAParameters.get( - InvalidKeySpecException::new, publicKeySpec.getParams()); - checkLockedParams(InvalidKeySpecException::new, params); - return new EdDSAPublicKeyImpl(params, publicKeySpec.getPoint()); - } else if (keySpec instanceof PKCS8EncodedKeySpec p8) { - PKCS8Key p8key = new EdDSAPrivateKeyImpl(p8.getEncoded()); - if (!p8key.hasPublicKey()) { - throw new InvalidKeySpecException("No public key found."); + return switch (keySpec) { + case X509EncodedKeySpec x509Spec -> { + EdDSAPublicKeyImpl result = + new EdDSAPublicKeyImpl(x509Spec.getEncoded()); + checkLockedParams(InvalidKeySpecException::new, + result.getParams()); + yield result; } - return new EdDSAPublicKeyImpl(p8key.getPubKeyEncoded()); - } else { - throw new InvalidKeySpecException(keySpec.getClass().getName() + - " not supported."); - } + case EdECPublicKeySpec publicKeySpec -> { + EdDSAParameters params = EdDSAParameters.get( + InvalidKeySpecException::new, publicKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + yield new EdDSAPublicKeyImpl(params, publicKeySpec.getPoint()); + } + case PKCS8EncodedKeySpec p8 -> { + PKCS8Key p8key = new EdDSAPrivateKeyImpl(p8.getEncoded()); + if (!p8key.hasPublicKey()) { + throw new InvalidKeySpecException("No public key found."); + } + yield new EdDSAPublicKeyImpl(p8key.getPubKeyEncoded()); + } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } private PrivateKey generatePrivateImpl(KeySpec keySpec) throws InvalidKeyException, InvalidKeySpecException { - if (keySpec instanceof PKCS8EncodedKeySpec) { - PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec) keySpec; - byte[] encoded = pkcsSpec.getEncoded(); - try { - EdDSAPrivateKeyImpl result = + return switch (keySpec) { + case PKCS8EncodedKeySpec pkcsSpec -> { + byte[] encoded = pkcsSpec.getEncoded(); + try { + EdDSAPrivateKeyImpl result = new EdDSAPrivateKeyImpl(encoded); - checkLockedParams(InvalidKeySpecException::new, + checkLockedParams(InvalidKeySpecException::new, result.getParams()); - return result; - } finally { - Arrays.fill(encoded, (byte) 0); + yield result; + } finally { + Arrays.fill(encoded, (byte) 0); + } } - } else if (keySpec instanceof EdECPrivateKeySpec) { - EdECPrivateKeySpec privateKeySpec = (EdECPrivateKeySpec) keySpec; - EdDSAParameters params = EdDSAParameters.get( - InvalidKeySpecException::new, privateKeySpec.getParams()); - checkLockedParams(InvalidKeySpecException::new, params); - byte[] bytes = privateKeySpec.getBytes(); - try { - return new EdDSAPrivateKeyImpl(params, bytes); - } finally { - Arrays.fill(bytes, (byte)0); + case EdECPrivateKeySpec privateKeySpec -> { + EdDSAParameters params = EdDSAParameters.get( + InvalidKeySpecException::new, privateKeySpec.getParams()); + checkLockedParams(InvalidKeySpecException::new, params); + byte[] bytes = privateKeySpec.getBytes(); + try { + yield new EdDSAPrivateKeyImpl(params, bytes); + } finally { + Arrays.fill(bytes, (byte) 0); + } } - } else { - throw new InvalidKeySpecException( - "Only PKCS8EncodedKeySpec and EdECPrivateKeySpec supported"); - } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } protected T engineGetKeySpec(Key key, Class keySpec) diff --git a/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java b/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java index f518bf5919b..0b8f2a0aded 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java @@ -320,71 +320,83 @@ public class RSAKeyFactory extends KeyFactorySpi { // internal implementation of generatePublic. See JCA doc private PublicKey generatePublic(KeySpec keySpec) throws GeneralSecurityException { - if (keySpec instanceof X509EncodedKeySpec) { - return RSAPublicKeyImpl.newKey(type, "X.509", - ((X509EncodedKeySpec)keySpec).getEncoded()); - } else if (keySpec instanceof RSAPublicKeySpec rsaSpec) { - try { - return new RSAPublicKeyImpl( - type, rsaSpec.getParams(), - rsaSpec.getModulus(), - rsaSpec.getPublicExponent() - ); - } catch (ProviderException e) { - throw new InvalidKeySpecException(e); + return switch (keySpec) { + case X509EncodedKeySpec x509 -> + RSAPublicKeyImpl.newKey(type, "X.509", x509.getEncoded()); + + case RSAPublicKeySpec rsaSpec -> { + try { + yield new RSAPublicKeyImpl( + type, rsaSpec.getParams(), + rsaSpec.getModulus(), + rsaSpec.getPublicExponent() + ); + } catch (ProviderException e) { + throw new InvalidKeySpecException(e); + } } - } else if (keySpec instanceof PKCS8EncodedKeySpec p8) { - PKCS8Key p8key = new PKCS8Key(p8.getEncoded()); - if (!p8key.hasPublicKey()) { - throw new InvalidKeySpecException("No public key found."); + case PKCS8EncodedKeySpec p8 -> { + PKCS8Key p8key = new PKCS8Key(p8.getEncoded()); + if (!p8key.hasPublicKey()) { + throw new InvalidKeySpecException("No public key found."); + } + yield RSAPublicKeyImpl.newKey(type, "X.509", + p8key.getPubKeyEncoded()); } - return RSAPublicKeyImpl.newKey(type, "X.509", - p8key.getPubKeyEncoded()); - } else { - throw new InvalidKeySpecException(keySpec.getClass().getName() + " not supported."); - } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } // internal implementation of generatePrivate. See JCA doc private PrivateKey generatePrivate(KeySpec keySpec) throws GeneralSecurityException { - if (keySpec instanceof PKCS8EncodedKeySpec) { - byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); - try { - return RSAPrivateCrtKeyImpl.newKey(type, "PKCS#8", encoded); - } finally { - Arrays.fill(encoded, (byte)0); + return switch (keySpec) { + case PKCS8EncodedKeySpec p8 -> { + byte[] encoded = p8.getEncoded(); + try { + yield RSAPrivateCrtKeyImpl.newKey(type, "PKCS#8", encoded); + } finally { + Arrays.fill(encoded, (byte) 0); + } } - } else if (keySpec instanceof RSAPrivateCrtKeySpec rsaSpec) { - try { - return new RSAPrivateCrtKeyImpl( - type, rsaSpec.getParams(), - rsaSpec.getModulus(), - rsaSpec.getPublicExponent(), - rsaSpec.getPrivateExponent(), - rsaSpec.getPrimeP(), - rsaSpec.getPrimeQ(), - rsaSpec.getPrimeExponentP(), - rsaSpec.getPrimeExponentQ(), - rsaSpec.getCrtCoefficient() - ); - } catch (ProviderException e) { - throw new InvalidKeySpecException(e); + case RSAPrivateCrtKeySpec rsaSpec -> { + try { + yield new RSAPrivateCrtKeyImpl( + type, rsaSpec.getParams(), + rsaSpec.getModulus(), + rsaSpec.getPublicExponent(), + rsaSpec.getPrivateExponent(), + rsaSpec.getPrimeP(), + rsaSpec.getPrimeQ(), + rsaSpec.getPrimeExponentP(), + rsaSpec.getPrimeExponentQ(), + rsaSpec.getCrtCoefficient() + ); + } catch (ProviderException e) { + throw new InvalidKeySpecException(e); + } } - } else if (keySpec instanceof RSAPrivateKeySpec rsaSpec) { - try { - return new RSAPrivateKeyImpl( - type, rsaSpec.getParams(), - rsaSpec.getModulus(), - rsaSpec.getPrivateExponent() - ); - } catch (ProviderException e) { - throw new InvalidKeySpecException(e); + case RSAPrivateKeySpec rsaSpec -> { + try { + yield new RSAPrivateKeyImpl( + type, rsaSpec.getParams(), + rsaSpec.getModulus(), + rsaSpec.getPrivateExponent() + ); + } catch (ProviderException e) { + throw new InvalidKeySpecException(e); + } } - } else { - throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " - + "and PKCS8EncodedKeySpec supported for RSA private keys"); - } + case null -> throw new InvalidKeySpecException( + "keySpec must not be null"); + default -> + throw new InvalidKeySpecException(keySpec.getClass().getName() + + " not supported."); + }; } protected T engineGetKeySpec(Key key, Class keySpec) From 14e41ab055955ffd7cf9e8129cc3269b4e3807b7 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Fri, 30 May 2025 20:14:14 +0000 Subject: [PATCH 032/216] 8357172: Extend try block in nsk/jdi tests to capture exceptions thrown by Debuggee.classByName() Reviewed-by: lmesnik, sspitsyn --- .../invokeMethod/invokemethod009.java | 20 +++---- .../invokeMethod/invokemethod010.java | 51 ++++++++---------- .../invokeMethod/invokemethod014.java | 26 ++++----- .../ClassType/newInstance/newinstance009.java | 53 ++++++++----------- .../invokeMethod/invokemethod002.java | 18 +++---- .../invokeMethod/invokemethod003.java | 30 +++++------ .../invokeMethod/invokemethod004.java | 37 ++++++------- .../invokeMethod/invokemethod005.java | 22 ++++---- .../invokeMethod/invokemethod006.java | 22 ++++---- .../invokeMethod/invokemethod007.java | 22 ++++---- .../invokeMethod/invokemethod008.java | 26 ++++----- .../invokeMethod/invokemethod009.java | 26 ++++----- .../invokeMethod/invokemethod014.java | 28 +++++----- .../ObjectReference/setValue/setvalue002.java | 36 ++++++------- .../ObjectReference/setValue/setvalue003.java | 37 ++++++------- .../ObjectReference/setValue/setvalue004.java | 37 ++++++------- .../ObjectReference/setValue/setvalue005.java | 39 ++++++-------- .../setValue/setvalue005/setvalue005.java | 24 ++++----- .../ownedMonitors/ownedmonitors002.java | 47 +++++++--------- .../popFrames/popframes006.java | 24 ++++----- .../popFrames/popframes007.java | 42 +++++++-------- .../nsk/jdi/ThreadReference/stop/stop002.java | 23 ++++---- 22 files changed, 318 insertions(+), 372 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod009.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod009.java index c5e1be8f4a3..fe96c69ace6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod009.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod009.java @@ -112,19 +112,19 @@ public class invokemethod009 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - thrRef = debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType, DEBUGGEE_STOPATLINE); ClassType clsType = (ClassType) rType; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod010.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod010.java index 65621fb712c..f813a447192 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod010.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod010.java @@ -111,36 +111,29 @@ public class invokemethod010 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - - thrRef = debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: unable to suspend debuggee thread"); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - log.display("Waiting for debuggee thread suspension ..."); - try { - Thread.currentThread().sleep(TIMEOUT_DELTA); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - } - try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + + thrRef = debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: unable to suspend debuggee thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee thread suspension ..."); + Thread.currentThread().sleep(TIMEOUT_DELTA); + } + // debuggee main class ClassType clsType = (ClassType) rType; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod014.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod014.java index c1b5a2a64ab..900a453a2da 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod014.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassType/invokeMethod/invokemethod014.java @@ -113,20 +113,20 @@ public class invokemethod014 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - ClassType clsType = (ClassType) rType; - - ThreadReference thrRef = - debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + ClassType clsType = (ClassType) rType; + + ThreadReference thrRef = + debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + suspendAtBP(rType, DEBUGGEE_STOPATLINE); for (int i=0; i ATTEMPTS) { - log.complain("TEST FAILED: unable to suspend debuggee thread"); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - log.display("Waiting for debuggee thread suspension ..."); - try { - Thread.currentThread().sleep(DELAY); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - } - try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + ClassType clsType = (ClassType) rType; + + ThreadReference thrRef = debuggee.threadByFieldName(rType, "thread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: unable to suspend debuggee thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee thread suspension ..."); + Thread.currentThread().sleep(DELAY); + } + List methList = rType.methodsByName(""); if (methList.isEmpty()) { log.complain("TEST FAILURE: the expected constructor " diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod002.java index 7c43d0b2fa5..44189cb3c3b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod002.java @@ -124,18 +124,18 @@ public class invokemethod002 { return quitDebuggee(); } - rType[0] = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + rType[0] = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); findObjRef(DEBUGGEE_LOCALVAR); rType[1] = objRef[1].referenceType(); // debuggee dummy class diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod003.java index a348f9ff78c..537be5cde65 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod003.java @@ -135,24 +135,24 @@ public class invokemethod003 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[3]; - // debuggee main class - rType[0] = debuggee.classByName(DEBUGGEE_CLASS); - // debuggee dummy interface - rType[1] = debuggee.classByName(DEBUGGEE_INTERFACE); - // debuggee dummy abstract class - rType[2] = debuggee.classByName(DEBUGGEE_ABSTRACTCLASS); + try { + ReferenceType[] rType = new ReferenceType[3]; + // debuggee main class + rType[0] = debuggee.classByName(DEBUGGEE_CLASS); + // debuggee dummy interface + rType[1] = debuggee.classByName(DEBUGGEE_INTERFACE); + // debuggee dummy abstract class + rType[2] = debuggee.classByName(DEBUGGEE_ABSTRACTCLASS); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod004.java index 3b26eb2a010..61a78285a6b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod004.java @@ -111,36 +111,29 @@ public class invokemethod004 { return quitDebuggee(); } - ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: unable to suspend debuggee thread"); + thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee thread suspension ..."); - try { + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: unable to suspend debuggee thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee thread suspension ..."); Thread.currentThread().sleep(1000); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); } - } // Check the tested assersion - try { ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); ReferenceType rType = objRef.referenceType(); // debuggee dummy class diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod005.java index fcc13dc3b10..a6f7806753d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod005.java @@ -113,20 +113,20 @@ public class invokemethod005 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[2]; - // debuggee main class - rType[0] = debuggee.classByName(DEBUGGEE_CLASS); + try { + ReferenceType[] rType = new ReferenceType[2]; + // debuggee main class + rType[0] = debuggee.classByName(DEBUGGEE_CLASS); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); rType[1] = objRef.referenceType(); // debuggee dummy class diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod006.java index 0583cf62b53..d914b8bacfc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod006.java @@ -111,20 +111,20 @@ public class invokemethod006 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[2]; - // debuggee main class - rType[0] = debuggee.classByName(DEBUGGEE_CLASS); + try { + ReferenceType[] rType = new ReferenceType[2]; + // debuggee main class + rType[0] = debuggee.classByName(DEBUGGEE_CLASS); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); rType[1] = objRef.referenceType(); // debuggee dummy class diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod007.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod007.java index fa5c9ec3e17..9dc343d69a9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod007.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod007.java @@ -127,20 +127,20 @@ public class invokemethod007 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[2]; - // debuggee main class - rType[0] = debuggee.classByName(DEBUGGEE_CLASS); + try { + ReferenceType[] rType = new ReferenceType[2]; + // debuggee main class + rType[0] = debuggee.classByName(DEBUGGEE_CLASS); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); rType[1] = objRef.referenceType(); // debuggee dummy class diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod008.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod008.java index c0426229e5b..7572c5adefe 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod008.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod008.java @@ -120,22 +120,22 @@ public class invokemethod008 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[3]; - // reference types of debuggee main & dummy classes - rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); - rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); - rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); + try { + ReferenceType[] rType = new ReferenceType[3]; + // reference types of debuggee main & dummy classes + rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); + rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); + rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod009.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod009.java index ce3545ac228..72ea170440e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod009.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod009.java @@ -120,22 +120,22 @@ public class invokemethod009 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[3]; - // reference types of debuggee main & dummy classes - rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); - rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); - rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); + try { + ReferenceType[] rType = new ReferenceType[3]; + // reference types of debuggee main & dummy classes + rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); + rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); + rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); - thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + thrRef = debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); ObjectReference objRef = findObjRef(DEBUGGEE_LOCALVAR); LinkedList argList = new LinkedList(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod014.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod014.java index 3005ed87a64..0950b4064db 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod014.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/invokeMethod/invokemethod014.java @@ -143,23 +143,23 @@ public class invokemethod014 { return quitDebuggee(); } - ReferenceType[] rType = new ReferenceType[3]; - // debuggee main & dummy classes - rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); - rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); - rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); + try { + ReferenceType[] rType = new ReferenceType[3]; + // debuggee main & dummy classes + rType[0] = debuggee.classByName(DEBUGGEE_CLASSES[0]); + rType[1] = debuggee.classByName(DEBUGGEE_CLASSES[1]); + rType[2] = debuggee.classByName(DEBUGGEE_CLASSES[2]); - ThreadReference thrRef = - debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } + ThreadReference thrRef = + debuggee.threadByFieldName(rType[0], "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } // Check the tested assersion - try { suspendAtBP(rType[0], DEBUGGEE_STOPATLINE); objRef = findObjRef(thrRef, DEBUGGEE_LOCALVAR); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue002.java index 1c4803cffef..b9c5a99a4ea 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue002.java @@ -109,35 +109,29 @@ public class setvalue002 { return quitDebuggee(); } - ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee's thread suspension ..."); - try { + thrRef.suspend(); + while (!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee's thread suspension ..."); Thread.currentThread().sleep(1000); - } catch(InterruptedException ie) { - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); } - } // Check the tested assersion - try { findObjRefs(DEBUGGEE_LOCALVAR); rType[0] = objRef[0].referenceType(); rType[1] = objRef[1].referenceType(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue003.java index 4fbe110ca96..8bb08f43c2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue003.java @@ -142,36 +142,29 @@ public class setvalue003 { return quitDebuggee(); } - ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee's thread suspension ..."); - try { + thrRef.suspend(); + while (!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee's thread suspension ..."); Thread.sleep(1000); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } } // Check the tested assertion - try { objRef = findObjRef(DEBUGGEE_LOCALVAR); rType = objRef.referenceType(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue004.java index 0eed84859eb..1928e965e32 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue004.java @@ -122,36 +122,29 @@ public class setvalue004 { return quitDebuggee(); } - ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee's thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee's thread suspension ..."); - try { + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: Unable to suspend debuggee's thread"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee's thread suspension ..."); Thread.currentThread().sleep(1000); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); } - } // Check the tested assersion - try { objRef = findObjRef(DEBUGGEE_LOCALVAR); rType = objRef.referenceType(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue005.java index b77ea99979d..25e1f0c37b6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/setValue/setvalue005.java @@ -109,37 +109,30 @@ public class setvalue005 { return quitDebuggee(); } - ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class + try { + ReferenceType debuggeeClass = debuggee.classByName(DEBUGGEE_CLASS); // debuggee main class - thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILED: Unable to suspend debuggee thread after " - + ATTEMPTS + " attempts"); + thrRef = debuggee.threadByFieldName(debuggeeClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: Method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee thread suspension ..."); - try { + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILED: Unable to suspend debuggee thread after " + + ATTEMPTS + " attempts"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee thread suspension ..."); Thread.currentThread().sleep(1000); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILED: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); } - } // Check the tested assersion - try { objRef = findObjRef(DEBUGGEE_LOCALVAR); rType = objRef.referenceType(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/setValue/setvalue005/setvalue005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/setValue/setvalue005/setvalue005.java index 3b8a49ac5d1..dd071f2e087 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/setValue/setvalue005/setvalue005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/StackFrame/setValue/setvalue005/setvalue005.java @@ -156,19 +156,19 @@ public class setvalue005 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - - ThreadReference thrRef = - debuggee.threadByFieldName(rType, "mainThread", DEBUGGEE_THRDNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRDNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + + ThreadReference thrRef = + debuggee.threadByFieldName(rType, "mainThread", DEBUGGEE_THRDNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRDNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + suspendAtBP(rType, DEBUGGEE_STOPATLINE); // find a stack frame which belongs to the "setvalue005tMainThr" thread diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/ownedMonitors/ownedmonitors002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/ownedMonitors/ownedmonitors002.java index 068670202c5..a77c153ab5d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/ownedMonitors/ownedmonitors002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/ownedMonitors/ownedmonitors002.java @@ -91,41 +91,34 @@ public class ownedmonitors002 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - ThreadReference thrRef = - debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - - int num = 0; - thrRef.suspend(); - while(!thrRef.isSuspended()) { - num++; - if (num > ATTEMPTS) { - log.complain("TEST FAILURE: Unable to suspend debuggee thread after " - + ATTEMPTS + " attempts"); + ThreadReference thrRef = + debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); tot_res = Consts.TEST_FAILED; return quitDebuggee(); } - log.display("Waiting for debuggee thread suspension ..."); - try { + + int num = 0; + thrRef.suspend(); + while(!thrRef.isSuspended()) { + num++; + if (num > ATTEMPTS) { + log.complain("TEST FAILURE: Unable to suspend debuggee thread after " + + ATTEMPTS + " attempts"); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + log.display("Waiting for debuggee thread suspension ..."); Thread.currentThread().sleep(DELAY); - } catch(InterruptedException ie) { - ie.printStackTrace(); - log.complain("TEST FAILURE: caught: " + ie); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); } - } // Check the tested assersion - try { List mons = thrRef.ownedMonitors(); if (vm.canGetOwnedMonitorInfo()) { log.display("CHECK PASSED: got a List of monitors owned by the thread," diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes006.java index ed60d3abe53..fe0543fe11f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes006.java @@ -106,20 +106,20 @@ public class popframes006 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - - ThreadReference thrRef = - debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - Field doExit = null; try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + + ThreadReference thrRef = + debuggee.threadByFieldName(rType, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + suspendAtBP(rType, DEBUGGEE_STOPATLINE); // debuggee field used to indicate that popping has been done diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes007.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes007.java index 350b89ef4b6..df086449bef 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes007.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes007.java @@ -106,29 +106,29 @@ public class popframes007 { return quitDebuggee(); } - // debuggee main class - ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); - - ThreadReference mainThread = - debuggee.threadByFieldName(rType, "mainThread", DEBUGGEE_MAIN_THREAD_NAME); - if (mainThread == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_MAIN_THREAD_NAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - - ThreadReference auxThread = - debuggee.threadByFieldName(rType, "auxThr", DEBUGGEE_AUX_THREAD_NAME); - if (auxThread == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_AUX_THREAD_NAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - Field doExit = null; try { + // debuggee main class + ReferenceType rType = debuggee.classByName(DEBUGGEE_CLASS); + + ThreadReference mainThread = + debuggee.threadByFieldName(rType, "mainThread", DEBUGGEE_MAIN_THREAD_NAME); + if (mainThread == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_MAIN_THREAD_NAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + + ThreadReference auxThread = + debuggee.threadByFieldName(rType, "auxThr", DEBUGGEE_AUX_THREAD_NAME); + if (auxThread == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_AUX_THREAD_NAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + suspendAtBP(rType, DEBUGGEE_STOPATLINE); // debuggee field used to indicate that popping has been done diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java index fcf38c5c5ab..02a87d9c42b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002.java @@ -115,22 +115,23 @@ public class stop002 { return quitDebuggee(); } - // debuggee main class - mainClass = debuggee.classByName(DEBUGGEE_CLASS); - - ThreadReference thrRef = debuggee.threadByFieldName(mainClass, "testThread", DEBUGGEE_THRNAME); - if (thrRef == null) { - log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " - + DEBUGGEE_THRNAME); - tot_res = Consts.TEST_FAILED; - return quitDebuggee(); - } - Field stopLoop1 = null; Field stopLoop2 = null; ObjectReference objRef = null; ObjectReference throwableRef = null; + try { + // debuggee main class + mainClass = debuggee.classByName(DEBUGGEE_CLASS); + + ThreadReference thrRef = debuggee.threadByFieldName(mainClass, "testThread", DEBUGGEE_THRNAME); + if (thrRef == null) { + log.complain("TEST FAILURE: method Debugee.threadByFieldName() returned null for debuggee thread " + + DEBUGGEE_THRNAME); + tot_res = Consts.TEST_FAILED; + return quitDebuggee(); + } + suspendAtBP(mainClass, DEBUGGEE_STOPATLINE); objRef = findObjRef(thrRef, DEBUGGEE_NON_THROWABLE_VAR); throwableRef = findObjRef(thrRef, DEBUGGEE_THROWABLE_VAR); From abbffc0103826a2e02fe52ef9b55890a57944933 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Fri, 30 May 2025 21:00:34 +0000 Subject: [PATCH 033/216] 8358202: ProblemList vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java Reviewed-by: sspitsyn, cjplummer --- test/hotspot/jtreg/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 125ca887078..1f10d38240b 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -162,6 +162,7 @@ vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all +vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8358094 generic-all vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all vmTestbase/nsk/jvmti/InterruptThread/intrpthrd003/TestDescription.java 8288911 macosx-all From 09301c1dc03a44e5c56a91303de81ba01dabfe71 Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Fri, 30 May 2025 21:11:38 +0000 Subject: [PATCH 034/216] 8356634: VectorShape#largestShapeFor should have public access Reviewed-by: psandoz --- .../jdk/incubator/vector/VectorShape.java | 19 +++++--- .../vector/PreferredSpeciesTest.java | 44 ++++++++++++++++++- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java index 89e0d38bcb0..f6e36450ce0 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -208,13 +208,22 @@ public enum VectorShape { } } - // non-public support for computing preferred shapes - - /*package-private*/ - static VectorShape largestShapeFor(Class etype) { + /** + * Finds the largest vector shape supported by the current + * platform for the element type {@code etype}. + * + * @param etype the element type + * @return the largest vector shape supported by the platform + * for {@code etype} + * @throws IllegalArgumentException if no such vector shape exists + * for the element type or the type is not a valid {@code ETYPE}. + */ + public static VectorShape largestShapeFor(Class etype) { return VectorShape.forBitSize(getMaxVectorBitSize(etype)); } + // non-public support for computing preferred shapes + /** * Finds the vector shape preferred by the current platform * for all vector element types. diff --git a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java index f105df5756c..eb8b0358538 100644 --- a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java +++ b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import org.testng.annotations.Test; /** * @test + * @bug 8356549 * @modules jdk.incubator.vector java.base/jdk.internal.vm.vector * @run testng PreferredSpeciesTest */ @@ -126,4 +127,45 @@ public class PreferredSpeciesTest { Assert.assertEquals(largestSpecies.length(), maxLaneCount); Assert.assertEquals(largestSpecies.length(), Math.max(species.length(), maxLaneCount)); } + + // Testing VectorShape.largestShapeFor() for 8356549 + @Test(dataProvider = "classesProvider") + void testLargestShapeFor(Class c) { + final int S_64_BITS = 64; + int elemSize = 0; + VectorSpecies maxVectorSpecies; + if (c == byte.class) { + elemSize = Byte.SIZE; + maxVectorSpecies = ByteVector.SPECIES_MAX; + } else if (c == short.class) { + elemSize = Short.SIZE; + maxVectorSpecies = ShortVector.SPECIES_MAX; + } else if (c == int.class) { + elemSize = Integer.SIZE; + maxVectorSpecies = IntVector.SPECIES_MAX; + } else if (c == long.class) { + elemSize = Long.SIZE; + maxVectorSpecies = LongVector.SPECIES_MAX; + } else if (c == float.class) { + elemSize = Float.SIZE; + maxVectorSpecies = FloatVector.SPECIES_MAX; + } else if (c == double.class) { + elemSize = Double.SIZE; + maxVectorSpecies = DoubleVector.SPECIES_MAX; + } else { + throw new IllegalArgumentException("Bad vector element type: " + c.getName()); + } + + VectorShape vs = VectorShape.largestShapeFor(c); + + int maxLaneCount = VectorSupport.getMaxLaneCount(c); + int max = Math.max(maxLaneCount * elemSize, S_64_BITS); + + //Assert we're using the same element when comparing shapes + Assert.assertEquals(c, maxVectorSpecies.elementType()); + + Assert.assertEquals(vs.vectorBitSize(), max); + Assert.assertEquals(vs.vectorBitSize(), maxVectorSpecies.vectorBitSize()); + + } } From db340e54f83cf7bf72abb94c9cf9cdac007ed38a Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Fri, 30 May 2025 21:11:58 +0000 Subject: [PATCH 035/216] 8356222: Thread.print command reports waiting on the Class initialization monitor for both carrier and virtual threads Reviewed-by: alanb, sspitsyn --- src/hotspot/share/runtime/javaThread.cpp | 4 +- src/hotspot/share/runtime/vframe.cpp | 7 +- src/hotspot/share/runtime/vframe.hpp | 4 +- .../dcmd/thread/ClassInitMonitorVThread.java | 134 ++++++++++++++++++ 4 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/dcmd/thread/ClassInitMonitorVThread.java diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index 060c0a33cdf..57f93f87d47 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1795,7 +1795,7 @@ void JavaThread::print_stack_on(outputStream* st) { // Print out lock information if (JavaMonitorsInStackTrace) { - jvf->print_lock_info_on(st, count); + jvf->print_lock_info_on(st, false/*is_virtual*/, count); } } else { // Ignore non-Java frames @@ -1837,7 +1837,7 @@ void JavaThread::print_vthread_stack_on(outputStream* st) { // Print out lock information if (JavaMonitorsInStackTrace) { - jvf->print_lock_info_on(st, count); + jvf->print_lock_info_on(st, true/*is_virtual*/, count); } } else { // Ignore non-Java frames diff --git a/src/hotspot/share/runtime/vframe.cpp b/src/hotspot/share/runtime/vframe.cpp index 723ddbbb106..a3c0c41b1b1 100644 --- a/src/hotspot/share/runtime/vframe.cpp +++ b/src/hotspot/share/runtime/vframe.cpp @@ -169,7 +169,7 @@ void javaVFrame::print_locked_object_class_name(outputStream* st, Handle obj, co } } -void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) { +void javaVFrame::print_lock_info_on(outputStream* st, bool is_virtual, int frame_count) { Thread* current = Thread::current(); ResourceMark rm(current); HandleMark hm(current); @@ -204,8 +204,9 @@ void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) { oop obj = thread()->current_park_blocker(); Klass* k = obj->klass(); st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", p2i(obj), k->external_name()); - } - else if (thread()->osthread()->get_state() == OBJECT_WAIT) { + } else if (thread()->osthread()->get_state() == OBJECT_WAIT && + // If this is a carrier thread with mounted virtual thread this is reported for the virtual thread. + (is_virtual || !thread()->is_vthread_mounted())) { // We are waiting on an Object monitor but Object.wait() isn't the // top-frame, so we should be waiting on a Class initialization monitor. InstanceKlass* k = thread()->class_to_be_initialized(); diff --git a/src/hotspot/share/runtime/vframe.hpp b/src/hotspot/share/runtime/vframe.hpp index de3fca7246b..c8c166f3236 100644 --- a/src/hotspot/share/runtime/vframe.hpp +++ b/src/hotspot/share/runtime/vframe.hpp @@ -139,8 +139,8 @@ class javaVFrame: public vframe { // printing used during stack dumps and diagnostics static void print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state); - void print_lock_info_on(outputStream* st, int frame_count); - void print_lock_info(int frame_count) { print_lock_info_on(tty, frame_count); } + void print_lock_info_on(outputStream* st, bool is_virtual, int frame_count); + void print_lock_info(bool is_virtual, int frame_count) { print_lock_info_on(tty, is_virtual, frame_count); } #ifndef PRODUCT public: diff --git a/test/hotspot/jtreg/serviceability/dcmd/thread/ClassInitMonitorVThread.java b/test/hotspot/jtreg/serviceability/dcmd/thread/ClassInitMonitorVThread.java new file mode 100644 index 00000000000..8fd5f02a9cb --- /dev/null +++ b/test/hotspot/jtreg/serviceability/dcmd/thread/ClassInitMonitorVThread.java @@ -0,0 +1,134 @@ +/* + * 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. + */ + +import jdk.test.lib.dcmd.PidJcmdExecutor; +import jdk.test.lib.process.OutputAnalyzer; +import java.util.concurrent.CountDownLatch; + +/* + * @test + * @bug 8356222 + * @summary Test jcmd Thread.print command for "waiting on the Class initialization monitor" case + * @requires vm.continuations + * @library /test/lib + * @run main ClassInitMonitorVThread + */ + +class LongInitClass { + static { + ClassInitMonitorVThread.longInitClass_waiting = true; + while (ClassInitMonitorVThread.longInitClass_wait) { + try { + Thread.sleep(10); + } catch (Exception ex) { + } + } + ClassInitMonitorVThread.longInitClass_waiting = false; + } + + LongInitClass() {} +} + +public class ClassInitMonitorVThread { + static volatile boolean longInitClass_wait; + static volatile boolean longInitClass_waiting; + + public static void main(String[] args) throws InterruptedException { + try { + // 1st thread starts class initialization + longInitClass_wait = true; + longInitClass_waiting = false; + Thread vthread1 = Thread.ofVirtual().name("Loader1").start(new Loader(null)); + while (!longInitClass_waiting) { + Thread.sleep(10); + } + + // 2nd thread is blocked at class initialization + // thread state is "RUNNING", so just wait some time after the thread is ready + CountDownLatch loaderReady = new CountDownLatch(1); + Thread vthread2 = Thread.ofVirtual().name("Loader2").start(new Loader(loaderReady)); + loaderReady.await(); + + Thread.sleep(100); + // try up to 20 times to avoid failures on slow environment + for (int iter = 20; iter > 0; iter--) { + try { + verify(vthread2); + break; + } catch (RuntimeException ex) { + if (iter == 0) { + throw ex; + } + System.out.println("Failed with: " + ex.getMessage() + ", retrying..."); + System.out.println(); + } + Thread.sleep(1000); + } + } finally { + longInitClass_wait = false; + } + } + + static void verify(Thread vthread2) { + boolean silent = true; + OutputAnalyzer output = new PidJcmdExecutor().execute("Thread.print -l", silent); + String out = output.getStdout(); + String carrierPrefix = "Carrying virtual thread #" + vthread2.threadId(); + String vthreadPrefix = "Mounted virtual thread " + "#" + vthread2.threadId(); + int carrierStart = out.indexOf(carrierPrefix); + int vthreadStart = out.indexOf(vthreadPrefix); + int vthreadEnd = out.indexOf("\n\n", vthreadStart); + String carrierOut = out.substring(carrierStart, vthreadStart); + String vthreadOut = out.substring(vthreadStart, vthreadEnd); + + System.out.println("carrier: " + carrierOut); + System.out.println("vthread: " + vthreadOut); + + String waitText = "- waiting on the Class initialization monitor for LongInitClass"; + + if (!vthreadOut.contains(waitText)) { + throw new RuntimeException("Vthread does not contain the lock"); + } + if (carrierOut.contains(waitText)) { + throw new RuntimeException("Carrier does contain the lock"); + } + } + + static class Loader implements Runnable { + CountDownLatch ready; + Loader(CountDownLatch ready) { + this.ready = ready; + } + public void run() { + try { + if (ready != null) { + ready.countDown(); + } + Class myClass = Class.forName("LongInitClass"); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + +} From 0df8c9684b8782ef830e2bd425217864c3f51784 Mon Sep 17 00:00:00 2001 From: Mohamed Issa Date: Fri, 30 May 2025 21:47:20 +0000 Subject: [PATCH 036/216] 8353686: Optimize Math.cbrt for x86 64 bit platforms Reviewed-by: sviswanathan, sparasa, jbhateja --- src/hotspot/cpu/x86/assembler_x86.cpp | 19 + src/hotspot/cpu/x86/assembler_x86.hpp | 4 + src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp | 17 +- src/hotspot/cpu/x86/macroAssembler_x86.cpp | 10 + src/hotspot/cpu/x86/macroAssembler_x86.hpp | 9 +- src/hotspot/cpu/x86/stubGenerator_x86_64.cpp | 3 + src/hotspot/cpu/x86/stubGenerator_x86_64.hpp | 1 + .../cpu/x86/stubGenerator_x86_64_cbrt.cpp | 366 ++++++++++++++++++ .../templateInterpreterGenerator_x86_64.cpp | 4 + src/hotspot/share/c1/c1_Compiler.cpp | 1 + src/hotspot/share/c1/c1_GraphBuilder.cpp | 1 + src/hotspot/share/c1/c1_LIRGenerator.cpp | 1 + src/hotspot/share/c1/c1_Runtime1.cpp | 1 + src/hotspot/share/classfile/vmIntrinsics.cpp | 3 + src/hotspot/share/classfile/vmIntrinsics.hpp | 5 +- .../share/interpreter/abstractInterpreter.cpp | 3 + .../share/interpreter/abstractInterpreter.hpp | 6 +- .../templateInterpreterGenerator.cpp | 3 +- .../zero/zeroInterpreterGenerator.cpp | 2 + src/hotspot/share/jvmci/jvmciCompilerToVM.hpp | 3 +- .../share/jvmci/jvmciCompilerToVMInit.cpp | 2 + src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 1 + src/hotspot/share/opto/c2compiler.cpp | 1 + src/hotspot/share/opto/library_call.cpp | 4 + .../share/runtime/stubDeclarations.hpp | 2 + .../share/classes/java/lang/Math.java | 1 + .../org/openjdk/bench/java/lang/CbrtPerf.java | 187 +++++++++ 27 files changed, 648 insertions(+), 12 deletions(-) create mode 100644 src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp create mode 100644 test/micro/org/openjdk/bench/java/lang/CbrtPerf.java diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 1b17663971d..84c08dda848 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -2867,6 +2867,17 @@ void Assembler::mov(Register dst, Register src) { movq(dst, src); } +void Assembler::movapd(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionMark im(this); + InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_rex_vex_w_reverted(); + simd_prefix(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int8(0x28); + emit_operand(dst, src, 0); +} + void Assembler::movapd(XMMRegister dst, XMMRegister src) { int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit; InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); @@ -8072,6 +8083,14 @@ void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src, int vector emit_operand(dst, src, 0); } +void Assembler::orpd(XMMRegister dst, XMMRegister src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + InstructionAttr attributes(AVX_128bit, /* rex_w */ !_legacy_mode_dq, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_rex_vex_w_reverted(); + int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int16(0x56, (0xC0 | encode)); +} + void Assembler::unpckhpd(XMMRegister dst, XMMRegister src) { InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_rex_vex_w_reverted(); diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 719334701a5..10e6264160c 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -950,6 +950,7 @@ private: // New cpus require use of movaps and movapd to avoid partial register stall // when moving between registers. void movaps(XMMRegister dst, XMMRegister src); + void movapd(XMMRegister dst, Address src); void movapd(XMMRegister dst, XMMRegister src); // End avoid using directly @@ -2450,6 +2451,9 @@ private: void vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len); + // Bitwise Logical OR of Packed Floating-Point Values + void orpd(XMMRegister dst, XMMRegister src); + void unpckhpd(XMMRegister dst, XMMRegister src); void unpcklpd(XMMRegister dst, XMMRegister src); diff --git a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp index 60ce3419dfb..3ea2e99fe57 100644 --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp @@ -720,7 +720,8 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog || x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos || x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan || - x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dtanh + x->id() == vmIntrinsics::_dlog10 || x->id() == vmIntrinsics::_dtanh || + x->id() == vmIntrinsics::_dcbrt ) { do_LibmIntrinsic(x); return; @@ -807,7 +808,7 @@ void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { } break; case vmIntrinsics::_dpow: - if (StubRoutines::dpow() != nullptr) { + if (StubRoutines::dpow() != nullptr) { __ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args()); } else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args()); @@ -828,18 +829,24 @@ void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) { } break; case vmIntrinsics::_dtan: - if (StubRoutines::dtan() != nullptr) { + if (StubRoutines::dtan() != nullptr) { __ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args()); } else { __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args()); } break; case vmIntrinsics::_dtanh: - assert(StubRoutines::dtanh() != nullptr, "tanh intrinsic not found"); - if (StubRoutines::dtanh() != nullptr) { + assert(StubRoutines::dtanh() != nullptr, "tanh intrinsic not found"); + if (StubRoutines::dtanh() != nullptr) { __ call_runtime_leaf(StubRoutines::dtanh(), getThreadTemp(), result_reg, cc->args()); } break; + case vmIntrinsics::_dcbrt: + assert(StubRoutines::dcbrt() != nullptr, "cbrt intrinsic not found"); + if (StubRoutines::dcbrt() != nullptr) { + __ call_runtime_leaf(StubRoutines::dcbrt(), getThreadTemp(), result_reg, cc->args()); + } + break; default: ShouldNotReachHere(); } diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index f58a8dca98e..803bce48945 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -2250,6 +2250,16 @@ void MacroAssembler::evmovdqaq(XMMRegister dst, AddressLiteral src, int vector_l } } +void MacroAssembler::movapd(XMMRegister dst, AddressLiteral src, Register rscratch) { + assert(rscratch != noreg || always_reachable(src), "missing"); + + if (reachable(src)) { + Assembler::movapd(dst, as_Address(src)); + } else { + lea(rscratch, src); + Assembler::movapd(dst, Address(rscratch, 0)); + } +} void MacroAssembler::movdqa(XMMRegister dst, AddressLiteral src, Register rscratch) { assert(rscratch != noreg || always_reachable(src), "missing"); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index efd1a4c154f..f7ac6fb4297 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -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 @@ -995,6 +995,8 @@ public: void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); } void andpd(XMMRegister dst, AddressLiteral src, Register rscratch = noreg); + void andnpd(XMMRegister dst, XMMRegister src) { Assembler::andnpd(dst, src); } + void andps(XMMRegister dst, XMMRegister src) { Assembler::andps(dst, src); } void andps(XMMRegister dst, Address src) { Assembler::andps(dst, src); } void andps(XMMRegister dst, AddressLiteral src, Register rscratch = noreg); @@ -1007,6 +1009,8 @@ public: void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); } void comisd(XMMRegister dst, AddressLiteral src, Register rscratch = noreg); + void orpd(XMMRegister dst, XMMRegister src) { Assembler::orpd(dst, src); } + void cmp32_mxcsr_std(Address mxcsr_save, Register tmp, Register rscratch = noreg); void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } void ldmxcsr(AddressLiteral src, Register rscratch = noreg); @@ -1241,6 +1245,9 @@ public: void evmovdquq(XMMRegister dst, KRegister mask, AddressLiteral src, bool merge, int vector_len, Register rscratch = noreg); void evmovdqaq(XMMRegister dst, KRegister mask, AddressLiteral src, bool merge, int vector_len, Register rscratch = noreg); + using Assembler::movapd; + void movapd(XMMRegister dst, AddressLiteral src, Register rscratch = noreg); + // Move Aligned Double Quadword void movdqa(XMMRegister dst, XMMRegister src) { Assembler::movdqa(dst, src); } void movdqa(XMMRegister dst, Address src) { Assembler::movdqa(dst, src); } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index 413836840c5..1014c1c376f 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -3692,6 +3692,9 @@ void StubGenerator::generate_libm_stubs() { if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtanh)) { StubRoutines::_dtanh = generate_libmTanh(); // from stubGenerator_x86_64_tanh.cpp } + if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcbrt)) { + StubRoutines::_dcbrt = generate_libmCbrt(); // from stubGenerator_x86_64_cbrt.cpp + } if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) { StubRoutines::_dexp = generate_libmExp(); // from stubGenerator_x86_64_exp.cpp } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp index 6069c9dbc8e..2f1e46f3132 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp @@ -556,6 +556,7 @@ class StubGenerator: public StubCodeGenerator { address generate_libmCos(); address generate_libmTan(); address generate_libmTanh(); + address generate_libmCbrt(); address generate_libmExp(); address generate_libmPow(); address generate_libmLog(); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp new file mode 100644 index 00000000000..da60a9be276 --- /dev/null +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2025, Intel Corporation. All rights reserved. + * Intel Math Library (LIBM) Source Code + * + * 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 "macroAssembler_x86.hpp" +#include "stubGenerator_x86_64.hpp" + +/******************************************************************************/ +// ALGORITHM DESCRIPTION +// --------------------- +// +// x=2^{3*k+j} * 1.b1 b2 ... b5 b6 ... b52 +// Let r=(x*2^{-3k-j} - 1.b1 b2 ... b5 1)* rcp[b1 b2 ..b5], +// where rcp[b1 b2 .. b5]=1/(1.b1 b2 b3 b4 b5 1) in double precision +// cbrt(2^j * 1. b1 b2 .. b5 1) is approximated as T[j][b1..b5]+D[j][b1..b5] +// (T stores the high 53 bits, D stores the low order bits) +// Result=2^k*T+(2^k*T*r)*P+2^k*D +// where P=p1+p2*r+..+p8*r^7 +// +// Special cases: +// cbrt(NaN) = quiet NaN +// cbrt(+/-INF) = +/-INF +// cbrt(+/-0) = +/-0 +// +/******************************************************************************/ + +ATTRIBUTE_ALIGNED(4) static const juint _SIG_MASK[] = +{ + 0, 1032192 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _EXP_MASK[] = +{ + 0, 3220176896 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _EXP_MSK2[] = +{ + 0, 3220193280 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _EXP_MSK3[] = +{ + 4294967295, 1048575 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _SCALE63[] = +{ + 0, 1138753536 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _ZERON[] = +{ + 0, 2147483648 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _INF[] = +{ + 0, 2146435072 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _NEG_INF[] = +{ + 0, 4293918720 +}; + +ATTRIBUTE_ALIGNED(16) static const juint _coeff_table[] = +{ + 1553778919, 3213899486, 3534952507, 3215266280, 1646371399, + 3214412045, 477218588, 3216798151, 3582521621, 1066628362, + 1007461464, 1068473053, 889629714, 1067378449, 1431655765, + 1070945621 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _rcp_table[] = +{ + 528611360, 3220144632, 2884679527, 3220082993, 1991868891, 3220024928, + 2298714891, 3219970134, 58835168, 3219918343, 3035110223, 3219869313, + 1617585086, 3219822831, 2500867033, 3219778702, 4241943008, 3219736752, + 258732970, 3219696825, 404232216, 3219658776, 2172167368, 3219622476, + 1544257904, 3219587808, 377579543, 3219554664, 1616385542, 3219522945, + 813783277, 3219492562, 3940743189, 3219463431, 2689777499, 3219435478, + 1700977147, 3219408632, 3169102082, 3219382828, 327235604, 3219358008, + 1244336319, 3219334115, 1300311200, 3219311099, 3095471925, 3219288912, + 2166487928, 3219267511, 2913108253, 3219246854, 293672978, 3219226904, + 288737297, 3219207624, 1810275472, 3219188981, 174592167, 3219170945, + 3539053052, 3219153485, 2164392968, 3219136576 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _cbrt_table[] = +{ + 572345495, 1072698681, 1998204467, 1072709382, 3861501553, 1072719872, + 2268192434, 1072730162, 2981979308, 1072740260, 270859143, 1072750176, + 2958651392, 1072759916, 313113243, 1072769490, 919449400, 1072778903, + 2809328903, 1072788162, 2222981587, 1072797274, 2352530781, 1072806244, + 594152517, 1072815078, 1555767199, 1072823780, 4282421314, 1072832355, + 2355578597, 1072840809, 1162590619, 1072849145, 797864051, 1072857367, + 431273680, 1072865479, 2669831148, 1072873484, 733477752, 1072881387, + 4280220604, 1072889189, 801961634, 1072896896, 2915370760, 1072904508, + 1159613482, 1072912030, 2689944798, 1072919463, 1248687822, 1072926811, + 2967951030, 1072934075, 630170432, 1072941259, 3760898254, 1072948363, + 0, 1072955392, 2370273294, 1072962345, 1261754802, 1072972640, + 546334065, 1072986123, 1054893830, 1072999340, 1571187597, 1073012304, + 1107975175, 1073025027, 3606909377, 1073037519, 1113616747, 1073049792, + 4154744632, 1073061853, 3358931423, 1073073713, 4060702372, 1073085379, + 747576176, 1073096860, 3023138255, 1073108161, 1419988548, 1073119291, + 1914185305, 1073130255, 294389948, 1073141060, 3761802570, 1073151710, + 978281566, 1073162213, 823148820, 1073172572, 2420954441, 1073182792, + 3815449908, 1073192878, 2046058587, 1073202835, 1807524753, 1073212666, + 2628681401, 1073222375, 3225667357, 1073231966, 1555307421, 1073241443, + 3454043099, 1073250808, 1208137896, 1073260066, 3659916772, 1073269218, + 1886261264, 1073278269, 3593647839, 1073287220, 3086012205, 1073296075, + 2769796922, 1073304836, 888716057, 1073317807, 2201465623, 1073334794, + 164369365, 1073351447, 3462666733, 1073367780, 2773905457, 1073383810, + 1342879088, 1073399550, 2543933975, 1073415012, 1684477781, 1073430209, + 3532178543, 1073445151, 1147747300, 1073459850, 1928031793, 1073474314, + 2079717015, 1073488553, 4016765315, 1073502575, 3670431139, 1073516389, + 3549227225, 1073530002, 11637607, 1073543422, 588220169, 1073556654, + 2635407503, 1073569705, 2042029317, 1073582582, 1925128962, 1073595290, + 4136375664, 1073607834, 759964600, 1073620221, 4257606771, 1073632453, + 297278907, 1073644538, 3655053093, 1073656477, 2442253172, 1073668277, + 1111876799, 1073679941, 3330973139, 1073691472, 3438879452, 1073702875, + 3671565478, 1073714153, 1317849547, 1073725310, 1642364115, 1073736348 +}; + +ATTRIBUTE_ALIGNED(4) static const juint _D_table[] = +{ + 4050900474, 1014427190, 1157977860, 1016444461, 1374568199, 1017271387, + 2809163288, 1016882676, 3742377377, 1013168191, 3101606597, 1017541672, + 65224358, 1017217597, 2691591250, 1017266643, 4020758549, 1017689313, + 1316310992, 1018030788, 1031537856, 1014090882, 3261395239, 1016413641, + 886424999, 1016313335, 3114776834, 1014195875, 1681120620, 1017825416, + 1329600273, 1016625740, 465474623, 1017097119, 4251633980, 1017169077, + 1986990133, 1017710645, 752958613, 1017159641, 2216216792, 1018020163, + 4282860129, 1015924861, 1557627859, 1016039538, 3889219754, 1018086237, + 3684996408, 1017353275, 723532103, 1017717141, 2951149676, 1012528470, + 831890937, 1017830553, 1031212645, 1017387331, 2741737450, 1017604974, + 2863311531, 1003776682, 4276736099, 1013153088, 4111778382, 1015673686, + 1728065769, 1016413986, 2708718031, 1018078833, 1069335005, 1015291224, + 700037144, 1016482032, 2904566452, 1017226861, 4074156649, 1017622651, + 25019565, 1015245366, 3601952608, 1015771755, 3267129373, 1017904664, + 503203103, 1014921629, 2122011730, 1018027866, 3927295461, 1014189456, + 2790625147, 1016024251, 1330460186, 1016940346, 4033568463, 1015538390, + 3695818227, 1017509621, 257573361, 1017208868, 3227697852, 1017337964, + 234118548, 1017169577, 4009025803, 1017278524, 1948343394, 1017749310, + 678398162, 1018144239, 3083864863, 1016669086, 2415453452, 1017890370, + 175467344, 1017330033, 3197359580, 1010339928, 2071276951, 1015941358, + 268372543, 1016737773, 938132959, 1017389108, 1816750559, 1017337448, + 4119203749, 1017152174, 2578653878, 1013108497, 2470331096, 1014678606, + 123855735, 1016553320, 1265650889, 1014782687, 3414398172, 1017182638, + 1040773369, 1016158401, 3483628886, 1016886550, 4140499405, 1016191425, + 3893477850, 1016964495, 3935319771, 1009634717, 2978982660, 1015027112, + 2452709923, 1017990229, 3190365712, 1015835149, 4237588139, 1015832925, + 2610678389, 1017962711, 2127316774, 1017405770, 824267502, 1017959463, + 2165924042, 1017912225, 2774007076, 1013257418, 4123916326, 1017582284, + 1976417958, 1016959909, 4092806412, 1017711279, 119251817, 1015363631, + 3475418768, 1017675415, 1972580503, 1015470684, 815541017, 1017517969, + 2429917451, 1017397776, 4062888482, 1016749897, 68284153, 1017925678, + 2207779246, 1016320298, 1183466520, 1017408657, 143326427, 1017060403 +}; + +#define __ _masm-> + +address StubGenerator::generate_libmCbrt() { + StubGenStubId stub_id = StubGenStubId::dcbrt_id; + 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 B1_1, B1_2, B1_4; + + address SIG_MASK = (address)_SIG_MASK; + address EXP_MASK = (address)_EXP_MASK; + address EXP_MSK2 = (address)_EXP_MSK2; + address EXP_MSK3 = (address)_EXP_MSK3; + address SCALE63 = (address)_SCALE63; + address ZERON = (address)_ZERON; + address INF = (address)_INF; + address NEG_INF = (address)_NEG_INF; + address coeff_table = (address)_coeff_table; + address rcp_table = (address)_rcp_table; + address cbrt_table = (address)_cbrt_table; + address D_table = (address)_D_table; + + __ enter(); // required for proper stackwalking of RuntimeStub frame + + __ bind(B1_1); + __ subq(rsp, 24); + __ movsd(Address(rsp), xmm0); + + __ bind(B1_2); + __ movq(xmm7, xmm0); + __ movl(rdx, 524032); + __ movsd(xmm5, ExternalAddress(EXP_MSK3), r11 /*rscratch*/); + __ movsd(xmm3, ExternalAddress(EXP_MSK2), r11 /*rscratch*/); + __ psrlq(xmm7, 44); + __ pextrw(rcx, xmm7, 0); + __ movdl(rax, xmm7); + __ movsd(xmm1, ExternalAddress(EXP_MASK), r11 /*rscratch*/); + __ movsd(xmm2, ExternalAddress(SIG_MASK), r11 /*rscratch*/); + __ andl(rcx, 248); + __ lea(r8, ExternalAddress(rcp_table)); + __ movsd(xmm4, Address(rcx, r8, Address::times_1)); + __ movq(r9, rax); + __ 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); + __ andpd(xmm0, xmm5); + __ orpd(xmm3, xmm2); + __ orpd(xmm1, xmm0); + __ movapd(xmm5, ExternalAddress(coeff_table), r11 /*rscratch*/); + __ movl(rax, 5462); + __ movapd(xmm6, ExternalAddress(coeff_table + 16), r11 /*rscratch*/); + __ mull(rdx); + __ movq(rdx, r9); + __ andq(r9, 2047); + __ shrl(rax, 14); + __ andl(rdx, 2048); + __ subq(r9, rax); + __ subq(r9, rax); + __ subq(r9, rax); + __ shlq(r9, 8); + __ addl(rax, 682); + __ orl(rax, rdx); + __ movdl(xmm7, rax); + __ addq(rcx, r9); + __ psllq(xmm7, 52); + + __ bind(L_2TAG_PACKET_2_0_1); + __ movapd(xmm2, ExternalAddress(coeff_table + 32), r11 /*rscratch*/); + __ movapd(xmm0, ExternalAddress(coeff_table + 48), r11 /*rscratch*/); + __ subsd(xmm1, xmm3); + __ movq(xmm3, xmm7); + __ lea(r8, ExternalAddress(cbrt_table)); + __ mulsd(xmm7, Address(rcx, r8, Address::times_1)); + __ mulsd(xmm1, xmm4); + __ lea(r8, ExternalAddress(D_table)); + __ mulsd(xmm3, Address(rcx, r8, Address::times_1)); + __ movapd(xmm4, xmm1); + __ unpcklpd(xmm1, xmm1); + __ mulpd(xmm5, xmm1); + __ mulpd(xmm6, xmm1); + __ mulpd(xmm1, xmm1); + __ addpd(xmm2, xmm5); + __ addpd(xmm0, xmm6); + __ mulpd(xmm2, xmm1); + __ mulpd(xmm1, xmm1); + __ mulsd(xmm4, xmm7); + __ addpd(xmm0, xmm2); + __ mulsd(xmm1, xmm0); + __ unpckhpd(xmm0, xmm0); + __ addsd(xmm0, xmm1); + __ mulsd(xmm0, xmm4); + __ addsd(xmm0, xmm3); + __ addsd(xmm0, xmm7); + __ jmp(B1_4); + + __ bind(L_2TAG_PACKET_0_0_1); + __ mulsd(xmm0, ExternalAddress(SCALE63), r11 /*rscratch*/); + __ movq(xmm7, xmm0); + __ movl(rdx, 524032); + __ psrlq(xmm7, 44); + __ pextrw(rcx, xmm7, 0); + __ movdl(rax, xmm7); + __ andl(rcx, 248); + __ lea(r8, ExternalAddress(rcp_table)); + __ movsd(xmm4, Address(rcx, r8, Address::times_1)); + __ movq(r9, rax); + __ 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); + __ orpd(xmm1, xmm0); + __ movapd(xmm5, ExternalAddress(coeff_table), r11 /*rscratch*/); + __ movl(rax, 5462); + __ movapd(xmm6, ExternalAddress(coeff_table + 16), r11 /*rscratch*/); + __ mull(rdx); + __ movq(rdx, r9); + __ andq(r9, 2047); + __ shrl(rax, 14); + __ andl(rdx, 2048); + __ subq(r9, rax); + __ subq(r9, rax); + __ subq(r9, rax); + __ shlq(r9, 8); + __ addl(rax, 661); + __ orl(rax, rdx); + __ movdl(xmm7, rax); + __ addq(rcx, r9); + __ 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); + + return start; +} + +#undef __ diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp index 6be702f2699..9ea4aeeccfa 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_64.cpp @@ -468,6 +468,10 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M assert(StubRoutines::dtanh() != nullptr, "not initialized"); __ movdbl(xmm0, Address(rsp, wordSize)); __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtanh()))); + } else if (kind == Interpreter::java_lang_math_cbrt) { + assert(StubRoutines::dcbrt() != nullptr, "not initialized"); + __ movdbl(xmm0, Address(rsp, wordSize)); + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcbrt()))); } else if (kind == Interpreter::java_lang_math_abs) { assert(StubRoutines::x86::double_sign_mask() != nullptr, "not initialized"); __ movdbl(xmm0, Address(rsp, wordSize)); diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index dd13b84edf5..b5fa7dcf247 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -168,6 +168,7 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_dtan: #if defined(AMD64) case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: #endif case vmIntrinsics::_dlog: case vmIntrinsics::_dlog10: diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 201ee695f69..8658bebdaee 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -3298,6 +3298,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope) case vmIntrinsics::_dcos : // fall through case vmIntrinsics::_dtan : // fall through case vmIntrinsics::_dtanh : // fall through + case vmIntrinsics::_dcbrt : // fall through case vmIntrinsics::_dlog : // fall through case vmIntrinsics::_dlog10 : // fall through case vmIntrinsics::_dexp : // fall through diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 214da537993..341de0ac0c2 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -2870,6 +2870,7 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { case vmIntrinsics::_dtanh: // fall through case vmIntrinsics::_dsin : // fall through case vmIntrinsics::_dcos : // fall through + case vmIntrinsics::_dcbrt : // fall through case vmIntrinsics::_dexp : // fall through case vmIntrinsics::_dpow : do_MathIntrinsic(x); break; case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break; diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 93b8ed4410b..7c41c09d378 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -365,6 +365,7 @@ const char* Runtime1::name_for_address(address entry) { FUNCTION_CASE(entry, StubRoutines::dcos()); FUNCTION_CASE(entry, StubRoutines::dtan()); FUNCTION_CASE(entry, StubRoutines::dtanh()); + FUNCTION_CASE(entry, StubRoutines::dcbrt()); #undef FUNCTION_CASE diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index f76458b2662..6fd5c07e137 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -92,6 +92,7 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) { case vmIntrinsics::_dcos: case vmIntrinsics::_dtan: case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: case vmIntrinsics::_dlog: case vmIntrinsics::_dlog10: case vmIntrinsics::_dexp: @@ -144,6 +145,7 @@ bool vmIntrinsics::can_trap(vmIntrinsics::ID id) { case vmIntrinsics::_dcos: case vmIntrinsics::_dtan: case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: case vmIntrinsics::_dlog: case vmIntrinsics::_dlog10: case vmIntrinsics::_dexp: @@ -288,6 +290,7 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { case vmIntrinsics::_dcos: case vmIntrinsics::_dtan: case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: case vmIntrinsics::_dlog: case vmIntrinsics::_dexp: case vmIntrinsics::_dpow: diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 2959f35ef2c..eeefddfedfc 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -135,7 +135,7 @@ class methodHandle; do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \ do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \ do_name(floor_name, "floor") do_name(ceil_name, "ceil") do_name(rint_name, "rint") \ - do_name(round_name, "round") do_name(tanh_name,"tanh") \ + do_name(round_name, "round") do_name(tanh_name,"tanh") do_name(cbrt_name,"cbrt") \ \ do_name(addExact_name,"addExact") \ do_name(decrementExact_name,"decrementExact") \ @@ -161,7 +161,8 @@ class methodHandle; do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \ do_intrinsic(_dtan, java_lang_Math, tan_name, double_double_signature, F_S) \ do_intrinsic(_datan2, java_lang_Math, atan2_name, double2_double_signature, F_S) \ - do_intrinsic(_dtanh, java_lang_Math, tanh_name, double_double_signature, F_S) \ + do_intrinsic(_dtanh, java_lang_Math, tanh_name, double_double_signature, F_S) \ + do_intrinsic(_dcbrt, java_lang_Math, cbrt_name, double_double_signature, F_S) \ do_intrinsic(_dsqrt, java_lang_Math, sqrt_name, double_double_signature, F_S) \ do_intrinsic(_dlog, java_lang_Math, log_name, double_double_signature, F_S) \ do_intrinsic(_dlog10, java_lang_Math, log10_name, double_double_signature, F_S) \ diff --git a/src/hotspot/share/interpreter/abstractInterpreter.cpp b/src/hotspot/share/interpreter/abstractInterpreter.cpp index 25e23a15a58..1de7dd824f8 100644 --- a/src/hotspot/share/interpreter/abstractInterpreter.cpp +++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp @@ -138,6 +138,7 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan case vmIntrinsics::_dcos: return java_lang_math_cos; case vmIntrinsics::_dtan: return java_lang_math_tan; case vmIntrinsics::_dtanh: return java_lang_math_tanh; + case vmIntrinsics::_dcbrt: return java_lang_math_cbrt; case vmIntrinsics::_dabs: return java_lang_math_abs; case vmIntrinsics::_dlog: return java_lang_math_log; case vmIntrinsics::_dlog10: return java_lang_math_log10; @@ -199,6 +200,7 @@ vmIntrinsics::ID AbstractInterpreter::method_intrinsic(MethodKind kind) { case java_lang_math_cos : return vmIntrinsics::_dcos; case java_lang_math_tan : return vmIntrinsics::_dtan; case java_lang_math_tanh : return vmIntrinsics::_dtanh; + case java_lang_math_cbrt : return vmIntrinsics::_dcbrt; case java_lang_math_abs : return vmIntrinsics::_dabs; case java_lang_math_log : return vmIntrinsics::_dlog; case java_lang_math_log10 : return vmIntrinsics::_dlog10; @@ -303,6 +305,7 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) { case java_lang_math_cos : tty->print("java_lang_math_cos" ); break; case java_lang_math_tan : tty->print("java_lang_math_tan" ); break; case java_lang_math_tanh : tty->print("java_lang_math_tanh" ); break; + case java_lang_math_cbrt : tty->print("java_lang_math_cbrt" ); break; case java_lang_math_abs : tty->print("java_lang_math_abs" ); break; case java_lang_math_log : tty->print("java_lang_math_log" ); break; case java_lang_math_log10 : tty->print("java_lang_math_log10" ); break; diff --git a/src/hotspot/share/interpreter/abstractInterpreter.hpp b/src/hotspot/share/interpreter/abstractInterpreter.hpp index cc1a66f442d..b6876b3a2da 100644 --- a/src/hotspot/share/interpreter/abstractInterpreter.hpp +++ b/src/hotspot/share/interpreter/abstractInterpreter.hpp @@ -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 @@ -39,7 +39,7 @@ // Organization of the interpreter(s). There exists two different interpreters in hotpot // an assembly language version (aka template interpreter) and a high level language version -// (aka c++ interpreter). Th division of labor is as follows: +// (aka c++ interpreter). The division of labor is as follows: // Template Interpreter Zero Interpreter Functionality // @@ -73,6 +73,7 @@ class AbstractInterpreter: AllStatic { java_lang_math_cos, // implementation of java.lang.Math.cos (x) java_lang_math_tan, // implementation of java.lang.Math.tan (x) java_lang_math_tanh, // implementation of java.lang.Math.tanh (x) + java_lang_math_cbrt, // implementation of java.lang.Math.cbrt (x) java_lang_math_abs, // implementation of java.lang.Math.abs (x) java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x) java_lang_math_sqrt_strict, // implementation of java.lang.StrictMath.sqrt(x) @@ -152,6 +153,7 @@ class AbstractInterpreter: AllStatic { case vmIntrinsics::_dcos : // fall thru case vmIntrinsics::_dtan : // fall thru case vmIntrinsics::_dtanh : // fall thru + case vmIntrinsics::_dcbrt : // fall thru case vmIntrinsics::_dabs : // fall thru case vmIntrinsics::_dsqrt : // fall thru case vmIntrinsics::_dsqrt_strict : // fall thru diff --git a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp index 1d3be066941..533c88cce9e 100644 --- a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp +++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp @@ -194,6 +194,7 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(java_lang_math_cos ) method_entry(java_lang_math_tan ) method_entry(java_lang_math_tanh ) + method_entry(java_lang_math_cbrt ) method_entry(java_lang_math_abs ) method_entry(java_lang_math_sqrt ) method_entry(java_lang_math_sqrt_strict) @@ -453,6 +454,7 @@ address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpret case Interpreter::java_lang_math_cos : // fall thru case Interpreter::java_lang_math_tan : // fall thru case Interpreter::java_lang_math_tanh : // fall thru + case Interpreter::java_lang_math_cbrt : // fall thru case Interpreter::java_lang_math_abs : // fall thru case Interpreter::java_lang_math_log : // fall thru case Interpreter::java_lang_math_log10 : // fall thru @@ -487,4 +489,3 @@ address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpret } return entry_point; } - diff --git a/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp b/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp index faa36fc1ab1..c4eeb3fa840 100644 --- a/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp +++ b/src/hotspot/share/interpreter/zero/zeroInterpreterGenerator.cpp @@ -54,6 +54,7 @@ void ZeroInterpreterGenerator::generate_all() { method_entry(java_lang_math_cos ); method_entry(java_lang_math_tan ); method_entry(java_lang_math_tanh ); + method_entry(java_lang_math_cbrt ); method_entry(java_lang_math_abs ); method_entry(java_lang_math_sqrt ); method_entry(java_lang_math_sqrt_strict); @@ -96,6 +97,7 @@ address ZeroInterpreterGenerator::generate_method_entry( case Interpreter::java_lang_math_cos : // fall thru case Interpreter::java_lang_math_tan : // fall thru case Interpreter::java_lang_math_tanh : // fall thru + case Interpreter::java_lang_math_cbrt : // fall thru case Interpreter::java_lang_math_abs : // fall thru case Interpreter::java_lang_math_log : // fall thru case Interpreter::java_lang_math_log10 : // fall thru diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp index c71993b7414..41531b083fc 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, 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 @@ -125,6 +125,7 @@ class CompilerToVM { static address dcos; static address dtan; static address dtanh; + static address dcbrt; static address dexp; static address dlog; static address dlog10; diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index 7b28eea59d5..1beb1917b9a 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -145,6 +145,7 @@ address CompilerToVM::Data::dsin; address CompilerToVM::Data::dcos; address CompilerToVM::Data::dtan; address CompilerToVM::Data::dtanh; +address CompilerToVM::Data::dcbrt; address CompilerToVM::Data::dexp; address CompilerToVM::Data::dlog; address CompilerToVM::Data::dlog10; @@ -287,6 +288,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) { } SET_TRIGFUNC_OR_NULL(dtanh); + SET_TRIGFUNC_OR_NULL(dcbrt); #undef SET_TRIGFUNC_OR_NULL diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index fc5b80f1d2e..cf9e6ed46d5 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -141,6 +141,7 @@ static_field(CompilerToVM::Data, dcos, address) \ static_field(CompilerToVM::Data, dtan, address) \ static_field(CompilerToVM::Data, dtanh, address) \ + static_field(CompilerToVM::Data, dcbrt, address) \ static_field(CompilerToVM::Data, dexp, address) \ static_field(CompilerToVM::Data, dlog, address) \ static_field(CompilerToVM::Data, dlog10, address) \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 272692446ae..0c642211e1f 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -616,6 +616,7 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_dcos: case vmIntrinsics::_dtan: case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: case vmIntrinsics::_dabs: case vmIntrinsics::_fabs: case vmIntrinsics::_iabs: diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 8a31711f85e..29f737bce08 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -245,6 +245,7 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_dcos: case vmIntrinsics::_dtan: case vmIntrinsics::_dtanh: + case vmIntrinsics::_dcbrt: case vmIntrinsics::_dabs: case vmIntrinsics::_fabs: case vmIntrinsics::_iabs: @@ -1886,6 +1887,9 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) { case vmIntrinsics::_dtanh: return StubRoutines::dtanh() != nullptr ? runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtanh(), "dtanh") : false; + case vmIntrinsics::_dcbrt: + return StubRoutines::dcbrt() != nullptr ? + runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dcbrt(), "dcbrt") : false; case vmIntrinsics::_dexp: return StubRoutines::dexp() != nullptr ? runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") : diff --git a/src/hotspot/share/runtime/stubDeclarations.hpp b/src/hotspot/share/runtime/stubDeclarations.hpp index 46feaaf0175..5dc7d293662 100644 --- a/src/hotspot/share/runtime/stubDeclarations.hpp +++ b/src/hotspot/share/runtime/stubDeclarations.hpp @@ -591,6 +591,8 @@ do_entry(initial, dtan, dtan, dtan) \ do_stub(initial, dtanh) \ do_entry(initial, dtanh, dtanh, dtanh) \ + do_stub(initial, dcbrt) \ + do_entry(initial, dcbrt, dcbrt, dcbrt) \ do_stub(initial, fmod) \ do_entry(initial, fmod, fmod, fmod) \ /* following generic entries should really be x86_32 only */ \ diff --git a/src/java.base/share/classes/java/lang/Math.java b/src/java.base/share/classes/java/lang/Math.java index 9956077bb09..9108ba7d944 100644 --- a/src/java.base/share/classes/java/lang/Math.java +++ b/src/java.base/share/classes/java/lang/Math.java @@ -445,6 +445,7 @@ public final class Math { * @return the cube root of {@code a}. * @since 1.5 */ + @IntrinsicCandidate public static double cbrt(double a) { return StrictMath.cbrt(a); } diff --git a/test/micro/org/openjdk/bench/java/lang/CbrtPerf.java b/test/micro/org/openjdk/bench/java/lang/CbrtPerf.java new file mode 100644 index 00000000000..0143b76fe6c --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/CbrtPerf.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.lang; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.annotations.OperationsPerInvocation; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Random; + +public class CbrtPerf { + + @Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.MILLISECONDS) + @Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.MILLISECONDS) + @Fork(2) + @BenchmarkMode(Mode.Throughput) + @State(Scope.Thread) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public static class CbrtPerfRanges { + public static int cbrtInputCount = 2048; + + @Param({"0", "1"}) + public int cbrtRangeIndex; + + public double [] cbrtPosRandInputs; + public double [] cbrtNegRandInputs; + public int cbrtInputIndex = 0; + public double cbrtRangeInputs[][] = { {0.0, 0x1.0P-1022}, {0x1.0P-1022, 1.7976931348623157E308} }; + + @Setup + public void setupValues() { + Random random = new Random(1023); + + // Fill the positive and negative cbrt vectors with random values + cbrtPosRandInputs = new double[cbrtInputCount]; + cbrtNegRandInputs = new double[cbrtInputCount]; + + for (int i = 0; i < cbrtInputCount; i++) { + double cbrtLowerBound = cbrtRangeInputs[cbrtRangeIndex][0]; + double cbrtUpperBound = cbrtRangeInputs[cbrtRangeIndex][1]; + cbrtPosRandInputs[i] = random.nextDouble(cbrtLowerBound, cbrtUpperBound); + cbrtNegRandInputs[i] = random.nextDouble(-cbrtUpperBound, -cbrtLowerBound); + } + } + + @Benchmark + @OperationsPerInvocation(2048) + public double cbrtPosRangeDouble() { + double res = 0.0; + for (int i = 0; i < cbrtInputCount; i++) { + res += Math.cbrt(cbrtPosRandInputs[i]); + } + return res; + } + + @Benchmark + @OperationsPerInvocation(2048) + public double cbrtNegRangeDouble() { + double res = 0.0; + for (int i = 0; i < cbrtInputCount; i++) { + res += Math.cbrt(cbrtNegRandInputs[i]); + } + return res; + } + } + + @Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) + @Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) + @Fork(2) + @BenchmarkMode(Mode.Throughput) + @State(Scope.Thread) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public static class CbrtPerfConstant { + public static final double constDouble0 = 0.0; + public static final double constDouble1 = 1.0; + public static final double constDouble27 = 27.0; + public static final double constDouble512 = 512.0; + + @Benchmark + public double cbrtConstDouble0() { + return Math.cbrt(constDouble0); + } + + @Benchmark + public double cbrtConstDouble1() { + return Math.cbrt(constDouble1); + } + + @Benchmark + public double cbrtConstDouble27() { + return Math.cbrt(constDouble27); + } + + @Benchmark + public double cbrtConstDouble512() { + return Math.cbrt(constDouble512); + } + } + + @Warmup(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS) + @Measurement(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) + @Fork(2) + @BenchmarkMode(Mode.Throughput) + @State(Scope.Thread) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public static class CbrtPerfSpecialValues { + public double double0 = 0.0; + public double doubleNegative0 = -0.0; + public double doubleInf = Double.POSITIVE_INFINITY; + public double doubleNegativeInf = Double.NEGATIVE_INFINITY; + public double doubleNaN = Double.NaN; + + @Benchmark + public double cbrtDouble0() { + return Math.cbrt(double0); + } + + @Benchmark + public double cbrtDoubleNegative0() { + return Math.cbrt(doubleNegative0); + } + + @Benchmark + public double cbrtDoubleInf() { + return Math.cbrt(doubleInf); + } + + @Benchmark + public double cbrtDoubleNegativeInf() { + return Math.cbrt(doubleNegativeInf); + } + + @Benchmark + public double cbrtDoubleNaN() { + return Math.cbrt(doubleNaN); + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(CbrtPerfRanges.class.getSimpleName()) + .build(); + + new Runner(opt).run(); + + opt = new OptionsBuilder() + .include(CbrtPerfConstant.class.getSimpleName()) + .build(); + + new Runner(opt).run(); + } +} From 2926435d228f21a227763ff4efcf32e511aa258a Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Fri, 30 May 2025 23:06:36 +0000 Subject: [PATCH 037/216] 8341346: Add support for exporting TLS Keying Material Reviewed-by: hchao, jnimeh, weijun --- .../sun/crypto/provider/TlsPrfGenerator.java | 6 +- .../javax/net/ssl/ExtendedSSLSession.java | 112 +++- .../internal/spec/TlsPrfParameterSpec.java | 48 +- .../classes/sun/security/ssl/Finished.java | 12 + .../sun/security/ssl/SSLSessionImpl.java | 297 ++++++++- .../classes/sun/security/ssl/ServerHello.java | 6 + .../security/pkcs11/P11SecretKeyFactory.java | 1 + .../security/pkcs11/P11TlsPrfGenerator.java | 8 +- .../ExportKeyingMaterialTests.java | 573 ++++++++++++++++++ 9 files changed, 1043 insertions(+), 20 deletions(-) create mode 100644 test/jdk/javax/net/ssl/ExtendedSSLSession/ExportKeyingMaterialTests.java diff --git a/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java index f8f733b6d2f..6ca019ae87b 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -147,7 +147,7 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi { throw new InvalidParameterException(MSG); } - SecretKey engineGenerateKey0(boolean tls12) { + protected SecretKey engineGenerateKey0(boolean tls12) { if (spec == null) { throw new IllegalStateException( "TlsPrfGenerator must be initialized"); @@ -163,7 +163,7 @@ abstract class TlsPrfGenerator extends KeyGeneratorSpi { spec.getPRFBlockSize()) : doTLS10PRF(secret, labelBytes, spec.getSeed(), n)); try { - return new SecretKeySpec(prfBytes, "TlsPrf"); + return new SecretKeySpec(prfBytes, spec.getKeyAlg()); } finally { Arrays.fill(prfBytes, (byte)0); } diff --git a/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java b/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java index 2b98f4845cf..980ff77d83a 100644 --- a/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java +++ b/src/java.base/share/classes/javax/net/ssl/ExtendedSSLSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package javax.net.ssl; import java.util.List; +import javax.crypto.SecretKey; /** * Extends the {@code SSLSession} interface to support additional @@ -163,4 +164,113 @@ public abstract class ExtendedSSLSession implements SSLSession { public List getStatusResponses() { throw new UnsupportedOperationException(); } + + /** + * Generates Exported Keying Material (EKM) calculated according to the + * algorithms defined in RFCs 5705/8446. + *

      + * RFC 5705 (for (D)TLSv1.2 and earlier) calculates different EKM + * values depending on whether {@code context} is null or non-null/empty. + * RFC 8446 (TLSv1.3) treats a null context as non-null/empty. + *

      + * {@code label} will be converted to bytes using + * the {@link java.nio.charset.StandardCharsets#UTF_8} + * character encoding. + * + * @spec https://www.rfc-editor.org/info/rfc5705 + * RFC 5705: Keying Material Exporters for Transport Layer + * Security (TLS) + * @spec https://www.rfc-editor.org/info/rfc8446 + * RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 + * + * @implSpec The default implementation throws + * {@code UnsupportedOperationException}. + * + * @param keyAlg the algorithm of the resultant {@code SecretKey} object. + * See the SecretKey Algorithms section in the + * + * Java Security Standard Algorithm Names Specification + * for information about standard secret key algorithm + * names. + * @param label the label bytes used in the EKM calculation. + * {@code label} will be converted to a {@code byte[]} + * before the operation begins. + * @param context the context bytes used in the EKM calculation, or null + * @param length the number of bytes of EKM material needed + * + * @throws SSLKeyException if the key cannot be generated + * @throws IllegalArgumentException if {@code keyAlg} is empty, + * {@code length} is non-positive, or if the {@code label} or + * {@code context} length can not be accommodated + * @throws NullPointerException if {@code keyAlg} or {@code label} is null + * @throws IllegalStateException if this session does not have the + * necessary key generation material (for example, a session + * under construction during handshaking) + * @throws UnsupportedOperationException if the underlying provider + * does not implement the operation + * + * @return a {@code SecretKey} that contains {@code length} bytes of the + * EKM material + * + * @since 25 + */ + public SecretKey exportKeyingMaterialKey(String keyAlg, + String label, byte[] context, int length) throws SSLKeyException { + throw new UnsupportedOperationException( + "Underlying provider does not implement the method"); + } + + /** + * Generates Exported Keying Material (EKM) calculated according to the + * algorithms defined in RFCs 5705/8446. + *

      + * RFC 5705 (for (D)TLSv1.2 and earlier) calculates different EKM + * values depending on whether {@code context} is null or non-null/empty. + * RFC 8446 (TLSv1.3) treats a null context as non-null/empty. + *

      + * {@code label} will be converted to bytes using + * the {@link java.nio.charset.StandardCharsets#UTF_8} + * character encoding. + *

      + * Depending on the chosen underlying key derivation mechanism, the + * raw bytes might not be extractable/exportable. In such cases, the + * {@link #exportKeyingMaterialKey(String, String, byte[], int)} method + * should be used instead to access the generated key material. + * + * @spec https://www.rfc-editor.org/info/rfc5705 + * RFC 5705: Keying Material Exporters for Transport Layer + * Security (TLS) + * @spec https://www.rfc-editor.org/info/rfc8446 + * RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 + * + * @implSpec The default implementation throws + * {@code UnsupportedOperationException}. + * + * @param label the label bytes used in the EKM calculation. + * {@code label} will be converted to a {@code byte[]} + * before the operation begins. + * @param context the context bytes used in the EKM calculation, or null + * @param length the number of bytes of EKM material needed + * + * @throws SSLKeyException if the key cannot be generated + * @throws IllegalArgumentException if {@code length} is non-positive, + * or if the {@code label} or {@code context} length can + * not be accommodated + * @throws NullPointerException if {@code label} is null + * @throws IllegalStateException if this session does not have the + * necessary key generation material (for example, a session + * under construction during handshaking) + * @throws UnsupportedOperationException if the underlying provider + * does not implement the operation, or if the derived + * keying material is not extractable + * + * @return a byte array of size {@code length} that contains the EKM + * material + * @since 25 + */ + public byte[] exportKeyingMaterialData( + String label, byte[] context, int length) throws SSLKeyException { + throw new UnsupportedOperationException( + "Underlying provider does not implement the method"); + } } diff --git a/src/java.base/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java b/src/java.base/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java index f87579ebb70..14abf9f30dc 100644 --- a/src/java.base/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java +++ b/src/java.base/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -45,6 +45,7 @@ import javax.crypto.SecretKey; public class TlsPrfParameterSpec implements AlgorithmParameterSpec { private final SecretKey secret; + private final String keyAlg; private final String label; private final byte[] seed; private final int outputLength; @@ -72,13 +73,45 @@ public class TlsPrfParameterSpec implements AlgorithmParameterSpec { public TlsPrfParameterSpec(SecretKey secret, String label, byte[] seed, int outputLength, String prfHashAlg, int prfHashLength, int prfBlockSize) { - if ((label == null) || (seed == null)) { - throw new NullPointerException("label and seed must not be null"); + this(secret, "TlsPrf", label, seed, outputLength, prfHashAlg, + prfHashLength, prfBlockSize); + } + + /** + * Constructs a new TlsPrfParameterSpec. + * + * @param secret the secret to use in the calculation (or null) + * @param keyAlg the algorithm name for the generated {@code SecretKey} + * @param label the label to use in the calculation + * @param seed the random seed to use in the calculation + * @param outputLength the length in bytes of the output key to be produced + * @param prfHashAlg the name of the TLS PRF hash algorithm to use. + * Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF. + * @param prfHashLength the output length of the TLS PRF hash algorithm. + * Used only for TLS 1.2+. + * @param prfBlockSize the input block size of the TLS PRF hash algorithm. + * Used only for TLS 1.2+. + * + * @throws NullPointerException if keyAlg, label or seed is null + * @throws IllegalArgumentException if outputLength is negative or + * keyAlg is empty + */ + public TlsPrfParameterSpec(SecretKey secret, String keyAlg, + String label, byte[] seed, int outputLength, + String prfHashAlg, int prfHashLength, int prfBlockSize) { + + if ((keyAlg == null) || (label == null) || (seed == null)) { + throw new NullPointerException( + "keyAlg, label or seed must not be null"); + } + if (keyAlg.isEmpty()) { + throw new IllegalArgumentException("keyAlg can not be empty"); } if (outputLength <= 0) { throw new IllegalArgumentException("outputLength must be positive"); } this.secret = secret; + this.keyAlg = keyAlg; this.label = label; this.seed = seed.clone(); this.outputLength = outputLength; @@ -87,6 +120,15 @@ public class TlsPrfParameterSpec implements AlgorithmParameterSpec { this.prfBlockSize = prfBlockSize; } + /** + * Returns the key algorithm name to use when generating the SecretKey. + * + * @return the key algorithm name + */ + public String getKeyAlg() { + return keyAlg; + } + /** * Returns the secret to use in the PRF calculation, or null if there is no * secret. diff --git a/src/java.base/share/classes/sun/security/ssl/Finished.java b/src/java.base/share/classes/sun/security/ssl/Finished.java index dcb499b6d0c..e388672cb7f 100644 --- a/src/java.base/share/classes/sun/security/ssl/Finished.java +++ b/src/java.base/share/classes/sun/security/ssl/Finished.java @@ -745,6 +745,12 @@ final class Finished { "Failure to derive application secrets", gse); } + // Calculate/save the exporter_master_secret. It uses + // the same handshakeHash as the client/server app traffic. + SecretKey exporterSecret = kd.deriveKey( + "TlsExporterMasterSecret"); + chc.handshakeSession.setExporterMasterSecret(exporterSecret); + // The resumption master secret is stored in the session so // it can be used after the handshake is completed. SSLSecretDerivation sd = ((SSLSecretDerivation) kd).forContext(chc); @@ -1099,6 +1105,12 @@ final class Finished { shc.baseReadSecret = readSecret; shc.conContext.inputRecord.changeReadCiphers(readCipher); + // Calculate/save the exporter_master_secret. It uses + // the same handshakeHash as the client/server app traffic. + SecretKey exporterSecret = kd.deriveKey( + "TlsExporterMasterSecret"); + shc.handshakeSession.setExporterMasterSecret(exporterSecret); + // The resumption master secret is stored in the session so // it can be used after the handshake is completed. shc.handshakeHash.update(); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java index 032aa7de5b3..5eb9f72af46 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -27,28 +27,32 @@ package sun.security.ssl; import java.io.IOException; import java.net.InetAddress; import java.nio.ByteBuffer; -import java.security.Principal; -import java.security.PrivateKey; +import java.nio.charset.StandardCharsets; +import java.security.*; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.ReentrantLock; import java.util.zip.Adler32; +import javax.crypto.KDF; +import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.spec.HKDFParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.net.ssl.ExtendedSSLSession; -import javax.net.ssl.SNIHostName; -import javax.net.ssl.SNIServerName; -import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLSessionBindingEvent; -import javax.net.ssl.SSLSessionBindingListener; -import javax.net.ssl.SSLSessionContext; +import javax.net.ssl.*; + +import sun.security.ssl.CipherSuite.HashAlg; +import sun.security.internal.spec.TlsPrfParameterSpec; +import static sun.security.ssl.CipherSuite.HashAlg.H_NONE; +import static sun.security.ssl.ProtocolVersion.*; +import sun.security.util.KeyUtil; import sun.security.provider.X509Factory; import sun.security.ssl.X509Authentication.X509Possession; @@ -99,6 +103,9 @@ final class SSLSessionImpl extends ExtendedSSLSession { private Collection peerSupportedSignAlgs; //for certificate private boolean useDefaultPeerSignAlgs = false; private List statusResponses; + private SecretKey exporterMasterSecret; // TLSv1.3+ exporter info + private RandomCookie clientRandom; // TLSv1.2- exporter info + private RandomCookie serverRandom; private SecretKey resumptionMasterSecret; private SecretKey preSharedKey; private byte[] pskIdentity; @@ -612,6 +619,15 @@ final class SSLSessionImpl extends ExtendedSSLSession { masterSecret = secret; } + void setExporterMasterSecret(SecretKey secret) { + exporterMasterSecret = secret; + } + + void setRandoms(RandomCookie client, RandomCookie server) { + clientRandom = client; + serverRandom = server; + } + void setResumptionMasterSecret(SecretKey secret) { resumptionMasterSecret = secret; } @@ -1397,6 +1413,269 @@ final class SSLSessionImpl extends ExtendedSSLSession { return requestedServerNames; } + /* + * keyAlg is used for switching between Keys/Data. If keyAlg is + * non-null, we are producing a Key, otherwise data. + */ + public Object exportKeyingMaterial( + String keyAlg, String label, byte[] context, int length) + throws SSLKeyException { + + // Global preconditions + + Objects.requireNonNull(label, "label can not be null"); + if (length < 1) { + throw new IllegalArgumentException( + "length must be positive"); + } + + // Calculations are primarily based on protocol version. + if (protocolVersion.useTLS13PlusSpec()) { + + // Unlikely, but check anyway. + if (exporterMasterSecret == null) { + throw new IllegalStateException( + "Exporter master secret not captured"); + } + + // TLS 1.3+ using HKDF-based calcs. + // TLS 1.3 (RFC 8446) + + // Check the label/context lengths: + // struct { + // uint16 length = Length; + // opaque label<7..255> = "tls13 " + Label; + // opaque context<0..255> = Context; + // } HkdfLabel; + // label can have 249 bytes (+6 for "tls13 "), and context 255 + + // RFC 8446 allows for length of 2^16-1 (65536), but RFC 5869 + // states: + // + // L length of output keying material in octets + // (<= 255*HashLen) + if (length > (255 * cipherSuite.hashAlg.hashLength )) { + throw new IllegalArgumentException( + "length is too large"); + } + + byte[] hkdfInfoLabel = + ("tls13 " + label).getBytes(StandardCharsets.UTF_8); + if ((hkdfInfoLabel.length < 7) || hkdfInfoLabel.length > 255) { + throw new IllegalArgumentException( + "label length outside range"); + } + + // If no context (null) is provided, RFC 8446 requires an empty + // context be used, unlike RFC 5705. + context = (context != null ? context : new byte[0]); + if (context.length > 255) { + throw new IllegalArgumentException( + "context length outside range"); + } + + // Do RFC 8446:7.1-7.5 calculations + + /* + * TLS-Exporter(label, context_value, key_length) = + * HKDF-Expand-Label(Derive-Secret(Secret, label, ""), + * "exporter", Hash(context_value), key_length) + * + * Derive-Secret(Secret, Label, Messages) = + * HKDF-Expand-Label(Secret, Label, + * Transcript-Hash(Messages), Hash.length) + */ + + try { + // Use the ciphersuite's hashAlg for these calcs. + HashAlg hashAlg = cipherSuite.hashAlg; + KDF hkdf = KDF.getInstance(hashAlg.hkdfAlgorithm); + + // First calculate the inner Derive-Secret(Secret, label, "") + MessageDigest md; + byte[] emptyHash; + + // Create the "" digest... + try { + md = MessageDigest.getInstance(hashAlg.toString()); + emptyHash = md.digest(); + } catch (NoSuchAlgorithmException nsae) { + throw new ProviderException( + "Hash algorithm " + cipherSuite.hashAlg.name + + " is not available", nsae); + } + + // ...then the hkdfInfo... + byte[] hkdfInfo = SSLSecretDerivation.createHkdfInfo( + hkdfInfoLabel, emptyHash, hashAlg.hashLength); + + // ...then the "inner" HKDF-Expand-Label() to get the + // derivedSecret that is used as the Secret in the "outer" + // HKDF-Expand-Label(). + SecretKey derivedSecret = hkdf.deriveKey("TlsKey", + HKDFParameterSpec.expandOnly(exporterMasterSecret, + hkdfInfo, hashAlg.hashLength)); + try { + // Now do the "outer" HKDF-Expand-Label. + // HKDF-Expand-Label(derivedSecret, "exporter", + // Hash(context_value), key_length) + + // If a context was supplied, use it, otherwise, use the + // previous hashed value of ""... + byte[] hash = ((context.length > 0) ? + md.digest(context) : emptyHash); + + // ...now the hkdfInfo... + hkdfInfo = SSLSecretDerivation.createHkdfInfo( + ("tls13 exporter").getBytes(StandardCharsets.UTF_8), + hash, length); + + // ...now the final expand. + return ((keyAlg != null) ? + hkdf.deriveKey(keyAlg, + HKDFParameterSpec.expandOnly(derivedSecret, + hkdfInfo, length)) : + hkdf.deriveData( + HKDFParameterSpec.expandOnly(derivedSecret, + hkdfInfo, length))); + } finally { + KeyUtil.destroySecretKeys(derivedSecret); + } + } catch (Exception e) { + // For whatever reason, we couldn't generate. Wrap and return. + throw new SSLKeyException("Couldn't generate Exporter/HKDF", e); + } + } else if (protocolVersion.useTLS10PlusSpec()) { + + // Unlikely, but check if randoms were not captured. + if (clientRandom == null || serverRandom == null) { + throw new IllegalStateException("Random nonces not captured"); + } + + // RFC 7505 using PRF-based calcs. + // TLS 1/1.1/1.2 (RFCs 2246/4346/5246) or + // DTLS 1.0/1.2 (RFCs 4347/6347) + + // Note: In RFC 7627: + // + // If a client or server chooses to continue with a full handshake + // without the extended master secret extension ... they MUST NOT + // export any key material based on the new master secret for any + // subsequent application-level authentication ... it MUST + // disable [RFC5705] ... + if (!useExtendedMasterSecret) { + throw new SSLKeyException( + "Exporters require extended master secrets"); + } + + // Check for a "disambiguating label string" (i.e. non-empty). + // Don't see a max length restriction. + if (label.isEmpty()) { + throw new IllegalArgumentException( + "label length outside range"); + } + + // context length must fit in 2 unsigned bytes. + if ((context != null) && (context.length > 0xFFFF)) { + throw new IllegalArgumentException( + "Only 16-bit context lengths supported"); + } + + // Perform RFC 5705 calculations using the internal SunJCE PRF. + String prfAlg; + HashAlg hashAlg; + if (protocolVersion == TLS12) { + prfAlg = "SunTls12Prf"; + hashAlg = cipherSuite.hashAlg; + } else { // all other cases + prfAlg = "SunTlsPrf"; + hashAlg = H_NONE; + } + + // Make a seed with randoms and optional context + // Note that if context is null, it is omitted from the calc + byte[] clientRandomBytes = clientRandom.randomBytes; + byte[] serverRandomBytes = serverRandom.randomBytes; + byte[] seed = new byte[ + clientRandomBytes.length + serverRandomBytes.length + + ((context != null) ? (2 + context.length) : 0)]; + + int pos = 0; + System.arraycopy( + clientRandomBytes, 0, seed, pos, clientRandomBytes.length); + pos += clientRandomBytes.length; + System.arraycopy( + serverRandomBytes, 0, seed, pos, serverRandomBytes.length); + pos += serverRandomBytes.length; + if (context != null) { + // RFC 5705, "If no context is provided, ..." + seed[pos++] = (byte) ((context.length >> 8) & 0xFF); + seed[pos++] = (byte) ((context.length) & 0xFF); + System.arraycopy( + context, 0, seed, pos, context.length); + } + + // Call the PRF function. + try { + @SuppressWarnings("deprecation") + TlsPrfParameterSpec spec = new TlsPrfParameterSpec( + masterSecret, (keyAlg == null) ? "TlsKey" : keyAlg, + label, seed, length, + hashAlg.name, hashAlg.hashLength, hashAlg.blockSize); + KeyGenerator kg = KeyGenerator.getInstance(prfAlg); + kg.init(spec); + SecretKey key = kg.generateKey(); + if (keyAlg != null) { + return key; + } else { + byte[] b = key.getEncoded(); + if (b == null) { + throw new UnsupportedOperationException( + "Could not extract encoding from SecretKey"); + } + return b; + } + } catch (NoSuchAlgorithmException | + InvalidAlgorithmParameterException e) { + throw new SSLKeyException("Could not generate Exporter/PRF", e); + } + } else { + // SSLv3 is vulnerable to a triple handshake attack and can't be + // mitigated by RFC 7627. Don't support this or any other + // unknown protocol. + throw new SSLKeyException( + "Exporters not supported in " + protocolVersion); + } + } + + /** + * Generate Exported Key Material (EKM) calculated according to the + * algorithms defined in RFCs 5705/8446. + */ + @Override + public SecretKey exportKeyingMaterialKey(String keyAlg, + String label, byte[] context, int length) throws SSLKeyException { + + Objects.requireNonNull(keyAlg, "keyAlg can not be null"); + if (keyAlg.isEmpty()) { + throw new IllegalArgumentException( + "keyAlg is empty"); + } + + return (SecretKey) exportKeyingMaterial(keyAlg, label, context, + length); + } + + /** + * Generate Exported Key Material (EKM) calculated according to the + * algorithms defined in RFCs 5705/8446. + */ + @Override + public byte[] exportKeyingMaterialData( + String label, byte[] context, int length) throws SSLKeyException { + return (byte[])exportKeyingMaterial(null, label, context, length); + } + /** Returns a string representation of this SSL session */ @Override public String toString() { diff --git a/src/java.base/share/classes/sun/security/ssl/ServerHello.java b/src/java.base/share/classes/sun/security/ssl/ServerHello.java index e38022f1c3e..d092d6c07de 100644 --- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java +++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java @@ -356,6 +356,9 @@ final class ServerHello { clientHello); shc.serverHelloRandom = shm.serverRandom; + shc.handshakeSession.setRandoms(shc.clientHelloRandom, + shc.serverHelloRandom); + // Produce extensions for ServerHello handshake message. SSLExtension[] serverHelloExtensions = shc.sslConfig.getEnabledExtensions( @@ -1129,6 +1132,9 @@ final class ServerHello { chc.sslConfig.maximumPacketSize); } + chc.handshakeSession.setRandoms(chc.clientHelloRandom, + chc.serverHelloRandom); + // // update // diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java index b80ccc35352..a2c7a072769 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java @@ -276,6 +276,7 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi { putKeyInfo(new TLSKeyInfo("TlsClientAppTrafficSecret")); putKeyInfo(new TLSKeyInfo("TlsClientHandshakeTrafficSecret")); putKeyInfo(new TLSKeyInfo("TlsEarlySecret")); + putKeyInfo(new TLSKeyInfo("TlsExporterMasterSecret")); putKeyInfo(new TLSKeyInfo("TlsFinishedSecret")); putKeyInfo(new TLSKeyInfo("TlsHandshakeSecret")); putKeyInfo(new TLSKeyInfo("TlsKey")); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java index 32f99b3fd5a..f6691a3d279 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -155,7 +155,7 @@ final class P11TlsPrfGenerator extends KeyGeneratorSpi { token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length); byte[] out = token.p11.C_SignFinal (session.id(), spec.getOutputLength()); - return new SecretKeySpec(out, "TlsPrf"); + return new SecretKeySpec(out, spec.getKeyAlg()); } catch (PKCS11Exception e) { throw new ProviderException("Could not calculate PRF", e); } finally { @@ -181,7 +181,7 @@ final class P11TlsPrfGenerator extends KeyGeneratorSpi { token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length); byte[] out = token.p11.C_SignFinal (session.id(), spec.getOutputLength()); - return new SecretKeySpec(out, "TlsPrf"); + return new SecretKeySpec(out, spec.getKeyAlg()); } catch (PKCS11Exception e) { throw new ProviderException("Could not calculate PRF", e); } finally { @@ -201,7 +201,7 @@ final class P11TlsPrfGenerator extends KeyGeneratorSpi { session = token.getOpSession(); token.p11.C_DeriveKey(session.id(), new CK_MECHANISM(mechanism, params), keyID, null); - return new SecretKeySpec(out, "TlsPrf"); + return new SecretKeySpec(out, spec.getKeyAlg()); } catch (PKCS11Exception e) { throw new ProviderException("Could not calculate PRF", e); } finally { diff --git a/test/jdk/javax/net/ssl/ExtendedSSLSession/ExportKeyingMaterialTests.java b/test/jdk/javax/net/ssl/ExtendedSSLSession/ExportKeyingMaterialTests.java new file mode 100644 index 00000000000..77d47d07475 --- /dev/null +++ b/test/jdk/javax/net/ssl/ExtendedSSLSession/ExportKeyingMaterialTests.java @@ -0,0 +1,573 @@ +/* + * 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. + */ + +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + +/* + * @test + * @bug 8341346 + * @summary Add support for exporting TLS Keying Material + * @library /javax/net/ssl/templates /test/lib /test/jdk/sun/security/pkcs11 + * @build SSLEngineTemplate + * @run main/othervm ExportKeyingMaterialTests + * @run main/othervm ExportKeyingMaterialTests PKCS11 + */ + +import java.security.Security; +import java.util.Arrays; +import javax.crypto.SecretKey; +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.HandshakeStatus; +import java.nio.ByteBuffer; +import java.util.Random; + +import static jdk.test.lib.Asserts.*; + +/** + * A SSLEngine usage example which simplifies the presentation + * by removing the I/O and multi-threading concerns. + *

      + * The test creates two SSLEngines, simulating a client and server. + * The "transport" layer consists two byte buffers: think of them + * as directly connected pipes. + *

      + * Note, this is a *very* simple example: real code will be much more + * involved. For example, different threading and I/O models could be + * used, transport mechanisms could close unexpectedly, and so on. + *

      + * When this application runs, notice that several messages + * (wrap/unwrap) pass before any application data is consumed or + * produced. + */ +public class ExportKeyingMaterialTests extends SSLEngineTemplate { + + private String protocol; + private String ciphersuite; + + protected ExportKeyingMaterialTests(String protocol, String ciphersuite) + throws Exception { + super(); + this.protocol = protocol; + this.ciphersuite = ciphersuite; + } + + /* + * Configure the engines. + */ + private void configureEngines(SSLEngine clientEngine, + SSLEngine serverEngine) { + + clientEngine.setUseClientMode(true); + + // Get/set parameters if needed + SSLParameters paramsClient = clientEngine.getSSLParameters(); + paramsClient.setProtocols(new String[] { protocol }); + paramsClient.setCipherSuites(new String[] { ciphersuite }); + clientEngine.setSSLParameters(paramsClient); + + serverEngine.setUseClientMode(false); + serverEngine.setNeedClientAuth(true); + + // Get/set parameters if needed + // + SSLParameters paramsServer = serverEngine.getSSLParameters(); + paramsServer.setProtocols(new String[] { + "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" + }); + serverEngine.setSSLParameters(paramsServer); + } + + public static void main(String[] args) throws Exception { + // Turn off the disabled Algorithms so we can also test SSLv3/TLSv1/etc. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + + if ((args.length > 0) && (args[0].equals("PKCS11"))) { + Security.insertProviderAt( + PKCS11Test.getSunPKCS11(PKCS11Test.getNssConfig()), 1); + } + + // Exercise all of the triggers which capture data + // in the various key exchange algorithms. + + // Use appropriate protocol/ciphersuite combos for TLSv1.3 + new ExportKeyingMaterialTests( + "TLSv1.3", "TLS_AES_128_GCM_SHA256").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.3", "TLS_AES_256_GCM_SHA384").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.3", "TLS_CHACHA20_POLY1305_SHA256").runTest(); + + // Try the various GCM suites for TLSv1.2 + new ExportKeyingMaterialTests( + "TLSv1.2", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.2", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.2", "TLS_RSA_WITH_AES_256_GCM_SHA384").runTest(); + + // Try one TLSv1.2/CBC suite just for grins, the triggers are the same. + new ExportKeyingMaterialTests( + "TLSv1.2", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256").runTest(); + + // Use appropriate protocol/ciphersuite combos. Some of the 1.2 + // suites (e.g. GCM) can't be used in earlier TLS versions. + new ExportKeyingMaterialTests( + "TLSv1.1", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.1", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA").runTest(); + new ExportKeyingMaterialTests( + "TLSv1.1", "TLS_RSA_WITH_AES_256_CBC_SHA").runTest(); + + new ExportKeyingMaterialTests( + "TLSv1", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA").runTest(); + new ExportKeyingMaterialTests( + "TLSv1", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA").runTest(); + new ExportKeyingMaterialTests( + "TLSv1", "TLS_RSA_WITH_AES_256_CBC_SHA").runTest(); + + try { + new ExportKeyingMaterialTests( + "SSLv3", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA").runTest(); + throw new Exception("SSLv3 export test should not have passed"); + } catch (SSLException e) { + System.out.println("SSLv3 test failed as expected"); + } + + System.out.println("All tests PASSED"); + } + + // + // Private methods that used to build the common part of the test. + // + + private void runTest() throws Exception { + SSLEngineResult clientResult; + SSLEngineResult serverResult; + + configureEngines(clientEngine, serverEngine); + + boolean dataDone = false; + while (isOpen(clientEngine) || isOpen(serverEngine)) { + log("================="); + + // client wrap + log("---Client Wrap---"); + clientResult = clientEngine.wrap(clientOut, cTOs); + logEngineStatus(clientEngine, clientResult); + runDelegatedTasks(clientEngine); + + // server wrap + log("---Server Wrap---"); + serverResult = serverEngine.wrap(serverOut, sTOc); + logEngineStatus(serverEngine, serverResult); + runDelegatedTasks(serverEngine); + + cTOs.flip(); + sTOc.flip(); + + // client unwrap + log("---Client Unwrap---"); + clientResult = clientEngine.unwrap(sTOc, clientIn); + logEngineStatus(clientEngine, clientResult); + runDelegatedTasks(clientEngine); + + // server unwrap + log("---Server Unwrap---"); + serverResult = serverEngine.unwrap(cTOs, serverIn); + logEngineStatus(serverEngine, serverResult); + runDelegatedTasks(serverEngine); + + cTOs.compact(); + sTOc.compact(); + + // After we've transferred all application data between the client + // and server, we close the clientEngine's outbound stream. + // This generates a close_notify handshake message, which the + // server engine receives and responds by closing itself. + if (!dataDone && (clientOut.limit() == serverIn.position()) && + (serverOut.limit() == clientIn.position())) { + + runExporterTests( + (ExtendedSSLSession) clientEngine.getSession(), + (ExtendedSSLSession) serverEngine.getSession()); + + // A sanity check to ensure we got what was sent. + checkTransfer(serverOut, clientIn); + checkTransfer(clientOut, serverIn); + + log("\tClosing clientEngine's *OUTBOUND*..."); + clientEngine.closeOutbound(); + logEngineStatus(clientEngine); + + dataDone = true; + log("\tClosing serverEngine's *OUTBOUND*..."); + serverEngine.closeOutbound(); + logEngineStatus(serverEngine); + } + } + } + + private static void runExporterTests( + ExtendedSSLSession clientSession, + ExtendedSSLSession serverSession) throws Exception { + + SecretKey clientKey, serverKey; + + // Create output arrays + byte[] clientBytes, serverBytes; + + // Create various input arrays and fill with junk. + Random random = new Random(); + byte[] bytes = new byte[20]; + random.nextBytes(bytes); + + // Slightly change 1 byte in the middle + byte[] bytesDiff = Arrays.copyOf(bytes, bytes.length); + bytesDiff[bytes.length/2]++; + + byte[] bytesDiffSize = new byte[21]; + random.nextBytes(bytesDiffSize); + + // Run a bunch of similar derivations using both the Key/Data methods, + // exercising the various valid/invalid combinations. + + // We may need to adjust if it turns out that this is run with + // non-extractable keys if .equals() doesn't work. + + // Inputs exactly equal. + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + assertEquals(clientKey, serverKey, + "Key: Equal inputs but exporters are not equal"); + log("Key: Equal inputs test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + bytes, 128); + assertEqualsByteArray(clientBytes, serverBytes, + "Data: Equal inputs but exporters are not equal"); + log("Data: Equal inputs test passed"); + + // Different labels, now use exportKeyingMaterialData() for coverage + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "goodbye", bytes, 128); + assertNotEquals(clientKey, serverKey, + "Key: Different labels but exporters same"); + log("Key: Different labels test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 128); + serverBytes = serverSession.exportKeyingMaterialData("goodbye", + bytes, 128); + assertNotEqualsByteArray(clientBytes, serverBytes, + "Data: Different labels but exporters same"); + log("Data: Different labels test passed"); + + // Different output sizes + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 127); + assertNotEquals(clientKey, serverKey, + "Key: Different output sizes but exporters same"); + log("Key: Different output size test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + bytes, 127); + assertEquals(clientBytes.length, 128, "client length != 128"); + assertEquals(serverBytes.length, 127, "server length != 127"); + assertNotEqualsByteArray(clientBytes, serverBytes, + "Data: Different output sizes but exporters same"); + log("Data: Different output size test passed"); + + // Different context values + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", bytesDiff, 128); + assertNotEquals(clientKey, serverKey, + "Key: Different context but exporters same"); + log("Key: Different context test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + bytesDiff, 128); + assertNotEqualsByteArray(clientBytes, serverBytes, + "Data: Different context but exporters same"); + log("Data: Different context test passed"); + + // Different context sizes + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", bytesDiffSize, 128); + assertNotEquals(clientKey, serverKey, + "Key: Different context sizes but exporters same"); + log("Key: Different context sizes test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + bytesDiffSize, 128); + assertNotEqualsByteArray(clientBytes, serverBytes, + "Data: Different context sizes but exporters same"); + log("Data: Different context sizes test passed"); + + // No context, but otherwise the same + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", null, 128); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", null, 128); + assertEquals(clientKey, serverKey, + "Key: No context and exporters are not the same"); + log("Key: No context test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + null, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + null, 128); + assertEqualsByteArray(clientBytes, serverBytes, + "Data: No context and exporters are not the same"); + log("Data: No context test passed"); + + // Smaller key size + clientKey = clientSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 5); + serverKey = serverSession.exportKeyingMaterialKey( + "Generic", "hello", bytes, 5); + assertEquals(clientKey, serverKey, + "Key: Smaller key size should be the same"); + log("Key: Smaller key size test passed"); + + clientBytes = clientSession.exportKeyingMaterialData("hello", + bytes, 5); + serverBytes = serverSession.exportKeyingMaterialData("hello", + bytes, 5); + assertEqualsByteArray(clientBytes, serverBytes, + "Data: Smaller key size should be the same"); + log("Data: Smaller key size test passed"); + + // Check error conditions + + try { + clientSession.exportKeyingMaterialKey(null, "hello", bytes, 32); + throw new Exception("null keyAlg accepted"); + } catch (NullPointerException e) { + log("null keyAlg test passed"); + } + + try { + clientSession.exportKeyingMaterialKey("", "hello", bytes, 32); + throw new Exception("empty keyAlg accepted"); + } catch (IllegalArgumentException e) { + log("empty keyAlg test passed"); + } + + try { + clientSession.exportKeyingMaterialData("hello", bytes, -1); + throw new Exception("negative length accepted"); + } catch (IllegalArgumentException e) { + log("negative length test passed"); + } + + try { + clientSession.exportKeyingMaterialData("hello", bytes, 0); + throw new Exception("zero length accepted"); + } catch (IllegalArgumentException e) { + log("zero length test passed"); + } + + try { + clientSession.exportKeyingMaterialData(null, bytes, 128); + throw new Exception("null label accepted"); + } catch (NullPointerException e) { + log("null label test passed"); + } + + try { + clientSession.exportKeyingMaterialData("", bytes, 128); + throw new Exception("empty label accepted"); + } catch (IllegalArgumentException e) { + log("empty label test passed"); + } + + switch (clientSession.getProtocol()) { + + case "TLSv1.3": + // 249 bytes is the max label we can accept (<7..255>, since + // "tls13 " is added in HkdfLabel) + String longString = + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "1234567890123456789012345678901234567890123456789"; + + clientSession.exportKeyingMaterialData(longString, bytes, 128); + log("large label test passed in TLSv1.3"); + + try { + clientSession.exportKeyingMaterialData( + longString + "0", bytes, 128); + throw new Exception("too large label accepted in TLSv1.3"); + } catch (IllegalArgumentException e) { + log("too large label test passed in TLSv1.3"); + } + + // 255 bytes is the max context we can accept (<0..255>) + clientSession.exportKeyingMaterialData( + longString, new byte[255], 128); + log("large context test passed in TLSv1.3"); + + try { + clientSession.exportKeyingMaterialData( + longString, new byte[256], 128); + throw new Exception("too large context accepted in TLSv1.3"); + } catch (IllegalArgumentException e) { + log("too large context test passed in TLSv1.3"); + } + + // RFC 5869 says 255*HashLen bytes is the max length we can accept. + // So we'll choose something a bit bigger than the largest + // hashLen/ciphertext which is 384 (48 bytes) so this will always + // fail. + try { + clientSession.exportKeyingMaterialData( + longString, new byte[256], 12240); + throw new Exception("too large length accepted in TLSv1.3"); + } catch (IllegalArgumentException e) { + log("too large length test passed in TLSv1.3"); + } + + // Do a null/byte[0] comparison. Exporters should be the same. + clientBytes = clientSession.exportKeyingMaterialData("hello", + null, 128); + serverBytes = serverSession.exportKeyingMaterialData("hello", + new byte[0], 128); + assertEqualsByteArray(clientBytes, serverBytes, + "Data: null vs. empty context should be the same"); + + break; + + case "TLSv1": + case "TLSv1.1": + case "TLSv1.2": + // Don't see a limit of the label.length or output length. + + // Check for large context.length + try { + clientSession.exportKeyingMaterialData("hello", + new byte[1 << 16], 128); + throw new Exception("large context accepted in " + + "TLSv1/TLSv1.1/TLSv1.2"); + } catch (IllegalArgumentException e) { + log("large context passed in TLSv1/TLSv1.1/TLSv1.2"); + } + + // Do a null/byte[0] comparison. Should NOT be the same. + clientBytes = clientSession.exportKeyingMaterialData( + "hello", null, 128); + serverBytes = serverSession.exportKeyingMaterialData( + "hello", new byte[0], 128); + assertNotEqualsByteArray(clientBytes, serverBytes, + "empty vs. null context but exporters same"); + log("Data: empty vs. null context, " + + "different exporters test passed"); + + break; + + default: + throw new RuntimeException("Unknown protocol: " + clientSession.getProtocol()); + } + + } + + static boolean isOpen(SSLEngine engine) { + return (!engine.isOutboundDone() || !engine.isInboundDone()); + } + + private static void logEngineStatus(SSLEngine engine) { + log("\tCurrent HS State: " + engine.getHandshakeStatus()); + log("\tisInboundDone() : " + engine.isInboundDone()); + log("\tisOutboundDone(): " + engine.isOutboundDone()); + } + + private static void logEngineStatus( + SSLEngine engine, SSLEngineResult result) { + log("\tResult Status : " + result.getStatus()); + log("\tResult HS Status : " + result.getHandshakeStatus()); + log("\tEngine HS Status : " + engine.getHandshakeStatus()); + log("\tisInboundDone() : " + engine.isInboundDone()); + log("\tisOutboundDone() : " + engine.isOutboundDone()); + log("\tMore Result : " + result); + } + + private static void log(String message) { + System.err.println(message); + } + + // If the result indicates that we have outstanding tasks to do, + // go ahead and run them in this thread. + protected static void runDelegatedTasks(SSLEngine engine) throws Exception { + if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log(" running delegated task..."); + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + logEngineStatus(engine); + } + } + + // Simple check to make sure everything came across as expected. + static void checkTransfer(ByteBuffer a, ByteBuffer b) + throws Exception { + a.flip(); + b.flip(); + + if (!a.equals(b)) { + throw new Exception("Data didn't transfer cleanly"); + } else { + log("\tData transferred cleanly"); + } + + a.position(a.limit()); + b.position(b.limit()); + a.limit(a.capacity()); + b.limit(b.capacity()); + } +} From 5ad02c98f1d9227bb6abdd37126f2a351d4e1a50 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sat, 31 May 2025 00:16:40 +0000 Subject: [PATCH 038/216] 8355004: Apply java.io.Serial annotations in java.compiler Reviewed-by: liach, darcy --- .../annotation/processing/FilerException.java | 8 ++++++-- .../lang/model/UnknownEntityException.java | 5 ++++- .../UnknownAnnotationValueException.java | 5 ++++- .../element/UnknownDirectiveException.java | 5 ++++- .../model/element/UnknownElementException.java | 5 ++++- .../lang/model/type/MirroredTypeException.java | 11 +++++++---- .../lang/model/type/MirroredTypesException.java | 17 ++++++++++------- .../lang/model/type/UnknownTypeException.java | 5 ++++- 8 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java b/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java index 26ee999e533..1561cf05a59 100644 --- a/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java +++ b/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package javax.annotation.processing; import java.io.IOException; +import java.io.Serial; /** * Indicates a {@link Filer} detected an attempt to open a file that @@ -38,7 +39,10 @@ import java.io.IOException; * @since 1.6 */ public class FilerException extends IOException { - static final long serialVersionUID = 8426423106453163293L; + + @Serial + private static final long serialVersionUID = 8426423106453163293L; + /** * Constructs an exception with the specified detail message. * @param s the detail message, which should include the name of diff --git a/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java b/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java index 2ca3a1d988c..6bbf114c327 100644 --- a/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java +++ b/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -25,6 +25,8 @@ package javax.lang.model; +import java.io.Serial; + /** * Superclass of exceptions which indicate that an unknown kind of * entity was encountered. This situation can occur if the language @@ -39,6 +41,7 @@ package javax.lang.model; */ public class UnknownEntityException extends RuntimeException { + @Serial private static final long serialVersionUID = 269L; /** diff --git a/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java b/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java index 869235d88d3..6f672d014fb 100644 --- a/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java +++ b/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,8 @@ package javax.lang.model.element; +import java.io.Serial; + import javax.lang.model.UnknownEntityException; /** @@ -40,6 +42,7 @@ import javax.lang.model.UnknownEntityException; */ public class UnknownAnnotationValueException extends UnknownEntityException { + @Serial private static final long serialVersionUID = 269L; private transient AnnotationValue av; diff --git a/src/java.compiler/share/classes/javax/lang/model/element/UnknownDirectiveException.java b/src/java.compiler/share/classes/javax/lang/model/element/UnknownDirectiveException.java index 7139573824a..4cec97d79f2 100644 --- a/src/java.compiler/share/classes/javax/lang/model/element/UnknownDirectiveException.java +++ b/src/java.compiler/share/classes/javax/lang/model/element/UnknownDirectiveException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,8 @@ package javax.lang.model.element; +import java.io.Serial; + import javax.lang.model.UnknownEntityException; /** @@ -39,6 +41,7 @@ import javax.lang.model.UnknownEntityException; */ public class UnknownDirectiveException extends UnknownEntityException { + @Serial private static final long serialVersionUID = 269L; private final transient ModuleElement.Directive directive; diff --git a/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java b/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java index bb1f1d495b6..723724cd4a3 100644 --- a/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java +++ b/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,8 @@ package javax.lang.model.element; +import java.io.Serial; + import javax.lang.model.UnknownEntityException; /** @@ -39,6 +41,7 @@ import javax.lang.model.UnknownEntityException; */ public class UnknownElementException extends UnknownEntityException { + @Serial private static final long serialVersionUID = 269L; private transient Element element; diff --git a/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypeException.java b/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypeException.java index 61117bc2cc6..dcf336d305b 100644 --- a/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypeException.java +++ b/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypeException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,10 +25,11 @@ package javax.lang.model.type; -import java.io.ObjectInputStream; import java.io.IOException; -import javax.lang.model.element.Element; +import java.io.ObjectInputStream; +import java.io.Serial; +import javax.lang.model.element.Element; /** * Thrown when an application attempts to access the {@link Class} object @@ -40,7 +41,8 @@ import javax.lang.model.element.Element; */ public class MirroredTypeException extends MirroredTypesException { - private static final long serialVersionUID = 269; + @Serial + private static final long serialVersionUID = 269L; private transient TypeMirror type; // cannot be serialized @@ -72,6 +74,7 @@ public class MirroredTypeException extends MirroredTypesException { * deserialization * @throws IOException for an IO problem during deserialization */ + @Serial private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); diff --git a/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypesException.java b/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypesException.java index 9fa3c5e8c3c..b89654a453c 100644 --- a/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypesException.java +++ b/src/java.compiler/share/classes/javax/lang/model/type/MirroredTypesException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,13 +25,14 @@ package javax.lang.model.type; -import java.util.ArrayList; -import java.util.List; -import java.util.Collections; -import java.io.ObjectInputStream; import java.io.IOException; -import javax.lang.model.element.Element; +import java.io.ObjectInputStream; +import java.io.Serial; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.lang.model.element.Element; /** * Thrown when an application attempts to access a sequence of {@link @@ -43,7 +44,8 @@ import javax.lang.model.element.Element; */ public class MirroredTypesException extends RuntimeException { - private static final long serialVersionUID = 269; + @Serial + private static final long serialVersionUID = 269L; transient List types; // cannot be serialized @@ -87,6 +89,7 @@ public class MirroredTypesException extends RuntimeException { * deserialization * @throws IOException for an IO problem during deserialization */ + @Serial private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); diff --git a/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java b/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java index dac3fecf86c..9127e2a4efe 100644 --- a/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java +++ b/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,8 @@ package javax.lang.model.type; +import java.io.Serial; + import javax.lang.model.UnknownEntityException; /** @@ -39,6 +41,7 @@ import javax.lang.model.UnknownEntityException; */ public class UnknownTypeException extends UnknownEntityException { + @Serial private static final long serialVersionUID = 269L; private transient TypeMirror type; From d9d00d33a6a0d540a10e0a58f6df27cae46d2753 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sat, 31 May 2025 00:26:50 +0000 Subject: [PATCH 039/216] 8358107: Rollback JDK-8357299 changeset Reviewed-by: psadhukhan --- .../share/native/libawt/java2d/loops/Blit.c | 21 ++++--- .../java/awt/Graphics/BrokenBoundsClip.java | 60 ------------------- 2 files changed, 12 insertions(+), 69 deletions(-) delete mode 100644 test/jdk/java/awt/Graphics/BrokenBoundsClip.java diff --git a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c index cbba3e4cacb..8a41584deef 100644 --- a/src/java.desktop/share/native/libawt/java2d/loops/Blit.c +++ b/src/java.desktop/share/native/libawt/java2d/loops/Blit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,16 +74,19 @@ Java_sun_java2d_loops_Blit_Blit srcInfo.bounds.x1 = srcx; srcInfo.bounds.y1 = srcy; - srcInfo.bounds.x2 = UNSAFE_TO_ADD(srcx, width) - ? clipInfo.bounds.x2 : (srcx + width); - srcInfo.bounds.y2 = UNSAFE_TO_ADD(srcy, height) - ? clipInfo.bounds.y2 : (srcy + height); + if (UNSAFE_TO_ADD(srcx, width) || + UNSAFE_TO_ADD(srcy, height) || + UNSAFE_TO_ADD(dstx, width) || + UNSAFE_TO_ADD(dsty, height)) { + return; + } + + srcInfo.bounds.x2 = srcx + width; + srcInfo.bounds.y2 = srcy + height; dstInfo.bounds.x1 = dstx; dstInfo.bounds.y1 = dsty; - dstInfo.bounds.x2 = UNSAFE_TO_ADD(dstx, width) - ? clipInfo.bounds.x2 : (dstx + width); - dstInfo.bounds.y2 = UNSAFE_TO_ADD(dsty, height) - ? clipInfo.bounds.y2 : (dsty + height); + dstInfo.bounds.x2 = dstx + width; + dstInfo.bounds.y2 = dsty + height; if (UNSAFE_TO_SUB(srcx, dstx) || UNSAFE_TO_SUB(srcy, dsty)) { return; diff --git a/test/jdk/java/awt/Graphics/BrokenBoundsClip.java b/test/jdk/java/awt/Graphics/BrokenBoundsClip.java deleted file mode 100644 index 3ba8ebe2e3f..00000000000 --- a/test/jdk/java/awt/Graphics/BrokenBoundsClip.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8357299 - * @summary Verifies if Graphics copyArea doesn't copy any pixels - * when there is overflow - * @run main BrokenBoundsClip - */ - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; - -import static java.awt.image.BufferedImage.TYPE_INT_RGB; - -public final class BrokenBoundsClip { - - public static final int SIZE = 100; - - public static void main(String[] args) { - BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB); - - Graphics2D g2d = bi.createGraphics(); - g2d.setColor(Color.RED); - g2d.fillRect(SIZE / 2, SIZE / 2, SIZE / 2, SIZE / 2); - - g2d.copyArea(bi.getWidth() / 2, bi.getHeight() / 2, - Integer.MAX_VALUE , Integer.MAX_VALUE , - -bi.getWidth() / 2, -bi.getHeight() / 2); - int actual = bi.getRGB(0, 0); - int expected = Color.RED.getRGB(); - if (actual != expected) { - System.err.println("Actual: " + Integer.toHexString(actual)); - System.err.println("Expected: " + Integer.toHexString(expected)); - throw new RuntimeException("Wrong color"); - } - } -} From c67fc735959ddd41a8d1116908ca7bae9b966016 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Sat, 31 May 2025 00:40:23 +0000 Subject: [PATCH 040/216] 8320189: vmTestbase/nsk/jvmti/scenarios/bcinstr/BI02/bi02t001 memory corruption when using -Xcheck:jni Reviewed-by: lmesnik, amenkov --- .../bcinstr/BI02/bi02t001/bi02t001.cpp | 17 +++----------- .../bcinstr/BI03/bi03t001/bi03t001.cpp | 16 +++----------- test/lib/jdk/test/lib/jvmti/jvmti_common.hpp | 22 ++++++++++++++++++- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI02/bi02t001/bi02t001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI02/bi02t001/bi02t001.cpp index ea558bc0cd4..955171446cb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI02/bi02t001/bi02t001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI02/bi02t001/bi02t001.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -49,7 +49,7 @@ const char* CLASS_NAME = "nsk/jvmti/scenarios/bcinstr/BI02/bi02t001a"; /** callback functions **/ static void JNICALL -ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env, +ClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv *jni, jclass class_being_redefined, jobject loader, const char* name, jobject protection_domain, jint class_data_len, const unsigned char* class_data, @@ -61,18 +61,7 @@ ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env, if (class_being_redefined == nullptr) { /* sent by class load */ - - if (!NSK_JNI_VERIFY(jni_env, (*new_class_data_len = - jni_env->GetArrayLength(classBytes)) > 0)) { - nsk_jvmti_setFailStatus(); - return; - } - - if (!NSK_JNI_VERIFY(jni_env, (*new_class_data = (unsigned char*) - jni_env->GetByteArrayElements(classBytes, nullptr)) != nullptr)) { - nsk_jvmti_setFailStatus(); - return; - } + *new_class_data = jni_array_to_jvmti_allocated(jvmti, jni, classBytes, new_class_data_len); } } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI03/bi03t001/bi03t001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI03/bi03t001/bi03t001.cpp index dddc47377ca..eacfe962217 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI03/bi03t001/bi03t001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI03/bi03t001/bi03t001.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -49,7 +49,7 @@ const char* CLASS_NAME = "nsk/jvmti/scenarios/bcinstr/BI03/bi03t001a"; /** callback functions **/ static void JNICALL -ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env, +ClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv *jni, jclass class_being_redefined, jobject loader, const char* name, jobject protection_domain, jint class_data_len, const unsigned char* class_data, @@ -62,17 +62,7 @@ ClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv *jni_env, if (class_being_redefined == nullptr) { /* sent by class load */ - if (!NSK_JNI_VERIFY(jni_env, (*new_class_data_len = - jni_env->GetArrayLength(classBytes)) > 0)) { - nsk_jvmti_setFailStatus(); - return; - } - - if (!NSK_JNI_VERIFY(jni_env, (*new_class_data = (unsigned char*) - jni_env->GetByteArrayElements(classBytes, nullptr)) != nullptr)) { - nsk_jvmti_setFailStatus(); - return; - } + *new_class_data = jni_array_to_jvmti_allocated(jvmti, jni, classBytes, new_class_data_len); } } } diff --git a/test/lib/jdk/test/lib/jvmti/jvmti_common.hpp b/test/lib/jdk/test/lib/jvmti/jvmti_common.hpp index 5efd58e7773..e77abb400e0 100644 --- a/test/lib/jdk/test/lib/jvmti/jvmti_common.hpp +++ b/test/lib/jdk/test/lib/jvmti/jvmti_common.hpp @@ -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 @@ -447,7 +447,27 @@ static jthread get_current_thread(jvmtiEnv *jvmti, JNIEnv* jni) { return thread; } +/* Used in a couple of nsk/jvmti/scenarios tests to convert jbyteArray to a JVMTI allocated */ +static unsigned char* jni_array_to_jvmti_allocated(jvmtiEnv *jvmti, JNIEnv *jni, jbyteArray arr, jint* len_ptr) { + unsigned char* new_arr = nullptr; + jint len = jni->GetArrayLength(arr); + if (len <= 0) { + fatal(jni, "JNI GetArrayLength returned a non-positive value"); + } + jbyte* jni_arr = jni->GetByteArrayElements(arr, nullptr); + if (jni_arr == nullptr) { + fatal(jni, "JNI GetByteArrayElements returned nullptr"); + } + jvmtiError err = jvmti->Allocate(len, &new_arr); + check_jvmti_status(jni, err, "JVMTI Allocate returned an error code"); + + memcpy(new_arr, jni_arr, (size_t)len); + jni->ReleaseByteArrayElements(arr, jni_arr, JNI_ABORT); + + *len_ptr = len; + return new_arr; +} /* Commonly used helper functions */ const char* From c62223a5af747bc5cbdd3d970dd994f74aa08834 Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Sat, 31 May 2025 00:41:16 +0000 Subject: [PATCH 041/216] 8358215: ProblemList jdk/incubator/vector/PreferredSpeciesTest.java Reviewed-by: psandoz --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index d08d148a9f8..8caa521e896 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -765,6 +765,7 @@ sun/tools/jstat/jstatLineCounts4.sh 8248691,8268211 jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586 jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-x64 +jdk/incubator/vector/PreferredSpeciesTest.java 8356634 generic-all ############################################################################ From 061b24d4f9d8635944683766532e9252c3ba0152 Mon Sep 17 00:00:00 2001 From: David Briemann Date: Sat, 31 May 2025 02:47:26 +0000 Subject: [PATCH 042/216] 8357304: [PPC64] C2: Implement MinV, MaxV and Reduction nodes Reviewed-by: mdoerr, varadam --- src/hotspot/cpu/ppc/assembler_ppc.hpp | 18 +++ src/hotspot/cpu/ppc/assembler_ppc.inline.hpp | 9 ++ src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp | 45 ++++++ src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp | 2 + src/hotspot/cpu/ppc/ppc.ad | 135 ++++++++++++++++++ .../loopopts/superword/MinMaxRed_Int.java | 4 + 6 files changed, 213 insertions(+) diff --git a/src/hotspot/cpu/ppc/assembler_ppc.hpp b/src/hotspot/cpu/ppc/assembler_ppc.hpp index 491bd107819..314517fd56a 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp @@ -591,6 +591,10 @@ class Assembler : public AbstractAssembler { XVRDPIC_OPCODE = (60u << OPCODE_SHIFT | 235u << 2), XVRDPIM_OPCODE = (60u << OPCODE_SHIFT | 249u << 2), XVRDPIP_OPCODE = (60u << OPCODE_SHIFT | 233u << 2), + XVMINSP_OPCODE = (60u << OPCODE_SHIFT | 200u << 3), + XVMINDP_OPCODE = (60u << OPCODE_SHIFT | 232u << 3), + XVMAXSP_OPCODE = (60u << OPCODE_SHIFT | 192u << 3), + XVMAXDP_OPCODE = (60u << OPCODE_SHIFT | 224u << 3), // Deliver A Random Number (introduced with POWER9) DARN_OPCODE = (31u << OPCODE_SHIFT | 755u << 1), @@ -699,15 +703,19 @@ class Assembler : public AbstractAssembler { VMAXSB_OPCODE = (4u << OPCODE_SHIFT | 258u ), VMAXSW_OPCODE = (4u << OPCODE_SHIFT | 386u ), VMAXSH_OPCODE = (4u << OPCODE_SHIFT | 322u ), + VMAXSD_OPCODE = (4u << OPCODE_SHIFT | 450u ), VMAXUB_OPCODE = (4u << OPCODE_SHIFT | 2u ), VMAXUW_OPCODE = (4u << OPCODE_SHIFT | 130u ), VMAXUH_OPCODE = (4u << OPCODE_SHIFT | 66u ), + VMAXUD_OPCODE = (4u << OPCODE_SHIFT | 194u ), VMINSB_OPCODE = (4u << OPCODE_SHIFT | 770u ), VMINSW_OPCODE = (4u << OPCODE_SHIFT | 898u ), VMINSH_OPCODE = (4u << OPCODE_SHIFT | 834u ), + VMINSD_OPCODE = (4u << OPCODE_SHIFT | 962u ), VMINUB_OPCODE = (4u << OPCODE_SHIFT | 514u ), VMINUW_OPCODE = (4u << OPCODE_SHIFT | 642u ), VMINUH_OPCODE = (4u << OPCODE_SHIFT | 578u ), + VMINUD_OPCODE = (4u << OPCODE_SHIFT | 706u ), VCMPEQUB_OPCODE= (4u << OPCODE_SHIFT | 6u ), VCMPEQUH_OPCODE= (4u << OPCODE_SHIFT | 70u ), @@ -2302,15 +2310,19 @@ class Assembler : public AbstractAssembler { inline void vmaxsb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxsw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxsh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vmaxsd( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxub( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxuw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vmaxuh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vmaxud( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminsh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vminsd( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminub( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminuw( VectorRegister d, VectorRegister a, VectorRegister b); inline void vminuh( VectorRegister d, VectorRegister a, VectorRegister b); + inline void vminud( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequb( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequh( VectorRegister d, VectorRegister a, VectorRegister b); inline void vcmpequw( VectorRegister d, VectorRegister a, VectorRegister b); @@ -2435,6 +2447,12 @@ class Assembler : public AbstractAssembler { inline void xvrdpim( VectorSRegister d, VectorSRegister b); inline void xvrdpip( VectorSRegister d, VectorSRegister b); + // The following functions do not match exactly the Java.math semantics. + inline void xvminsp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmindp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmaxsp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xvmaxdp( VectorSRegister d, VectorSRegister a, VectorSRegister b); + // VSX Extended Mnemonics inline void xxspltd( VectorSRegister d, VectorSRegister a, int x); inline void xxmrghd( VectorSRegister d, VectorSRegister a, VectorSRegister b); diff --git a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp index 176994cf92c..792e5d6d5ad 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp @@ -908,6 +908,11 @@ inline void Assembler::xvrdpic( VectorSRegister d, VectorSRegister b) inline void Assembler::xvrdpim( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIM_OPCODE | vsrt(d) | vsrb(b)); } inline void Assembler::xvrdpip( VectorSRegister d, VectorSRegister b) { emit_int32( XVRDPIP_OPCODE | vsrt(d) | vsrb(b)); } +inline void Assembler::xvminsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmindp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMINDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmaxsp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMAXSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xvmaxdp(VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMAXDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } + inline void Assembler::mtvrd( VectorRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } inline void Assembler::mfvrd( Register a, VectorRegister d) { emit_int32( MFVSRD_OPCODE | vsrt(d->to_vsr()) | ra(a)); } inline void Assembler::mtvrwz( VectorRegister d, Register a) { emit_int32( MTVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); } @@ -1022,15 +1027,19 @@ inline void Assembler::vavguh( VectorRegister d, VectorRegister a, VectorRegist inline void Assembler::vmaxsb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxsw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxsh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vmaxsd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXSD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxuw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vmaxuh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vmaxud( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMAXUD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminsh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vminsd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINSD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUB_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminuw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUW_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vminuh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUH_OPCODE | vrt(d) | vra(a) | vrb(b)); } +inline void Assembler::vminud( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMINUD_OPCODE | vrt(d) | vra(a) | vrb(b)); } inline void Assembler::vcmpequb(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUB_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } inline void Assembler::vcmpequh(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUH_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } inline void Assembler::vcmpequw(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCMPEQUW_OPCODE | vrt(d) | vra(a) | vrb(b) | vcmp_rc(0)); } diff --git a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp index 5e18be552a9..eab3df03fde 100644 --- a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.cpp @@ -619,3 +619,48 @@ void C2_MacroAssembler::count_positives(Register src, Register cnt, Register res bind(Ldone); subf(result, src, result); // Result is offset from src. } + +void C2_MacroAssembler::reduceI(int opcode, Register dst, Register iSrc, VectorRegister vSrc, + VectorRegister vTmp1, VectorRegister vTmp2) { + + auto fn_vec_op = [this](int opcode, const VectorRegister &dst, const VectorRegister &a, const VectorRegister &b) { + switch(opcode) { + case Op_AddReductionVI: vadduwm(dst, a, b); break; + case Op_MulReductionVI: vmuluwm(dst, a , b); break; + case Op_AndReductionV: vand(dst, a, b); break; + case Op_OrReductionV: vor(dst, a, b); break; + case Op_XorReductionV: vxor(dst, a, b); break; + case Op_MinReductionV: vminsw(dst, a, b); break; + case Op_MaxReductionV: vmaxsw(dst, a, b); break; + default: assert(false, "wrong opcode"); + } + }; + + auto fn_scalar_op = [this](int opcode, const Register &dst, const Register &a, const Register &b) { + switch (opcode) { + case Op_AddReductionVI: add(dst, a, b); break; + case Op_MulReductionVI: mullw(dst, a, b); break; + case Op_AndReductionV: andr(dst, a, b); break; + case Op_OrReductionV: orr(dst, a, b); break; + case Op_XorReductionV: xorr(dst, a, b); break; + case Op_MinReductionV: + cmpw(CR0, a, b); + isel(dst, CR0, Assembler::less, /*invert*/false, a, b); + break; + case Op_MaxReductionV: + cmpw(CR0, a, b); + isel(dst, CR0, Assembler::greater, /*invert*/false, a, b); + break; + default: assert(false, "wrong opcode"); + } + }; + + // vSrc = [i0,i1,i2,i3] + vsldoi(vTmp1, vSrc, vSrc, 8); // vTmp1 <- [i2,i3,i0,i1] + fn_vec_op(opcode, vTmp2, vSrc, vTmp1); // vTmp2 <- [op(i0,i2), op(i1,i3), op(i2,i0), op(i3,i1)] + vsldoi(vTmp1, vTmp2, vTmp2, 4); // vTmp1 <- [op(i1,i3), op(i2,i0), op(i3,i1), op(i0,i2)] + fn_vec_op(opcode, vTmp1, vTmp1, vTmp2); // vTmp1 <- [op(i0,i1,i2,i3), op(i0,i1,i2,i3), op(i0,i1,i2,i3), op(i0,i1,i2,i3)] + mfvsrwz(R0, vTmp1.to_vsr()); // R0 <- op(i0,i1,i2,i3) + fn_scalar_op(opcode, dst, iSrc, R0); // dst <- op(iSrc, R0) +} + diff --git a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp index 345d5a6350d..16b6d1935ba 100644 --- a/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/c2_MacroAssembler_ppc.hpp @@ -73,4 +73,6 @@ void count_positives(Register src, Register cnt, Register result, Register tmp1, Register tmp2); + void reduceI(int opcode, Register dst, Register iSrc, VectorRegister vSrc, VectorRegister vTmp1, VectorRegister vTmp2); + #endif // CPU_PPC_C2_MACROASSEMBLER_PPC_HPP diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 38bb150d6c7..128e566d0f3 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -2399,6 +2399,18 @@ bool Matcher::match_rule_supported(int opcode) { case Op_SubVL: case Op_MulVI: case Op_RoundDoubleModeV: + case Op_MinV: + case Op_MaxV: + case Op_AndV: + case Op_OrV: + case Op_XorV: + case Op_AddReductionVI: + case Op_MulReductionVI: + case Op_AndReductionV: + case Op_OrReductionV: + case Op_XorReductionV: + case Op_MinReductionV: + case Op_MaxReductionV: return SuperwordUseVSX; case Op_PopCountVI: case Op_PopCountVL: @@ -2440,6 +2452,22 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) { if (!match_rule_supported(opcode) || !vector_size_supported(bt, vlen)) { return false; } + // Special cases + switch (opcode) { + // Reductions only support INT at the moment. + case Op_AddReductionVI: + case Op_MulReductionVI: + case Op_AndReductionV: + case Op_OrReductionV: + case Op_XorReductionV: + case Op_MinReductionV: + case Op_MaxReductionV: + return bt == T_INT; + // MaxV, MinV need types == INT || LONG. + case Op_MaxV: + case Op_MinV: + return bt == T_INT || bt == T_LONG; + } return true; // Per default match rules are supported. } @@ -13485,6 +13513,113 @@ instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ ins_pipe(pipe_class_default); %} +// Vector Min / Max Instructions + +instruct vmin_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MinV src1 src2)); + format %{ "VMIN $dst,$src1,$src2\t// vector min" %} + size(4); + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + switch (bt) { + case T_INT: + __ vminsw($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + break; + case T_LONG: + __ vminsd($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + break; + default: + ShouldNotReachHere(); + } + %} + ins_pipe(pipe_class_default); +%} + +instruct vmax_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MaxV src1 src2)); + format %{ "VMAX $dst,$src1,$src2\t// vector max" %} + size(4); + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + switch (bt) { + case T_INT: + __ vmaxsw($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + break; + case T_LONG: + __ vmaxsd($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + break; + default: + ShouldNotReachHere(); + } + %} + ins_pipe(pipe_class_default); +%} + +instruct vand(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AndV src1 src2)); + size(4); + format %{ "VAND $dst,$src1,$src2\t// and vectors" %} + ins_encode %{ + __ vand($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + %} + ins_pipe(pipe_class_default); +%} + +instruct vor(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (OrV src1 src2)); + size(4); + format %{ "VOR $dst,$src1,$src2\t// or vectors" %} + ins_encode %{ + __ vor($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + %} + ins_pipe(pipe_class_default); +%} + +instruct vxor(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (XorV src1 src2)); + size(4); + format %{ "VXOR $dst,$src1,$src2\t// xor vectors" %} + ins_encode %{ + __ vxor($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); + %} + ins_pipe(pipe_class_default); +%} + +instruct reductionI_arith_logic(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2) %{ + predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT); + match(Set dst (AddReductionVI srcInt srcVec)); + match(Set dst (MulReductionVI srcInt srcVec)); + match(Set dst (AndReductionV srcInt srcVec)); + match(Set dst ( OrReductionV srcInt srcVec)); + match(Set dst (XorReductionV srcInt srcVec)); + effect(TEMP tmp1, TEMP tmp2); + ins_cost(DEFAULT_COST * 6); + format %{ "REDUCEI_ARITH_LOGIC // $dst,$srcInt,$srcVec,$tmp1,$tmp2\t// reduce vector int add/mul/and/or/xor" %} + size(24); + ins_encode %{ + int opcode = this->ideal_Opcode(); + __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorSRegister->to_vr(), + $tmp1$$VectorSRegister->to_vr(), $tmp2$$VectorSRegister->to_vr()); + %} + ins_pipe(pipe_class_default); +%} + +instruct reductionI_min_max(iRegIdst dst, iRegIsrc srcInt, vecX srcVec, vecX tmp1, vecX tmp2, flagsRegCR0 cr0) %{ + predicate(Matcher::vector_element_basic_type(n->in(2)) == T_INT); + match(Set dst (MinReductionV srcInt srcVec)); + match(Set dst (MaxReductionV srcInt srcVec)); + effect(TEMP tmp1, TEMP tmp2, KILL cr0); + ins_cost(DEFAULT_COST * 7); + format %{ "REDUCEI_MINMAX // $dst,$srcInt,$srcVec,$tmp1,$tmp2,cr0\t// reduce vector int min/max" %} + size(28); + ins_encode %{ + int opcode = this->ideal_Opcode(); + __ reduceI(opcode, $dst$$Register, $srcInt$$Register, $srcVec$$VectorSRegister->to_vr(), + $tmp1$$VectorSRegister->to_vr(), $tmp2$$VectorSRegister->to_vr()); + %} + ins_pipe(pipe_class_default); +%} + // Vector Absolute Instructions instruct vabs4F_reg(vecX dst, vecX src) %{ diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java b/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java index 54c1e4f1e46..0b84f4e346a 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java @@ -96,6 +96,8 @@ public class MinMaxRed_Int { @IR(applyIfPlatform = {"riscv64", "true"}, applyIfCPUFeature = {"rvv", "true"}, counts = {IRNode.MIN_REDUCTION_V, " > 0"}) + @IR(applyIfPlatform = {"ppc", "true"}, + counts = {IRNode.MIN_REDUCTION_V, " > 0"}) public static int minReductionImplement(int[] a, int[] b, int res) { for (int i = 0; i < a.length; i++) { res = Math.min(res, a[i] * b[i]); @@ -110,6 +112,8 @@ public class MinMaxRed_Int { @IR(applyIfPlatform = {"riscv64", "true"}, applyIfCPUFeature = {"rvv", "true"}, counts = {IRNode.MAX_REDUCTION_V, " > 0"}) + @IR(applyIfPlatform = {"ppc", "true"}, + counts = {IRNode.MAX_REDUCTION_V, " > 0"}) public static int maxReductionImplement(int[] a, int[] b, int res) { for (int i = 0; i < a.length; i++) { res = Math.max(res, a[i] * b[i]); From 19360a904b180f6608c6dcd574c77f78f1880673 Mon Sep 17 00:00:00 2001 From: Chad Rakoczy Date: Sat, 31 May 2025 02:48:33 +0000 Subject: [PATCH 043/216] 8356949: AArch64: Tighten up template interpreter method entry code Reviewed-by: aph, shade --- .../templateInterpreterGenerator_aarch64.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index af41ab3ef69..0ed064f48ba 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -865,6 +865,10 @@ void TemplateInterpreterGenerator::lock_method() { // rcpool: cp cache // stack_pointer: previous sp void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { + // Save ConstMethod* in r5_const_method for later use to avoid loading multiple times + Register r5_const_method = r5; + __ ldr(r5_const_method, Address(rmethod, Method::const_offset())); + // initialize fixed part of activation frame if (native_call) { __ sub(esp, sp, 14 * wordSize); @@ -875,8 +879,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ stp(zr, zr, Address(sp, 12 * wordSize)); } else { __ sub(esp, sp, 12 * wordSize); - __ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod - __ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase + __ add(rbcp, r5_const_method, in_bytes(ConstMethod::codes_offset())); // get codebase __ mov(rscratch1, frame::interpreter_frame_initial_sp_offset); __ stp(rscratch1, rbcp, Address(__ pre(sp, -12 * wordSize))); } @@ -896,9 +899,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { __ stp(rfp, lr, Address(sp, 10 * wordSize)); __ lea(rfp, Address(sp, 10 * wordSize)); - __ ldr(rcpool, Address(rmethod, Method::const_offset())); - __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset())); - __ ldr(rcpool, Address(rcpool, ConstantPool::cache_offset())); + // Save ConstantPool* in r11_constants for later use to avoid loading multiple times + Register r11_constants = r11; + __ ldr(r11_constants, Address(r5_const_method, ConstMethod::constants_offset())); + __ ldr(rcpool, Address(r11_constants, ConstantPool::cache_offset())); __ sub(rscratch1, rlocals, rfp); __ lsr(rscratch1, rscratch1, Interpreter::logStackElementSize); // rscratch1 = rlocals - fp(); // Store relativized rlocals, see frame::interpreter_frame_locals(). @@ -908,11 +912,12 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // leave last_sp as null __ stp(zr, r19_sender_sp, Address(sp, 8 * wordSize)); - // Get mirror - __ load_mirror(r10, rmethod, r5, rscratch2); + // Get mirror. Resolve ConstantPool* -> InstanceKlass* -> Java mirror. + __ ldr(r10, Address(r11_constants, ConstantPool::pool_holder_offset())); + __ ldr(r10, Address(r10, in_bytes(Klass::java_mirror_offset()))); + __ resolve_oop_handle(r10, rscratch1, rscratch2); if (! native_call) { - __ ldr(rscratch1, Address(rmethod, Method::const_offset())); - __ ldrh(rscratch1, Address(rscratch1, ConstMethod::max_stack_offset())); + __ ldrh(rscratch1, Address(r5_const_method, ConstMethod::max_stack_offset())); __ add(rscratch1, rscratch1, MAX2(3, Method::extra_stack_entries())); __ sub(rscratch1, sp, rscratch1, ext::uxtw, 3); __ andr(rscratch1, rscratch1, -16); From 3a3ea7e17fff100e368c956350bb9aaa2261b8a9 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sat, 31 May 2025 07:06:08 +0000 Subject: [PATCH 044/216] 8357598: Toolkit.removeAWTEventListener should handle null listener in AWTEventListenerProxy Reviewed-by: aivanov, dnguyen --- .../share/classes/java/awt/Toolkit.java | 2 +- .../AWTEventListenerProxyTest.java | 51 ++++++++++++------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Toolkit.java b/src/java.desktop/share/classes/java/awt/Toolkit.java index cc664f03cb1..d3d8fa2e268 100644 --- a/src/java.desktop/share/classes/java/awt/Toolkit.java +++ b/src/java.desktop/share/classes/java/awt/Toolkit.java @@ -1735,7 +1735,7 @@ public abstract class Toolkit { public void removeAWTEventListener(AWTEventListener listener) { AWTEventListener localL = deProxyAWTEventListener(listener); - if (listener == null) { + if (localL == null) { return; } diff --git a/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java b/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java index a2c8613efc9..3be61fd199b 100644 --- a/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java +++ b/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,7 +23,7 @@ /* @test - @bug 4290704 + @bug 4290704 8357598 @summary Test use of AWTEventListenerProxyTest class */ @@ -38,33 +38,31 @@ public class AWTEventListenerProxyTest { public static void main(String[] args) throws Exception { EventQueue.invokeAndWait(() -> { Toolkit tk = Toolkit.getDefaultToolkit(); - if ("sun.awt.X11.XToolkit".equals(tk.getClass().getName())) { - System.out.println("Do not test for XAWT Toolkit."); - System.out.println("Passing automatically."); - return; - } // check that if no listeners added, returns a 0-length array, // not null - AWTEventListener[] array1 = tk.getAWTEventListeners(); - if (array1 == null || array1.length != 0) { - System.out.println("[Empty array test failed!!]"); - throw new RuntimeException("Test failed -" + - " didn't return 0-sized array"); - } + verify(tk, 0); System.out.println("[Empty array test passed]"); + // check that if a null listener is added, returns an empty array + tk.addAWTEventListener(null, AWTEvent.ACTION_EVENT_MASK); + verify(tk, 0); + NullProxyListener nl = new NullProxyListener(); + tk.addAWTEventListener(nl, AWTEvent.ACTION_EVENT_MASK); + verify(tk, 0); + // check that if a null listener is removed, returns an empty array + tk.removeAWTEventListener(null); + verify(tk, 0); + tk.removeAWTEventListener(nl); + verify(tk, 0); + // simple add/get test DumbListener dl1 = new DumbListener(); final long dl1MASK = AWTEvent.ACTION_EVENT_MASK; tk.addAWTEventListener(dl1, dl1MASK); + verify(tk, 1); - array1 = tk.getAWTEventListeners(); - if (array1 == null || array1.length != 1) { - System.out.println("[Simple add/get test failed!!]"); - throw new RuntimeException("Test failed - didn't " + - "return array of 1"); - } + AWTEventListener[] array1 = tk.getAWTEventListeners(); AWTEventListenerProxy dp1 = (AWTEventListenerProxy) array1[0]; EventListener getdl1 = dp1.getListener(); if (getdl1 != dl1) { @@ -165,8 +163,23 @@ public class AWTEventListenerProxyTest { }); } + private static void verify(Toolkit tk, int expected) { + AWTEventListener[] array = tk.getAWTEventListeners(); + if (array == null || array.length != expected) { + System.out.println("[Simple test failed!!]"); + throw new RuntimeException( + "Test didn't return " + expected + "-sized array"); + } + } + public static class DumbListener implements AWTEventListener { public DumbListener() {} public void eventDispatched(AWTEvent e) {} } + + public final static class NullProxyListener extends AWTEventListenerProxy { + public NullProxyListener() { + super(0, null); + } + } } From 84002d12ed83c8254422fdda349aa647422d0768 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 31 May 2025 13:02:58 +0000 Subject: [PATCH 045/216] 8228773: URLClassLoader constructors should include API note warning that the parent should not be null Reviewed-by: alanb, mullan --- .../classes/java/net/URLClassLoader.java | 50 +++++++++++++++---- .../java/security/SecureClassLoader.java | 22 ++++++-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java index 90bb1c56f11..4b579554e0a 100644 --- a/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/src/java.base/share/classes/java/net/URLClassLoader.java @@ -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 @@ -77,8 +77,15 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * the URL is assumed to refer to a JAR file which will be downloaded and * opened as needed. * + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * * @param urls the URLs from which to load classes and resources - * @param parent the parent class loader for delegation + * @param parent the parent class loader for delegation, can be {@code null} + * for the bootstrap class loader * @throws NullPointerException if {@code urls} or any of its * elements is {@code null}. */ @@ -89,12 +96,12 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { /** * Constructs a new URLClassLoader for the specified URLs using the - * default delegation parent {@code ClassLoader}. The URLs will - * be searched in the order specified for classes and resources after - * first searching in the parent class loader. Any URL that ends with - * a '/' is assumed to refer to a directory. Otherwise, the URL is - * assumed to refer to a JAR file which will be downloaded and opened - * as needed. + * {@linkplain ClassLoader#getSystemClassLoader() system class loader + * as the parent}. The URLs will be searched in the order + * specified for classes and resources after first searching in the + * parent class loader. Any URL that ends with a '/' is assumed to + * refer to a directory. Otherwise, the URL is assumed to refer to + * a JAR file which will be downloaded and opened as needed. * * @param urls the URLs from which to load classes and resources * @@ -113,8 +120,15 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * factory argument will be used as the stream handler factory to * obtain protocol handlers when creating new jar URLs. * + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * * @param urls the URLs from which to load classes and resources - * @param parent the parent class loader for delegation + * @param parent the parent class loader for delegation, can be {@code null} + * for the bootstrap class loader * @param factory the URLStreamHandlerFactory to use when creating URLs * * @throws NullPointerException if {@code urls} or any of its @@ -135,9 +149,16 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * Otherwise, the URL is assumed to refer to a JAR file which will be * downloaded and opened as needed. * + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * * @param name class loader name; or {@code null} if not named * @param urls the URLs from which to load classes and resources - * @param parent the parent class loader for delegation + * @param parent the parent class loader for delegation, can be {@code null} + * for the bootstrap class loader * * @throws IllegalArgumentException if the given name is empty. * @throws NullPointerException if {@code urls} or any of its @@ -159,9 +180,16 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * The factory argument will be used as the stream handler factory to * obtain protocol handlers when creating new jar URLs. * + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * * @param name class loader name; or {@code null} if not named * @param urls the URLs from which to load classes and resources - * @param parent the parent class loader for delegation + * @param parent the parent class loader for delegation, can be {@code null} + * for the bootstrap class loader * @param factory the URLStreamHandlerFactory to use when creating URLs * * @throws IllegalArgumentException if the given name is empty. diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java index 8a6ba76e211..b398d7332d7 100644 --- a/src/java.base/share/classes/java/security/SecureClassLoader.java +++ b/src/java.base/share/classes/java/security/SecureClassLoader.java @@ -64,15 +64,22 @@ public class SecureClassLoader extends ClassLoader { * Creates a new {@code SecureClassLoader} using the specified parent * class loader for delegation. * - * @param parent the parent ClassLoader + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * + * @param parent the parent ClassLoader, can be {@code null} for the bootstrap + * class loader */ protected SecureClassLoader(ClassLoader parent) { super(parent); } /** - * Creates a new {@code SecureClassLoader} using the default parent class - * loader for delegation. + * Creates a new {@code SecureClassLoader} using the + * {@linkplain ClassLoader#getSystemClassLoader() system class loader as the parent}. */ protected SecureClassLoader() { super(); @@ -82,8 +89,15 @@ public class SecureClassLoader extends ClassLoader { * Creates a new {@code SecureClassLoader} of the specified name and * using the specified parent class loader for delegation. * + * @apiNote If {@code parent} is specified as {@code null} (for the + * bootstrap class loader) then there is no guarantee that all platform + * classes are visible. + * See {@linkplain ClassLoader##builtinLoaders Run-time Built-in Class Loaders} + * for information on the bootstrap class loader and other built-in class loaders. + * * @param name class loader name; or {@code null} if not named - * @param parent the parent class loader + * @param parent the parent class loader, can be {@code null} for the bootstrap + * class loader * * @throws IllegalArgumentException if the given name is empty. * From a3f9e222632d29982ef1463e6c391d5896524705 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 31 May 2025 16:31:24 +0000 Subject: [PATCH 046/216] 8358218: Problemlist jdk/incubator/vector/PreferredSpeciesTest.java#id0 Reviewed-by: psandoz --- test/jdk/ProblemList.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 8caa521e896..090b5eb71d7 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -765,7 +765,7 @@ sun/tools/jstat/jstatLineCounts4.sh 8248691,8268211 jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586 jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-x64 -jdk/incubator/vector/PreferredSpeciesTest.java 8356634 generic-all +jdk/incubator/vector/PreferredSpeciesTest.java#id0 8358217 generic-all ############################################################################ From fc3d3d9b303652275599e315b2d7e534d92080ea Mon Sep 17 00:00:00 2001 From: Srinivas Vamsi Parasa Date: Sat, 31 May 2025 23:07:55 +0000 Subject: [PATCH 047/216] 8351994: Enable Extended EVEX to REX2/REX demotion when src and dst are the same Reviewed-by: sviswanathan, jbhateja, epeter --- src/hotspot/cpu/x86/assembler_x86.cpp | 595 +- src/hotspot/cpu/x86/assembler_x86.hpp | 39 +- src/hotspot/cpu/x86/vm_version_x86.cpp | 12 +- src/hotspot/cpu/x86/vm_version_x86.hpp | 3 +- src/hotspot/cpu/x86/x86_64.ad | 135 - test/hotspot/gtest/x86/asmtest.out.h | 5022 ++++++++++------- test/hotspot/gtest/x86/test_assembler_x86.cpp | 2 +- test/hotspot/gtest/x86/x86-asmtest.py | 186 +- 8 files changed, 3382 insertions(+), 2612 deletions(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 84c08dda848..3fb64c8f644 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -280,15 +280,14 @@ void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { emit_int24(op1, (op2 | encode(dst)), imm8); } - -void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) { +void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32, bool optimize_rax_dst) { assert(isByte(op1) && isByte(op2), "wrong opcode"); assert(op1 == 0x81, "Unexpected opcode"); if (is8bit(imm32)) { emit_int24(op1 | 0x02, // set sign bit op2 | encode(dst), imm32 & 0xFF); - } else if (dst == rax) { + } else if (optimize_rax_dst && dst == rax) { switch (op2) { case 0xD0: emit_int8(0x15); break; // adc case 0xC0: emit_int8(0x05); break; // add @@ -307,21 +306,6 @@ void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) { } } -void Assembler::emit_arith_ndd(int op1, int op2, Register dst, int32_t imm32) { - assert(isByte(op1) && isByte(op2), "wrong opcode"); - assert(op1 == 0x81, "Unexpected opcode"); - // This code cache friendly optimization saves 3 bytes per encoding, which offsets the EVEX encoding penalty. - if (is8bit(imm32)) { - emit_int24(op1 | 0x02, // set sign bit - op2 | encode(dst), - imm32 & 0xFF); - } - else { - emit_int16(op1, (op2 | encode(dst))); - emit_int32(imm32); - } -} - // Force generation of a 4 byte immediate value even if it fits into 8bit void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) { assert(isByte(op1) && isByte(op2), "wrong opcode"); @@ -1364,7 +1348,7 @@ void Assembler::eaddl(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rax, src, imm32); } @@ -1416,7 +1400,7 @@ void Assembler::eaddl(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x01); emit_operand(src2, src1, 0); } @@ -1427,9 +1411,7 @@ void Assembler::addl(Register dst, int32_t imm32) { } void Assembler::eaddl(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xC0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x81, 0xC0, no_flags); } void Assembler::addl(Register dst, Address src) { @@ -1441,11 +1423,7 @@ void Assembler::addl(Register dst, Address src) { void Assembler::eaddl(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x03); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x03, no_flags); } void Assembler::addl(Register dst, Register src) { @@ -1457,7 +1435,7 @@ void Assembler::eaddl(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void)evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void)emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x03, 0xC0, src1, src2); } @@ -1647,7 +1625,7 @@ void Assembler::eandl(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rsp, src, imm32); } @@ -1657,9 +1635,7 @@ void Assembler::andl(Register dst, int32_t imm32) { } void Assembler::eandl(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xE0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x81, 0xE0, no_flags); } void Assembler::andl(Address dst, Register src) { @@ -1678,11 +1654,7 @@ void Assembler::andl(Register dst, Address src) { void Assembler::eandl(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x23); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x23, no_flags); } void Assembler::andl(Register dst, Register src) { @@ -1694,7 +1666,7 @@ void Assembler::eandl(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x23, 0xC0, src1, src2); } @@ -1841,9 +1813,7 @@ void Assembler::cmovl(Condition cc, Register dst, Register src) { } void Assembler::ecmovl(Condition cc, Register dst, Register src1, Register src2) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); - emit_int16((0x40 | cc), (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x40 | cc, false /* no_flags */, true /* is_map1 */, true /* swap */); } void Assembler::cmovl(Condition cc, Register dst, Address src) { @@ -1855,11 +1825,7 @@ void Assembler::cmovl(Condition cc, Register dst, Address src) { void Assembler::ecmovl(Condition cc, Register dst, Register src1, Address src2) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); - emit_int8((0x40 | cc)); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, (0x40 | cc) , false /* no_flags */, true /* is_map1 */); } void Assembler::cmpb(Address dst, Register reg) { @@ -2029,7 +1995,7 @@ void Assembler::crc32(Register crc, Register v, int8_t sizeInBytes) { assert(VM_Version::supports_sse4_2(), ""); if (needs_eevex(crc, v)) { InstructionAttr attributes(AVX_128bit, /* rex_w */ sizeInBytes == 8, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = vex_prefix_and_encode(crc->encoding(), 0, v->encoding(), sizeInBytes == 2 ? VEX_SIMD_66 : VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, true); + int encode = vex_prefix_and_encode(crc->encoding(), 0, v->encoding(), sizeInBytes == 2 ? VEX_SIMD_66 : VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, true); emit_int16(sizeInBytes == 1 ? (unsigned char)0xF0 : (unsigned char)0xF1, (0xC0 | encode)); } else { int8_t w = 0x01; @@ -2076,7 +2042,7 @@ void Assembler::crc32(Register crc, Address adr, int8_t sizeInBytes) { if (needs_eevex(crc, adr.base(), adr.index())) { InstructionAttr attributes(AVX_128bit, /* vex_w */ sizeInBytes == 8, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - vex_prefix(adr, 0, crc->encoding(), sizeInBytes == 2 ? VEX_SIMD_66 : VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + vex_prefix(adr, 0, crc->encoding(), sizeInBytes == 2 ? VEX_SIMD_66 : VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes); emit_int8(sizeInBytes == 1 ? (unsigned char)0xF0 : (unsigned char)0xF1); emit_operand(crc, adr, 0); } else { @@ -2473,7 +2439,7 @@ void Assembler::edecl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xFF); emit_operand(rcx, src, 0); } @@ -2521,7 +2487,7 @@ void Assembler::idivl(Register src) { void Assembler::eidivl(Register src, bool no_flags) { // Signed InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xF8 | encode)); } @@ -2532,7 +2498,7 @@ void Assembler::divl(Register src) { // Unsigned void Assembler::edivl(Register src, bool no_flags) { // Unsigned InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xF0 | encode)); } @@ -2543,7 +2509,7 @@ void Assembler::imull(Register src) { void Assembler::eimull(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xE8 | encode)); } @@ -2553,9 +2519,7 @@ void Assembler::imull(Register dst, Register src) { } void Assembler::eimull(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int16((unsigned char)0xAF, (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */); } void Assembler::imull(Register dst, Address src, int32_t value) { @@ -2576,7 +2540,7 @@ void Assembler::eimull(Register dst, Address src, int32_t value, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (is8bit(value)) { emit_int8((unsigned char)0x6B); emit_operand(dst, src, 1); @@ -2600,7 +2564,7 @@ void Assembler::imull(Register dst, Register src, int value) { void Assembler::eimull(Register dst, Register src, int value, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (is8bit(value)) { emit_int24(0x6B, (0xC0 | encode), value & 0xFF); } else { @@ -2618,11 +2582,7 @@ void Assembler::imull(Register dst, Address src) { void Assembler::eimull(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8((unsigned char)0xAF); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, (unsigned char)0xAF, no_flags, true /* is_map1 */); } void Assembler::incl(Address dst) { @@ -2638,7 +2598,7 @@ void Assembler::eincl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xFF); emit_operand(rax, src, 0); } @@ -2830,7 +2790,7 @@ void Assembler::lzcntl(Register dst, Register src) { void Assembler::elzcntl(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF5, (0xC0 | encode)); } @@ -2848,7 +2808,7 @@ void Assembler::elzcntl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF5); emit_operand(dst, src, 0); } @@ -4066,7 +4026,7 @@ void Assembler::emull(Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF7); emit_operand(rsp, src, 0); } @@ -4078,7 +4038,7 @@ void Assembler::mull(Register src) { void Assembler::emull(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xE0 | encode)); } @@ -4121,7 +4081,7 @@ void Assembler::negl(Register dst) { void Assembler::enegl(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xD8 | encode)); } @@ -4136,7 +4096,7 @@ void Assembler::enegl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF7); emit_operand(as_Register(3), src, 0); } @@ -4454,7 +4414,7 @@ void Assembler::notl(Register dst) { void Assembler::enotl(Register dst, Register src) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes); emit_int16((unsigned char)0xF7, (0xD0 | encode)); } @@ -4462,7 +4422,7 @@ void Assembler::eorw(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x0B, 0xC0, src1, src2); } @@ -4476,7 +4436,7 @@ void Assembler::eorl(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rcx, src, imm32); } @@ -4486,9 +4446,7 @@ void Assembler::orl(Register dst, int32_t imm32) { } void Assembler::eorl(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xC8, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x81, 0xC8, no_flags); } void Assembler::orl(Register dst, Address src) { @@ -4500,11 +4458,7 @@ void Assembler::orl(Register dst, Address src) { void Assembler::eorl(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x0B); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x0B, no_flags); } void Assembler::orl(Register dst, Register src) { @@ -4516,7 +4470,7 @@ void Assembler::eorl(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x0B, 0xC0, src1, src2); } @@ -4531,7 +4485,7 @@ void Assembler::eorl(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x09); emit_operand(src2, src1, 0); } @@ -4548,7 +4502,7 @@ void Assembler::eorb(Register dst, Address src, int imm8, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0x80); emit_operand(rcx, src, 1); emit_int8(imm8); @@ -4565,7 +4519,7 @@ void Assembler::eorb(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x08); emit_operand(src2, src1, 0); } @@ -5693,7 +5647,7 @@ void Assembler::epopcntl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0x88); emit_operand(dst, src, 0); } @@ -5708,7 +5662,7 @@ void Assembler::popcntl(Register dst, Register src) { void Assembler::epopcntl(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_popcnt(), "must support"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0x88, (0xC0 | encode)); } @@ -6259,7 +6213,7 @@ void Assembler::rcll(Register dst, int imm8) { void Assembler::ercll(Register dst, Register src, int imm8) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xD0 | encode)); } else { @@ -6342,7 +6296,7 @@ void Assembler::roll(Register dst, int imm8) { void Assembler::eroll(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xC0 | encode)); } else { @@ -6357,7 +6311,7 @@ void Assembler::roll(Register dst) { void Assembler::eroll(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xC0 | encode)); } @@ -6374,7 +6328,7 @@ void Assembler::rorl(Register dst, int imm8) { void Assembler::erorl(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xC8 | encode)); } else { @@ -6389,7 +6343,7 @@ void Assembler::rorl(Register dst) { void Assembler::erorl(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xC8 | encode)); } @@ -6400,7 +6354,7 @@ void Assembler::rorq(Register dst) { void Assembler::erorq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xC8 | encode)); } @@ -6417,7 +6371,7 @@ void Assembler::rorq(Register dst, int imm8) { void Assembler::erorq(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xC8 | encode)); } else { @@ -6432,7 +6386,7 @@ void Assembler::rolq(Register dst) { void Assembler::erolq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xC0 | encode)); } @@ -6449,7 +6403,7 @@ void Assembler::rolq(Register dst, int imm8) { void Assembler::erolq(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xC0 | encode)); } else { @@ -6477,7 +6431,7 @@ void Assembler::esall(Register dst, Address src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(4), src, 0); @@ -6500,7 +6454,7 @@ void Assembler::esall(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(4), src, 0); } @@ -6518,7 +6472,7 @@ void Assembler::sall(Register dst, int imm8) { void Assembler::esall(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xE0 | encode)); } else { @@ -6533,7 +6487,7 @@ void Assembler::sall(Register dst) { void Assembler::esall(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xE0 | encode)); } @@ -6557,7 +6511,7 @@ void Assembler::esarl(Register dst, Address src, int imm8, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(7), src, 0); @@ -6580,7 +6534,7 @@ void Assembler::esarl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(7), src, 0); } @@ -6598,7 +6552,7 @@ void Assembler::sarl(Register dst, int imm8) { void Assembler::esarl(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xF8 | encode)); } else { @@ -6613,7 +6567,7 @@ void Assembler::sarl(Register dst) { void Assembler::esarl(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xF8 | encode)); } @@ -6754,7 +6708,7 @@ void Assembler::shll(Register dst, int imm8) { void Assembler::eshll(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1 ) { emit_int16((unsigned char)0xD1, (0xE0 | encode)); } else { @@ -6769,7 +6723,7 @@ void Assembler::shll(Register dst) { void Assembler::eshll(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xE0 | encode)); } @@ -6787,7 +6741,7 @@ void Assembler::shrl(Register dst, int imm8) { void Assembler::eshrl(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xE8 | encode)); } @@ -6803,7 +6757,7 @@ void Assembler::shrl(Register dst) { void Assembler::eshrl(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xD3, (0xE8 | encode)); } @@ -6818,7 +6772,7 @@ void Assembler::eshrl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(5), src, 0); } @@ -6843,7 +6797,7 @@ void Assembler::eshrl(Register dst, Address src, int imm8, bool no_flags) { assert(isShiftCount(imm8), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(5), src, 0); @@ -6861,11 +6815,7 @@ void Assembler::shldl(Register dst, Register src) { } void Assembler::eshldl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int16(0xA5, (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0xA5, no_flags, true /* is_map1 */); } void Assembler::shldl(Register dst, Register src, int8_t imm8) { @@ -6874,11 +6824,7 @@ void Assembler::shldl(Register dst, Register src, int8_t imm8) { } void Assembler::eshldl(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int24(0x24, (0xC0 | encode), imm8); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), imm8, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x24, no_flags, true /* is_map1 */); } void Assembler::shrdl(Register dst, Register src) { @@ -6887,11 +6833,7 @@ void Assembler::shrdl(Register dst, Register src) { } void Assembler::eshrdl(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int16(0xAD, (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0xAD, no_flags, true /* is_map1 */); } void Assembler::shrdl(Register dst, Register src, int8_t imm8) { @@ -6900,11 +6842,7 @@ void Assembler::shrdl(Register dst, Register src, int8_t imm8) { } void Assembler::eshrdl(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int24(0x2C, (0xC0 | encode), imm8); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), imm8, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x2C, no_flags, true /* is_map1 */); } void Assembler::shldq(Register dst, Register src, int8_t imm8) { @@ -6913,11 +6851,7 @@ void Assembler::shldq(Register dst, Register src, int8_t imm8) { } void Assembler::eshldq(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int24(0x24, (0xC0 | encode), imm8); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), imm8, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x24, no_flags, true /* is_map1 */); } void Assembler::shrdq(Register dst, Register src, int8_t imm8) { @@ -6926,11 +6860,7 @@ void Assembler::shrdq(Register dst, Register src, int8_t imm8) { } void Assembler::eshrdq(Register dst, Register src1, Register src2, int8_t imm8, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - int encode = evex_prefix_and_encode_ndd(src2->encoding(), dst->encoding(), src1->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int24(0x2C, (0xC0 | encode), imm8); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), imm8, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x2C, no_flags, true /* is_map1 */); } // copies a single word from [esi] to [edi] @@ -7020,7 +6950,7 @@ void Assembler::esubl(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rbp, src, imm32); } @@ -7035,7 +6965,7 @@ void Assembler::esubl(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x29); emit_operand(src2, src1, 0); } @@ -7046,9 +6976,7 @@ void Assembler::subl(Register dst, int32_t imm32) { } void Assembler::esubl(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xE8, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x81, 0xE8, no_flags); } // Force generation of a 4 byte immediate value even if it fits into 8bit @@ -7059,7 +6987,7 @@ void Assembler::subl_imm32(Register dst, int32_t imm32) { void Assembler::esubl_imm32(Register dst, Register src, int32_t imm32, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_imm32(0x81, 0xE8, src, imm32); } @@ -7072,11 +7000,7 @@ void Assembler::subl(Register dst, Address src) { void Assembler::esubl(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x2B); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x2B, no_flags); } void Assembler::subl(Register dst, Register src) { @@ -7088,7 +7012,7 @@ void Assembler::esubl(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x2B, 0xC0, src1, src2); } @@ -7193,7 +7117,7 @@ void Assembler::tzcntl(Register dst, Register src) { void Assembler::etzcntl(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF4, (0xC0 | encode)); } @@ -7211,7 +7135,7 @@ void Assembler::etzcntl(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF4); emit_operand(dst, src, 0); } @@ -7226,7 +7150,7 @@ void Assembler::tzcntq(Register dst, Register src) { void Assembler::etzcntq(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF4, (0xC0 | encode)); } @@ -7244,7 +7168,7 @@ void Assembler::etzcntq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF4); emit_operand(dst, src, 0); } @@ -7368,7 +7292,7 @@ void Assembler::exorl(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, as_Register(6), src, imm32); } @@ -7378,9 +7302,7 @@ void Assembler::xorl(Register dst, int32_t imm32) { } void Assembler::exorl(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xF0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x81, 0xF0, no_flags); } void Assembler::xorl(Register dst, Address src) { @@ -7392,11 +7314,7 @@ void Assembler::xorl(Register dst, Address src) { void Assembler::exorl(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x33); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_32bit, 0x33, no_flags); } void Assembler::xorl(Register dst, Register src) { @@ -7408,7 +7326,7 @@ void Assembler::exorl(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith(0x33, 0xC0, src1, src2); } @@ -7423,7 +7341,7 @@ void Assembler::exorl(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x31); emit_operand(src2, src1, 0); } @@ -7437,11 +7355,7 @@ void Assembler::xorb(Register dst, Address src) { void Assembler::exorb(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x32); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_8bit, 0x32, no_flags); } void Assembler::xorb(Address dst, Register src) { @@ -7455,7 +7369,7 @@ void Assembler::exorb(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_8bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x30); emit_operand(src2, src1, 0); } @@ -7470,13 +7384,7 @@ void Assembler::xorw(Register dst, Address src) { void Assembler::exorw(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_16bit); - // NDD shares its encoding bits with NDS bits for regular EVEX instruction. - // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_66, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x33); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_16bit, 0x33, no_flags); } // AVX 3-operands scalar float-point arithmetic instructions @@ -12977,12 +12885,35 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix } } -void Assembler::evex_prefix_ndd(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags) { +void Assembler::eevex_prefix_ndd(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags) { attributes->set_is_evex_instruction(); vex_prefix(adr, ndd_enc, xreg_enc, pre, opc, attributes, /* nds_is_ndd */ true, no_flags); } -void Assembler::evex_prefix_nf(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags) { +void Assembler::emit_eevex_or_demote(Register dst, Register src1, Address src2, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1) { + if (is_demotable(no_flags, dst->encoding(), src1->encoding())) { + if (size == EVEX_64bit) { + emit_prefix_and_int8(get_prefixq(src2, dst, is_map1), opcode_byte); + } else { + // For 32-bit, 16-bit and 8-bit + if (size == EVEX_16bit) { + emit_int8(0x66); + } + prefix(src2, dst, false, is_map1); + emit_int8(opcode_byte); + } + } else { + bool vex_w = (size == EVEX_64bit) ? true : false; + InstructionAttr attributes(AVX_128bit, vex_w, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, size); + eevex_prefix_ndd(src2, dst->encoding(), src1->encoding(), pre, opc, &attributes, no_flags); + emit_int8(opcode_byte); + } + emit_operand(src1, src2, 0); +} + +void Assembler::eevex_prefix_nf(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags) { attributes->set_is_evex_instruction(); vex_prefix(adr, ndd_enc, xreg_enc, pre, opc, attributes, /* nds_is_ndd */ false, no_flags); } @@ -13044,18 +12975,98 @@ int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexS return (((dst_enc & 7) << 3) | (src_enc & 7)); } -int Assembler::evex_prefix_and_encode_ndd(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, - InstructionAttr *attributes, bool no_flags) { +void Assembler::emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, int8_t imm8, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1) { + bool is_prefixq = (size == EVEX_64bit) ? true : false; + if (is_demotable(no_flags, dst_enc, nds_enc)) { + int encode = is_prefixq ? prefixq_and_encode(src_enc, dst_enc, is_map1) : prefix_and_encode(src_enc, dst_enc, is_map1); + emit_opcode_prefix_and_encoding((unsigned char)(opcode_byte | 0x80), 0xC0, encode, imm8); + } else { + InstructionAttr attributes(AVX_128bit, is_prefixq, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, size); + int encode = emit_eevex_prefix_or_demote_ndd(src_enc, dst_enc, nds_enc, pre, opc, &attributes, no_flags); + emit_int24(opcode_byte, (0xC0 | encode), imm8); + } +} + +void Assembler::emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1, bool swap) { + int encode; + bool is_prefixq = (size == EVEX_64bit) ? true : false; + if (is_demotable(no_flags, dst_enc, nds_enc)) { + if (size == EVEX_16bit) { + emit_int8(0x66); + } + + if (swap) { + encode = is_prefixq ? prefixq_and_encode(dst_enc, src_enc, is_map1) : prefix_and_encode(dst_enc, src_enc, is_map1); + } else { + encode = is_prefixq ? prefixq_and_encode(src_enc, dst_enc, is_map1) : prefix_and_encode(src_enc, dst_enc, is_map1); + } + emit_opcode_prefix_and_encoding((unsigned char)opcode_byte, 0xC0, encode); + } else { + InstructionAttr attributes(AVX_128bit, is_prefixq, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_is_evex_instruction(); + if (swap) { + encode = vex_prefix_and_encode(nds_enc, dst_enc, src_enc, pre, opc, &attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); + } else { + encode = vex_prefix_and_encode(src_enc, dst_enc, nds_enc, pre, opc, &attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); + } + emit_int16(opcode_byte, (0xC0 | encode)); + } +} + +int Assembler::emit_eevex_prefix_or_demote_ndd(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags, bool use_prefixq) { + if (is_demotable(no_flags, dst_enc, nds_enc)) { + if (pre == VEX_SIMD_66) { + emit_int8(0x66); + } + return use_prefixq ? prefixq_and_encode(dst_enc, src_enc) : prefix_and_encode(dst_enc, src_enc); + } attributes->set_is_evex_instruction(); return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); } -int Assembler::evex_prefix_and_encode_nf(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, - InstructionAttr *attributes, bool no_flags) { +int Assembler::emit_eevex_prefix_or_demote_ndd(int dst_enc, int nds_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags, bool use_prefixq) { + //Demote RegReg and RegRegImm instructions + if (is_demotable(no_flags, dst_enc, nds_enc)) { + return use_prefixq ? prefixq_and_encode(dst_enc) : prefix_and_encode(dst_enc); + } + attributes->set_is_evex_instruction(); + return vex_prefix_and_encode(0, dst_enc, nds_enc, pre, opc, attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); +} + +int Assembler::emit_eevex_prefix_ndd(int dst_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags) { + attributes->set_is_evex_instruction(); + return vex_prefix_and_encode(0, 0, dst_enc, pre, opc, attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); +} + +int Assembler::eevex_prefix_and_encode_nf(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags) { attributes->set_is_evex_instruction(); return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, attributes, /* src_is_gpr */ true, /* nds_is_ndd */ false, no_flags); } +void Assembler::emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register nds, int32_t imm32, VexSimdPrefix pre, VexOpcode opc, + int size, int op1, int op2, bool no_flags) { + int dst_enc = dst->encoding(); + int nds_enc = nds->encoding(); + bool demote = is_demotable(no_flags, dst_enc, nds_enc); + if (demote) { + (size == EVEX_64bit) ? (void) prefixq_and_encode(dst_enc) : (void) prefix_and_encode(dst_enc); + } else { + bool vex_w = (size == EVEX_64bit) ? true : false; + InstructionAttr attributes(AVX_128bit, vex_w, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + //attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, size); + attributes.set_is_evex_instruction(); + vex_prefix_and_encode(0, dst_enc, nds_enc, pre, opc, &attributes, /* src_is_gpr */ true, /* nds_is_ndd */ true, no_flags); + + } + emit_arith(op1, op2, nds, imm32, demote); +} + void Assembler::simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) { if (UseAVX > 0) { @@ -13081,6 +13092,10 @@ int Assembler::simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegis } } +bool Assembler::is_demotable(bool no_flags, int dst_enc, int nds_enc) { + return (!no_flags && dst_enc == nds_enc); +} + void Assembler::vmaxss(XMMRegister dst, XMMRegister nds, XMMRegister src) { assert(VM_Version::supports_avx(), ""); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); @@ -14515,7 +14530,7 @@ void Assembler::eaddq(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rax, src, imm32); } @@ -14529,7 +14544,7 @@ void Assembler::eaddq(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x01); emit_operand(src2, src1, 0); } @@ -14540,9 +14555,7 @@ void Assembler::addq(Register dst, int32_t imm32) { } void Assembler::eaddq(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xC0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x81, 0xC0, no_flags); } void Assembler::addq(Register dst, Address src) { @@ -14553,11 +14566,7 @@ void Assembler::addq(Register dst, Address src) { void Assembler::eaddq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x03); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x03, no_flags); } void Assembler::addq(Register dst, Register src) { @@ -14569,7 +14578,7 @@ void Assembler::eaddq(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith(0x03, 0xC0, src1, src2); } @@ -14577,7 +14586,7 @@ void Assembler::adcxq(Register dst, Register src) { //assert(VM_Version::supports_adx(), "adx instructions not supported"); if (needs_rex2(dst, src)) { InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C, &attributes, true); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, true); emit_int16((unsigned char)0x66, (0xC0 | encode)); } else { emit_int8(0x66); @@ -14590,16 +14599,19 @@ void Assembler::adcxq(Register dst, Register src) { } void Assembler::eadcxq(Register dst, Register src1, Register src2) { - InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C, &attributes); - emit_int16((unsigned char)0x66, (0xC0 | encode)); + if (is_demotable(false, dst->encoding(), src1->encoding())) { + return adcxq(dst, src2); + } + InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, false /* no_flags */, true /* use_prefixq */); + emit_int16((unsigned char)0x66, (0xC0 | encode)); } void Assembler::adoxq(Register dst, Register src) { //assert(VM_Version::supports_adx(), "adx instructions not supported"); if (needs_rex2(dst, src)) { InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_3C, &attributes, true); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, true); emit_int16((unsigned char)0x66, (0xC0 | encode)); } else { emit_int8((unsigned char)0xF3); @@ -14612,9 +14624,12 @@ void Assembler::adoxq(Register dst, Register src) { } void Assembler::eadoxq(Register dst, Register src1, Register src2) { - InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_3C, &attributes); - emit_int16((unsigned char)0x66, (0xC0 | encode)); + if (is_demotable(false, dst->encoding(), src1->encoding())) { + return adoxq(dst, src2); + } + InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, false /* no_flags */, true /* use_prefixq */); + emit_int16((unsigned char)0x66, (0xC0 | encode)); } void Assembler::andq(Address dst, int32_t imm32) { @@ -14627,7 +14642,7 @@ void Assembler::eandq(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, as_Register(4), src, imm32); } @@ -14637,9 +14652,7 @@ void Assembler::andq(Register dst, int32_t imm32) { } void Assembler::eandq(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xE0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x81, 0xE0, no_flags); } void Assembler::andq(Register dst, Address src) { @@ -14650,11 +14663,7 @@ void Assembler::andq(Register dst, Address src) { void Assembler::eandq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x23); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x23, no_flags); } void Assembler::andq(Register dst, Register src) { @@ -14666,7 +14675,7 @@ void Assembler::eandq(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith(0x23, 0xC0, src1, src2); } @@ -14680,7 +14689,7 @@ void Assembler::eandq(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x21); emit_operand(src2, src1, 0); } @@ -14819,9 +14828,7 @@ void Assembler::cmovq(Condition cc, Register dst, Register src) { } void Assembler::ecmovq(Condition cc, Register dst, Register src1, Register src2) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); - emit_int16((0x40 | cc), (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x40 | cc, false /* no_flags */, true /* is_map1 */, true /* swap */); } void Assembler::cmovq(Condition cc, Register dst, Address src) { @@ -14833,11 +14840,7 @@ void Assembler::cmovq(Condition cc, Register dst, Address src) { void Assembler::ecmovq(Condition cc, Register dst, Register src1, Address src2) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); - emit_int8((0x40 | cc)); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, (0x40 | cc) , false /* no_flags */, true /* is_map1 */); } void Assembler::cmpq(Address dst, int32_t imm32) { @@ -14936,7 +14939,7 @@ void Assembler::decl(Register dst) { void Assembler::edecl(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xFF, (0xC8 | encode)); } @@ -14949,7 +14952,7 @@ void Assembler::decq(Register dst) { void Assembler::edecq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xFF, (0xC8 | encode)); } @@ -14964,7 +14967,7 @@ void Assembler::edecq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xFF); emit_operand(rcx, src, 0); } @@ -15004,7 +15007,7 @@ void Assembler::idivq(Register src) { void Assembler::eidivq(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xF8 | encode)); } @@ -15015,7 +15018,7 @@ void Assembler::divq(Register src) { void Assembler::edivq(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xF0 | encode)); } @@ -15025,15 +15028,16 @@ void Assembler::imulq(Register dst, Register src) { } void Assembler::eimulq(Register dst, Register src, bool no_flags) { + if (is_demotable(no_flags, dst->encoding(), src->encoding())) { + return imulq(dst); + } InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xAF, (0xC0 | encode)); } void Assembler::eimulq(Register dst, Register src1, Register src2, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int16((unsigned char)0xAF, (0xC0 | encode)); + emit_eevex_or_demote(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0xAF, no_flags, true /* is_map1 */, true /* swap */); } void Assembler::imulq(Register src) { @@ -15043,7 +15047,7 @@ void Assembler::imulq(Register src) { void Assembler::eimulq(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xE8 | encode)); } @@ -15065,7 +15069,7 @@ void Assembler::eimulq(Register dst, Address src, int32_t value, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (is8bit(value)) { emit_int8((unsigned char)0x6B); emit_operand(dst, src, 1); @@ -15089,7 +15093,7 @@ void Assembler::imulq(Register dst, Register src, int value) { void Assembler::eimulq(Register dst, Register src, int value, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (is8bit(value)) { emit_int24(0x6B, (0xC0 | encode), (value & 0xFF)); } else { @@ -15109,7 +15113,7 @@ void Assembler::eimulq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xAF); emit_operand(dst, src, 0); @@ -15117,11 +15121,7 @@ void Assembler::eimulq(Register dst, Address src, bool no_flags) { void Assembler::eimulq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_32bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8((unsigned char)0xAF); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, (unsigned char)0xAF, no_flags, true /* is_map1 */); } void Assembler::incl(Register dst) { @@ -15135,8 +15135,7 @@ void Assembler::eincl(Register dst, Register src, bool no_flags) { // Don't use it directly. Use MacroAssembler::incrementl() instead. // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - // int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xFF, (0xC0 | encode)); } @@ -15151,7 +15150,7 @@ void Assembler::eincq(Register dst, Register src, bool no_flags) { // Don't use it directly. Use MacroAssembler::incrementq() instead. // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xFF, (0xC0 | encode)); } @@ -15167,7 +15166,7 @@ void Assembler::eincq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char) 0xFF); emit_operand(rax, src, 0); } @@ -15243,7 +15242,7 @@ void Assembler::lzcntq(Register dst, Register src) { void Assembler::elzcntq(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF5, (0xC0 | encode)); } @@ -15261,7 +15260,7 @@ void Assembler::elzcntq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF5); emit_operand(dst, src, 0); } @@ -15388,7 +15387,7 @@ void Assembler::emulq(Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_nf(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0xF7); emit_operand(rsp, src, 0); } @@ -15400,7 +15399,7 @@ void Assembler::mulq(Register src) { void Assembler::emulq(Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(0, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0xF7, (0xE0 | encode)); } @@ -15418,7 +15417,7 @@ void Assembler::negq(Register dst) { void Assembler::enegq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xF7, (0xD8 | encode)); } @@ -15432,7 +15431,7 @@ void Assembler::enegq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xF7); emit_operand(as_Register(3), src, 0); } @@ -15444,7 +15443,7 @@ void Assembler::notq(Register dst) { void Assembler::enotq(Register dst, Register src) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, false /* no_flags */, true /* use_prefixq */); emit_int16((unsigned char)0xF7, (0xD0 | encode)); } @@ -15488,7 +15487,7 @@ void Assembler::eorq(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, as_Register(1), src, imm32); } @@ -15502,7 +15501,7 @@ void Assembler::eorq(Register dst, Address src1, Register src2, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x09); emit_operand(src2, src1, 0); } @@ -15513,9 +15512,7 @@ void Assembler::orq(Register dst, int32_t imm32) { } void Assembler::eorq(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xC8, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x81, 0xC8, no_flags); } void Assembler::orq_imm32(Register dst, int32_t imm32) { @@ -15525,7 +15522,7 @@ void Assembler::orq_imm32(Register dst, int32_t imm32) { void Assembler::eorq_imm32(Register dst, Register src, int32_t imm32, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith_imm32(0x81, 0xC8, src, imm32); } @@ -15537,11 +15534,7 @@ void Assembler::orq(Register dst, Address src) { void Assembler::eorq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x0B); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x0B, no_flags); } void Assembler::orq(Register dst, Register src) { @@ -15553,7 +15546,7 @@ void Assembler::eorq(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith(0x0B, 0xC0, src1, src2); } @@ -15570,7 +15563,7 @@ void Assembler::epopcntq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_nf(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char) 0x88); emit_operand(dst, src, 0); } @@ -15585,7 +15578,7 @@ void Assembler::popcntq(Register dst, Register src) { void Assembler::epopcntq(Register dst, Register src, bool no_flags) { assert(VM_Version::supports_popcnt(), "must support"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = eevex_prefix_and_encode_nf(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int16((unsigned char)0x88, (0xC0 | encode)); } @@ -15810,7 +15803,7 @@ void Assembler::rclq(Register dst, int imm8) { void Assembler::erclq(Register dst, Register src, int imm8) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, false /* no_flags */, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xD0 | encode)); } else { @@ -15831,7 +15824,7 @@ void Assembler::rcrq(Register dst, int imm8) { void Assembler::ercrq(Register dst, Register src, int imm8) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, false /* no_flags */, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xD8 | encode)); } else { @@ -15894,7 +15887,7 @@ void Assembler::esalq(Register dst, Address src, int imm8, bool no_flags) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(4), src, 0); @@ -15916,7 +15909,7 @@ void Assembler::esalq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(4), src, 0); } @@ -15934,7 +15927,7 @@ void Assembler::salq(Register dst, int imm8) { void Assembler::esalq(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xE0 | encode)); } else { @@ -15949,7 +15942,7 @@ void Assembler::salq(Register dst) { void Assembler::esalq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xE0 | encode)); } @@ -15972,7 +15965,7 @@ void Assembler::esarq(Register dst, Address src, int imm8, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(7), src, 0); @@ -15994,7 +15987,7 @@ void Assembler::esarq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(7), src, 0); } @@ -16011,7 +16004,7 @@ void Assembler::sarq(Register dst, int imm8) { void Assembler::esarq(Register dst, Register src, int imm8, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xF8 | encode)); } else { @@ -16026,7 +16019,7 @@ void Assembler::sarq(Register dst) { void Assembler::esarq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xF8 | encode)); } @@ -16065,7 +16058,7 @@ void Assembler::shlq(Register dst, int imm8) { void Assembler::eshlq(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1 ) { emit_int16((unsigned char)0xD1, (0xE0 | encode)); } else { @@ -16080,7 +16073,7 @@ void Assembler::shlq(Register dst) { void Assembler::eshlq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xE0 | encode)); } @@ -16098,7 +16091,7 @@ void Assembler::shrq(Register dst, int imm8) { void Assembler::eshrq(Register dst, Register src, int imm8, bool no_flags) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); if (imm8 == 1) { emit_int16((unsigned char)0xD1, (0xE8 | encode)); } @@ -16114,7 +16107,7 @@ void Assembler::shrq(Register dst) { void Assembler::eshrq(Register dst, Register src, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - int encode = evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + int encode = emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_int16((unsigned char)0xD3, (0xE8 | encode)); } @@ -16128,7 +16121,7 @@ void Assembler::eshrq(Register dst, Address src, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8((unsigned char)0xD3); emit_operand(as_Register(5), src, 0); } @@ -16152,7 +16145,7 @@ void Assembler::eshrq(Register dst, Address src, int imm8, bool no_flags) { assert(isShiftCount(imm8 >> 1), "illegal shift count"); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); if (imm8 == 1) { emit_int8((unsigned char)0xD1); emit_operand(as_Register(5), src, 0); @@ -16174,7 +16167,7 @@ void Assembler::esubq(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, rbp, src, imm32); } @@ -16188,7 +16181,7 @@ void Assembler::esubq(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x29); emit_operand(src2, src1, 0); } @@ -16199,9 +16192,7 @@ void Assembler::subq(Register dst, int32_t imm32) { } void Assembler::esubq(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xE8, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x81, 0xE8, no_flags); } // Force generation of a 4 byte immediate value even if it fits into 8bit @@ -16212,7 +16203,7 @@ void Assembler::subq_imm32(Register dst, int32_t imm32) { void Assembler::esubq_imm32(Register dst, Register src, int32_t imm32, bool no_flags) { InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - (void) evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith_imm32(0x81, 0xE8, src, imm32); } @@ -16224,11 +16215,7 @@ void Assembler::subq(Register dst, Address src) { void Assembler::esubq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x2B); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x2B, no_flags); } void Assembler::subq(Register dst, Register src) { @@ -16240,7 +16227,7 @@ void Assembler::esubq(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith(0x2B, 0xC0, src1, src2); } @@ -16305,7 +16292,7 @@ void Assembler::exorq(Register dst, Register src1, Register src2, bool no_flags) InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // NDD shares its encoding bits with NDS bits for regular EVEX instruction. // Therefore, DST is passed as the second argument to minimize changes in the leaf level routine. - (void) evex_prefix_and_encode_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, /* MAP4 */VEX_OPCODE_0F_3C, &attributes, no_flags); + (void) emit_eevex_prefix_or_demote_ndd(src1->encoding(), dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags, true /* use_prefixq */); emit_arith(0x33, 0xC0, src1, src2); } @@ -16317,11 +16304,7 @@ void Assembler::xorq(Register dst, Address src) { void Assembler::exorq(Register dst, Register src1, Address src2, bool no_flags) { InstructionMark im(this); - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src2, dst->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_int8(0x33); - emit_operand(src1, src2, 0); + emit_eevex_or_demote(dst, src1, src2, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x33, no_flags); } void Assembler::xorq(Register dst, int32_t imm32) { @@ -16330,9 +16313,7 @@ void Assembler::xorq(Register dst, int32_t imm32) { } void Assembler::exorq(Register dst, Register src, int32_t imm32, bool no_flags) { - InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); - evex_prefix_and_encode_ndd(0, dst->encoding(), src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); - emit_arith_ndd(0x81, 0xF0, src, imm32); + emit_eevex_prefix_or_demote_arith_ndd(dst, src, imm32, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, EVEX_64bit, 0x81, 0xF0, no_flags); } void Assembler::xorq(Address dst, int32_t imm32) { @@ -16345,7 +16326,7 @@ void Assembler::exorq(Register dst, Address src, int32_t imm32, bool no_flags) { InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src, dst->encoding(), 0, VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_arith_operand(0x81, as_Register(6), src, imm32); } @@ -16360,7 +16341,7 @@ void Assembler::esetzucc(Condition cc, Register dst) { assert(0 <= cc && cc < 16, "illegal cc"); InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); // Encoding Format : eevex_prefix (4 bytes) | opcode_cc | modrm - int encode = evex_prefix_and_encode_ndd(0, 0, dst->encoding(), VEX_SIMD_F2, /* MAP4 */VEX_OPCODE_0F_3C, &attributes); + int encode = emit_eevex_prefix_ndd(dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_3C /* MAP4 */, &attributes); // demotion disabled emit_opcode_prefix_and_encoding((0x40 | cc), 0xC0, encode); } @@ -16368,7 +16349,7 @@ void Assembler::exorq(Register dst, Address src1, Register src2, bool no_flags) InstructionMark im(this); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_NOSCALE, /* input_size_in_bits */ EVEX_64bit); - evex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C, &attributes, no_flags); + eevex_prefix_ndd(src1, dst->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_3C /* MAP4 */, &attributes, no_flags); emit_int8(0x31); emit_operand(src2, src1, 0); } diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 10e6264160c..b1959e23722 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -772,25 +772,42 @@ private: void evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_v, bool evex_r, bool evex_b, bool eevex_x, int nds_enc, VexSimdPrefix pre, VexOpcode opc, bool no_flags = false); - void evex_prefix_ndd(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, - InstructionAttr *attributes, bool no_flags = false); + void eevex_prefix_ndd(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags = false); - void evex_prefix_nf(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, - InstructionAttr *attributes, bool no_flags = false); + void eevex_prefix_nf(Address adr, int ndd_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags = false); void vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool nds_is_ndd = false, bool no_flags = false); - int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, + int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool src_is_gpr = false, bool nds_is_ndd = false, bool no_flags = false); - int evex_prefix_and_encode_ndd(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, - InstructionAttr *attributes, bool no_flags = false); - - int evex_prefix_and_encode_nf(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + int eevex_prefix_and_encode_nf(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags = false); + int emit_eevex_prefix_ndd(int dst_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes, bool no_flags = false); + + int emit_eevex_prefix_or_demote_ndd(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags = false, bool use_prefixq = false); + + int emit_eevex_prefix_or_demote_ndd(int dst_enc, int nds_enc, VexSimdPrefix pre, VexOpcode opc, + InstructionAttr *attributes, bool no_flags = false, bool use_prefixq = false); + + void emit_eevex_prefix_or_demote_arith_ndd(Register dst, Register nds, int32_t imm32, VexSimdPrefix pre, VexOpcode opc, + int size, int op1, int op2, bool no_flags); + + void emit_eevex_or_demote(Register dst, Register src1, Address src2, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags = false, bool is_map1 = false); + + void emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1 = false, bool swap = false); + + void emit_eevex_or_demote(int dst_enc, int nds_enc, int src_enc, int8_t imm8, VexSimdPrefix pre, VexOpcode opc, + int size, int opcode_byte, bool no_flags, bool is_map1 = false); + void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes); @@ -798,10 +815,10 @@ private: VexOpcode opc, InstructionAttr *attributes, bool src_is_gpr = false); // Helper functions for groups of instructions + bool is_demotable(bool no_flags, int dst_enc, int nds_enc); void emit_arith_b(int op1, int op2, Register dst, int imm8); - void emit_arith(int op1, int op2, Register dst, int32_t imm32); - void emit_arith_ndd(int op1, int op2, Register dst, int32_t imm32); + void emit_arith(int op1, int op2, Register dst, int32_t imm32, bool optimize_rax_dst = true); // Force generation of a 4 byte immediate value even if it fits into 8bit void emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32); void emit_arith(int op1, int op2, Register dst, Register src); diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 3f126039684..152866e65f3 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -909,7 +909,7 @@ void VM_Version::get_processor_features() { } // Check if processor has Intel Ecore - if (FLAG_IS_DEFAULT(EnableX86ECoreOpts) && is_intel() && cpu_family() == 6 && + if (FLAG_IS_DEFAULT(EnableX86ECoreOpts) && is_intel() && is_intel_server_family() && (_model == 0x97 || _model == 0xAA || _model == 0xAC || _model == 0xAF || _model == 0xCC || _model == 0xDD)) { FLAG_SET_DEFAULT(EnableX86ECoreOpts, true); @@ -1594,7 +1594,7 @@ void VM_Version::get_processor_features() { if (FLAG_IS_DEFAULT(UseStoreImmI16)) { UseStoreImmI16 = false; // don't use it on Intel cpus } - if (cpu_family() == 6 || cpu_family() == 15) { + if (is_intel_server_family() || cpu_family() == 15) { if (FLAG_IS_DEFAULT(UseAddressNop)) { // Use it on all Intel cpus starting from PentiumPro UseAddressNop = true; @@ -1610,7 +1610,7 @@ void VM_Version::get_processor_features() { UseXmmRegToRegMoveAll = false; } } - if (cpu_family() == 6 && supports_sse3()) { // New Intel cpus + if (is_intel_server_family() && supports_sse3()) { // New Intel cpus #ifdef COMPILER2 if (FLAG_IS_DEFAULT(MaxLoopPad)) { // For new Intel cpus do the next optimization: @@ -1848,7 +1848,7 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(AllocatePrefetchDistance, allocate_prefetch_distance(use_watermark_prefetch)); } - if (is_intel() && cpu_family() == 6 && supports_sse3()) { + if (is_intel() && is_intel_server_family() && supports_sse3()) { if (FLAG_IS_DEFAULT(AllocatePrefetchLines) && supports_sse4_2() && supports_ht()) { // Nehalem based cpus FLAG_SET_DEFAULT(AllocatePrefetchLines, 4); @@ -3262,7 +3262,7 @@ int VM_Version::allocate_prefetch_distance(bool use_watermark_prefetch) { return 128; // Athlon } } else { // Intel - if (supports_sse3() && cpu_family() == 6) { + if (supports_sse3() && is_intel_server_family()) { if (supports_sse4_2() && supports_ht()) { // Nehalem based cpus return 192; } else if (use_watermark_prefetch) { // watermark prefetching on Core @@ -3270,7 +3270,7 @@ int VM_Version::allocate_prefetch_distance(bool use_watermark_prefetch) { } } if (supports_sse2()) { - if (cpu_family() == 6) { + if (is_intel_server_family()) { return 256; // Pentium M, Core, Core2 } else { return 512; // Pentium 4 diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index a544eeb71b8..3c8971e474b 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -791,6 +791,7 @@ public: static uint32_t cpu_stepping() { return _cpuid_info.cpu_stepping(); } static int cpu_family() { return _cpu;} static bool is_P6() { return cpu_family() >= 6; } + static bool is_intel_server_family() { return cpu_family() == 6 || cpu_family() == 19; } static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' static bool is_hygon() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x6F677948; } // 'ogyH' static bool is_amd_family() { return is_amd() || is_hygon(); } @@ -946,7 +947,7 @@ public: } // Intel Core and newer cpus have fast IDIV instruction (excluding Atom). - static bool has_fast_idiv() { return is_intel() && cpu_family() == 6 && + static bool has_fast_idiv() { return is_intel() && is_intel_server_family() && supports_sse3() && _model != 0x1C; } static bool supports_compare_and_exchange() { return true; } diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 751e9bda513..22490ba7bb3 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -7052,21 +7052,6 @@ instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) ins_pipe(ialu_reg_mem); %} -instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (AddI (LoadI src1) src2)); - effect(KILL cr); - flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); - - ins_cost(150); - format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} - ins_encode %{ - __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); - %} - ins_pipe(ialu_reg_mem); -%} - instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) %{ predicate(UseAPX); @@ -7370,21 +7355,6 @@ instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr ins_pipe(ialu_reg_mem); %} -instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (AddL (LoadL src1) src2)); - effect(KILL cr); - flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); - - ins_cost(150); - format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} - ins_encode %{ - __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); - %} - ins_pipe(ialu_reg_mem); -%} - instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) %{ match(Set dst (StoreL dst (AddL (LoadL dst) src))); @@ -8596,7 +8566,6 @@ instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) %{ - predicate(!UseAPX); match(Set dst (MulI src imm)); effect(KILL cr); @@ -8608,20 +8577,6 @@ instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) ins_pipe(ialu_reg_reg_alu0); %} -instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (MulI src1 src2)); - effect(KILL cr); - - ins_cost(300); - format %{ "eimull $dst, $src1, $src2\t# int ndd" %} - ins_encode %{ - __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); - %} - ins_pipe(ialu_reg_reg_alu0); -%} - instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) %{ predicate(!UseAPX); @@ -8652,7 +8607,6 @@ instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) %{ - predicate(!UseAPX); match(Set dst (MulI (LoadI src) imm)); effect(KILL cr); @@ -8664,20 +8618,6 @@ instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) ins_pipe(ialu_reg_mem_alu0); %} -instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (MulI (LoadI src1) src2)); - effect(KILL cr); - - ins_cost(300); - format %{ "eimull $dst, $src1, $src2\t# int ndd" %} - ins_encode %{ - __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); - %} - ins_pipe(ialu_reg_mem_alu0); -%} - instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) %{ match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); @@ -8718,7 +8658,6 @@ instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) %{ - predicate(!UseAPX); match(Set dst (MulL src imm)); effect(KILL cr); @@ -8730,20 +8669,6 @@ instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) ins_pipe(ialu_reg_reg_alu0); %} -instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (MulL src1 src2)); - effect(KILL cr); - - ins_cost(300); - format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} - ins_encode %{ - __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); - %} - ins_pipe(ialu_reg_reg_alu0); -%} - instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) %{ predicate(!UseAPX); @@ -8774,7 +8699,6 @@ instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) %{ - predicate(!UseAPX); match(Set dst (MulL (LoadL src) imm)); effect(KILL cr); @@ -8786,20 +8710,6 @@ instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) ins_pipe(ialu_reg_mem_alu0); %} -instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (MulL (LoadL src1) src2)); - effect(KILL cr); - - ins_cost(300); - format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} - ins_encode %{ - __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); - %} - ins_pipe(ialu_reg_mem_alu0); -%} - instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) %{ match(Set dst (MulHiL src rax)); @@ -10689,21 +10599,6 @@ instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr ins_pipe(ialu_reg_mem); %} -instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (XorI (LoadI 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 %{ "exorl $dst, $src1, $src2\t# int ndd" %} - ins_encode %{ - __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); - %} - ins_pipe(ialu_reg_mem); -%} - // Xor Memory with Register instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) %{ @@ -10883,21 +10778,6 @@ instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr ins_pipe(ialu_reg_mem); %} -instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) -%{ - predicate(UseAPX); - match(Set dst (AndL (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 %{ "eandq $dst, $src1, $src2\t# long ndd" %} - ins_encode %{ - __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); - %} - ins_pipe(ialu_reg_mem); -%} - // And Memory with Register instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) %{ @@ -11393,21 +11273,6 @@ instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr ins_pipe(ialu_reg_mem); %} -instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) -%{ - predicate(UseAPX); - 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 %{ - __ exorq($dst$$Register, $src1$$Address, $src2$$Register, false); - %} - ins_pipe(ialu_reg_mem); -%} - // Xor Memory with Register instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) %{ diff --git a/test/hotspot/gtest/x86/asmtest.out.h b/test/hotspot/gtest/x86/asmtest.out.h index ac4a8a21aeb..a2071bafc20 100644 --- a/test/hotspot/gtest/x86/asmtest.out.h +++ b/test/hotspot/gtest/x86/asmtest.out.h @@ -191,547 +191,765 @@ __ emull(Address(r22, r10, (Address::ScaleFactor)1, -0x3d379b56), false); // {EVEX}mul dword ptr [r22+r10*2-0x3d379b56] IID177 __ emull(Address(r11, -0x3249efaf), true); // {NF}mul dword ptr [r11-0x3249efaf] IID178 __ elzcntl(r9, r16, false); // {EVEX}lzcnt r9d, r16d IID179 - __ elzcntl(r23, r28, true); // {NF}lzcnt r23d, r28d IID180 - __ enegl(r8, r30, false); // {EVEX}neg r8d, r30d IID181 - __ enegl(r23, r11, true); // {NF}neg r23d, r11d IID182 - __ epopcntl(r13, r16, false); // {EVEX}popcnt r13d, r16d IID183 - __ epopcntl(r11, r11, true); // {NF}popcnt r11d, r11d IID184 - __ enotl(r26, rcx); // {EVEX}not r26d, ecx IID185 - __ eroll(rbx, r10, false); // {EVEX}rol ebx, r10d, cl IID186 - __ eroll(r14, r29, true); // {NF}rol r14d, r29d, cl IID187 - __ erorl(r15, r20, false); // {EVEX}ror r15d, r20d, cl IID188 - __ erorl(r17, r12, true); // {NF}ror r17d, r12d, cl IID189 - __ esall(r12, rbx, false); // {EVEX}sal r12d, ebx, cl IID190 - __ esall(r23, r27, true); // {NF}sal r23d, r27d, cl IID191 - __ esarl(r29, r20, false); // {EVEX}sar r29d, r20d, cl IID192 - __ esarl(r28, rdx, true); // {NF}sar r28d, edx, cl IID193 - __ edecl(r8, r27, false); // {EVEX}dec r8d, r27d IID194 - __ edecl(rbx, r15, true); // {NF}dec ebx, r15d IID195 - __ eincl(r11, r27, false); // {EVEX}inc r11d, r27d IID196 - __ eincl(r29, r25, true); // {NF}inc r29d, r25d IID197 - __ eshll(r12, r8, false); // {EVEX}shl r12d, r8d, cl IID198 - __ eshll(r11, r18, true); // {NF}shl r11d, r18d, cl IID199 - __ eshrl(rdx, r13, false); // {EVEX}shr edx, r13d, cl IID200 - __ eshrl(r23, r24, true); // {NF}shr r23d, r24d, cl IID201 - __ etzcntl(r15, r15, false); // {EVEX}tzcnt r15d, r15d IID202 - __ etzcntl(r26, r28, true); // {NF}tzcnt r26d, r28d IID203 - __ elzcntl(rbx, Address(r25, r14, (Address::ScaleFactor)0, +0x1c13fdb6), false); // {EVEX}lzcnt ebx, dword ptr [r25+r14*1+0x1c13fdb6] IID204 - __ elzcntl(r9, Address(r31, r28, (Address::ScaleFactor)3, -0x30bf8b7f), true); // {NF}lzcnt r9d, dword ptr [r31+r28*8-0x30bf8b7f] IID205 - __ enegl(r8, Address(r25, -0x9c80fe2), false); // {EVEX}neg r8d, dword ptr [r25-0x9c80fe2] IID206 - __ enegl(r22, Address(r27, r19, (Address::ScaleFactor)2, +0x38f27c09), true); // {NF}neg r22d, dword ptr [r27+r19*4+0x38f27c09] IID207 - __ epopcntl(r21, Address(r14, r30, (Address::ScaleFactor)2, +0x39f92c7b), false); // {EVEX}popcnt r21d, dword ptr [r14+r30*4+0x39f92c7b] IID208 - __ epopcntl(r26, Address(r23, r14, (Address::ScaleFactor)3, -0x602e1b3d), true); // {NF}popcnt r26d, dword ptr [r23+r14*8-0x602e1b3d] IID209 - __ esall(r25, Address(r28, r23, (Address::ScaleFactor)1, +0x4ff120ef), false); // {EVEX}sal r25d, dword ptr [r28+r23*2+0x4ff120ef], cl IID210 - __ esall(r29, Address(r24, r16, (Address::ScaleFactor)3, -0x6821bb43), true); // {NF}sal r29d, dword ptr [r24+r16*8-0x6821bb43], cl IID211 - __ esarl(r23, Address(r11, r31, (Address::ScaleFactor)2, +0x7f4224bb), false); // {EVEX}sar r23d, dword ptr [r11+r31*4+0x7f4224bb], cl IID212 - __ esarl(r12, Address(r23, r31, (Address::ScaleFactor)1, -0x28f87a8), true); // {NF}sar r12d, dword ptr [r23+r31*2-0x28f87a8], cl IID213 - __ edecl(r19, Address(r16, r30, (Address::ScaleFactor)1, -0x27b89e0d), false); // {EVEX}dec r19d, dword ptr [r16+r30*2-0x27b89e0d] IID214 - __ edecl(r26, Address(r25, +0x3d145d48), true); // {NF}dec r26d, dword ptr [r25+0x3d145d48] IID215 - __ eincl(r13, Address(r27, r24, (Address::ScaleFactor)1, +0x625f3862), false); // {EVEX}inc r13d, dword ptr [r27+r24*2+0x625f3862] IID216 - __ eincl(r11, Address(r22, +0x765904a6), true); // {NF}inc r11d, dword ptr [r22+0x765904a6] IID217 - __ eshrl(r25, Address(rdx, r17, (Address::ScaleFactor)1, -0x7d50376f), false); // {EVEX}shr r25d, dword ptr [rdx+r17*2-0x7d50376f], cl IID218 - __ eshrl(r22, Address(r12, -0x50325da9), true); // {NF}shr r22d, dword ptr [r12-0x50325da9], cl IID219 - __ etzcntl(r13, Address(r13, r20, (Address::ScaleFactor)0, -0xbf3e86c), false); // {EVEX}tzcnt r13d, dword ptr [r13+r20*1-0xbf3e86c] IID220 - __ etzcntl(r26, Address(r14, r19, (Address::ScaleFactor)1, -0x24c59cb9), true); // {NF}tzcnt r26d, dword ptr [r14+r19*2-0x24c59cb9] IID221 - __ eaddl(r22, Address(r27, r31, (Address::ScaleFactor)2, -0x7f80902f), 1048576, false); // {EVEX}add r22d, dword ptr [r27+r31*4-0x7f80902f], 1048576 IID222 - __ eaddl(r31, Address(rdx, r21, (Address::ScaleFactor)3, -0x557cc036), 268435456, true); // {NF}add r31d, dword ptr [rdx+r21*8-0x557cc036], 268435456 IID223 - __ eandl(r10, Address(r26, +0x4e6bebf9), 4096, false); // {EVEX}and r10d, dword ptr [r26+0x4e6bebf9], 4096 IID224 - __ eandl(r13, Address(r30, +0x14f1a5fd), 256, true); // {NF}and r13d, dword ptr [r30+0x14f1a5fd], 256 IID225 - __ eimull(r27, Address(r29, r8, (Address::ScaleFactor)0, +0x37988799), 1, false); // {EVEX}imul r27d, dword ptr [r29+r8*1+0x37988799], 1 IID226 - __ eimull(r27, Address(r9, -0x446d2dc1), 256, true); // {NF}imul r27d, dword ptr [r9-0x446d2dc1], 256 IID227 - __ eorl(r17, Address(r20, r25, (Address::ScaleFactor)0, +0x4957b5db), 16, false); // {EVEX}or r17d, dword ptr [r20+r25*1+0x4957b5db], 16 IID228 - __ eorl(r25, Address(r29, r31, (Address::ScaleFactor)1, +0x3c26a53e), 1, true); // {NF}or r25d, dword ptr [r29+r31*2+0x3c26a53e], 1 IID229 - __ eorb(r15, Address(r9, -0x25974a1e), 64, false); // {EVEX}or r15b, byte ptr [r9-0x25974a1e], 64 IID230 - __ eorb(r11, Address(r16, r15, (Address::ScaleFactor)2, +0x66a0329f), 4, true); // {NF}or r11b, byte ptr [r16+r15*4+0x66a0329f], 4 IID231 - __ esall(rcx, Address(rcx, r27, (Address::ScaleFactor)0, +0x38c6485e), 1, false); // {EVEX}sal ecx, dword ptr [rcx+r27*1+0x38c6485e], 1 IID232 - __ esall(r25, Address(r8, r10, (Address::ScaleFactor)0, +0x79131c34), 8, true); // {NF}sal r25d, dword ptr [r8+r10*1+0x79131c34], 8 IID233 - __ esarl(r13, Address(r9, r31, (Address::ScaleFactor)2, +0x12718ba9), 2, false); // {EVEX}sar r13d, dword ptr [r9+r31*4+0x12718ba9], 2 IID234 - __ esarl(r15, Address(r25, -0x505836f3), 16, true); // {NF}sar r15d, dword ptr [r25-0x505836f3], 16 IID235 - __ eshrl(r15, Address(rcx, r19, (Address::ScaleFactor)0, +0xc5c1510), 1, false); // {EVEX}shr r15d, dword ptr [rcx+r19*1+0xc5c1510], 1 IID236 - __ eshrl(r13, Address(r29, r21, (Address::ScaleFactor)2, -0x6c67309c), 8, true); // {NF}shr r13d, dword ptr [r29+r21*4-0x6c67309c], 8 IID237 - __ esubl(rbx, Address(r12, r8, (Address::ScaleFactor)1, -0x3575087f), 4096, false); // {EVEX}sub ebx, dword ptr [r12+r8*2-0x3575087f], 4096 IID238 - __ esubl(r28, Address(rbx, r21, (Address::ScaleFactor)3, -0x55f83db8), 65536, true); // {NF}sub r28d, dword ptr [rbx+r21*8-0x55f83db8], 65536 IID239 - __ exorl(r30, Address(r21, r26, (Address::ScaleFactor)0, +0x3b4d14e1), 1, false); // {EVEX}xor r30d, dword ptr [r21+r26*1+0x3b4d14e1], 1 IID240 - __ exorl(r28, Address(r18, -0x452348a1), 16777216, true); // {NF}xor r28d, dword ptr [r18-0x452348a1], 16777216 IID241 - __ eaddl(r18, Address(rdx, r10, (Address::ScaleFactor)2, -0x161e1d47), r16, false); // {EVEX}add r18d, dword ptr [rdx+r10*4-0x161e1d47], r16d IID242 - __ eaddl(r27, Address(r25, r18, (Address::ScaleFactor)3, -0x679bb823), rdx, true); // {NF}add r27d, dword ptr [r25+r18*8-0x679bb823], edx IID243 - __ eorl(r27, Address(r31, r29, (Address::ScaleFactor)3, +0x19ed7934), r9, false); // {EVEX}or r27d, dword ptr [r31+r29*8+0x19ed7934], r9d IID244 - __ eorl(r22, Address(r8, r16, (Address::ScaleFactor)2, -0x1bf71f78), r17, true); // {NF}or r22d, dword ptr [r8+r16*4-0x1bf71f78], r17d IID245 - __ eorb(rcx, Address(r15, r28, (Address::ScaleFactor)3, -0x6a4a3934), r16, false); // {EVEX}or cl, byte ptr [r15+r28*8-0x6a4a3934], r16b IID246 - __ eorb(r28, Address(r23, r12, (Address::ScaleFactor)2, +0x3c2449f7), r16, true); // {NF}or r28b, byte ptr [r23+r12*4+0x3c2449f7], r16b IID247 - __ esubl(r22, Address(r27, r10, (Address::ScaleFactor)1, -0x3c29396f), r9, false); // {EVEX}sub r22d, dword ptr [r27+r10*2-0x3c29396f], r9d IID248 - __ esubl(r10, Address(r16, -0x165064ff), r17, true); // {NF}sub r10d, dword ptr [r16-0x165064ff], r17d IID249 - __ exorl(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false); // {EVEX}xor r28d, dword ptr [r30+r11*1+0x17281e3a], r20d IID250 - __ exorl(rdx, Address(rbx, r31, (Address::ScaleFactor)3, +0x7753d0dc), r17, true); // {NF}xor edx, dword ptr [rbx+r31*8+0x7753d0dc], r17d IID251 - __ exorb(r9, Address(r31, +0x72a4f58e), r30, false); // {EVEX}xor r9b, byte ptr [r31+0x72a4f58e], r30b IID252 - __ exorb(r24, Address(r25, r15, (Address::ScaleFactor)0, +0x20fc1a0a), r16, true); // {NF}xor r24b, byte ptr [r25+r15*1+0x20fc1a0a], r16b IID253 - __ eaddl(r12, rbx, 65536, false); // {EVEX}add r12d, ebx, 65536 IID254 - __ eaddl(rax, r11, 65536, false); // {EVEX}add eax, r11d, 65536 IID255 - __ eaddl(r24, r16, 268435456, true); // {NF}add r24d, r16d, 268435456 IID256 - __ eaddl(rax, r18, 268435456, true); // {NF}add eax, r18d, 268435456 IID257 - __ eandl(r29, r13, 1, false); // {EVEX}and r29d, r13d, 1 IID258 - __ eandl(rax, r13, 1, false); // {EVEX}and eax, r13d, 1 IID259 - __ eandl(r31, r22, 1, true); // {NF}and r31d, r22d, 1 IID260 - __ eandl(rax, r29, 1, true); // {NF}and eax, r29d, 1 IID261 - __ eimull(r23, r29, 65536, false); // {EVEX}imul r23d, r29d, 65536 IID262 - __ eimull(rax, r15, 65536, false); // {EVEX}imul eax, r15d, 65536 IID263 - __ eimull(r21, r9, 268435456, true); // {NF}imul r21d, r9d, 268435456 IID264 - __ eimull(rax, r15, 268435456, true); // {NF}imul eax, r15d, 268435456 IID265 - __ eorl(rdx, r18, 65536, false); // {EVEX}or edx, r18d, 65536 IID266 - __ eorl(rax, r15, 65536, false); // {EVEX}or eax, r15d, 65536 IID267 - __ eorl(r8, r9, 256, true); // {NF}or r8d, r9d, 256 IID268 - __ eorl(rax, r27, 256, true); // {NF}or eax, r27d, 256 IID269 - __ ercll(r9, r15, 8); // {EVEX}rcl r9d, r15d, 8 IID270 - __ ercll(rax, r18, 8); // {EVEX}rcl eax, r18d, 8 IID271 - __ eroll(r12, rbx, 16, false); // {EVEX}rol r12d, ebx, 16 IID272 - __ eroll(rax, r19, 16, false); // {EVEX}rol eax, r19d, 16 IID273 - __ eroll(r10, r11, 16, true); // {NF}rol r10d, r11d, 16 IID274 - __ eroll(rax, r18, 16, true); // {NF}rol eax, r18d, 16 IID275 - __ erorl(rdx, r14, 1, false); // {EVEX}ror edx, r14d, 1 IID276 - __ erorl(rax, r22, 1, false); // {EVEX}ror eax, r22d, 1 IID277 - __ erorl(r25, r31, 16, true); // {NF}ror r25d, r31d, 16 IID278 - __ erorl(rax, r19, 16, true); // {NF}ror eax, r19d, 16 IID279 - __ esall(r9, r15, 2, false); // {EVEX}sal r9d, r15d, 2 IID280 - __ esall(rax, r13, 2, false); // {EVEX}sal eax, r13d, 2 IID281 - __ esall(r21, r16, 1, true); // {NF}sal r21d, r16d, 1 IID282 - __ esall(rax, r21, 1, true); // {NF}sal eax, r21d, 1 IID283 - __ esarl(r26, r23, 8, false); // {EVEX}sar r26d, r23d, 8 IID284 - __ esarl(rax, r28, 8, false); // {EVEX}sar eax, r28d, 8 IID285 - __ esarl(r26, r14, 4, true); // {NF}sar r26d, r14d, 4 IID286 - __ esarl(rax, r10, 4, true); // {NF}sar eax, r10d, 4 IID287 - __ eshll(r22, r9, 1, false); // {EVEX}shl r22d, r9d, 1 IID288 - __ eshll(rax, r18, 1, false); // {EVEX}shl eax, r18d, 1 IID289 - __ eshll(r30, r24, 16, true); // {NF}shl r30d, r24d, 16 IID290 - __ eshll(rax, r23, 16, true); // {NF}shl eax, r23d, 16 IID291 - __ eshrl(r11, r8, 16, false); // {EVEX}shr r11d, r8d, 16 IID292 - __ eshrl(rax, r16, 16, false); // {EVEX}shr eax, r16d, 16 IID293 - __ eshrl(r11, r12, 8, true); // {NF}shr r11d, r12d, 8 IID294 - __ eshrl(rax, r29, 8, true); // {NF}shr eax, r29d, 8 IID295 - __ esubl(r16, r21, 1048576, false); // {EVEX}sub r16d, r21d, 1048576 IID296 - __ esubl(rax, r15, 1048576, false); // {EVEX}sub eax, r15d, 1048576 IID297 - __ esubl(r9, r18, 16777216, true); // {NF}sub r9d, r18d, 16777216 IID298 + __ elzcntl(r23, r23, false); // {EVEX}lzcnt r23d, r23d IID180 + __ elzcntl(r28, r8, true); // {NF}lzcnt r28d, r8d IID181 + __ elzcntl(r30, r30, true); // {NF}lzcnt r30d, r30d IID182 + __ enegl(r23, r11, false); // {EVEX}neg r23d, r11d IID183 + __ enegl(r13, r13, false); // neg r13d IID184 + __ enegl(r16, r11, true); // {NF}neg r16d, r11d IID185 + __ enegl(r11, r11, true); // {NF}neg r11d, r11d IID186 + __ epopcntl(r26, rcx, false); // {EVEX}popcnt r26d, ecx IID187 #endif // _LP64 - __ esubl(rax, rbx, 16777216, true); // {NF}sub eax, ebx, 16777216 IID299 + __ epopcntl(rbx, rbx, false); // {EVEX}popcnt ebx, ebx IID188 #ifdef _LP64 - __ exorl(r19, r23, 65536, false); // {EVEX}xor r19d, r23d, 65536 IID300 - __ exorl(rax, r17, 65536, false); // {EVEX}xor eax, r17d, 65536 IID301 - __ exorl(r29, r18, 1048576, true); // {NF}xor r29d, r18d, 1048576 IID302 - __ exorl(rax, r14, 1048576, true); // {NF}xor eax, r14d, 1048576 IID303 - __ esubl_imm32(r19, r15, 16777216, false); // {EVEX}sub r19d, r15d, 16777216 IID304 - __ esubl_imm32(rax, r27, 16777216, false); // {EVEX}sub eax, r27d, 16777216 IID305 - __ esubl_imm32(r23, r27, 1073741824, true); // {NF}sub r23d, r27d, 1073741824 IID306 - __ esubl_imm32(rax, r23, 1073741824, true); // {NF}sub eax, r23d, 1073741824 IID307 - __ eaddl(r8, r12, Address(r28, r24, (Address::ScaleFactor)3, -0x6d6d7e68), false); // {EVEX}add r8d, r12d, dword ptr [r28+r24*8-0x6d6d7e68] IID308 - __ eaddl(r24, r13, Address(r24, r25, (Address::ScaleFactor)3, +0x784673fd), true); // {NF}add r24d, r13d, dword ptr [r24+r25*8+0x784673fd] IID309 - __ eandl(r24, r21, Address(r8, r13, (Address::ScaleFactor)2, -0x63663889), false); // {EVEX}and r24d, r21d, dword ptr [r8+r13*4-0x63663889] IID310 - __ eandl(r12, r24, Address(r30, -0x67526556), true); // {NF}and r12d, r24d, dword ptr [r30-0x67526556] IID311 - __ eimull(r13, r13, Address(rbx, r25, (Address::ScaleFactor)2, -0x5f394dd9), false); // {EVEX}imul r13d, r13d, dword ptr [rbx+r25*4-0x5f394dd9] IID312 - __ eimull(r26, r25, Address(r25, rdx, (Address::ScaleFactor)3, -0x2e39f79a), true); // {NF}imul r26d, r25d, dword ptr [r25+rdx*8-0x2e39f79a] IID313 - __ eorl(r28, r8, Address(rdx, r24, (Address::ScaleFactor)3, -0xed99a54), false); // {EVEX}or r28d, r8d, dword ptr [rdx+r24*8-0xed99a54] IID314 - __ eorl(r31, r22, Address(r30, r20, (Address::ScaleFactor)3, +0x3ac41cbd), true); // {NF}or r31d, r22d, dword ptr [r30+r20*8+0x3ac41cbd] IID315 - __ esubl(r24, r30, Address(r13, r17, (Address::ScaleFactor)1, +0x1efdc2e3), false); // {EVEX}sub r24d, r30d, dword ptr [r13+r17*2+0x1efdc2e3] IID316 - __ esubl(r16, r16, Address(r9, r15, (Address::ScaleFactor)1, +0x769feb34), true); // {NF}sub r16d, r16d, dword ptr [r9+r15*2+0x769feb34] IID317 - __ exorl(r19, r25, Address(r10, +0x2239b429), false); // {EVEX}xor r19d, r25d, dword ptr [r10+0x2239b429] IID318 - __ exorl(r25, r19, Address(r16, r24, (Address::ScaleFactor)1, +0x1c71faea), true); // {NF}xor r25d, r19d, dword ptr [r16+r24*2+0x1c71faea] IID319 - __ exorb(r19, r10, Address(r28, -0x299a0cfd), false); // {EVEX}xor r19b, r10b, byte ptr [r28-0x299a0cfd] IID320 - __ exorb(rbx, r28, Address(r23, r24, (Address::ScaleFactor)1, -0x5d78ddd9), true); // {NF}xor bl, r28b, byte ptr [r23+r24*2-0x5d78ddd9] IID321 - __ exorw(r10, r9, Address(r13, r30, (Address::ScaleFactor)2, +0x11151188), false); // {EVEX}xor r10w, r9w, word ptr [r13+r30*4+0x11151188] IID322 - __ exorw(r16, r17, Address(rdx, r31, (Address::ScaleFactor)0, +0x61936ce7), true); // {NF}xor r16w, r17w, word ptr [rdx+r31*1+0x61936ce7] IID323 - __ eaddl(r13, rbx, r28, false); // {load}{EVEX}add r13d, ebx, r28d IID324 - __ eaddl(rbx, r29, r22, true); // {load}{NF}add ebx, r29d, r22d IID325 - __ eandl(rbx, r8, r8, false); // {load}{EVEX}and ebx, r8d, r8d IID326 - __ eandl(r11, r16, r13, true); // {load}{NF}and r11d, r16d, r13d IID327 - __ eimull(r12, r15, r17, false); // {load}{EVEX}imul r12d, r15d, r17d IID328 - __ eimull(r23, r31, r20, true); // {load}{NF}imul r23d, r31d, r20d IID329 - __ eorw(r22, r26, r10, false); // {load}{EVEX}or r22w, r26w, r10w IID330 - __ eorw(r25, r19, r11, true); // {load}{NF}or r25w, r19w, r11w IID331 - __ eorl(r19, r30, r8, false); // {load}{EVEX}or r19d, r30d, r8d IID332 - __ eorl(r12, r10, rdx, true); // {load}{NF}or r12d, r10d, edx IID333 - __ eshldl(r22, r20, r30, false); // {load}{EVEX}shld r22d, r20d, r30d, cl IID334 - __ eshldl(r18, r19, r18, true); // {load}{NF}shld r18d, r19d, r18d, cl IID335 - __ eshrdl(r25, r18, rcx, false); // {load}{EVEX}shrd r25d, r18d, ecx, cl IID336 - __ eshrdl(r19, r16, r25, true); // {load}{NF}shrd r19d, r16d, r25d, cl IID337 - __ esubl(r11, r31, r24, false); // {load}{EVEX}sub r11d, r31d, r24d IID338 - __ esubl(r14, r30, r16, true); // {load}{NF}sub r14d, r30d, r16d IID339 - __ exorl(r9, r11, r26, false); // {load}{EVEX}xor r9d, r11d, r26d IID340 - __ exorl(r27, rdx, r31, true); // {load}{NF}xor r27d, edx, r31d IID341 - __ eshldl(r29, r10, rcx, 16, false); // {EVEX}shld r29d, r10d, ecx, 16 IID342 - __ eshldl(r15, r23, r17, 16, true); // {NF}shld r15d, r23d, r17d, 16 IID343 - __ eshrdl(r27, r13, r15, 8, false); // {EVEX}shrd r27d, r13d, r15d, 8 IID344 - __ eshrdl(r15, r29, r26, 16, true); // {NF}shrd r15d, r29d, r26d, 16 IID345 - __ ecmovl (Assembler::Condition::overflow, r18, r9, r9); // cmovo r18d, r9d, r9d IID346 - __ ecmovl (Assembler::Condition::noOverflow, r22, r30, r23); // cmovno r22d, r30d, r23d IID347 - __ ecmovl (Assembler::Condition::below, r11, r20, r11); // cmovb r11d, r20d, r11d IID348 - __ ecmovl (Assembler::Condition::aboveEqual, rbx, r28, r16); // cmovae ebx, r28d, r16d IID349 - __ ecmovl (Assembler::Condition::zero, r20, r17, r24); // cmovz r20d, r17d, r24d IID350 - __ ecmovl (Assembler::Condition::notZero, r22, r16, r15); // cmovnz r22d, r16d, r15d IID351 - __ ecmovl (Assembler::Condition::belowEqual, r15, r28, r29); // cmovbe r15d, r28d, r29d IID352 - __ ecmovl (Assembler::Condition::above, r16, r25, r25); // cmova r16d, r25d, r25d IID353 - __ ecmovl (Assembler::Condition::negative, r17, r13, r17); // cmovs r17d, r13d, r17d IID354 - __ ecmovl (Assembler::Condition::positive, r23, rbx, r30); // cmovns r23d, ebx, r30d IID355 - __ ecmovl (Assembler::Condition::parity, r15, r22, r11); // cmovp r15d, r22d, r11d IID356 - __ ecmovl (Assembler::Condition::noParity, r27, rdx, r22); // cmovnp r27d, edx, r22d IID357 - __ ecmovl (Assembler::Condition::less, r9, r17, r28); // cmovl r9d, r17d, r28d IID358 - __ ecmovl (Assembler::Condition::greaterEqual, r24, r11, r26); // cmovge r24d, r11d, r26d IID359 - __ ecmovl (Assembler::Condition::lessEqual, r12, rcx, rbx); // cmovle r12d, ecx, ebx IID360 - __ ecmovl (Assembler::Condition::greater, r28, r22, r22); // cmovg r28d, r22d, r22d IID361 - __ ecmovl (Assembler::Condition::overflow, r10, r14, Address(rcx, r17, (Address::ScaleFactor)3, -0x7857b23d)); // cmovo r10d, r14d, dword ptr [rcx+r17*8-0x7857b23d] IID362 - __ ecmovl (Assembler::Condition::noOverflow, r17, r12, Address(r26, r24, (Address::ScaleFactor)3, +0x10642223)); // cmovno r17d, r12d, dword ptr [r26+r24*8+0x10642223] IID363 - __ ecmovl (Assembler::Condition::below, r26, r8, Address(r31, -0xb2d2be4)); // cmovb r26d, r8d, dword ptr [r31-0xb2d2be4] IID364 - __ ecmovl (Assembler::Condition::aboveEqual, r12, r20, Address(r12, r22, (Address::ScaleFactor)2, -0x667ff72b)); // cmovae r12d, r20d, dword ptr [r12+r22*4-0x667ff72b] IID365 - __ ecmovl (Assembler::Condition::zero, r22, r9, Address(r27, r23, (Address::ScaleFactor)2, +0x66ce4d22)); // cmovz r22d, r9d, dword ptr [r27+r23*4+0x66ce4d22] IID366 - __ ecmovl (Assembler::Condition::notZero, r12, r8, Address(r30, r27, (Address::ScaleFactor)3, -0x2b9676e1)); // cmovnz r12d, r8d, dword ptr [r30+r27*8-0x2b9676e1] IID367 - __ ecmovl (Assembler::Condition::belowEqual, r17, r20, Address(r9, r30, (Address::ScaleFactor)3, -0x351022df)); // cmovbe r17d, r20d, dword ptr [r9+r30*8-0x351022df] IID368 - __ ecmovl (Assembler::Condition::above, rdx, r8, Address(r14, +0x3d6b7a59)); // cmova edx, r8d, dword ptr [r14+0x3d6b7a59] IID369 - __ ecmovl (Assembler::Condition::negative, rcx, r31, Address(r11, r14, (Address::ScaleFactor)2, +0x2cd585f2)); // cmovs ecx, r31d, dword ptr [r11+r14*4+0x2cd585f2] IID370 - __ ecmovl (Assembler::Condition::positive, r25, r18, Address(r24, r11, (Address::ScaleFactor)2, -0x3f699c34)); // cmovns r25d, r18d, dword ptr [r24+r11*4-0x3f699c34] IID371 - __ ecmovl (Assembler::Condition::parity, r18, r8, Address(r19, r17, (Address::ScaleFactor)2, -0x390da4c5)); // cmovp r18d, r8d, dword ptr [r19+r17*4-0x390da4c5] IID372 - __ ecmovl (Assembler::Condition::noParity, r11, r29, Address(r29, rdx, (Address::ScaleFactor)2, +0x3a94a93f)); // cmovnp r11d, r29d, dword ptr [r29+rdx*4+0x3a94a93f] IID373 - __ ecmovl (Assembler::Condition::less, r13, r29, Address(r15, r23, (Address::ScaleFactor)1, +0x76d43532)); // cmovl r13d, r29d, dword ptr [r15+r23*2+0x76d43532] IID374 - __ ecmovl (Assembler::Condition::greaterEqual, r15, r12, Address(r13, r9, (Address::ScaleFactor)1, +0x16f7a5b)); // cmovge r15d, r12d, dword ptr [r13+r9*2+0x16f7a5b] IID375 - __ ecmovl (Assembler::Condition::lessEqual, r9, rdx, Address(r17, r23, (Address::ScaleFactor)1, +0x43b6bfe1)); // cmovle r9d, edx, dword ptr [r17+r23*2+0x43b6bfe1] IID376 - __ ecmovl (Assembler::Condition::greater, r28, r20, Address(r24, r10, (Address::ScaleFactor)0, -0x326e802f)); // cmovg r28d, r20d, dword ptr [r24+r10*1-0x326e802f] IID377 + __ epopcntl(r10, r14, true); // {NF}popcnt r10d, r14d IID189 + __ epopcntl(r29, r29, true); // {NF}popcnt r29d, r29d IID190 + __ enotl(r15, r20); // {EVEX}not r15d, r20d IID191 + __ enotl(r17, r17); // not r17d IID192 + __ eroll(r12, r12, false); // rol r12d, cl IID193 +#endif // _LP64 + __ eroll(rbx, rbx, false); // rol ebx, cl IID194 +#ifdef _LP64 + __ eroll(r23, r27, true); // {NF}rol r23d, r27d, cl IID195 + __ eroll(r29, r29, true); // {NF}rol r29d, r29d, cl IID196 + __ erorl(r20, r28, false); // {EVEX}ror r20d, r28d, cl IID197 +#endif // _LP64 + __ erorl(rdx, rdx, false); // ror edx, cl IID198 +#ifdef _LP64 + __ erorl(r8, r27, true); // {NF}ror r8d, r27d, cl IID199 +#endif // _LP64 + __ erorl(rbx, rbx, true); // {NF}ror ebx, ebx, cl IID200 +#ifdef _LP64 + __ esall(r15, r11, false); // {EVEX}sal r15d, r11d, cl IID201 + __ esall(r27, r27, false); // sal r27d, cl IID202 + __ esall(r29, r25, true); // {NF}sal r29d, r25d, cl IID203 + __ esall(r12, r12, true); // {NF}sal r12d, r12d, cl IID204 + __ esarl(r8, r11, false); // {EVEX}sar r8d, r11d, cl IID205 + __ esarl(r18, r18, false); // sar r18d, cl IID206 + __ esarl(rdx, r13, true); // {NF}sar edx, r13d, cl IID207 + __ esarl(r23, r23, true); // {NF}sar r23d, r23d, cl IID208 + __ edecl(r24, r15, false); // {EVEX}dec r24d, r15d IID209 + __ edecl(r15, r15, false); // dec r15d IID210 + __ edecl(r26, r28, true); // {NF}dec r26d, r28d IID211 +#endif // _LP64 + __ edecl(rbx, rbx, true); // {NF}dec ebx, ebx IID212 +#ifdef _LP64 + __ eincl(r25, r14, false); // {EVEX}inc r25d, r14d IID213 + __ eincl(r12, r12, false); // inc r12d IID214 + __ eincl(rcx, r23, true); // {NF}inc ecx, r23d IID215 + __ eincl(r29, r29, true); // {NF}inc r29d, r29d IID216 + __ eshll(r22, r24, false); // {EVEX}shl r22d, r24d, cl IID217 + __ eshll(r15, r15, false); // shl r15d, cl IID218 + __ eshll(r9, r31, true); // {NF}shl r9d, r31d, cl IID219 + __ eshll(r28, r28, true); // {NF}shl r28d, r28d, cl IID220 + __ eshrl(r21, r18, false); // {EVEX}shr r21d, r18d, cl IID221 + __ eshrl(r24, r24, false); // shr r24d, cl IID222 + __ eshrl(r14, r19, true); // {NF}shr r14d, r19d, cl IID223 + __ eshrl(r8, r8, true); // {NF}shr r8d, r8d, cl IID224 + __ etzcntl(r25, r9, false); // {EVEX}tzcnt r25d, r9d IID225 + __ etzcntl(r26, r26, false); // {EVEX}tzcnt r26d, r26d IID226 + __ etzcntl(r8, r30, true); // {NF}tzcnt r8d, r30d IID227 + __ etzcntl(r26, r26, true); // {NF}tzcnt r26d, r26d IID228 + __ elzcntl(r29, Address(r25, r20, (Address::ScaleFactor)3, -0x9c80fe2), false); // {EVEX}lzcnt r29d, dword ptr [r25+r20*8-0x9c80fe2] IID229 + __ elzcntl(r22, Address(r27, r19, (Address::ScaleFactor)2, +0x38f27c09), true); // {NF}lzcnt r22d, dword ptr [r27+r19*4+0x38f27c09] IID230 + __ enegl(r21, Address(r14, r30, (Address::ScaleFactor)2, +0x39f92c7b), false); // {EVEX}neg r21d, dword ptr [r14+r30*4+0x39f92c7b] IID231 + __ enegl(r26, Address(r23, r14, (Address::ScaleFactor)3, -0x602e1b3d), true); // {NF}neg r26d, dword ptr [r23+r14*8-0x602e1b3d] IID232 + __ epopcntl(r25, Address(r28, r23, (Address::ScaleFactor)1, +0x4ff120ef), false); // {EVEX}popcnt r25d, dword ptr [r28+r23*2+0x4ff120ef] IID233 + __ epopcntl(r29, Address(r24, r16, (Address::ScaleFactor)3, -0x6821bb43), true); // {NF}popcnt r29d, dword ptr [r24+r16*8-0x6821bb43] IID234 + __ esall(r23, Address(r11, r31, (Address::ScaleFactor)2, +0x7f4224bb), false); // {EVEX}sal r23d, dword ptr [r11+r31*4+0x7f4224bb], cl IID235 + __ esall(r12, Address(r23, r31, (Address::ScaleFactor)1, -0x28f87a8), true); // {NF}sal r12d, dword ptr [r23+r31*2-0x28f87a8], cl IID236 + __ esarl(r19, Address(r16, r30, (Address::ScaleFactor)1, -0x27b89e0d), false); // {EVEX}sar r19d, dword ptr [r16+r30*2-0x27b89e0d], cl IID237 + __ esarl(r26, Address(r25, +0x3d145d48), true); // {NF}sar r26d, dword ptr [r25+0x3d145d48], cl IID238 + __ edecl(r13, Address(r27, r24, (Address::ScaleFactor)1, +0x625f3862), false); // {EVEX}dec r13d, dword ptr [r27+r24*2+0x625f3862] IID239 + __ edecl(r11, Address(r22, +0x765904a6), true); // {NF}dec r11d, dword ptr [r22+0x765904a6] IID240 + __ eincl(r25, Address(rdx, r17, (Address::ScaleFactor)1, -0x7d50376f), false); // {EVEX}inc r25d, dword ptr [rdx+r17*2-0x7d50376f] IID241 + __ eincl(r22, Address(r12, -0x50325da9), true); // {NF}inc r22d, dword ptr [r12-0x50325da9] IID242 + __ eshrl(r13, Address(r13, r20, (Address::ScaleFactor)0, -0xbf3e86c), false); // {EVEX}shr r13d, dword ptr [r13+r20*1-0xbf3e86c], cl IID243 + __ eshrl(r26, Address(r14, r19, (Address::ScaleFactor)1, -0x24c59cb9), true); // {NF}shr r26d, dword ptr [r14+r19*2-0x24c59cb9], cl IID244 + __ etzcntl(r16, Address(r22, r27, (Address::ScaleFactor)2, -0x7f80902f), false); // {EVEX}tzcnt r16d, dword ptr [r22+r27*4-0x7f80902f] IID245 + __ etzcntl(r20, Address(r31, rdx, (Address::ScaleFactor)3, +0x12254818), true); // {NF}tzcnt r20d, dword ptr [r31+rdx*8+0x12254818] IID246 + __ eaddl(r21, Address(r12, r10, (Address::ScaleFactor)3, +0x6417cf06), 1048576, false); // {EVEX}add r21d, dword ptr [r12+r10*8+0x6417cf06], 1048576 IID247 + __ eaddl(r9, Address(r13, +0x14f1a5fd), 4096, true); // {NF}add r9d, dword ptr [r13+0x14f1a5fd], 4096 IID248 + __ eandl(r27, Address(r29, r8, (Address::ScaleFactor)0, +0x37988799), 1, false); // {EVEX}and r27d, dword ptr [r29+r8*1+0x37988799], 1 IID249 + __ eandl(r27, Address(r9, -0x446d2dc1), 256, true); // {NF}and r27d, dword ptr [r9-0x446d2dc1], 256 IID250 + __ eimull(r17, Address(r20, r25, (Address::ScaleFactor)0, +0x4957b5db), 16, false); // {EVEX}imul r17d, dword ptr [r20+r25*1+0x4957b5db], 16 IID251 + __ eimull(r25, Address(r29, r31, (Address::ScaleFactor)1, +0x3c26a53e), 1, true); // {NF}imul r25d, dword ptr [r29+r31*2+0x3c26a53e], 1 IID252 + __ eorl(r15, Address(r9, -0x25974a1e), 268435456, false); // {EVEX}or r15d, dword ptr [r9-0x25974a1e], 268435456 IID253 + __ eorl(r11, Address(r16, r15, (Address::ScaleFactor)2, +0x66a0329f), 4096, true); // {NF}or r11d, dword ptr [r16+r15*4+0x66a0329f], 4096 IID254 + __ eorb(rcx, Address(rcx, r27, (Address::ScaleFactor)0, +0x38c6485e), 1, false); // {EVEX}or cl, byte ptr [rcx+r27*1+0x38c6485e], 1 IID255 + __ eorb(r25, Address(r8, r10, (Address::ScaleFactor)0, +0x79131c34), 64, true); // {NF}or r25b, byte ptr [r8+r10*1+0x79131c34], 64 IID256 + __ esall(r13, Address(r9, r31, (Address::ScaleFactor)2, +0x12718ba9), 2, false); // {EVEX}sal r13d, dword ptr [r9+r31*4+0x12718ba9], 2 IID257 + __ esall(r15, Address(r25, -0x505836f3), 16, true); // {NF}sal r15d, dword ptr [r25-0x505836f3], 16 IID258 + __ esarl(r15, Address(rcx, r19, (Address::ScaleFactor)0, +0xc5c1510), 1, false); // {EVEX}sar r15d, dword ptr [rcx+r19*1+0xc5c1510], 1 IID259 + __ esarl(r13, Address(r29, r21, (Address::ScaleFactor)2, -0x6c67309c), 8, true); // {NF}sar r13d, dword ptr [r29+r21*4-0x6c67309c], 8 IID260 + __ eshrl(r11, Address(rbx, +0x749f67d0), 16, false); // {EVEX}shr r11d, dword ptr [rbx+0x749f67d0], 16 IID261 + __ eshrl(r14, Address(r14, -0x55f83db8), 4, true); // {NF}shr r14d, dword ptr [r14-0x55f83db8], 4 IID262 + __ esubl(r30, Address(r21, r26, (Address::ScaleFactor)0, +0x3b4d14e1), 1, false); // {EVEX}sub r30d, dword ptr [r21+r26*1+0x3b4d14e1], 1 IID263 + __ esubl(r28, Address(r18, -0x452348a1), 16777216, true); // {NF}sub r28d, dword ptr [r18-0x452348a1], 16777216 IID264 + __ exorl(rdx, Address(r10, r16, (Address::ScaleFactor)2, -0x161e1d47), 16777216, false); // {EVEX}xor edx, dword ptr [r10+r16*4-0x161e1d47], 16777216 IID265 + __ exorl(rdx, Address(r29, r23, (Address::ScaleFactor)1, +0x1b34e2f8), 16777216, true); // {NF}xor edx, dword ptr [r29+r23*2+0x1b34e2f8], 16777216 IID266 + __ eaddl(r19, Address(r27, r31, (Address::ScaleFactor)0, +0x1f3ce7d8), r29, false); // {EVEX}add r19d, dword ptr [r27+r31*1+0x1f3ce7d8], r29d IID267 + __ eaddl(r28, Address(r24, rcx, (Address::ScaleFactor)3, -0x6053edc2), r28, false); // {EVEX}add r28d, dword ptr [r24+rcx*8-0x6053edc2], r28d IID268 + __ eaddl(r17, Address(r18, r24, (Address::ScaleFactor)3, -0x1bf71f78), r29, true); // {NF}add r17d, dword ptr [r18+r24*8-0x1bf71f78], r29d IID269 + __ eaddl(rcx, Address(r15, r28, (Address::ScaleFactor)1, +0x15b8216), rcx, true); // {NF}add ecx, dword ptr [r15+r28*2+0x15b8216], ecx IID270 + __ eorl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false); // {EVEX}or r30d, dword ptr [rbx+rdx*8-0x463540b4], r28d IID271 + __ eorl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false); // {EVEX}or r18d, dword ptr [r28+r10*8+0x3523a73b], r18d IID272 + __ eorl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true); // {NF}or r9d, dword ptr [r15+r15*2-0x2a0bdd56], r21d IID273 + __ eorl(r16, Address(r23, -0x165064ff), r16, true); // {NF}or r16d, dword ptr [r23-0x165064ff], r16d IID274 + __ eorb(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false); // {EVEX}or r28b, byte ptr [r30+r11*1+0x17281e3a], r20b IID275 + __ eorb(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false); // {EVEX}or dl, byte ptr [rbx+r31*4+0x2477b5bb], dl IID276 + __ eorb(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true); // {NF}or r16b, byte ptr [r11+rcx*2-0x3175d1af], r24b IID277 + __ eorb(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true); // {NF}or bl, byte ptr [r11+r20*8-0x22d67bd3], bl IID278 + __ esubl(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false); // {EVEX}sub r26d, dword ptr [r27+r30*2-0x3d9bce2e], edx IID279 + __ esubl(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false); // {EVEX}sub r31d, dword ptr [r22+r29*2+0x14218519], r31d IID280 + __ esubl(r21, Address(r9, -0x1050127a), r13, true); // {NF}sub r21d, dword ptr [r9-0x1050127a], r13d IID281 + __ esubl(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true); // {NF}sub r31d, dword ptr [r9+r8*1-0xae18961], r31d IID282 + __ exorl(r15, Address(r18, +0x5c2bbce5), r12, false); // {EVEX}xor r15d, dword ptr [r18+0x5c2bbce5], r12d IID283 + __ exorl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false); // {EVEX}xor r27d, dword ptr [r25+r23*1+0x5c6078b3], r27d IID284 + __ exorl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true); // {NF}xor r18d, dword ptr [r8+rdx*8-0x9ed3881], r14d IID285 + __ exorl(r9, Address(r15, +0x775acdad), r9, true); // {NF}xor r9d, dword ptr [r15+0x775acdad], r9d IID286 + __ exorb(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false); // {EVEX}xor r21b, byte ptr [r18+r26*2+0x2fe31fd5], r23b IID287 + __ exorb(r10, Address(r27, +0xa3150de), r10, false); // {EVEX}xor r10b, byte ptr [r27+0xa3150de], r10b IID288 + __ exorb(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true); // {NF}xor r18b, byte ptr [r22+r30*8+0x1ad4e897], r24b IID289 + __ exorb(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true); // {NF}xor r8b, byte ptr [r16+r20*1+0x626eae82], r8b IID290 + __ eaddl(r21, r15, 1048576, false); // {EVEX}add r21d, r15d, 1048576 IID291 + __ eaddl(rax, r18, 1048576, false); // {EVEX}add eax, r18d, 1048576 IID292 + __ eaddl(r18, r18, 256, false); // add r18d, 256 IID293 + __ eaddl(r13, r19, 16, true); // {NF}add r13d, r19d, 16 IID294 + __ eaddl(rax, r23, 16, true); // {NF}add eax, r23d, 16 IID295 + __ eaddl(r25, r25, 16777216, true); // {NF}add r25d, r25d, 16777216 IID296 + __ eandl(r29, r18, 1048576, false); // {EVEX}and r29d, r18d, 1048576 IID297 + __ eandl(rax, r14, 1048576, false); // {EVEX}and eax, r14d, 1048576 IID298 + __ eandl(r19, r19, 65536, false); // and r19d, 65536 IID299 + __ eandl(r27, r25, 1048576, true); // {NF}and r27d, r25d, 1048576 IID300 + __ eandl(rax, r20, 1048576, true); // {NF}and eax, r20d, 1048576 IID301 + __ eandl(r28, r28, 16, true); // {NF}and r28d, r28d, 16 IID302 + __ eimull(r31, r22, 4096, false); // {EVEX}imul r31d, r22d, 4096 IID303 +#endif // _LP64 + __ eimull(rax, rbx, 4096, false); // {EVEX}imul eax, ebx, 4096 IID304 +#ifdef _LP64 + __ eimull(r24, r24, 1048576, false); // {EVEX}imul r24d, r24d, 1048576 IID305 + __ eimull(r21, r16, 65536, true); // {NF}imul r21d, r16d, 65536 IID306 + __ eimull(rax, r24, 65536, true); // {NF}imul eax, r24d, 65536 IID307 + __ eimull(r13, r13, 16, true); // {NF}imul r13d, r13d, 16 IID308 + __ eorl(r29, r8, 16777216, false); // {EVEX}or r29d, r8d, 16777216 IID309 + __ eorl(rax, r12, 16777216, false); // {EVEX}or eax, r12d, 16777216 IID310 + __ eorl(r30, r30, 4096, false); // or r30d, 4096 IID311 + __ eorl(r24, rdx, 16, true); // {NF}or r24d, edx, 16 IID312 + __ eorl(rax, r8, 16, true); // {NF}or eax, r8d, 16 IID313 + __ eorl(r13, r13, 4096, true); // {NF}or r13d, r13d, 4096 IID314 + __ ercll(r25, r13, 1); // {EVEX}rcl r25d, r13d, 1 IID315 + __ ercll(rax, r18, 1); // {EVEX}rcl eax, r18d, 1 IID316 + __ ercll(r9, r9, 16); // rcl r9d, 16 IID317 + __ eroll(r26, r25, 8, false); // {EVEX}rol r26d, r25d, 8 IID318 +#endif // _LP64 + __ eroll(rax, rdx, 8, false); // {EVEX}rol eax, edx, 8 IID319 +#ifdef _LP64 + __ eroll(r24, r24, 16, false); // rol r24d, 16 IID320 + __ eroll(r24, rcx, 8, true); // {NF}rol r24d, ecx, 8 IID321 + __ eroll(rax, r30, 8, true); // {NF}rol eax, r30d, 8 IID322 + __ eroll(r28, r28, 16, true); // {NF}rol r28d, r28d, 16 IID323 + __ erorl(r17, r28, 4, false); // {EVEX}ror r17d, r28d, 4 IID324 +#endif // _LP64 + __ erorl(rax, rdx, 4, false); // {EVEX}ror eax, edx, 4 IID325 +#ifdef _LP64 + __ erorl(r8, r8, 16, false); // ror r8d, 16 IID326 + __ erorl(r19, rdx, 16, true); // {NF}ror r19d, edx, 16 IID327 + __ erorl(rax, r31, 16, true); // {NF}ror eax, r31d, 16 IID328 + __ erorl(r22, r22, 8, true); // {NF}ror r22d, r22d, 8 IID329 + __ esall(r23, r25, 16, false); // {EVEX}sal r23d, r25d, 16 IID330 + __ esall(rax, r14, 16, false); // {EVEX}sal eax, r14d, 16 IID331 + __ esall(r31, r31, 8, false); // sal r31d, 8 IID332 + __ esall(r30, r24, 2, true); // {NF}sal r30d, r24d, 2 IID333 + __ esall(rax, r29, 2, true); // {NF}sal eax, r29d, 2 IID334 + __ esall(r8, r8, 2, true); // {NF}sal r8d, r8d, 2 IID335 + __ esarl(r18, r24, 16, false); // {EVEX}sar r18d, r24d, 16 IID336 + __ esarl(rax, r13, 16, false); // {EVEX}sar eax, r13d, 16 IID337 + __ esarl(r24, r24, 1, false); // sar r24d, 1 IID338 + __ esarl(r28, r17, 16, true); // {NF}sar r28d, r17d, 16 IID339 + __ esarl(rax, r24, 16, true); // {NF}sar eax, r24d, 16 IID340 + __ esarl(r17, r17, 4, true); // {NF}sar r17d, r17d, 4 IID341 + __ eshll(r24, rcx, 4, false); // {EVEX}shl r24d, ecx, 4 IID342 + __ eshll(rax, r16, 4, false); // {EVEX}shl eax, r16d, 4 IID343 + __ eshll(r15, r15, 2, false); // shl r15d, 2 IID344 + __ eshll(r14, r27, 4, true); // {NF}shl r14d, r27d, 4 IID345 + __ eshll(rax, r23, 4, true); // {NF}shl eax, r23d, 4 IID346 + __ eshll(r30, r30, 4, true); // {NF}shl r30d, r30d, 4 IID347 + __ eshrl(r27, rdx, 2, false); // {EVEX}shr r27d, edx, 2 IID348 + __ eshrl(rax, r19, 2, false); // {EVEX}shr eax, r19d, 2 IID349 + __ eshrl(r20, r20, 2, false); // shr r20d, 2 IID350 + __ eshrl(r21, r23, 1, true); // {NF}shr r21d, r23d, 1 IID351 + __ eshrl(rax, r30, 1, true); // {NF}shr eax, r30d, 1 IID352 + __ eshrl(r25, r25, 2, true); // {NF}shr r25d, r25d, 2 IID353 + __ esubl(r24, r19, 1048576, false); // {EVEX}sub r24d, r19d, 1048576 IID354 + __ esubl(rax, r14, 1048576, false); // {EVEX}sub eax, r14d, 1048576 IID355 + __ esubl(r22, r22, 268435456, false); // sub r22d, 268435456 IID356 + __ esubl(r24, r24, 65536, true); // {NF}sub r24d, r24d, 65536 IID357 + __ esubl(rax, r14, 65536, true); // {NF}sub eax, r14d, 65536 IID358 + __ esubl(r28, r28, 268435456, true); // {NF}sub r28d, r28d, 268435456 IID359 + __ exorl(rbx, r20, 256, false); // {EVEX}xor ebx, r20d, 256 IID360 + __ exorl(rax, r15, 256, false); // {EVEX}xor eax, r15d, 256 IID361 +#endif // _LP64 + __ exorl(rbx, rbx, 4096, false); // xor ebx, 4096 IID362 +#ifdef _LP64 + __ exorl(r24, r30, 65536, true); // {NF}xor r24d, r30d, 65536 IID363 + __ exorl(rax, r31, 65536, true); // {NF}xor eax, r31d, 65536 IID364 + __ exorl(r31, r31, 4096, true); // {NF}xor r31d, r31d, 4096 IID365 + __ esubl_imm32(r20, r10, 1048576, false); // {EVEX}sub r20d, r10d, 1048576 IID366 + __ esubl_imm32(rax, r13, 1048576, false); // {EVEX}sub eax, r13d, 1048576 IID367 + __ esubl_imm32(r25, r25, 1048576, false); // sub r25d, 1048576 IID368 + __ esubl_imm32(r23, r12, 1073741824, true); // {NF}sub r23d, r12d, 1073741824 IID369 + __ esubl_imm32(rax, r16, 1073741824, true); // {NF}sub eax, r16d, 1073741824 IID370 + __ esubl_imm32(r31, r31, 65536, true); // {NF}sub r31d, r31d, 65536 IID371 + __ eaddl(r17, r13, Address(r9, +0x7fef2f98), false); // {EVEX}add r17d, r13d, dword ptr [r9+0x7fef2f98] IID372 + __ eaddl(r29, r8, Address(r22, -0x4df70aac), true); // {NF}add r29d, r8d, dword ptr [r22-0x4df70aac] IID373 + __ eandl(r13, r17, Address(r12, r15, (Address::ScaleFactor)3, +0x50a8a902), false); // {EVEX}and r13d, r17d, dword ptr [r12+r15*8+0x50a8a902] IID374 + __ eandl(r22, r25, Address(r26, r10, (Address::ScaleFactor)2, +0x70ea2754), true); // {NF}and r22d, r25d, dword ptr [r26+r10*4+0x70ea2754] IID375 + __ eimull(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false); // {EVEX}imul r19d, r12d, dword ptr [r30+r8*1+0x6a1a0a73] IID376 + __ eimull(r30, r18, Address(r18, r19, (Address::ScaleFactor)2, -0x7fcd28c7), true); // {NF}imul r30d, r18d, dword ptr [r18+r19*4-0x7fcd28c7] IID377 + __ eorl(r16, r31, Address(r25, r11, (Address::ScaleFactor)3, +0x482d5dbc), false); // {EVEX}or r16d, r31d, dword ptr [r25+r11*8+0x482d5dbc] IID378 + __ eorl(r9, r27, Address(r11, +0x43d5ee01), true); // {NF}or r9d, r27d, dword ptr [r11+0x43d5ee01] IID379 + __ esubl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false); // {EVEX}sub ecx, r23d, dword ptr [r21+r15*4+0x2825c2bc] IID380 + __ esubl(r27, r22, Address(r13, r15, (Address::ScaleFactor)1, +0x771f0da7), true); // {NF}sub r27d, r22d, dword ptr [r13+r15*2+0x771f0da7] IID381 + __ exorl(r9, r30, Address(r9, r22, (Address::ScaleFactor)3, -0x4ad6c88e), false); // {EVEX}xor r9d, r30d, dword ptr [r9+r22*8-0x4ad6c88e] IID382 + __ exorl(r11, r16, Address(rbx, r28, (Address::ScaleFactor)2, +0xb0223ee), true); // {NF}xor r11d, r16d, dword ptr [rbx+r28*4+0xb0223ee] IID383 + __ exorb(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false); // {EVEX}xor r15b, r29b, byte ptr [r15+r28*2-0x1f297a69] IID384 + __ exorb(r17, r30, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), true); // {NF}xor r17b, r30b, byte ptr [r23+rbx*2+0xadc7545] IID385 + __ exorw(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), false); // {EVEX}xor r27w, r9w, word ptr [rdx+r22*4-0x43d90f61] IID386 + __ exorw(rbx, r22, Address(r28, r22, (Address::ScaleFactor)0, -0x7d30a0b1), true); // {NF}xor bx, r22w, word ptr [r28+r22*1-0x7d30a0b1] IID387 + __ eaddl(r14, r24, rcx, false); // {load}{EVEX}add r14d, r24d, ecx IID388 + __ eaddl(r8, r8, r17, false); // {load}add r8d, r17d IID389 + __ eaddl(r26, r24, r12, true); // {load}{NF}add r26d, r24d, r12d IID390 + __ eaddl(r24, r24, r23, true); // {load}{NF}add r24d, r24d, r23d IID391 + __ eandl(r13, r26, r31, false); // {load}{EVEX}and r13d, r26d, r31d IID392 + __ eandl(r11, r11, r8, false); // {load}and r11d, r8d IID393 + __ eandl(rcx, r19, r15, true); // {load}{NF}and ecx, r19d, r15d IID394 + __ eandl(r12, r12, r12, true); // {load}{NF}and r12d, r12d, r12d IID395 + __ eimull(r22, r20, r19, false); // {load}{EVEX}imul r22d, r20d, r19d IID396 + __ eimull(r8, r8, rdx, false); // {load}imul r8d, edx IID397 + __ eimull(r22, r27, r23, true); // {load}{NF}imul r22d, r27d, r23d IID398 + __ eimull(r9, r9, r18, true); // {load}{NF}imul r9d, r9d, r18d IID399 + __ eorw(rcx, r30, r13, false); // {load}{EVEX}or cx, r30w, r13w IID400 + __ eorw(r28, r28, r19, false); // {load}or r28w, r19w IID401 + __ eorw(r12, r30, r27, true); // {load}{NF}or r12w, r30w, r27w IID402 + __ eorw(r8, r8, r22, true); // {load}{NF}or r8w, r8w, r22w IID403 + __ eorl(r16, rcx, r30, false); // {load}{EVEX}or r16d, ecx, r30d IID404 + __ eorl(r10, r10, r25, false); // {load}or r10d, r25d IID405 + __ eorl(r15, r17, r17, true); // {load}{NF}or r15d, r17d, r17d IID406 + __ eorl(r9, r9, r30, true); // {load}{NF}or r9d, r9d, r30d IID407 + __ eshldl(r20, r21, r8, false); // {load}{EVEX}shld r20d, r21d, r8d, cl IID408 + __ eshldl(r26, r26, r14, false); // {load}shld r26d, r14d IID409 + __ eshldl(r16, rdx, r14, true); // {load}{NF}shld r16d, edx, r14d, cl IID410 + __ eshldl(r19, r19, r8, true); // {load}{NF}shld r19d, r19d, r8d, cl IID411 + __ eshrdl(r27, rbx, r26, false); // {load}{EVEX}shrd r27d, ebx, r26d, cl IID412 + __ eshrdl(r28, r28, r19, false); // {load}shrd r28d, r19d IID413 + __ eshrdl(rcx, r11, r14, true); // {load}{NF}shrd ecx, r11d, r14d, cl IID414 + __ eshrdl(r31, r31, r19, true); // {load}{NF}shrd r31d, r31d, r19d, cl IID415 + __ esubl(r26, r13, r25, false); // {load}{EVEX}sub r26d, r13d, r25d IID416 + __ esubl(r24, r24, r11, false); // {load}sub r24d, r11d IID417 + __ esubl(r18, r20, r13, true); // {load}{NF}sub r18d, r20d, r13d IID418 + __ esubl(r16, r16, r18, true); // {load}{NF}sub r16d, r16d, r18d IID419 + __ exorl(r19, r17, r8, false); // {load}{EVEX}xor r19d, r17d, r8d IID420 + __ exorl(r19, r19, r13, false); // {load}xor r19d, r13d IID421 + __ exorl(r23, r13, r15, true); // {load}{NF}xor r23d, r13d, r15d IID422 + __ exorl(r11, r11, r29, true); // {load}{NF}xor r11d, r11d, r29d IID423 + __ eshldl(r29, r17, r17, 1, false); // {EVEX}shld r29d, r17d, r17d, 1 IID424 + __ eshldl(r22, r22, r24, 4, false); // shld r22d, r24d, 4 IID425 + __ eshldl(r8, r28, r11, 16, true); // {NF}shld r8d, r28d, r11d, 16 IID426 + __ eshldl(r15, r15, r23, 4, true); // {NF}shld r15d, r15d, r23d, 4 IID427 + __ eshrdl(r29, r22, r16, 4, false); // {EVEX}shrd r29d, r22d, r16d, 4 IID428 + __ eshrdl(r13, r13, r9, 4, false); // shrd r13d, r9d, 4 IID429 + __ eshrdl(r15, r21, r12, 2, true); // {NF}shrd r15d, r21d, r12d, 2 IID430 + __ eshrdl(r17, r17, r23, 2, true); // {NF}shrd r17d, r17d, r23d, 2 IID431 + __ ecmovl (Assembler::Condition::overflow, rdx, r16, r29); // cmovo edx, r16d, r29d IID432 + __ ecmovl (Assembler::Condition::overflow, r10, r10, r21); // cmovo r10d, r21d IID433 + __ ecmovl (Assembler::Condition::noOverflow, r17, r29, r18); // cmovno r17d, r29d, r18d IID434 + __ ecmovl (Assembler::Condition::noOverflow, r28, r28, r24); // cmovno r28d, r24d IID435 + __ ecmovl (Assembler::Condition::below, r10, r20, r27); // cmovb r10d, r20d, r27d IID436 + __ ecmovl (Assembler::Condition::below, r10, r10, r14); // cmovb r10d, r14d IID437 + __ ecmovl (Assembler::Condition::aboveEqual, r11, r27, rcx); // cmovae r11d, r27d, ecx IID438 + __ ecmovl (Assembler::Condition::aboveEqual, r22, r22, r15); // cmovae r22d, r15d IID439 + __ ecmovl (Assembler::Condition::zero, r31, r30, r19); // cmovz r31d, r30d, r19d IID440 + __ ecmovl (Assembler::Condition::zero, r19, r19, r26); // cmovz r19d, r26d IID441 + __ ecmovl (Assembler::Condition::notZero, r21, r14, r26); // cmovnz r21d, r14d, r26d IID442 + __ ecmovl (Assembler::Condition::notZero, r20, r20, r15); // cmovnz r20d, r15d IID443 + __ ecmovl (Assembler::Condition::belowEqual, r12, r13, r23); // cmovbe r12d, r13d, r23d IID444 + __ ecmovl (Assembler::Condition::belowEqual, r28, r28, r20); // cmovbe r28d, r20d IID445 + __ ecmovl (Assembler::Condition::above, r20, r24, r11); // cmova r20d, r24d, r11d IID446 + __ ecmovl (Assembler::Condition::above, r10, r10, r15); // cmova r10d, r15d IID447 + __ ecmovl (Assembler::Condition::negative, r19, r20, r23); // cmovs r19d, r20d, r23d IID448 + __ ecmovl (Assembler::Condition::negative, r15, r15, r26); // cmovs r15d, r26d IID449 + __ ecmovl (Assembler::Condition::positive, r19, r24, r23); // cmovns r19d, r24d, r23d IID450 + __ ecmovl (Assembler::Condition::positive, r28, r28, r11); // cmovns r28d, r11d IID451 + __ ecmovl (Assembler::Condition::parity, r13, r13, rdx); // cmovp r13d, edx IID452 + __ ecmovl (Assembler::Condition::parity, r31, r31, r23); // cmovp r31d, r23d IID453 + __ ecmovl (Assembler::Condition::noParity, r23, r9, r27); // cmovnp r23d, r9d, r27d IID454 + __ ecmovl (Assembler::Condition::noParity, r21, r21, r20); // cmovnp r21d, r20d IID455 + __ ecmovl (Assembler::Condition::less, r24, r21, r29); // cmovl r24d, r21d, r29d IID456 + __ ecmovl (Assembler::Condition::less, rbx, rbx, r11); // cmovl ebx, r11d IID457 + __ ecmovl (Assembler::Condition::greaterEqual, r21, rbx, rcx); // cmovge r21d, ebx, ecx IID458 + __ ecmovl (Assembler::Condition::greaterEqual, r31, r31, r21); // cmovge r31d, r21d IID459 + __ ecmovl (Assembler::Condition::lessEqual, r15, r25, r30); // cmovle r15d, r25d, r30d IID460 + __ ecmovl (Assembler::Condition::lessEqual, r23, r23, r25); // cmovle r23d, r25d IID461 + __ ecmovl (Assembler::Condition::greater, r18, rcx, r10); // cmovg r18d, ecx, r10d IID462 + __ ecmovl (Assembler::Condition::greater, rcx, rcx, r31); // cmovg ecx, r31d IID463 + __ ecmovl (Assembler::Condition::overflow, r21, r19, Address(r26, -0x6e290873)); // cmovo r21d, r19d, dword ptr [r26-0x6e290873] IID464 + __ ecmovl (Assembler::Condition::noOverflow, r24, r19, Address(r22, rcx, (Address::ScaleFactor)0, +0x11f85f9a)); // cmovno r24d, r19d, dword ptr [r22+rcx*1+0x11f85f9a] IID465 + __ ecmovl (Assembler::Condition::below, r17, r24, Address(r20, +0x534d775e)); // cmovb r17d, r24d, dword ptr [r20+0x534d775e] IID466 + __ ecmovl (Assembler::Condition::aboveEqual, r20, r18, Address(r20, -0x47c94ecd)); // cmovae r20d, r18d, dword ptr [r20-0x47c94ecd] IID467 + __ ecmovl (Assembler::Condition::zero, r9, r13, Address(r23, -0x4b83c563)); // cmovz r9d, r13d, dword ptr [r23-0x4b83c563] IID468 + __ ecmovl (Assembler::Condition::notZero, r11, r25, Address(r24, r14, (Address::ScaleFactor)1, -0x446507af)); // cmovnz r11d, r25d, dword ptr [r24+r14*2-0x446507af] IID469 + __ ecmovl (Assembler::Condition::belowEqual, r14, r24, Address(r30, r13, (Address::ScaleFactor)2, +0xd0661d)); // cmovbe r14d, r24d, dword ptr [r30+r13*4+0xd0661d] IID470 + __ ecmovl (Assembler::Condition::above, r13, r25, Address(r14, r27, (Address::ScaleFactor)3, +0x47e1403)); // cmova r13d, r25d, dword ptr [r14+r27*8+0x47e1403] IID471 + __ ecmovl (Assembler::Condition::negative, r24, r19, Address(rcx, rdx, (Address::ScaleFactor)3, -0x644a5318)); // cmovs r24d, r19d, dword ptr [rcx+rdx*8-0x644a5318] IID472 + __ ecmovl (Assembler::Condition::positive, r26, r24, Address(r22, r22, (Address::ScaleFactor)0, +0x70352446)); // cmovns r26d, r24d, dword ptr [r22+r22*1+0x70352446] IID473 + __ ecmovl (Assembler::Condition::parity, r19, r26, Address(r8, r30, (Address::ScaleFactor)2, +0x78a12f5c)); // cmovp r19d, r26d, dword ptr [r8+r30*4+0x78a12f5c] IID474 + __ ecmovl (Assembler::Condition::noParity, r29, r11, Address(r25, r20, (Address::ScaleFactor)0, +0x27a8303a)); // cmovnp r29d, r11d, dword ptr [r25+r20*1+0x27a8303a] IID475 + __ ecmovl (Assembler::Condition::less, r22, r24, Address(r27, r16, (Address::ScaleFactor)1, +0x2541a10)); // cmovl r22d, r24d, dword ptr [r27+r16*2+0x2541a10] IID476 + __ ecmovl (Assembler::Condition::greaterEqual, r31, r15, Address(r8, r16, (Address::ScaleFactor)3, +0x558e3251)); // cmovge r31d, r15d, dword ptr [r8+r16*8+0x558e3251] IID477 + __ ecmovl (Assembler::Condition::lessEqual, r27, r18, Address(r8, r10, (Address::ScaleFactor)0, -0x471987b7)); // cmovle r27d, r18d, dword ptr [r8+r10*1-0x471987b7] IID478 + __ ecmovl (Assembler::Condition::greater, r18, r16, Address(r18, r19, (Address::ScaleFactor)2, -0x120ae81e)); // cmovg r18d, r16d, dword ptr [r18+r19*4-0x120ae81e] IID479 #endif // _LP64 #ifdef _LP64 - __ adcq(r27, rcx); // {load}adc r27, rcx IID378 - __ cmpq(r22, r15); // {load}cmp r22, r15 IID379 - __ imulq(r31, r30); // {load}imul r31, r30 IID380 - __ popcntq(r19, r19); // {load}popcnt r19, r19 IID381 - __ sbbq(r26, r21); // {load}sbb r26, r21 IID382 - __ subq(r14, r26); // {load}sub r14, r26 IID383 - __ tzcntq(r20, r15); // {load}tzcnt r20, r15 IID384 - __ lzcntq(r12, r13); // {load}lzcnt r12, r13 IID385 - __ addq(r23, r28); // {load}add r23, r28 IID386 - __ andq(r20, r20); // {load}and r20, r20 IID387 - __ orq(r24, r11); // {load}or r24, r11 IID388 - __ xorq(r10, r15); // {load}xor r10, r15 IID389 - __ movq(r19, r20); // {load}mov r19, r20 IID390 - __ bsfq(r23, r15); // {load}bsf r23, r15 IID391 - __ bsrq(r26, r19); // {load}bsr r26, r19 IID392 - __ btq(r24, r23); // {load}bt r24, r23 IID393 - __ xchgq(r28, r11); // {load}xchg r28, r11 IID394 - __ testq(r13, r13); // {load}test r13, r13 IID395 - __ addq(Address(r31, r23, (Address::ScaleFactor)3, +0x59da0437), rdx); // add qword ptr [r31+r23*8+0x59da0437], rdx IID396 - __ andq(Address(r21, r20, (Address::ScaleFactor)3, +0x6fd0d557), r27); // and qword ptr [r21+r20*8+0x6fd0d557], r27 IID397 - __ cmpq(Address(r21, +0x23ef6744), r11); // cmp qword ptr [r21+0x23ef6744], r11 IID398 - __ orq(Address(r10, rcx, (Address::ScaleFactor)3, +0x7e8544ab), rcx); // or qword ptr [r10+rcx*8+0x7e8544ab], rcx IID399 - __ xorq(Address(rcx, r24, (Address::ScaleFactor)3, -0x79ca4889), rbx); // xor qword ptr [rcx+r24*8-0x79ca4889], rbx IID400 - __ subq(Address(r27, r31, (Address::ScaleFactor)0, +0x11f85f9a), r27); // sub qword ptr [r27+r31*1+0x11f85f9a], r27 IID401 - __ movq(Address(r20, r16, (Address::ScaleFactor)3, +0x72158dda), r17); // mov qword ptr [r20+r16*8+0x72158dda], r17 IID402 - __ xaddq(Address(r29, r9, (Address::ScaleFactor)2, +0x6e8febd1), r12); // xadd qword ptr [r29+r9*4+0x6e8febd1], r12 IID403 - __ andq(Address(r15, -0x47c94ecd), 268435456); // and qword ptr [r15-0x47c94ecd], 268435456 IID404 - __ addq(Address(r23, r19, (Address::ScaleFactor)1, +0x32bfde3f), 256); // add qword ptr [r23+r19*2+0x32bfde3f], 256 IID405 - __ cmpq(Address(r15, r11, (Address::ScaleFactor)3, +0x548e7560), 4096); // cmp qword ptr [r15+r11*8+0x548e7560], 4096 IID406 - __ sarq(Address(r20, r14, (Address::ScaleFactor)1, +0x1b43fc34), 2); // sar qword ptr [r20+r14*2+0x1b43fc34], 2 IID407 - __ salq(Address(r26, r21, (Address::ScaleFactor)0, -0x3bae50c3), 8); // sal qword ptr [r26+r21*1-0x3bae50c3], 8 IID408 - __ sbbq(Address(r22, r10, (Address::ScaleFactor)3, +0x47e1403), 65536); // sbb qword ptr [r22+r10*8+0x47e1403], 65536 IID409 - __ shrq(Address(rcx, rdx, (Address::ScaleFactor)2, +0x7ea3924d), 16); // shr qword ptr [rcx+rdx*4+0x7ea3924d], 16 IID410 - __ subq(Address(rcx, r26, (Address::ScaleFactor)3, -0x356ea53e), 16); // sub qword ptr [rcx+r26*8-0x356ea53e], 16 IID411 - __ xorq(Address(r30, r26, (Address::ScaleFactor)2, +0x78a12f5c), 16); // xor qword ptr [r30+r26*4+0x78a12f5c], 16 IID412 - __ orq(Address(r11, r10, (Address::ScaleFactor)1, +0x3713b5b5), 268435456); // or qword ptr [r11+r10*2+0x3713b5b5], 268435456 IID413 - __ movq(Address(r30, r30, (Address::ScaleFactor)3, +0x2541a10), 65536); // mov qword ptr [r30+r30*8+0x2541a10], 65536 IID414 - __ testq(Address(r16, r15, (Address::ScaleFactor)3, +0x558e3251), -16); // test qword ptr [r16+r15*8+0x558e3251], -16 IID415 - __ addq(r27, Address(r8, r10, (Address::ScaleFactor)2, +0x635f732d)); // add r27, qword ptr [r8+r10*4+0x635f732d] IID416 - __ andq(r21, Address(r12, r31, (Address::ScaleFactor)0, -0x75e8c4a0)); // and r21, qword ptr [r12+r31*1-0x75e8c4a0] IID417 - __ cmpq(r18, Address(r19, r16, (Address::ScaleFactor)2, -0x120ae81e)); // cmp r18, qword ptr [r19+r16*4-0x120ae81e] IID418 - __ lzcntq(rbx, Address(r31, r30, (Address::ScaleFactor)0, +0x1ec3265d)); // lzcnt rbx, qword ptr [r31+r30*1+0x1ec3265d] IID419 - __ orq(r16, Address(rdx, r26, (Address::ScaleFactor)0, +0x3586831b)); // or r16, qword ptr [rdx+r26*1+0x3586831b] IID420 - __ adcq(r12, Address(r18, -0x3c3e9f7a)); // adc r12, qword ptr [r18-0x3c3e9f7a] IID421 - __ imulq(rcx, Address(r8, r21, (Address::ScaleFactor)3, +0x6b1515ab)); // imul rcx, qword ptr [r8+r21*8+0x6b1515ab] IID422 - __ popcntq(r29, Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d)); // popcnt r29, qword ptr [rcx+r23*4+0x4ff06c4d] IID423 - __ sbbq(r26, Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189)); // sbb r26, qword ptr [r24+r10*2-0x75d9a189] IID424 - __ subq(r17, Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c)); // sub r17, qword ptr [rbx+rbx*1+0x4033d59c] IID425 - __ tzcntq(r18, Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d)); // tzcnt r18, qword ptr [r22+r12*8-0x3893347d] IID426 - __ xorq(r12, Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560)); // xor r12, qword ptr [r20+r23*8+0x4b311560] IID427 - __ movq(r29, Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657)); // mov r29, qword ptr [r10+r28*4+0x5c3a2657] IID428 - __ leaq(r22, Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f)); // lea r22, qword ptr [r13+r25*8+0x1a3d6f3f] IID429 - __ cvttsd2siq(r25, Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8)); // cvttsd2si r25, qword ptr [r17+r24*8-0x35addbd8] IID430 - __ xchgq(r18, Address(r25, +0x632184c3)); // xchg r18, qword ptr [r25+0x632184c3] IID431 - __ testq(r29, Address(r18, r13, (Address::ScaleFactor)1, -0x5039fd8a)); // test r29, qword ptr [r18+r13*2-0x5039fd8a] IID432 - __ addq(r20, 4096); // add r20, 4096 IID433 - __ andq(r9, 16); // and r9, 16 IID434 - __ adcq(rdx, 256); // adc rdx, 256 IID435 - __ cmpq(r22, 16777216); // cmp r22, 16777216 IID436 - __ rclq(r17, 1); // rcl r17, 1 IID437 - __ rcrq(r31, 1); // rcr r31, 1 IID438 - __ rolq(r27, 4); // rol r27, 4 IID439 - __ rorq(r28, 2); // ror r28, 2 IID440 - __ sarq(rcx, 16); // sar rcx, 16 IID441 - __ salq(r31, 8); // sal r31, 8 IID442 - __ sbbq(r27, 1048576); // sbb r27, 1048576 IID443 - __ shlq(r20, 16); // shl r20, 16 IID444 - __ shrq(r31, 8); // shr r31, 8 IID445 - __ subq(r27, 1048576); // sub r27, 1048576 IID446 - __ xorq(r22, 4096); // xor r22, 4096 IID447 - __ movq(r8, 4096); // mov r8, 4096 IID448 - __ mov64(r28, 1099511627776); // mov r28, 1099511627776 IID449 - __ btq(r13, 1); // bt r13, 1 IID450 - __ testq(r16, -1048576); // test r16, -1048576 IID451 - __ orq_imm32(r20, 262144); // or r20, 262144 IID452 - __ subq_imm32(r18, 1048576); // sub r18, 1048576 IID453 - __ cmovq(Assembler::Condition::overflow, rbx, Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615)); // cmovo rbx, qword ptr [r29+r8*1+0x1d022615] IID454 - __ cmovq(Assembler::Condition::noOverflow, rdx, Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2)); // cmovno rdx, qword ptr [r12+r28*2-0x34c898e2] IID455 - __ cmovq(Assembler::Condition::below, r27, Address(r10, rcx, (Address::ScaleFactor)3, -0x1ef7abf1)); // cmovb r27, qword ptr [r10+rcx*8-0x1ef7abf1] IID456 - __ cmovq(Assembler::Condition::aboveEqual, r14, Address(r13, r29, (Address::ScaleFactor)2, -0x7c4c8369)); // cmovae r14, qword ptr [r13+r29*4-0x7c4c8369] IID457 - __ cmovq(Assembler::Condition::zero, r15, Address(r23, rcx, (Address::ScaleFactor)2, -0x6bd22ccf)); // cmovz r15, qword ptr [r23+rcx*4-0x6bd22ccf] IID458 - __ cmovq(Assembler::Condition::notZero, r24, Address(r15, r10, (Address::ScaleFactor)1, -0x7ffb3d09)); // cmovnz r24, qword ptr [r15+r10*2-0x7ffb3d09] IID459 - __ cmovq(Assembler::Condition::belowEqual, r23, Address(r11, +0x276a863b)); // cmovbe r23, qword ptr [r11+0x276a863b] IID460 - __ cmovq(Assembler::Condition::above, r28, Address(r29, +0x3fb4396e)); // cmova r28, qword ptr [r29+0x3fb4396e] IID461 - __ cmovq(Assembler::Condition::negative, r26, Address(r27, rcx, (Address::ScaleFactor)3, +0x4ddea61c)); // cmovs r26, qword ptr [r27+rcx*8+0x4ddea61c] IID462 - __ cmovq(Assembler::Condition::positive, r10, Address(r22, r19, (Address::ScaleFactor)1, +0x2a126966)); // cmovns r10, qword ptr [r22+r19*2+0x2a126966] IID463 - __ cmovq(Assembler::Condition::parity, r12, Address(r10, +0x3d7c59f)); // cmovp r12, qword ptr [r10+0x3d7c59f] IID464 - __ cmovq(Assembler::Condition::noParity, r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d)); // cmovnp r10, qword ptr [r8+r8*8-0xe61862d] IID465 - __ cmovq(Assembler::Condition::less, r23, Address(r29, -0x777ed96d)); // cmovl r23, qword ptr [r29-0x777ed96d] IID466 - __ cmovq(Assembler::Condition::greaterEqual, rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb)); // cmovge rcx, qword ptr [rbx+r19*2+0x53c601cb] IID467 - __ cmovq(Assembler::Condition::lessEqual, r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073)); // cmovle r14, qword ptr [r17+rbx*1-0x768bf073] IID468 - __ cmovq(Assembler::Condition::greater, r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c)); // cmovg r29, qword ptr [r10+r19*2+0x30c98d3c] IID469 - __ call(r10); // call r10 IID470 - __ divq(r16); // div r16 IID471 - __ idivq(r27); // idiv r27 IID472 - __ imulq(r9); // imul r9 IID473 - __ mulq(r13); // mul r13 IID474 - __ negq(r14); // neg r14 IID475 - __ notq(r18); // not r18 IID476 - __ rolq(r28); // rol r28, cl IID477 - __ rorq(r28); // ror r28, cl IID478 - __ sarq(r22); // sar r22, cl IID479 - __ salq(r8); // sal r8, cl IID480 - __ shlq(r12); // shl r12, cl IID481 - __ shrq(rbx); // shr rbx, cl IID482 - __ incrementq(rcx); // inc rcx IID483 - __ decrementq(r23); // dec r23 IID484 - __ pushp(rcx); // pushp rcx IID485 - __ popp(r26); // popp r26 IID486 - __ call(Address(r29, r10, (Address::ScaleFactor)0, +0x5655bc9f)); // call qword ptr [r29+r10*1+0x5655bc9f] IID487 - __ mulq(Address(rdx, r21, (Address::ScaleFactor)3, -0x6798a630)); // mul qword ptr [rdx+r21*8-0x6798a630] IID488 - __ negq(Address(r31, r24, (Address::ScaleFactor)0, -0x20071802)); // neg qword ptr [r31+r24*1-0x20071802] IID489 - __ sarq(Address(r21, rdx, (Address::ScaleFactor)2, -0x343cb9e5)); // sar qword ptr [r21+rdx*4-0x343cb9e5], cl IID490 - __ salq(Address(r20, r24, (Address::ScaleFactor)3, +0xa667574)); // sal qword ptr [r20+r24*8+0xa667574], cl IID491 - __ shrq(Address(r27, +0x76b77974)); // shr qword ptr [r27+0x76b77974], cl IID492 - __ incrementq(Address(r25, -0x534e8d31)); // inc qword ptr [r25-0x534e8d31] IID493 - __ decrementq(Address(r20, -0x180d3ea1)); // dec qword ptr [r20-0x180d3ea1] IID494 - __ imulq(r17, Address(r16, -0x2af2fd58), 4096); // imul r17, qword ptr [r16-0x2af2fd58], 4096 IID495 - __ imulq(r28, r25, 16); // imul r28, r25, 16 IID496 - __ shldq(r27, r13, 16); // shld r27, r13, 16 IID497 - __ shrdq(r8, r10, 16); // shrd r8, r10, 16 IID498 - __ pop2(r14, r8); // {load}pop2 r8, r14 IID499 - __ pop2p(r18, rbx); // {load}pop2p rbx, r18 IID500 - __ push2(r23, r19); // {load}push2 r19, r23 IID501 - __ push2p(r12, rbx); // {load}push2p rbx, r12 IID502 - __ movzbq(r9, Address(r14, r23, (Address::ScaleFactor)3, -0x428d2646)); // movzx r9, byte ptr [r14+r23*8-0x428d2646] IID503 - __ movzwq(r28, Address(r9, rcx, (Address::ScaleFactor)2, -0x72611661)); // movzx r28, word ptr [r9+rcx*4-0x72611661] IID504 - __ movsbq(rbx, Address(r24, r21, (Address::ScaleFactor)2, +0x3a6be990)); // movsx rbx, byte ptr [r24+r21*4+0x3a6be990] IID505 - __ movswq(r16, Address(r22, r10, (Address::ScaleFactor)0, +0x7ef8bdd)); // movsx r16, word ptr [r22+r10*1+0x7ef8bdd] IID506 - __ movzbq(r28, r14); // movzx r28, r14b IID507 - __ movzwq(r13, r28); // movzx r13, r28w IID508 - __ movsbq(r11, rdx); // movsx r11, dl IID509 - __ movswq(r12, r26); // movsx r12, r26w IID510 - __ cmpxchgq(r20, Address(r10, -0xbd2a8da)); // cmpxchg qword ptr [r10-0xbd2a8da], r20 IID511 - __ eidivq(r15, false); // {EVEX}idiv r15 IID512 - __ eidivq(r23, true); // {NF}idiv r23 IID513 - __ edivq(r14, false); // {EVEX}div r14 IID514 - __ edivq(r14, true); // {NF}div r14 IID515 - __ eimulq(r15, false); // {EVEX}imul r15 IID516 - __ eimulq(r20, true); // {NF}imul r20 IID517 - __ emulq(rcx, false); // {EVEX}mul rcx IID518 - __ emulq(r21, true); // {NF}mul r21 IID519 - __ emulq(Address(r16, r10, (Address::ScaleFactor)3, +0x5f66ac1e), false); // {EVEX}mul qword ptr [r16+r10*8+0x5f66ac1e] IID520 - __ emulq(Address(r21, r22, (Address::ScaleFactor)3, -0xbbc807d), true); // {NF}mul qword ptr [r21+r22*8-0xbbc807d] IID521 - __ eimulq(r22, r26, false); // {EVEX}imul r22, r26 IID522 - __ eimulq(r25, r21, true); // {NF}imul r25, r21 IID523 - __ elzcntq(r20, r13, false); // {EVEX}lzcnt r20, r13 IID524 - __ elzcntq(r25, r19, true); // {NF}lzcnt r25, r19 IID525 - __ enegq(r21, r30, false); // {EVEX}neg r21, r30 IID526 - __ enegq(r29, r11, true); // {NF}neg r29, r11 IID527 - __ enotq(r22, r8); // {EVEX}not r22, r8 IID528 - __ epopcntq(r12, r19, false); // {EVEX}popcnt r12, r19 IID529 - __ epopcntq(r29, r23, true); // {NF}popcnt r29, r23 IID530 - __ erolq(r28, r24, false); // {EVEX}rol r28, r24, cl IID531 - __ erolq(rdx, r20, true); // {NF}rol rdx, r20, cl IID532 - __ erorq(rbx, r30, false); // {EVEX}ror rbx, r30, cl IID533 - __ erorq(r10, r15, true); // {NF}ror r10, r15, cl IID534 - __ esalq(r17, r13, false); // {EVEX}sal r17, r13, cl IID535 - __ esalq(r21, r24, true); // {NF}sal r21, r24, cl IID536 - __ esarq(r31, r12, false); // {EVEX}sar r31, r12, cl IID537 - __ esarq(rdx, r24, true); // {NF}sar rdx, r24, cl IID538 - __ edecq(r21, r24, false); // {EVEX}dec r21, r24 IID539 - __ edecq(r15, r31, true); // {NF}dec r15, r31 IID540 - __ eincq(r10, rbx, false); // {EVEX}inc r10, rbx IID541 - __ eincq(r18, r8, true); // {NF}inc r18, r8 IID542 - __ eshlq(r10, r26, false); // {EVEX}shl r10, r26, cl IID543 - __ eshlq(r28, r14, true); // {NF}shl r28, r14, cl IID544 - __ eshrq(r10, r19, false); // {EVEX}shr r10, r19, cl IID545 - __ eshrq(r28, r21, true); // {NF}shr r28, r21, cl IID546 - __ etzcntq(r21, r22, false); // {EVEX}tzcnt r21, r22 IID547 - __ etzcntq(r16, r23, true); // {NF}tzcnt r16, r23 IID548 - __ eimulq(r11, Address(r18, r9, (Address::ScaleFactor)2, -0x132285a1), false); // {EVEX}imul r11, qword ptr [r18+r9*4-0x132285a1] IID549 - __ eimulq(r13, Address(r24, r15, (Address::ScaleFactor)3, +0x48f50ca0), true); // {NF}imul r13, qword ptr [r24+r15*8+0x48f50ca0] IID550 - __ elzcntq(r9, Address(r13, +0x2115cf0e), false); // {EVEX}lzcnt r9, qword ptr [r13+0x2115cf0e] IID551 - __ elzcntq(r27, Address(r30, +0x49cabbb), true); // {NF}lzcnt r27, qword ptr [r30+0x49cabbb] IID552 - __ enegq(r21, Address(r13, r31, (Address::ScaleFactor)2, +0x50a8f4d2), false); // {EVEX}neg r21, qword ptr [r13+r31*4+0x50a8f4d2] IID553 - __ enegq(r22, Address(r18, r20, (Address::ScaleFactor)1, -0x5da0584c), true); // {NF}neg r22, qword ptr [r18+r20*2-0x5da0584c] IID554 - __ epopcntq(r14, Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1), false); // {EVEX}popcnt r14, qword ptr [rbx+r22*4-0x606349d1] IID555 - __ epopcntq(r26, Address(r23, r22, (Address::ScaleFactor)3, -0x72c66c23), true); // {NF}popcnt r26, qword ptr [r23+r22*8-0x72c66c23] IID556 - __ esalq(r26, Address(r9, +0x334aba09), false); // {EVEX}sal r26, qword ptr [r9+0x334aba09], cl IID557 - __ esalq(r9, Address(r9, r30, (Address::ScaleFactor)3, -0x219a6102), true); // {NF}sal r9, qword ptr [r9+r30*8-0x219a6102], cl IID558 - __ esarq(r25, Address(r20, -0x2131bab1), false); // {EVEX}sar r25, qword ptr [r20-0x2131bab1], cl IID559 - __ esarq(r16, Address(r28, r16, (Address::ScaleFactor)1, +0x48c483b9), true); // {NF}sar r16, qword ptr [r28+r16*2+0x48c483b9], cl IID560 - __ edecq(r30, Address(r9, r16, (Address::ScaleFactor)0, -0x88ce84f), false); // {EVEX}dec r30, qword ptr [r9+r16*1-0x88ce84f] IID561 - __ edecq(r11, Address(r30, r29, (Address::ScaleFactor)2, +0x3eeb8fd0), true); // {NF}dec r11, qword ptr [r30+r29*4+0x3eeb8fd0] IID562 - __ eincq(r26, Address(r29, r10, (Address::ScaleFactor)3, +0x3ef4822e), false); // {EVEX}inc r26, qword ptr [r29+r10*8+0x3ef4822e] IID563 - __ eincq(r29, Address(r19, r20, (Address::ScaleFactor)2, -0x3f0f3db9), true); // {NF}inc r29, qword ptr [r19+r20*4-0x3f0f3db9] IID564 - __ eshrq(r8, Address(r30, r20, (Address::ScaleFactor)0, +0x15b56a17), false); // {EVEX}shr r8, qword ptr [r30+r20*1+0x15b56a17], cl IID565 - __ eshrq(r26, Address(r11, -0x2de86561), true); // {NF}shr r26, qword ptr [r11-0x2de86561], cl IID566 - __ etzcntq(r11, Address(rcx, r30, (Address::ScaleFactor)1, -0x32ffb1c2), false); // {EVEX}tzcnt r11, qword ptr [rcx+r30*2-0x32ffb1c2] IID567 - __ etzcntq(r23, Address(r9, r12, (Address::ScaleFactor)1, -0x54823e69), true); // {NF}tzcnt r23, qword ptr [r9+r12*2-0x54823e69] IID568 - __ eaddq(r20, Address(r13, rcx, (Address::ScaleFactor)3, -0x46116c0d), r15, false); // {EVEX}add r20, qword ptr [r13+rcx*8-0x46116c0d], r15 IID569 - __ eaddq(r13, Address(r9, r23, (Address::ScaleFactor)1, -0x286c7605), r16, true); // {NF}add r13, qword ptr [r9+r23*2-0x286c7605], r16 IID570 - __ eandq(r21, Address(r30, r17, (Address::ScaleFactor)0, +0xf4e30b2), r29, false); // {EVEX}and r21, qword ptr [r30+r17*1+0xf4e30b2], r29 IID571 - __ eandq(r30, Address(r17, r31, (Address::ScaleFactor)0, +0x3ab9dec4), r17, true); // {NF}and r30, qword ptr [r17+r31*1+0x3ab9dec4], r17 IID572 - __ eorq(r10, Address(r27, r30, (Address::ScaleFactor)1, -0x197f1266), r28, false); // {EVEX}or r10, qword ptr [r27+r30*2-0x197f1266], r28 IID573 - __ eorq(r9, Address(r29, r30, (Address::ScaleFactor)0, -0x24ea9b08), r11, true); // {NF}or r9, qword ptr [r29+r30*1-0x24ea9b08], r11 IID574 - __ esubq(r15, Address(r14, -0x4f44bf90), r16, false); // {EVEX}sub r15, qword ptr [r14-0x4f44bf90], r16 IID575 - __ esubq(rcx, Address(r21, r18, (Address::ScaleFactor)1, -0x11d0ac8f), r28, true); // {NF}sub rcx, qword ptr [r21+r18*2-0x11d0ac8f], r28 IID576 - __ exorq(r19, Address(r19, r18, (Address::ScaleFactor)0, -0xa5e55ec), r8, false); // {EVEX}xor r19, qword ptr [r19+r18*1-0xa5e55ec], r8 IID577 - __ exorq(r28, Address(r17, r28, (Address::ScaleFactor)1, -0x6eb42fe0), r16, true); // {NF}xor r28, qword ptr [r17+r28*2-0x6eb42fe0], r16 IID578 - __ eaddq(r17, Address(r18, -0x60ab1105), 16777216, false); // {EVEX}add r17, qword ptr [r18-0x60ab1105], 16777216 IID579 - __ eaddq(r25, Address(r19, r25, (Address::ScaleFactor)0, +0x122444d9), 65536, true); // {NF}add r25, qword ptr [r19+r25*1+0x122444d9], 65536 IID580 - __ eandq(r30, Address(r9, r28, (Address::ScaleFactor)1, -0x25b00cf3), 4096, false); // {EVEX}and r30, qword ptr [r9+r28*2-0x25b00cf3], 4096 IID581 - __ eandq(r9, Address(r22, rbx, (Address::ScaleFactor)1, -0x7e465026), 268435456, true); // {NF}and r9, qword ptr [r22+rbx*2-0x7e465026], 268435456 IID582 - __ eimulq(r12, Address(r25, r25, (Address::ScaleFactor)1, -0x432d68cc), 1, false); // {EVEX}imul r12, qword ptr [r25+r25*2-0x432d68cc], 1 IID583 - __ eimulq(r15, Address(r17, r31, (Address::ScaleFactor)3, -0x2b97565e), 16, true); // {NF}imul r15, qword ptr [r17+r31*8-0x2b97565e], 16 IID584 - __ eorq(r28, Address(rdx, r31, (Address::ScaleFactor)0, +0x3f1363b1), 256, false); // {EVEX}or r28, qword ptr [rdx+r31*1+0x3f1363b1], 256 IID585 - __ eorq(r16, Address(r12, r23, (Address::ScaleFactor)3, -0x1785863c), 16777216, true); // {NF}or r16, qword ptr [r12+r23*8-0x1785863c], 16777216 IID586 - __ esalq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), 2, false); // {EVEX}sal r8, qword ptr [r14+r24*4-0x714290a5], 2 IID587 - __ esalq(r8, Address(r15, r14, (Address::ScaleFactor)2, +0x21f13243), 16, true); // {NF}sal r8, qword ptr [r15+r14*4+0x21f13243], 16 IID588 - __ esarq(r10, Address(r13, r29, (Address::ScaleFactor)0, +0x7d04cb72), 2, false); // {EVEX}sar r10, qword ptr [r13+r29*1+0x7d04cb72], 2 IID589 - __ esarq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), 8, true); // {NF}sar r11, qword ptr [r21+r31*8-0x2176b4dc], 8 IID590 - __ eshrq(rcx, Address(r16, r12, (Address::ScaleFactor)1, +0x260c9a38), 4, false); // {EVEX}shr rcx, qword ptr [r16+r12*2+0x260c9a38], 4 IID591 - __ eshrq(r22, Address(r26, r9, (Address::ScaleFactor)0, -0x5e56bb62), 8, true); // {NF}shr r22, qword ptr [r26+r9*1-0x5e56bb62], 8 IID592 - __ esubq(r31, Address(rbx, r28, (Address::ScaleFactor)1, +0x2b00bb10), 1, false); // {EVEX}sub r31, qword ptr [rbx+r28*2+0x2b00bb10], 1 IID593 - __ esubq(r21, Address(r31, -0x6c10f4ad), 4096, true); // {NF}sub r21, qword ptr [r31-0x6c10f4ad], 4096 IID594 - __ exorq(r11, Address(r23, r30, (Address::ScaleFactor)1, +0x51a6026b), 65536, false); // {EVEX}xor r11, qword ptr [r23+r30*2+0x51a6026b], 65536 IID595 - __ exorq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), 16, true); // {NF}xor r14, qword ptr [r27+r10*4-0x34ad9bab], 16 IID596 - __ eaddq(r20, r23, 16777216, false); // {EVEX}add r20, r23, 16777216 IID597 - __ eaddq(rax, r30, 16777216, false); // {EVEX}add rax, r30, 16777216 IID598 - __ eaddq(r9, r21, 4096, true); // {NF}add r9, r21, 4096 IID599 - __ eaddq(rax, rbx, 4096, true); // {NF}add rax, rbx, 4096 IID600 - __ eandq(rdx, r21, 268435456, false); // {EVEX}and rdx, r21, 268435456 IID601 - __ eandq(rax, r8, 268435456, false); // {EVEX}and rax, r8, 268435456 IID602 - __ eandq(r19, r31, 65536, true); // {NF}and r19, r31, 65536 IID603 - __ eandq(rax, rbx, 65536, true); // {NF}and rax, rbx, 65536 IID604 - __ eimulq(r21, r9, 16777216, false); // {EVEX}imul r21, r9, 16777216 IID605 - __ eimulq(rax, r30, 16777216, false); // {EVEX}imul rax, r30, 16777216 IID606 - __ eimulq(r30, r18, 65536, true); // {NF}imul r30, r18, 65536 IID607 - __ eimulq(rax, r19, 65536, true); // {NF}imul rax, r19, 65536 IID608 - __ eorq(r20, r16, 1048576, false); // {EVEX}or r20, r16, 1048576 IID609 - __ eorq(rax, r28, 1048576, false); // {EVEX}or rax, r28, 1048576 IID610 - __ eorq(rbx, r24, 4096, true); // {NF}or rbx, r24, 4096 IID611 - __ eorq(rax, r22, 4096, true); // {NF}or rax, r22, 4096 IID612 - __ erclq(r20, r30, 4); // {EVEX}rcl r20, r30, 4 IID613 - __ erclq(rax, r22, 4); // {EVEX}rcl rax, r22, 4 IID614 - __ erolq(rcx, r28, 2, false); // {EVEX}rol rcx, r28, 2 IID615 - __ erolq(rax, r21, 2, false); // {EVEX}rol rax, r21, 2 IID616 - __ erolq(r26, r15, 4, true); // {NF}rol r26, r15, 4 IID617 - __ erolq(rax, r19, 4, true); // {NF}rol rax, r19, 4 IID618 - __ erorq(r24, r19, 8, false); // {EVEX}ror r24, r19, 8 IID619 - __ erorq(rax, r28, 8, false); // {EVEX}ror rax, r28, 8 IID620 - __ erorq(r25, r18, 4, true); // {NF}ror r25, r18, 4 IID621 - __ erorq(rax, r13, 4, true); // {NF}ror rax, r13, 4 IID622 - __ esalq(r27, r17, 2, false); // {EVEX}sal r27, r17, 2 IID623 - __ esalq(rax, rdx, 2, false); // {EVEX}sal rax, rdx, 2 IID624 - __ esalq(rbx, r28, 16, true); // {NF}sal rbx, r28, 16 IID625 - __ esalq(rax, r15, 16, true); // {NF}sal rax, r15, 16 IID626 - __ esarq(rbx, r12, 4, false); // {EVEX}sar rbx, r12, 4 IID627 - __ esarq(rax, rbx, 4, false); // {EVEX}sar rax, rbx, 4 IID628 - __ esarq(r17, rdx, 2, true); // {NF}sar r17, rdx, 2 IID629 - __ esarq(rax, r31, 2, true); // {NF}sar rax, r31, 2 IID630 - __ eshlq(r21, rbx, 4, false); // {EVEX}shl r21, rbx, 4 IID631 - __ eshlq(rax, r24, 4, false); // {EVEX}shl rax, r24, 4 IID632 - __ eshlq(r27, r13, 16, true); // {NF}shl r27, r13, 16 IID633 - __ eshlq(rax, r25, 16, true); // {NF}shl rax, r25, 16 IID634 - __ eshrq(rcx, r22, 16, false); // {EVEX}shr rcx, r22, 16 IID635 - __ eshrq(rax, r14, 16, false); // {EVEX}shr rax, r14, 16 IID636 - __ eshrq(r11, r30, 4, true); // {NF}shr r11, r30, 4 IID637 - __ eshrq(rax, r24, 4, true); // {NF}shr rax, r24, 4 IID638 - __ esubq(r20, r19, 256, false); // {EVEX}sub r20, r19, 256 IID639 - __ esubq(rax, r17, 256, false); // {EVEX}sub rax, r17, 256 IID640 - __ esubq(r31, r30, 65536, true); // {NF}sub r31, r30, 65536 IID641 - __ esubq(rax, r18, 65536, true); // {NF}sub rax, r18, 65536 IID642 - __ exorq(r18, r11, 4096, false); // {EVEX}xor r18, r11, 4096 IID643 - __ exorq(rax, r10, 4096, false); // {EVEX}xor rax, r10, 4096 IID644 - __ exorq(r24, r18, 268435456, true); // {NF}xor r24, r18, 268435456 IID645 - __ exorq(rax, rbx, 268435456, true); // {NF}xor rax, rbx, 268435456 IID646 - __ eorq_imm32(r26, r21, 4194304, false); // {EVEX}or r26, r21, 4194304 IID647 - __ eorq_imm32(rax, r8, 4194304, false); // {EVEX}or rax, r8, 4194304 IID648 - __ eorq_imm32(r22, r21, 262144, false); // {EVEX}or r22, r21, 262144 IID649 - __ eorq_imm32(rax, r27, 262144, false); // {EVEX}or rax, r27, 262144 IID650 - __ esubq_imm32(r16, r8, 4194304, false); // {EVEX}sub r16, r8, 4194304 IID651 - __ esubq_imm32(rax, rdx, 4194304, false); // {EVEX}sub rax, rdx, 4194304 IID652 - __ esubq_imm32(r20, r31, 1048576, true); // {NF}sub r20, r31, 1048576 IID653 - __ esubq_imm32(rax, r21, 1048576, true); // {NF}sub rax, r21, 1048576 IID654 - __ eaddq(r20, r14, Address(rcx, r16, (Address::ScaleFactor)0, +0x7c6654d9), false); // {EVEX}add r20, r14, qword ptr [rcx+r16*1+0x7c6654d9] IID655 - __ eaddq(r29, rcx, Address(r15, r23, (Address::ScaleFactor)0, +0x45b7f72d), true); // {NF}add r29, rcx, qword ptr [r15+r23*1+0x45b7f72d] IID656 - __ eandq(r19, r17, Address(r13, r22, (Address::ScaleFactor)1, -0x750c1996), false); // {EVEX}and r19, r17, qword ptr [r13+r22*2-0x750c1996] IID657 - __ eandq(r13, r8, Address(r31, r23, (Address::ScaleFactor)1, -0x2211b6b2), true); // {NF}and r13, r8, qword ptr [r31+r23*2-0x2211b6b2] IID658 - __ eorq(r11, r28, Address(r13, r11, (Address::ScaleFactor)3, +0x5c0013ab), false); // {EVEX}or r11, r28, qword ptr [r13+r11*8+0x5c0013ab] IID659 - __ eorq(rdx, r18, Address(r18, rcx, (Address::ScaleFactor)0, +0x59557e71), true); // {NF}or rdx, r18, qword ptr [r18+rcx*1+0x59557e71] IID660 - __ eimulq(r27, r11, Address(r22, -0x28469649), false); // {EVEX}imul r27, r11, qword ptr [r22-0x28469649] IID661 - __ eimulq(r10, r9, Address(r24, +0x49691d54), true); // {NF}imul r10, r9, qword ptr [r24+0x49691d54] IID662 - __ esubq(r24, r12, Address(r19, +0x22d529aa), false); // {EVEX}sub r24, r12, qword ptr [r19+0x22d529aa] IID663 - __ esubq(r20, r18, Address(r9, r10, (Address::ScaleFactor)2, -0x264a7a48), true); // {NF}sub r20, r18, qword ptr [r9+r10*4-0x264a7a48] IID664 - __ exorq(rbx, r9, Address(r14, r27, (Address::ScaleFactor)0, +0xf71c02f), false); // {EVEX}xor rbx, r9, qword ptr [r14+r27*1+0xf71c02f] IID665 - __ exorq(r25, r15, Address(r10, r12, (Address::ScaleFactor)1, +0x732367bd), true); // {NF}xor r25, r15, qword ptr [r10+r12*2+0x732367bd] IID666 - __ eaddq(r11, r9, r10, false); // {load}{EVEX}add r11, r9, r10 IID667 - __ eaddq(r25, r13, r16, true); // {load}{NF}add r25, r13, r16 IID668 - __ eadcxq(r11, r21, r25); // {load}{EVEX}adcx r11, r21, r25 IID669 - __ eadoxq(rdx, r20, rbx); // {load}{EVEX}adox rdx, r20, rbx IID670 - __ eandq(r25, r21, r26, false); // {load}{EVEX}and r25, r21, r26 IID671 - __ eandq(r23, r27, r21, true); // {load}{NF}and r23, r27, r21 IID672 - __ eimulq(r10, r10, r12, false); // {load}{EVEX}imul r10, r10, r12 IID673 - __ eimulq(r31, r12, r23, true); // {load}{NF}imul r31, r12, r23 IID674 - __ eorq(r16, r29, r14, false); // {load}{EVEX}or r16, r29, r14 IID675 - __ eorq(r19, r24, r23, true); // {load}{NF}or r19, r24, r23 IID676 - __ esubq(r14, r21, r15, false); // {load}{EVEX}sub r14, r21, r15 IID677 - __ esubq(r25, r9, r29, true); // {load}{NF}sub r25, r9, r29 IID678 - __ exorq(rdx, r11, r25, false); // {load}{EVEX}xor rdx, r11, r25 IID679 - __ exorq(r19, r10, r16, true); // {load}{NF}xor r19, r10, r16 IID680 - __ eshldq(r8, r23, r31, 8, false); // {EVEX}shld r8, r23, r31, 8 IID681 - __ eshldq(r31, rbx, r16, 2, true); // {NF}shld r31, rbx, r16, 2 IID682 - __ eshrdq(r24, r10, r9, 2, false); // {EVEX}shrd r24, r10, r9, 2 IID683 - __ eshrdq(r28, r26, r18, 16, true); // {NF}shrd r28, r26, r18, 16 IID684 - __ ecmovq (Assembler::Condition::overflow, r25, r20, r16); // cmovo r25, r20, r16 IID685 - __ ecmovq (Assembler::Condition::noOverflow, r21, rbx, r28); // cmovno r21, rbx, r28 IID686 - __ ecmovq (Assembler::Condition::below, r22, r19, r13); // cmovb r22, r19, r13 IID687 - __ ecmovq (Assembler::Condition::aboveEqual, r15, rdx, r8); // cmovae r15, rdx, r8 IID688 - __ ecmovq (Assembler::Condition::zero, r22, r14, r12); // cmovz r22, r14, r12 IID689 - __ ecmovq (Assembler::Condition::notZero, r24, r14, r24); // cmovnz r24, r14, r24 IID690 - __ ecmovq (Assembler::Condition::belowEqual, r13, r21, rbx); // cmovbe r13, r21, rbx IID691 - __ ecmovq (Assembler::Condition::above, rbx, r27, r14); // cmova rbx, r27, r14 IID692 - __ ecmovq (Assembler::Condition::negative, r24, r27, r17); // cmovs r24, r27, r17 IID693 - __ ecmovq (Assembler::Condition::positive, r21, r27, r27); // cmovns r21, r27, r27 IID694 - __ ecmovq (Assembler::Condition::parity, r27, r14, r24); // cmovp r27, r14, r24 IID695 - __ ecmovq (Assembler::Condition::noParity, r28, r29, r22); // cmovnp r28, r29, r22 IID696 - __ ecmovq (Assembler::Condition::less, r15, r13, r31); // cmovl r15, r13, r31 IID697 - __ ecmovq (Assembler::Condition::greaterEqual, r21, r15, r30); // cmovge r21, r15, r30 IID698 - __ ecmovq (Assembler::Condition::lessEqual, r20, r8, r13); // cmovle r20, r8, r13 IID699 - __ ecmovq (Assembler::Condition::greater, r31, r25, r27); // cmovg r31, r25, r27 IID700 - __ ecmovq (Assembler::Condition::overflow, r31, r15, Address(r14, r13, (Address::ScaleFactor)1, -0x6e68556)); // cmovo r31, r15, qword ptr [r14+r13*2-0x6e68556] IID701 - __ ecmovq (Assembler::Condition::noOverflow, r12, r28, Address(r30, r15, (Address::ScaleFactor)3, +0x3ba33f9e)); // cmovno r12, r28, qword ptr [r30+r15*8+0x3ba33f9e] IID702 - __ ecmovq (Assembler::Condition::below, r16, r25, Address(r12, r9, (Address::ScaleFactor)0, -0x28e03b33)); // cmovb r16, r25, qword ptr [r12+r9*1-0x28e03b33] IID703 - __ ecmovq (Assembler::Condition::aboveEqual, r8, r27, Address(r8, r25, (Address::ScaleFactor)3, -0x1e42bd95)); // cmovae r8, r27, qword ptr [r8+r25*8-0x1e42bd95] IID704 - __ ecmovq (Assembler::Condition::zero, rcx, r20, Address(r27, rbx, (Address::ScaleFactor)2, +0x46823c58)); // cmovz rcx, r20, qword ptr [r27+rbx*4+0x46823c58] IID705 - __ ecmovq (Assembler::Condition::notZero, rbx, r12, Address(r21, -0x635b8c8)); // cmovnz rbx, r12, qword ptr [r21-0x635b8c8] IID706 - __ ecmovq (Assembler::Condition::belowEqual, r23, rbx, Address(r27, r26, (Address::ScaleFactor)3, +0x922bcc0)); // cmovbe r23, rbx, qword ptr [r27+r26*8+0x922bcc0] IID707 - __ ecmovq (Assembler::Condition::above, r25, r9, Address(r23, +0xd2a14ec)); // cmova r25, r9, qword ptr [r23+0xd2a14ec] IID708 - __ ecmovq (Assembler::Condition::negative, r11, r19, Address(r11, -0xfb95a9d)); // cmovs r11, r19, qword ptr [r11-0xfb95a9d] IID709 - __ ecmovq (Assembler::Condition::positive, r13, r18, Address(r28, r19, (Address::ScaleFactor)0, +0x716b9b7e)); // cmovns r13, r18, qword ptr [r28+r19*1+0x716b9b7e] IID710 - __ ecmovq (Assembler::Condition::parity, r21, r16, Address(rcx, r29, (Address::ScaleFactor)0, -0x5af0441e)); // cmovp r21, r16, qword ptr [rcx+r29*1-0x5af0441e] IID711 - __ ecmovq (Assembler::Condition::noParity, r12, r31, Address(r20, r26, (Address::ScaleFactor)0, +0xe0b7fb1)); // cmovnp r12, r31, qword ptr [r20+r26*1+0xe0b7fb1] IID712 - __ ecmovq (Assembler::Condition::less, r15, r24, Address(r30, +0x2d3b7b4f)); // cmovl r15, r24, qword ptr [r30+0x2d3b7b4f] IID713 - __ ecmovq (Assembler::Condition::greaterEqual, r12, r15, Address(r14, r21, (Address::ScaleFactor)2, -0x1222aee8)); // cmovge r12, r15, qword ptr [r14+r21*4-0x1222aee8] IID714 - __ ecmovq (Assembler::Condition::lessEqual, rbx, r31, Address(r23, r20, (Address::ScaleFactor)0, -0x96e4d6a)); // cmovle rbx, r31, qword ptr [r23+r20*1-0x96e4d6a] IID715 - __ ecmovq (Assembler::Condition::greater, rdx, rdx, Address(r10, rdx, (Address::ScaleFactor)3, +0x3875f17c)); // cmovg rdx, rdx, qword ptr [r10+rdx*8+0x3875f17c] IID716 + __ adcq(rbx, r31); // {load}adc rbx, r31 IID480 + __ cmpq(r30, r31); // {load}cmp r30, r31 IID481 + __ imulq(r29, r28); // {load}imul r29, r28 IID482 + __ popcntq(r25, r10); // {load}popcnt r25, r10 IID483 + __ sbbq(r24, r20); // {load}sbb r24, r20 IID484 + __ subq(r16, rdx); // {load}sub r16, rdx IID485 + __ tzcntq(r26, r28); // {load}tzcnt r26, r28 IID486 + __ lzcntq(r28, r9); // {load}lzcnt r28, r9 IID487 + __ addq(r20, r24); // {load}add r20, r24 IID488 + __ andq(r24, r29); // {load}and r24, r29 IID489 + __ orq(r23, r27); // {load}or r23, r27 IID490 + __ xorq(r15, r12); // {load}xor r15, r12 IID491 + __ movq(r18, r19); // {load}mov r18, r19 IID492 + __ bsfq(r31, rcx); // {load}bsf r31, rcx IID493 + __ bsrq(r9, r13); // {load}bsr r9, r13 IID494 + __ btq(r20, rcx); // {load}bt r20, rcx IID495 + __ xchgq(r8, r21); // {load}xchg r8, r21 IID496 + __ testq(r24, r14); // {load}test r24, r14 IID497 + __ addq(Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d), r29); // add qword ptr [rcx+r23*4+0x4ff06c4d], r29 IID498 + __ andq(Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189), r26); // and qword ptr [r24+r10*2-0x75d9a189], r26 IID499 + __ cmpq(Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c), r17); // cmp qword ptr [rbx+rbx*1+0x4033d59c], r17 IID500 + __ orq(Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d), r18); // or qword ptr [r22+r12*8-0x3893347d], r18 IID501 + __ xorq(Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560), r12); // xor qword ptr [r20+r23*8+0x4b311560], r12 IID502 + __ subq(Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657), r29); // sub qword ptr [r10+r28*4+0x5c3a2657], r29 IID503 + __ movq(Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f), r22); // mov qword ptr [r13+r25*8+0x1a3d6f3f], r22 IID504 + __ xaddq(Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8), r25); // xadd qword ptr [r17+r24*8-0x35addbd8], r25 IID505 + __ andq(Address(r25, +0x632184c3), 16777216); // and qword ptr [r25+0x632184c3], 16777216 IID506 + __ addq(Address(r13, r13, (Address::ScaleFactor)0, -0x3972eac6), 16777216); // add qword ptr [r13+r13*1-0x3972eac6], 16777216 IID507 + __ cmpq(Address(r9, -0x13b4c806), 4096); // cmp qword ptr [r9-0x13b4c806], 4096 IID508 + __ sarq(Address(r31, +0x4fa7f551), 1); // sar qword ptr [r31+0x4fa7f551], 1 IID509 + __ salq(Address(r21, r31, (Address::ScaleFactor)2, +0x31aa8232), 1); // sal qword ptr [r21+r31*4+0x31aa8232], 1 IID510 + __ sbbq(Address(r24, r31, (Address::ScaleFactor)2, -0x466538b7), 268435456); // sbb qword ptr [r24+r31*4-0x466538b7], 268435456 IID511 + __ shrq(Address(r28, r22, (Address::ScaleFactor)0, -0x3efe85b1), 2); // shr qword ptr [r28+r22*1-0x3efe85b1], 2 IID512 + __ subq(Address(r16, -0x1389a3eb), 1048576); // sub qword ptr [r16-0x1389a3eb], 1048576 IID513 + __ xorq(Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615), 16); // xor qword ptr [r29+r8*1+0x1d022615], 16 IID514 + __ orq(Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2), 1); // or qword ptr [r12+r28*2-0x34c898e2], 1 IID515 + __ movq(Address(rcx, r24, (Address::ScaleFactor)2, -0x1644eb08), 256); // mov qword ptr [rcx+r24*4-0x1644eb08], 256 IID516 + __ testq(Address(r29, -0x7d23890b), -65536); // test qword ptr [r29-0x7d23890b], -65536 IID517 + __ addq(r23, Address(rcx, r19, (Address::ScaleFactor)2, +0x70eac654)); // add r23, qword ptr [rcx+r19*4+0x70eac654] IID518 + __ andq(rdx, Address(r24, r15, (Address::ScaleFactor)0, -0x204ddaa9)); // and rdx, qword ptr [r24+r15*1-0x204ddaa9] IID519 + __ cmpq(rdx, Address(r23, r11, (Address::ScaleFactor)3, +0x32c930bd)); // cmp rdx, qword ptr [r23+r11*8+0x32c930bd] IID520 + __ lzcntq(r28, Address(rdx, -0x5433c28f)); // lzcnt r28, qword ptr [rdx-0x5433c28f] IID521 + __ orq(r22, Address(r19, r14, (Address::ScaleFactor)1, -0x2cc67d38)); // or r22, qword ptr [r19+r14*2-0x2cc67d38] IID522 + __ adcq(r10, Address(r10, +0x3d7c59f)); // adc r10, qword ptr [r10+0x3d7c59f] IID523 + __ imulq(r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d)); // imul r10, qword ptr [r8+r8*8-0xe61862d] IID524 + __ popcntq(r23, Address(r29, -0x777ed96d)); // popcnt r23, qword ptr [r29-0x777ed96d] IID525 + __ sbbq(rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb)); // sbb rcx, qword ptr [rbx+r19*2+0x53c601cb] IID526 + __ subq(r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073)); // sub r14, qword ptr [r17+rbx*1-0x768bf073] IID527 + __ tzcntq(r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c)); // tzcnt r29, qword ptr [r10+r19*2+0x30c98d3c] IID528 + __ xorq(r10, Address(r16, r27, (Address::ScaleFactor)0, -0x3d08d602)); // xor r10, qword ptr [r16+r27*1-0x3d08d602] IID529 + __ movq(r18, Address(r28, r28, (Address::ScaleFactor)3, -0x62fbac91)); // mov r18, qword ptr [r28+r28*8-0x62fbac91] IID530 + __ leaq(rbx, Address(rcx, +0x450602a5)); // lea rbx, qword ptr [rcx+0x450602a5] IID531 + __ cvttsd2siq(r12, Address(r30, r31, (Address::ScaleFactor)0, -0x6798a630)); // cvttsd2si r12, qword ptr [r30+r31*1-0x6798a630] IID532 + __ xchgq(r31, Address(r24, r10, (Address::ScaleFactor)1, -0x706712ed)); // xchg r31, qword ptr [r24+r10*2-0x706712ed] IID533 + __ testq(r14, Address(r13, r20, (Address::ScaleFactor)3, +0x171081f2)); // test r14, qword ptr [r13+r20*8+0x171081f2] IID534 + __ addq(r31, 16); // add r31, 16 IID535 + __ andq(r25, 16); // and r25, 16 IID536 + __ adcq(r23, 256); // adc r23, 256 IID537 + __ cmpq(r19, 268435456); // cmp r19, 268435456 IID538 + __ rclq(r31, 1); // rcl r31, 1 IID539 + __ rcrq(r17, 1); // rcr r17, 1 IID540 + __ rolq(r25, 2); // rol r25, 2 IID541 + __ rorq(r17, 4); // ror r17, 4 IID542 + __ sarq(r28, 1); // sar r28, 1 IID543 + __ salq(r15, 4); // sal r15, 4 IID544 + __ sbbq(rbx, 65536); // sbb rbx, 65536 IID545 + __ shlq(r21, 1); // shl r21, 1 IID546 + __ shrq(r10, 1); // shr r10, 1 IID547 + __ subq(r14, 16); // sub r14, 16 IID548 + __ xorq(r18, 268435456); // xor r18, 268435456 IID549 + __ movq(r23, 16); // mov r23, 16 IID550 + __ mov64(r12, 1099511627776); // mov r12, 1099511627776 IID551 + __ btq(r14, 4); // bt r14, 4 IID552 + __ testq(r24, -4096); // test r24, -4096 IID553 + __ orq_imm32(r19, 1048576); // or r19, 1048576 IID554 + __ subq_imm32(rcx, 268435456); // sub rcx, 268435456 IID555 + __ cmovq(Assembler::Condition::overflow, rdx, Address(r19, rbx, (Address::ScaleFactor)3, +0x211c8c4)); // cmovo rdx, qword ptr [r19+rbx*8+0x211c8c4] IID556 + __ cmovq(Assembler::Condition::noOverflow, rbx, Address(r21, +0x49267743)); // cmovno rbx, qword ptr [r21+0x49267743] IID557 + __ cmovq(Assembler::Condition::below, r21, Address(r8, r28, (Address::ScaleFactor)1, -0x4c8c2946)); // cmovb r21, qword ptr [r8+r28*2-0x4c8c2946] IID558 + __ cmovq(Assembler::Condition::aboveEqual, r12, Address(r26, r20, (Address::ScaleFactor)0, -0x264df89c)); // cmovae r12, qword ptr [r26+r20*1-0x264df89c] IID559 + __ cmovq(Assembler::Condition::zero, r17, Address(r28, r9, (Address::ScaleFactor)2, +0x3497196b)); // cmovz r17, qword ptr [r28+r9*4+0x3497196b] IID560 + __ cmovq(Assembler::Condition::notZero, r13, Address(r15, r23, (Address::ScaleFactor)1, -0x27a30999)); // cmovnz r13, qword ptr [r15+r23*2-0x27a30999] IID561 + __ cmovq(Assembler::Condition::belowEqual, r22, Address(r22, +0xf39ab05)); // cmovbe r22, qword ptr [r22+0xf39ab05] IID562 + __ cmovq(Assembler::Condition::above, rcx, Address(r22, r26, (Address::ScaleFactor)3, -0x48c954c)); // cmova rcx, qword ptr [r22+r26*8-0x48c954c] IID563 + __ cmovq(Assembler::Condition::negative, r25, Address(r19, r21, (Address::ScaleFactor)0, +0xe405b0b)); // cmovs r25, qword ptr [r19+r21*1+0xe405b0b] IID564 + __ cmovq(Assembler::Condition::positive, r12, Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b)); // cmovns r12, qword ptr [r19+r29*8-0x7762044b] IID565 + __ cmovq(Assembler::Condition::parity, rbx, Address(r30, r10, (Address::ScaleFactor)1, -0x19798323)); // cmovp rbx, qword ptr [r30+r10*2-0x19798323] IID566 + __ cmovq(Assembler::Condition::noParity, r21, Address(r24, r31, (Address::ScaleFactor)0, -0x5731652b)); // cmovnp r21, qword ptr [r24+r31*1-0x5731652b] IID567 + __ cmovq(Assembler::Condition::less, r18, Address(r8, r10, (Address::ScaleFactor)1, -0x5613be89)); // cmovl r18, qword ptr [r8+r10*2-0x5613be89] IID568 + __ cmovq(Assembler::Condition::greaterEqual, r28, Address(r21, r21, (Address::ScaleFactor)3, +0x65a0fdc4)); // cmovge r28, qword ptr [r21+r21*8+0x65a0fdc4] IID569 + __ cmovq(Assembler::Condition::lessEqual, r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c)); // cmovle r23, qword ptr [r11+r18*1-0x1d1af10c] IID570 + __ cmovq(Assembler::Condition::greater, r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38)); // cmovg r22, qword ptr [r18+r12*2+0x1a5f1c38] IID571 + __ call(r23); // call r23 IID572 + __ divq(r30); // div r30 IID573 + __ idivq(r19); // idiv r19 IID574 + __ imulq(r9); // imul r9 IID575 + __ mulq(r13); // mul r13 IID576 + __ negq(r16); // neg r16 IID577 + __ notq(r29); // not r29 IID578 + __ rolq(rcx); // rol rcx, cl IID579 + __ rorq(r25); // ror r25, cl IID580 + __ sarq(r8); // sar r8, cl IID581 + __ salq(r27); // sal r27, cl IID582 + __ shlq(r30); // shl r30, cl IID583 + __ shrq(r23); // shr r23, cl IID584 + __ incrementq(rbx); // inc rbx IID585 + __ decrementq(r14); // dec r14 IID586 + __ pushp(r21); // pushp r21 IID587 + __ popp(r21); // popp r21 IID588 + __ call(Address(r20, r21, (Address::ScaleFactor)1, +0x56c6af2f)); // call qword ptr [r20+r21*2+0x56c6af2f] IID589 + __ mulq(Address(r31, r19, (Address::ScaleFactor)3, -0x1b4eb23)); // mul qword ptr [r31+r19*8-0x1b4eb23] IID590 + __ negq(Address(r27, r27, (Address::ScaleFactor)0, -0x58dbfc1f)); // neg qword ptr [r27+r27*1-0x58dbfc1f] IID591 + __ sarq(Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1)); // sar qword ptr [rbx+r22*4-0x606349d1], cl IID592 + __ salq(Address(r26, r23, (Address::ScaleFactor)3, +0xb95a079)); // sal qword ptr [r26+r23*8+0xb95a079], cl IID593 + __ shrq(Address(r14, r26, (Address::ScaleFactor)0, +0x3544e09)); // shr qword ptr [r14+r26*1+0x3544e09], cl IID594 + __ incrementq(Address(r27, rdx, (Address::ScaleFactor)0, +0x120b3250)); // inc qword ptr [r27+rdx*1+0x120b3250] IID595 + __ decrementq(Address(r9, r25, (Address::ScaleFactor)2, -0x34aaeccb)); // dec qword ptr [r9+r25*4-0x34aaeccb] IID596 + __ imulq(r20, Address(r16, r28, (Address::ScaleFactor)1, -0x59de05a5), 1048576); // imul r20, qword ptr [r16+r28*2-0x59de05a5], 1048576 IID597 + __ imulq(r17, r23, 256); // imul r17, r23, 256 IID598 + __ shldq(r19, r11, 8); // shld r19, r11, 8 IID599 + __ shrdq(r28, r10, 8); // shrd r28, r10, 8 IID600 + __ pop2(r29, r26); // {load}pop2 r26, r29 IID601 + __ pop2p(r22, r10); // {load}pop2p r10, r22 IID602 + __ push2(r25, r30); // {load}push2 r30, r25 IID603 + __ push2p(r28, r15); // {load}push2p r15, r28 IID604 + __ movzbq(r11, Address(r29, r19, (Address::ScaleFactor)2, -0x12368d34)); // movzx r11, byte ptr [r29+r19*4-0x12368d34] IID605 + __ movzwq(r14, Address(r8, r30, (Address::ScaleFactor)2, -0x4a9392de)); // movzx r14, word ptr [r8+r30*4-0x4a9392de] IID606 + __ movsbq(r28, Address(r23, r15, (Address::ScaleFactor)0, +0x6189cb54)); // movsx r28, byte ptr [r23+r15*1+0x6189cb54] IID607 + __ movswq(r28, Address(rbx, r23, (Address::ScaleFactor)3, -0x2de86561)); // movsx r28, word ptr [rbx+r23*8-0x2de86561] IID608 + __ movzbq(r11, rcx); // movzx r11, cl IID609 + __ movzwq(r30, r15); // movzx r30, r15w IID610 + __ movsbq(r14, rcx); // movsx r14, cl IID611 + __ movswq(r23, r9); // movsx r23, r9w IID612 + __ cmpxchgq(r12, Address(r13, r10, (Address::ScaleFactor)1, -0x7c62c3a)); // cmpxchg qword ptr [r13+r10*2-0x7c62c3a], r12 IID613 + __ eidivq(rcx, false); // {EVEX}idiv rcx IID614 + __ eidivq(r15, true); // {NF}idiv r15 IID615 + __ edivq(r23, false); // {EVEX}div r23 IID616 + __ edivq(r24, true); // {NF}div r24 IID617 + __ eimulq(r27, false); // {EVEX}imul r27 IID618 + __ eimulq(r30, true); // {NF}imul r30 IID619 + __ emulq(r12, false); // {EVEX}mul r12 IID620 + __ emulq(rcx, true); // {NF}mul rcx IID621 + __ emulq(Address(r13, r9, (Address::ScaleFactor)3, -0x226aab94), false); // {EVEX}mul qword ptr [r13+r9*8-0x226aab94] IID622 + __ emulq(Address(r13, r24, (Address::ScaleFactor)3, -0x286c7605), true); // {NF}mul qword ptr [r13+r24*8-0x286c7605] IID623 + __ eimulq(r21, r30, false); // {EVEX}imul r21, r30 IID624 + __ eimulq(r17, r17, false); // imul r17 IID625 + __ eimulq(r29, r12, true); // {NF}imul r29, r12 IID626 + __ eimulq(r30, r30, true); // {NF}imul r30, r30 IID627 + __ elzcntq(r24, r15, false); // {EVEX}lzcnt r24, r15 IID628 + __ elzcntq(r25, r25, false); // {EVEX}lzcnt r25, r25 IID629 + __ elzcntq(r25, r21, true); // {NF}lzcnt r25, r21 IID630 + __ elzcntq(r22, r22, true); // {NF}lzcnt r22, r22 IID631 + __ enegq(r17, r30, false); // {EVEX}neg r17, r30 IID632 + __ enegq(r17, r17, false); // neg r17 IID633 + __ enegq(r31, r17, true); // {NF}neg r31, r17 IID634 + __ enegq(r29, r29, true); // {NF}neg r29, r29 IID635 + __ enotq(r10, r9); // {EVEX}not r10, r9 IID636 + __ enotq(r24, r24); // not r24 IID637 + __ epopcntq(r28, r15, false); // {EVEX}popcnt r28, r15 IID638 + __ epopcntq(r10, r10, false); // {EVEX}popcnt r10, r10 IID639 + __ epopcntq(r27, r30, true); // {NF}popcnt r27, r30 IID640 + __ epopcntq(r28, r28, true); // {NF}popcnt r28, r28 IID641 + __ erolq(r28, r14, false); // {EVEX}rol r28, r14, cl IID642 + __ erolq(r23, r23, false); // rol r23, cl IID643 + __ erolq(r23, r24, true); // {NF}rol r23, r24, cl IID644 + __ erolq(r21, r21, true); // {NF}rol r21, r21, cl IID645 + __ erorq(r31, r22, false); // {EVEX}ror r31, r22, cl IID646 + __ erorq(r28, r28, false); // ror r28, cl IID647 + __ erorq(r17, r10, true); // {NF}ror r17, r10, cl IID648 + __ erorq(r9, r9, true); // {NF}ror r9, r9, cl IID649 + __ esalq(r29, r30, false); // {EVEX}sal r29, r30, cl IID650 + __ esalq(r11, r11, false); // sal r11, cl IID651 + __ esalq(r26, r11, true); // {NF}sal r26, r11, cl IID652 + __ esalq(r16, r16, true); // {NF}sal r16, r16, cl IID653 + __ esarq(rbx, r15, false); // {EVEX}sar rbx, r15, cl IID654 + __ esarq(r14, r14, false); // sar r14, cl IID655 + __ esarq(r25, r16, true); // {NF}sar r25, r16, cl IID656 + __ esarq(r8, r8, true); // {NF}sar r8, r8, cl IID657 + __ edecq(r11, r13, false); // {EVEX}dec r11, r13 IID658 + __ edecq(rcx, rcx, false); // dec rcx IID659 + __ edecq(r21, r18, true); // {NF}dec r21, r18 IID660 + __ edecq(r28, r28, true); // {NF}dec r28, r28 IID661 + __ eincq(r16, r16, false); // inc r16 IID662 + __ eincq(r29, r29, false); // inc r29 IID663 + __ eincq(r18, r9, true); // {NF}inc r18, r9 IID664 + __ eincq(r19, r19, true); // {NF}inc r19, r19 IID665 + __ eshlq(r19, r18, false); // {EVEX}shl r19, r18, cl IID666 + __ eshlq(r8, r8, false); // shl r8, cl IID667 + __ eshlq(r12, r15, true); // {NF}shl r12, r15, cl IID668 + __ eshlq(r29, r29, true); // {NF}shl r29, r29, cl IID669 + __ eshrq(r28, r24, false); // {EVEX}shr r28, r24, cl IID670 + __ eshrq(r19, r19, false); // shr r19, cl IID671 + __ eshrq(r8, r28, true); // {NF}shr r8, r28, cl IID672 + __ eshrq(r17, r17, true); // {NF}shr r17, r17, cl IID673 + __ etzcntq(r28, r16, false); // {EVEX}tzcnt r28, r16 IID674 + __ etzcntq(r14, r14, false); // {EVEX}tzcnt r14, r14 IID675 + __ etzcntq(r12, r31, true); // {NF}tzcnt r12, r31 IID676 + __ etzcntq(r14, r14, true); // {NF}tzcnt r14, r14 IID677 + __ eimulq(r31, Address(r13, -0x69c4b352), false); // {EVEX}imul r31, qword ptr [r13-0x69c4b352] IID678 + __ eimulq(r17, Address(r18, -0x60ab1105), true); // {NF}imul r17, qword ptr [r18-0x60ab1105] IID679 + __ elzcntq(r27, Address(r14, r25, (Address::ScaleFactor)2, +0x2798bf83), false); // {EVEX}lzcnt r27, qword ptr [r14+r25*4+0x2798bf83] IID680 + __ elzcntq(r23, Address(r10, r11, (Address::ScaleFactor)0, -0x378e635d), true); // {NF}lzcnt r23, qword ptr [r10+r11*1-0x378e635d] IID681 + __ enegq(rcx, Address(r19, r9, (Address::ScaleFactor)3, -0x6847d440), false); // {EVEX}neg rcx, qword ptr [r19+r9*8-0x6847d440] IID682 + __ enegq(rcx, Address(rbx, rcx, (Address::ScaleFactor)0, +0x6f92d38d), true); // {NF}neg rcx, qword ptr [rbx+rcx*1+0x6f92d38d] IID683 + __ epopcntq(r20, Address(r12, -0x2a8b27d6), false); // {EVEX}popcnt r20, qword ptr [r12-0x2a8b27d6] IID684 + __ epopcntq(r31, Address(r30, +0x4603f6d0), true); // {NF}popcnt r31, qword ptr [r30+0x4603f6d0] IID685 + __ esalq(rbx, Address(r24, +0x567d06f9), false); // {EVEX}sal rbx, qword ptr [r24+0x567d06f9], cl IID686 + __ esalq(r12, Address(r24, r28, (Address::ScaleFactor)0, -0x1c4c584e), true); // {NF}sal r12, qword ptr [r24+r28*1-0x1c4c584e], cl IID687 + __ esarq(r12, Address(r23, r24, (Address::ScaleFactor)2, -0x3157bcba), false); // {EVEX}sar r12, qword ptr [r23+r24*4-0x3157bcba], cl IID688 + __ esarq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), true); // {NF}sar r8, qword ptr [r14+r24*4-0x714290a5], cl IID689 + __ edecq(r23, Address(r8, r15, (Address::ScaleFactor)1, -0x5ae272dd), false); // {EVEX}dec r23, qword ptr [r8+r15*2-0x5ae272dd] IID690 + __ edecq(r13, Address(r29, r9, (Address::ScaleFactor)3, -0x5b5174a9), true); // {NF}dec r13, qword ptr [r29+r9*8-0x5b5174a9] IID691 + __ eincq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), false); // {EVEX}inc r11, qword ptr [r21+r31*8-0x2176b4dc] IID692 + __ eincq(r13, Address(rcx, r16, (Address::ScaleFactor)0, -0x36b448c9), true); // {NF}inc r13, qword ptr [rcx+r16*1-0x36b448c9] IID693 + __ eshrq(r26, Address(r25, rcx, (Address::ScaleFactor)2, -0x5f894993), false); // {EVEX}shr r26, qword ptr [r25+rcx*4-0x5f894993], cl IID694 + __ eshrq(r25, Address(r9, +0x51798d21), true); // {NF}shr r25, qword ptr [r9+0x51798d21], cl IID695 + __ etzcntq(r28, Address(r13, r26, (Address::ScaleFactor)2, +0x207196f6), false); // {EVEX}tzcnt r28, qword ptr [r13+r26*4+0x207196f6] IID696 + __ etzcntq(rbx, Address(r19, r13, (Address::ScaleFactor)0, -0x24d937d5), true); // {NF}tzcnt rbx, qword ptr [r19+r13*1-0x24d937d5] IID697 + __ eaddq(r17, Address(r30, +0x3935ccff), r31, false); // {EVEX}add r17, qword ptr [r30+0x3935ccff], r31 IID698 + __ eaddq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), r14, false); // {EVEX}add r14, qword ptr [r27+r10*4-0x34ad9bab], r14 IID699 + __ eaddq(r18, Address(r20, r23, (Address::ScaleFactor)0, +0x5ad3ed4b), r30, true); // {NF}add r18, qword ptr [r20+r23*1+0x5ad3ed4b], r30 IID700 + __ eaddq(r20, Address(rdx, -0x322a99e5), r20, true); // {NF}add r20, qword ptr [rdx-0x322a99e5], r20 IID701 + __ eandq(r31, Address(rbx, r27, (Address::ScaleFactor)3, +0x4ce247d2), r17, false); // {EVEX}and r31, qword ptr [rbx+r27*8+0x4ce247d2], r17 IID702 + __ eandq(r30, Address(r18, r19, (Address::ScaleFactor)1, -0x4ee3d14), r30, false); // {EVEX}and r30, qword ptr [r18+r19*2-0x4ee3d14], r30 IID703 + __ eandq(r28, Address(r11, rbx, (Address::ScaleFactor)3, -0x28994bbf), r24, true); // {NF}and r28, qword ptr [r11+rbx*8-0x28994bbf], r24 IID704 + __ eandq(r30, Address(r22, +0x7d21c24), r30, true); // {NF}and r30, qword ptr [r22+0x7d21c24], r30 IID705 + __ eorq(r26, Address(r15, r19, (Address::ScaleFactor)3, +0x58c21792), r20, false); // {EVEX}or r26, qword ptr [r15+r19*8+0x58c21792], r20 IID706 + __ eorq(r13, Address(r10, r27, (Address::ScaleFactor)2, -0x2c70d333), r13, false); // {EVEX}or r13, qword ptr [r10+r27*4-0x2c70d333], r13 IID707 + __ eorq(rbx, Address(r12, rbx, (Address::ScaleFactor)0, -0x1fb0f1bc), r26, true); // {NF}or rbx, qword ptr [r12+rbx*1-0x1fb0f1bc], r26 IID708 + __ eorq(r31, Address(r27, r31, (Address::ScaleFactor)1, +0x28d1756), r31, true); // {NF}or r31, qword ptr [r27+r31*2+0x28d1756], r31 IID709 + __ esubq(r24, Address(r28, r23, (Address::ScaleFactor)1, +0x6980f610), r27, false); // {EVEX}sub r24, qword ptr [r28+r23*2+0x6980f610], r27 IID710 + __ esubq(r15, Address(r11, r30, (Address::ScaleFactor)3, -0x49777e7), r15, false); // {EVEX}sub r15, qword ptr [r11+r30*8-0x49777e7], r15 IID711 + __ esubq(r17, Address(r25, r13, (Address::ScaleFactor)2, +0x31619e46), r31, true); // {NF}sub r17, qword ptr [r25+r13*4+0x31619e46], r31 IID712 + __ esubq(r18, Address(r11, r10, (Address::ScaleFactor)2, +0x1922861a), r18, true); // {NF}sub r18, qword ptr [r11+r10*4+0x1922861a], r18 IID713 + __ exorq(rbx, Address(r11, -0x4716d420), r21, false); // {EVEX}xor rbx, qword ptr [r11-0x4716d420], r21 IID714 + __ exorq(r8, Address(rdx, r9, (Address::ScaleFactor)2, -0x4cfe39c), r8, false); // {EVEX}xor r8, qword ptr [rdx+r9*4-0x4cfe39c], r8 IID715 + __ exorq(r16, Address(r14, r27, (Address::ScaleFactor)0, +0x7c6654d9), r25, true); // {NF}xor r16, qword ptr [r14+r27*1+0x7c6654d9], r25 IID716 + __ exorq(r29, Address(r15, -0x5efab479), r29, true); // {NF}xor r29, qword ptr [r15-0x5efab479], r29 IID717 + __ eaddq(r19, Address(r13, r22, (Address::ScaleFactor)2, +0x68b64559), 16777216, false); // {EVEX}add r19, qword ptr [r13+r22*4+0x68b64559], 16777216 IID718 + __ eaddq(r16, Address(r13, r31, (Address::ScaleFactor)3, -0x65143af5), 1, true); // {NF}add r16, qword ptr [r13+r31*8-0x65143af5], 1 IID719 + __ eandq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), 1, false); // {EVEX}and r31, qword ptr [r24+r13*2-0x25b16a0e], 1 IID720 + __ eandq(r11, Address(r28, -0xf6d4b26), 65536, true); // {NF}and r11, qword ptr [r28-0xf6d4b26], 65536 IID721 + __ eimulq(rcx, Address(r18, r10, (Address::ScaleFactor)0, +0x46ec6da1), 16777216, false); // {EVEX}imul rcx, qword ptr [r18+r10*1+0x46ec6da1], 16777216 IID722 + __ eimulq(r15, Address(r9, r10, (Address::ScaleFactor)3, -0x7fc36af3), 16, true); // {NF}imul r15, qword ptr [r9+r10*8-0x7fc36af3], 16 IID723 + __ eorq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), 1, false); // {EVEX}or r17, qword ptr [r27+r30*1+0x1b4cda2c], 1 IID724 + __ eorq(rdx, Address(r25, r14, (Address::ScaleFactor)2, -0x59aa6b85), 4096, true); // {NF}or rdx, qword ptr [r25+r14*4-0x59aa6b85], 4096 IID725 + __ esalq(r17, Address(r26, r21, (Address::ScaleFactor)1, -0x6ab1f15f), 8, false); // {EVEX}sal r17, qword ptr [r26+r21*2-0x6ab1f15f], 8 IID726 + __ esalq(r12, Address(r22, r17, (Address::ScaleFactor)0, -0x43ac14ab), 2, true); // {NF}sal r12, qword ptr [r22+r17*1-0x43ac14ab], 2 IID727 + __ esarq(r29, Address(r18, r16, (Address::ScaleFactor)0, -0x59dc0c61), 4, false); // {EVEX}sar r29, qword ptr [r18+r16*1-0x59dc0c61], 4 IID728 + __ esarq(r16, Address(r11, -0x7bdd314), 4, true); // {NF}sar r16, qword ptr [r11-0x7bdd314], 4 IID729 + __ eshrq(r26, Address(r23, r27, (Address::ScaleFactor)3, -0x55b92314), 16, false); // {EVEX}shr r26, qword ptr [r23+r27*8-0x55b92314], 16 IID730 + __ eshrq(r23, Address(r16, r29, (Address::ScaleFactor)1, +0x71311a1d), 2, true); // {NF}shr r23, qword ptr [r16+r29*2+0x71311a1d], 2 IID731 + __ esubq(r25, Address(r9, -0x9532bac), 1048576, false); // {EVEX}sub r25, qword ptr [r9-0x9532bac], 1048576 IID732 + __ esubq(r17, Address(r8, r23, (Address::ScaleFactor)0, +0x55d06ca2), 1048576, true); // {NF}sub r17, qword ptr [r8+r23*1+0x55d06ca2], 1048576 IID733 + __ exorq(r29, Address(r9, r24, (Address::ScaleFactor)0, -0x2c141c1), 1048576, false); // {EVEX}xor r29, qword ptr [r9+r24*1-0x2c141c1], 1048576 IID734 + __ exorq(r28, Address(r22, r19, (Address::ScaleFactor)1, -0x2d9d9abd), 16, true); // {NF}xor r28, qword ptr [r22+r19*2-0x2d9d9abd], 16 IID735 + __ eaddq(r22, r14, 16, false); // {EVEX}add r22, r14, 16 IID736 + __ eaddq(rax, r12, 16, false); // {EVEX}add rax, r12, 16 IID737 + __ eaddq(r24, r24, 65536, false); // add r24, 65536 IID738 + __ eaddq(r21, rbx, 65536, true); // {NF}add r21, rbx, 65536 IID739 + __ eaddq(rax, rbx, 65536, true); // {NF}add rax, rbx, 65536 IID740 + __ eaddq(r24, r24, 65536, true); // {NF}add r24, r24, 65536 IID741 + __ eandq(r21, r27, 16777216, false); // {EVEX}and r21, r27, 16777216 IID742 + __ eandq(rax, r27, 16777216, false); // {EVEX}and rax, r27, 16777216 IID743 + __ eandq(r24, r24, 65536, false); // and r24, 65536 IID744 + __ eandq(r13, r31, 1048576, true); // {NF}and r13, r31, 1048576 IID745 + __ eandq(rax, r21, 1048576, true); // {NF}and rax, r21, 1048576 IID746 + __ eandq(r30, r30, 1048576, true); // {NF}and r30, r30, 1048576 IID747 + __ eimulq(r8, r13, 268435456, false); // {EVEX}imul r8, r13, 268435456 IID748 + __ eimulq(rax, r31, 268435456, false); // {EVEX}imul rax, r31, 268435456 IID749 + __ eimulq(r13, r13, 65536, false); // {EVEX}imul r13, r13, 65536 IID750 + __ eimulq(r14, r29, 1048576, true); // {NF}imul r14, r29, 1048576 IID751 + __ eimulq(rax, r22, 1048576, true); // {NF}imul rax, r22, 1048576 IID752 + __ eimulq(r8, r8, 268435456, true); // {NF}imul r8, r8, 268435456 IID753 + __ eorq(r30, r15, 4096, false); // {EVEX}or r30, r15, 4096 IID754 + __ eorq(rax, r28, 4096, false); // {EVEX}or rax, r28, 4096 IID755 + __ eorq(r26, r26, 1048576, false); // or r26, 1048576 IID756 + __ eorq(r16, r12, 268435456, true); // {NF}or r16, r12, 268435456 IID757 + __ eorq(rax, r9, 268435456, true); // {NF}or rax, r9, 268435456 IID758 + __ eorq(r23, r23, 256, true); // {NF}or r23, r23, 256 IID759 + __ erclq(r15, r9, 16); // {EVEX}rcl r15, r9, 16 IID760 + __ erclq(rax, r8, 16); // {EVEX}rcl rax, r8, 16 IID761 + __ erclq(r25, r25, 1); // rcl r25, 1 IID762 + __ erolq(r9, r17, 16, false); // {EVEX}rol r9, r17, 16 IID763 + __ erolq(rax, r20, 16, false); // {EVEX}rol rax, r20, 16 IID764 + __ erolq(r27, r27, 1, false); // rol r27, 1 IID765 + __ erolq(r20, r31, 1, true); // {NF}rol r20, r31, 1 IID766 + __ erolq(rax, r18, 1, true); // {NF}rol rax, r18, 1 IID767 + __ erolq(r28, r28, 16, true); // {NF}rol r28, r28, 16 IID768 + __ erorq(r26, r18, 16, false); // {EVEX}ror r26, r18, 16 IID769 + __ erorq(rax, r24, 16, false); // {EVEX}ror rax, r24, 16 IID770 + __ erorq(r22, r22, 16, false); // ror r22, 16 IID771 + __ erorq(r27, r29, 1, true); // {NF}ror r27, r29, 1 IID772 + __ erorq(rax, r18, 1, true); // {NF}ror rax, r18, 1 IID773 + __ erorq(r21, r21, 1, true); // {NF}ror r21, r21, 1 IID774 + __ esalq(r12, rcx, 2, false); // {EVEX}sal r12, rcx, 2 IID775 + __ esalq(rax, r24, 2, false); // {EVEX}sal rax, r24, 2 IID776 + __ esalq(r22, r22, 8, false); // sal r22, 8 IID777 + __ esalq(r17, r23, 8, true); // {NF}sal r17, r23, 8 IID778 + __ esalq(rax, r27, 8, true); // {NF}sal rax, r27, 8 IID779 + __ esalq(r23, r23, 1, true); // {NF}sal r23, r23, 1 IID780 + __ esarq(r8, r25, 16, false); // {EVEX}sar r8, r25, 16 IID781 + __ esarq(rax, r23, 16, false); // {EVEX}sar rax, r23, 16 IID782 + __ esarq(r9, r9, 4, false); // sar r9, 4 IID783 + __ esarq(r22, r13, 1, true); // {NF}sar r22, r13, 1 IID784 + __ esarq(rax, r11, 1, true); // {NF}sar rax, r11, 1 IID785 + __ esarq(r12, r12, 2, true); // {NF}sar r12, r12, 2 IID786 + __ eshlq(rcx, r30, 8, false); // {EVEX}shl rcx, r30, 8 IID787 + __ eshlq(rax, r19, 8, false); // {EVEX}shl rax, r19, 8 IID788 + __ eshlq(r13, r13, 2, false); // shl r13, 2 IID789 + __ eshlq(r18, r11, 8, true); // {NF}shl r18, r11, 8 IID790 + __ eshlq(rax, r9, 8, true); // {NF}shl rax, r9, 8 IID791 + __ eshlq(rcx, rcx, 16, true); // {NF}shl rcx, rcx, 16 IID792 + __ eshrq(r10, r22, 4, false); // {EVEX}shr r10, r22, 4 IID793 + __ eshrq(rax, r9, 4, false); // {EVEX}shr rax, r9, 4 IID794 + __ eshrq(r12, r12, 2, false); // shr r12, 2 IID795 + __ eshrq(r26, r31, 8, true); // {NF}shr r26, r31, 8 IID796 + __ eshrq(rax, r12, 8, true); // {NF}shr rax, r12, 8 IID797 + __ eshrq(r28, r28, 1, true); // {NF}shr r28, r28, 1 IID798 + __ esubq(r15, r30, 65536, false); // {EVEX}sub r15, r30, 65536 IID799 + __ esubq(rax, rcx, 65536, false); // {EVEX}sub rax, rcx, 65536 IID800 + __ esubq(r26, r26, 16, false); // sub r26, 16 IID801 + __ esubq(r12, r14, 1, true); // {NF}sub r12, r14, 1 IID802 + __ esubq(rax, r21, 1, true); // {NF}sub rax, r21, 1 IID803 + __ esubq(r20, r20, 1048576, true); // {NF}sub r20, r20, 1048576 IID804 + __ exorq(r11, rbx, 16777216, false); // {EVEX}xor r11, rbx, 16777216 IID805 + __ exorq(rax, r23, 16777216, false); // {EVEX}xor rax, r23, 16777216 IID806 + __ exorq(r31, r31, 268435456, false); // xor r31, 268435456 IID807 + __ exorq(r29, r28, 4096, true); // {NF}xor r29, r28, 4096 IID808 + __ exorq(rax, r19, 4096, true); // {NF}xor rax, r19, 4096 IID809 + __ exorq(rdx, rdx, 268435456, true); // {NF}xor rdx, rdx, 268435456 IID810 + __ eorq_imm32(rdx, rdx, 1048576, false); // or rdx, 1048576 IID811 + __ eorq_imm32(rax, r22, 1048576, false); // {EVEX}or rax, r22, 1048576 IID812 + __ eorq_imm32(r29, r29, 1048576, false); // or r29, 1048576 IID813 + __ eorq_imm32(r17, rcx, 4194304, false); // {EVEX}or r17, rcx, 4194304 IID814 + __ eorq_imm32(rax, r25, 4194304, false); // {EVEX}or rax, r25, 4194304 IID815 + __ eorq_imm32(r27, r27, 1073741824, false); // or r27, 1073741824 IID816 + __ esubq_imm32(r16, r19, 4194304, false); // {EVEX}sub r16, r19, 4194304 IID817 + __ esubq_imm32(rax, r31, 4194304, false); // {EVEX}sub rax, r31, 4194304 IID818 + __ esubq_imm32(r26, r26, 262144, false); // sub r26, 262144 IID819 + __ esubq_imm32(r17, r22, 1073741824, true); // {NF}sub r17, r22, 1073741824 IID820 + __ esubq_imm32(rax, r18, 1073741824, true); // {NF}sub rax, r18, 1073741824 IID821 + __ esubq_imm32(r23, r23, 268435456, true); // {NF}sub r23, r23, 268435456 IID822 + __ eaddq(r13, r30, Address(r24, r19, (Address::ScaleFactor)1, +0x56ea3a3b), false); // {EVEX}add r13, r30, qword ptr [r24+r19*2+0x56ea3a3b] IID823 + __ eaddq(r29, r15, Address(r26, r27, (Address::ScaleFactor)3, -0x4b113958), true); // {NF}add r29, r15, qword ptr [r26+r27*8-0x4b113958] IID824 + __ eandq(r12, r30, Address(r31, -0x46103c74), false); // {EVEX}and r12, r30, qword ptr [r31-0x46103c74] IID825 + __ eandq(r27, r10, Address(r22, r25, (Address::ScaleFactor)1, +0x6a1ebee5), true); // {NF}and r27, r10, qword ptr [r22+r25*2+0x6a1ebee5] IID826 + __ eorq(r30, r26, Address(r11, r18, (Address::ScaleFactor)2, -0x2b9fff29), false); // {EVEX}or r30, r26, qword ptr [r11+r18*4-0x2b9fff29] IID827 + __ eorq(r9, r12, Address(r18, r17, (Address::ScaleFactor)0, +0xb4859f6), true); // {NF}or r9, r12, qword ptr [r18+r17*1+0xb4859f6] IID828 + __ eimulq(rdx, r17, Address(r24, rdx, (Address::ScaleFactor)2, +0x3d284cd8), false); // {EVEX}imul rdx, r17, qword ptr [r24+rdx*4+0x3d284cd8] IID829 + __ eimulq(r29, r26, Address(r30, r12, (Address::ScaleFactor)1, +0x6e813124), true); // {NF}imul r29, r26, qword ptr [r30+r12*2+0x6e813124] IID830 + __ esubq(rbx, r13, Address(r22, -0x702a289e), false); // {EVEX}sub rbx, r13, qword ptr [r22-0x702a289e] IID831 + __ esubq(r23, r29, Address(r25, rdx, (Address::ScaleFactor)0, -0x6252a7ed), true); // {NF}sub r23, r29, qword ptr [r25+rdx*1-0x6252a7ed] IID832 + __ exorq(r8, r18, Address(r19, r14, (Address::ScaleFactor)2, -0xebfa697), false); // {EVEX}xor r8, r18, qword ptr [r19+r14*4-0xebfa697] IID833 + __ exorq(r10, r28, Address(r26, +0x168381ca), true); // {NF}xor r10, r28, qword ptr [r26+0x168381ca] IID834 + __ eaddq(rcx, r18, r8, false); // {load}{EVEX}add rcx, r18, r8 IID835 + __ eaddq(rcx, rcx, r14, false); // {load}add rcx, r14 IID836 + __ eaddq(r23, r10, r16, true); // {load}{NF}add r23, r10, r16 IID837 + __ eaddq(r11, r11, r24, true); // {load}{NF}add r11, r11, r24 IID838 + __ eadcxq(r9, r18, rdx); // {load}{EVEX}adcx r9, r18, rdx IID839 + __ eadcxq(r8, r8, r15); // {load}adcx r8, r15 IID840 + __ eadoxq(r15, r22, r26); // {load}{EVEX}adox r15, r22, r26 IID841 + __ eadoxq(r11, r11, rdx); // {load}adox r11, rdx IID842 + __ eandq(r19, rdx, r22, false); // {load}{EVEX}and r19, rdx, r22 IID843 + __ eandq(r29, r29, r17, false); // {load}and r29, r17 IID844 + __ eandq(r23, r27, r15, true); // {load}{NF}and r23, r27, r15 IID845 + __ eandq(r9, r9, r13, true); // {load}{NF}and r9, r9, r13 IID846 + __ eimulq(r18, r15, r16, false); // {load}{EVEX}imul r18, r15, r16 IID847 + __ eimulq(rcx, rcx, r17, false); // {load}imul rcx, r17 IID848 + __ eimulq(r23, r12, r20, true); // {load}{NF}imul r23, r12, r20 IID849 + __ eimulq(r10, r10, r9, true); // {load}{NF}imul r10, r10, r9 IID850 + __ eorq(rdx, r19, r14, false); // {load}{EVEX}or rdx, r19, r14 IID851 + __ eorq(rcx, rcx, r13, false); // {load}or rcx, r13 IID852 + __ eorq(r9, r25, r29, true); // {load}{NF}or r9, r25, r29 IID853 + __ eorq(rdx, rdx, r25, true); // {load}{NF}or rdx, rdx, r25 IID854 + __ esubq(r23, r8, r16, false); // {load}{EVEX}sub r23, r8, r16 IID855 + __ esubq(r13, r13, r13, false); // {load}sub r13, r13 IID856 + __ esubq(r19, r12, r15, true); // {load}{NF}sub r19, r12, r15 IID857 + __ esubq(r9, r9, rdx, true); // {load}{NF}sub r9, r9, rdx IID858 + __ exorq(r13, r16, r31, false); // {load}{EVEX}xor r13, r16, r31 IID859 + __ exorq(r17, r17, r30, false); // {load}xor r17, r30 IID860 + __ exorq(r19, r30, r20, true); // {load}{NF}xor r19, r30, r20 IID861 + __ exorq(r31, r31, r13, true); // {load}{NF}xor r31, r31, r13 IID862 + __ eshldq(r22, r10, r13, 4, false); // {EVEX}shld r22, r10, r13, 4 IID863 + __ eshldq(r24, r24, r21, 16, false); // shld r24, r21, 16 IID864 + __ eshldq(r20, r13, r27, 16, true); // {NF}shld r20, r13, r27, 16 IID865 + __ eshldq(r31, r31, r19, 2, true); // {NF}shld r31, r31, r19, 2 IID866 + __ eshrdq(r30, r20, r11, 8, false); // {EVEX}shrd r30, r20, r11, 8 IID867 + __ eshrdq(rdx, rdx, r15, 1, false); // shrd rdx, r15, 1 IID868 + __ eshrdq(r28, r30, r14, 2, true); // {NF}shrd r28, r30, r14, 2 IID869 + __ eshrdq(r20, r20, r16, 1, true); // {NF}shrd r20, r20, r16, 1 IID870 + __ ecmovq (Assembler::Condition::overflow, r21, r17, r28); // cmovo r21, r17, r28 IID871 + __ ecmovq (Assembler::Condition::overflow, r15, r15, r30); // cmovo r15, r30 IID872 + __ ecmovq (Assembler::Condition::noOverflow, rcx, r15, r15); // cmovno rcx, r15, r15 IID873 + __ ecmovq (Assembler::Condition::noOverflow, rcx, rcx, r13); // cmovno rcx, r13 IID874 + __ ecmovq (Assembler::Condition::below, rdx, r26, r26); // cmovb rdx, r26, r26 IID875 + __ ecmovq (Assembler::Condition::below, r28, r28, r15); // cmovb r28, r15 IID876 + __ ecmovq (Assembler::Condition::aboveEqual, r8, rdx, rcx); // cmovae r8, rdx, rcx IID877 + __ ecmovq (Assembler::Condition::aboveEqual, rcx, rcx, rcx); // cmovae rcx, rcx IID878 + __ ecmovq (Assembler::Condition::zero, r10, r13, r9); // cmovz r10, r13, r9 IID879 + __ ecmovq (Assembler::Condition::zero, r14, r14, r27); // cmovz r14, r27 IID880 + __ ecmovq (Assembler::Condition::notZero, r11, r23, r9); // cmovnz r11, r23, r9 IID881 + __ ecmovq (Assembler::Condition::notZero, r11, r11, rdx); // cmovnz r11, rdx IID882 + __ ecmovq (Assembler::Condition::belowEqual, r31, r14, r25); // cmovbe r31, r14, r25 IID883 + __ ecmovq (Assembler::Condition::belowEqual, r20, r20, r12); // cmovbe r20, r12 IID884 + __ ecmovq (Assembler::Condition::above, rdx, r10, r28); // cmova rdx, r10, r28 IID885 + __ ecmovq (Assembler::Condition::above, r8, r8, r17); // cmova r8, r17 IID886 + __ ecmovq (Assembler::Condition::negative, rcx, r30, r23); // cmovs rcx, r30, r23 IID887 + __ ecmovq (Assembler::Condition::negative, r26, r26, r18); // cmovs r26, r18 IID888 + __ ecmovq (Assembler::Condition::positive, rdx, rbx, r18); // cmovns rdx, rbx, r18 IID889 + __ ecmovq (Assembler::Condition::positive, r21, r21, r13); // cmovns r21, r13 IID890 + __ ecmovq (Assembler::Condition::parity, r27, r28, r27); // cmovp r27, r28, r27 IID891 + __ ecmovq (Assembler::Condition::parity, r11, r11, r30); // cmovp r11, r30 IID892 + __ ecmovq (Assembler::Condition::noParity, rcx, r21, r18); // cmovnp rcx, r21, r18 IID893 + __ ecmovq (Assembler::Condition::noParity, rcx, rcx, r29); // cmovnp rcx, r29 IID894 + __ ecmovq (Assembler::Condition::less, rdx, r21, r12); // cmovl rdx, r21, r12 IID895 + __ ecmovq (Assembler::Condition::less, rdx, rdx, r26); // cmovl rdx, r26 IID896 + __ ecmovq (Assembler::Condition::greaterEqual, r17, rbx, r22); // cmovge r17, rbx, r22 IID897 + __ ecmovq (Assembler::Condition::greaterEqual, rdx, rdx, r11); // cmovge rdx, r11 IID898 + __ ecmovq (Assembler::Condition::lessEqual, rdx, r14, r8); // cmovle rdx, r14, r8 IID899 + __ ecmovq (Assembler::Condition::lessEqual, r14, r14, r8); // cmovle r14, r8 IID900 + __ ecmovq (Assembler::Condition::greater, r25, r29, r21); // cmovg r25, r29, r21 IID901 + __ ecmovq (Assembler::Condition::greater, r26, r26, r30); // cmovg r26, r30 IID902 + __ ecmovq (Assembler::Condition::overflow, r24, r21, Address(r13, r11, (Address::ScaleFactor)1, +0x439c521e)); // cmovo r24, r21, qword ptr [r13+r11*2+0x439c521e] IID903 + __ ecmovq (Assembler::Condition::noOverflow, r11, r18, Address(r29, r16, (Address::ScaleFactor)0, +0x632127f)); // cmovno r11, r18, qword ptr [r29+r16*1+0x632127f] IID904 + __ ecmovq (Assembler::Condition::below, r16, r8, Address(r8, r26, (Address::ScaleFactor)1, +0x10633def)); // cmovb r16, r8, qword ptr [r8+r26*2+0x10633def] IID905 + __ ecmovq (Assembler::Condition::aboveEqual, r13, r14, Address(r18, -0x54f69e38)); // cmovae r13, r14, qword ptr [r18-0x54f69e38] IID906 + __ ecmovq (Assembler::Condition::zero, r12, r8, Address(r31, r26, (Address::ScaleFactor)1, -0x7a1e447a)); // cmovz r12, r8, qword ptr [r31+r26*2-0x7a1e447a] IID907 + __ ecmovq (Assembler::Condition::notZero, r29, r29, Address(r19, r11, (Address::ScaleFactor)2, -0x35d82dd2)); // cmovnz r29, qword ptr [r19+r11*4-0x35d82dd2] IID908 + __ ecmovq (Assembler::Condition::belowEqual, rcx, r18, Address(r25, r28, (Address::ScaleFactor)0, +0x30be64a0)); // cmovbe rcx, r18, qword ptr [r25+r28*1+0x30be64a0] IID909 + __ ecmovq (Assembler::Condition::above, r28, r12, Address(r10, r16, (Address::ScaleFactor)1, -0x22b8fefa)); // cmova r28, r12, qword ptr [r10+r16*2-0x22b8fefa] IID910 + __ ecmovq (Assembler::Condition::negative, r11, r8, Address(rbx, r11, (Address::ScaleFactor)3, +0x25cc9e96)); // cmovs r11, r8, qword ptr [rbx+r11*8+0x25cc9e96] IID911 + __ ecmovq (Assembler::Condition::positive, r12, r27, Address(r11, -0xc2d70fe)); // cmovns r12, r27, qword ptr [r11-0xc2d70fe] IID912 + __ ecmovq (Assembler::Condition::parity, r8, r26, Address(r19, rbx, (Address::ScaleFactor)1, -0x486db7ea)); // cmovp r8, r26, qword ptr [r19+rbx*2-0x486db7ea] IID913 + __ ecmovq (Assembler::Condition::noParity, r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884)); // cmovnp r30, r10, qword ptr [r14+r18*8+0x14884884] IID914 + __ ecmovq (Assembler::Condition::less, r27, r8, Address(r29, r14, (Address::ScaleFactor)2, +0x92b7a8)); // cmovl r27, r8, qword ptr [r29+r14*4+0x92b7a8] IID915 + __ ecmovq (Assembler::Condition::greaterEqual, r14, r28, Address(r19, rdx, (Address::ScaleFactor)0, +0x9c2d45)); // cmovge r14, r28, qword ptr [r19+rdx*1+0x9c2d45] IID916 + __ ecmovq (Assembler::Condition::lessEqual, r25, r8, Address(rcx, r18, (Address::ScaleFactor)2, +0x6655c86b)); // cmovle r25, r8, qword ptr [rcx+r18*4+0x6655c86b] IID917 + __ ecmovq (Assembler::Condition::greater, r19, r21, Address(r10, r25, (Address::ScaleFactor)0, -0x1005430b)); // cmovg r19, r21, qword ptr [r10+r25*1-0x1005430b] IID918 #endif // _LP64 static const uint8_t insns[] = @@ -927,545 +1145,763 @@ 0x62, 0xbc, 0x7c, 0x08, 0xf7, 0xa4, 0x56, 0xaa, 0x64, 0xc8, 0xc2, // IID177 0x62, 0xd4, 0x7c, 0x0c, 0xf7, 0xa3, 0x51, 0x10, 0xb6, 0xcd, // IID178 0x62, 0x7c, 0x7c, 0x08, 0xf5, 0xc8, // IID179 - 0x62, 0xcc, 0x7c, 0x0c, 0xf5, 0xfc, // IID180 - 0x62, 0xdc, 0x3c, 0x18, 0xf7, 0xde, // IID181 - 0x62, 0xd4, 0x44, 0x14, 0xf7, 0xdb, // IID182 - 0x62, 0x7c, 0x7c, 0x08, 0x88, 0xe8, // IID183 - 0x62, 0x54, 0x7c, 0x0c, 0x88, 0xdb, // IID184 - 0x62, 0xf4, 0x2c, 0x10, 0xf7, 0xd1, // IID185 - 0x62, 0xd4, 0x64, 0x18, 0xd3, 0xc2, // IID186 - 0x62, 0xdc, 0x0c, 0x1c, 0xd3, 0xc5, // IID187 - 0x62, 0xfc, 0x04, 0x18, 0xd3, 0xcc, // IID188 - 0x62, 0xd4, 0x74, 0x14, 0xd3, 0xcc, // IID189 - 0x62, 0xf4, 0x1c, 0x18, 0xd3, 0xe3, // IID190 - 0x62, 0xdc, 0x44, 0x14, 0xd3, 0xe3, // IID191 - 0x62, 0xfc, 0x14, 0x10, 0xd3, 0xfc, // IID192 - 0x62, 0xf4, 0x1c, 0x14, 0xd3, 0xfa, // IID193 - 0x62, 0xdc, 0x3c, 0x18, 0xff, 0xcb, // IID194 - 0x62, 0xd4, 0x64, 0x1c, 0xff, 0xcf, // IID195 - 0x62, 0xdc, 0x24, 0x18, 0xff, 0xc3, // IID196 - 0x62, 0xdc, 0x14, 0x14, 0xff, 0xc1, // IID197 - 0x62, 0xd4, 0x1c, 0x18, 0xd3, 0xe0, // IID198 - 0x62, 0xfc, 0x24, 0x1c, 0xd3, 0xe2, // IID199 - 0x62, 0xd4, 0x6c, 0x18, 0xd3, 0xed, // IID200 - 0x62, 0xdc, 0x44, 0x14, 0xd3, 0xe8, // IID201 - 0x62, 0x54, 0x7c, 0x08, 0xf4, 0xff, // IID202 - 0x62, 0x4c, 0x7c, 0x0c, 0xf4, 0xd4, // IID203 - 0x62, 0x9c, 0x7c, 0x08, 0xf5, 0x9c, 0x31, 0xb6, 0xfd, 0x13, 0x1c, // IID204 - 0x62, 0x1c, 0x78, 0x0c, 0xf5, 0x8c, 0xe7, 0x81, 0x74, 0x40, 0xcf, // IID205 - 0x62, 0xdc, 0x3c, 0x18, 0xf7, 0x99, 0x1e, 0xf0, 0x37, 0xf6, // IID206 - 0x62, 0xdc, 0x48, 0x14, 0xf7, 0x9c, 0x9b, 0x09, 0x7c, 0xf2, 0x38, // IID207 - 0x62, 0x84, 0x78, 0x08, 0x88, 0xac, 0xb6, 0x7b, 0x2c, 0xf9, 0x39, // IID208 - 0x62, 0x2c, 0x7c, 0x0c, 0x88, 0x94, 0xf7, 0xc3, 0xe4, 0xd1, 0x9f, // IID209 - 0x62, 0xdc, 0x30, 0x10, 0xd3, 0xa4, 0x7c, 0xef, 0x20, 0xf1, 0x4f, // IID210 - 0x62, 0xdc, 0x10, 0x14, 0xd3, 0xa4, 0xc0, 0xbd, 0x44, 0xde, 0x97, // IID211 - 0x62, 0x94, 0x40, 0x10, 0xd3, 0xbc, 0xbb, 0xbb, 0x24, 0x42, 0x7f, // IID212 - 0x62, 0xbc, 0x18, 0x1c, 0xd3, 0xbc, 0x7f, 0x58, 0x78, 0x70, 0xfd, // IID213 - 0x62, 0xbc, 0x60, 0x10, 0xff, 0x8c, 0x70, 0xf3, 0x61, 0x47, 0xd8, // IID214 - 0x62, 0xdc, 0x2c, 0x14, 0xff, 0x89, 0x48, 0x5d, 0x14, 0x3d, // IID215 - 0x62, 0x9c, 0x10, 0x18, 0xff, 0x84, 0x43, 0x62, 0x38, 0x5f, 0x62, // IID216 - 0x62, 0xfc, 0x24, 0x1c, 0xff, 0x86, 0xa6, 0x04, 0x59, 0x76, // IID217 - 0x62, 0xf4, 0x30, 0x10, 0xd3, 0xac, 0x4a, 0x91, 0xc8, 0xaf, 0x82, // IID218 - 0x62, 0xd4, 0x4c, 0x14, 0xd3, 0xac, 0x24, 0x57, 0xa2, 0xcd, 0xaf, // IID219 - 0x62, 0x54, 0x78, 0x08, 0xf4, 0xac, 0x25, 0x94, 0x17, 0x0c, 0xf4, // IID220 - 0x62, 0x44, 0x78, 0x0c, 0xf4, 0x94, 0x5e, 0x47, 0x63, 0x3a, 0xdb, // IID221 - 0x62, 0x9c, 0x48, 0x10, 0x81, 0x84, 0xbb, 0xd1, 0x6f, 0x7f, 0x80, 0x00, 0x00, 0x10, 0x00, // IID222 - 0x62, 0xf4, 0x00, 0x14, 0x81, 0x84, 0xea, 0xca, 0x3f, 0x83, 0xaa, 0x00, 0x00, 0x00, 0x10, // IID223 - 0x62, 0xdc, 0x2c, 0x18, 0x81, 0xa2, 0xf9, 0xeb, 0x6b, 0x4e, 0x00, 0x10, 0x00, 0x00, // IID224 - 0x62, 0xdc, 0x14, 0x1c, 0x81, 0xa6, 0xfd, 0xa5, 0xf1, 0x14, 0x00, 0x01, 0x00, 0x00, // IID225 - 0x62, 0x0c, 0x7c, 0x08, 0x6b, 0x9c, 0x05, 0x99, 0x87, 0x98, 0x37, 0x01, // IID226 - 0x62, 0x44, 0x7c, 0x0c, 0x69, 0x99, 0x3f, 0xd2, 0x92, 0xbb, 0x00, 0x01, 0x00, 0x00, // IID227 - 0x62, 0xbc, 0x70, 0x10, 0x83, 0x8c, 0x0c, 0xdb, 0xb5, 0x57, 0x49, 0x10, // IID228 - 0x62, 0x9c, 0x30, 0x14, 0x83, 0x8c, 0x7d, 0x3e, 0xa5, 0x26, 0x3c, 0x01, // IID229 - 0x62, 0xd4, 0x04, 0x18, 0x80, 0x89, 0xe2, 0xb5, 0x68, 0xda, 0x40, // IID230 - 0x62, 0xbc, 0x24, 0x1c, 0x80, 0x8c, 0xb8, 0x9f, 0x32, 0xa0, 0x66, 0x04, // IID231 - 0x62, 0xb4, 0x70, 0x18, 0xd1, 0xa4, 0x19, 0x5e, 0x48, 0xc6, 0x38, // IID232 - 0x62, 0x94, 0x34, 0x14, 0xc1, 0xa4, 0x10, 0x34, 0x1c, 0x13, 0x79, 0x08, // IID233 - 0x62, 0x94, 0x10, 0x18, 0xc1, 0xbc, 0xb9, 0xa9, 0x8b, 0x71, 0x12, 0x02, // IID234 - 0x62, 0xdc, 0x04, 0x1c, 0xc1, 0xb9, 0x0d, 0xc9, 0xa7, 0xaf, 0x10, // IID235 - 0x62, 0xf4, 0x00, 0x18, 0xd1, 0xac, 0x19, 0x10, 0x15, 0x5c, 0x0c, // IID236 - 0x62, 0xdc, 0x10, 0x1c, 0xc1, 0xac, 0xad, 0x64, 0xcf, 0x98, 0x93, 0x08, // IID237 - 0x62, 0x94, 0x64, 0x18, 0x81, 0xac, 0x44, 0x81, 0xf7, 0x8a, 0xca, 0x00, 0x10, 0x00, 0x00, // IID238 - 0x62, 0xf4, 0x18, 0x14, 0x81, 0xac, 0xeb, 0x48, 0xc2, 0x07, 0xaa, 0x00, 0x00, 0x01, 0x00, // IID239 - 0x62, 0xbc, 0x08, 0x10, 0x83, 0xb4, 0x15, 0xe1, 0x14, 0x4d, 0x3b, 0x01, // IID240 - 0x62, 0xfc, 0x1c, 0x14, 0x81, 0xb2, 0x5f, 0xb7, 0xdc, 0xba, 0x00, 0x00, 0x00, 0x01, // IID241 - 0x62, 0xa4, 0x6c, 0x10, 0x01, 0x84, 0x92, 0xb9, 0xe2, 0xe1, 0xe9, // IID242 - 0x62, 0xdc, 0x20, 0x14, 0x01, 0x94, 0xd1, 0xdd, 0x47, 0x64, 0x98, // IID243 - 0x62, 0x1c, 0x20, 0x10, 0x09, 0x8c, 0xef, 0x34, 0x79, 0xed, 0x19, // IID244 - 0x62, 0xc4, 0x48, 0x14, 0x09, 0x8c, 0x80, 0x88, 0xe0, 0x08, 0xe4, // IID245 - 0x62, 0x84, 0x70, 0x18, 0x08, 0x84, 0xe7, 0xcc, 0xc6, 0xb5, 0x95, // IID246 - 0x62, 0xac, 0x1c, 0x14, 0x08, 0x84, 0xa7, 0xf7, 0x49, 0x24, 0x3c, // IID247 - 0x62, 0x1c, 0x4c, 0x10, 0x29, 0x8c, 0x53, 0x91, 0xc6, 0xd6, 0xc3, // IID248 - 0x62, 0xec, 0x2c, 0x1c, 0x29, 0x88, 0x01, 0x9b, 0xaf, 0xe9, // IID249 - 0x62, 0x8c, 0x1c, 0x10, 0x31, 0xa4, 0x1e, 0x3a, 0x1e, 0x28, 0x17, // IID250 - 0x62, 0xa4, 0x68, 0x1c, 0x31, 0x8c, 0xfb, 0xdc, 0xd0, 0x53, 0x77, // IID251 - 0x62, 0x4c, 0x34, 0x18, 0x30, 0xb7, 0x8e, 0xf5, 0xa4, 0x72, // IID252 - 0x62, 0x8c, 0x3c, 0x14, 0x30, 0x84, 0x39, 0x0a, 0x1a, 0xfc, 0x20, // IID253 - 0x62, 0xf4, 0x1c, 0x18, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID254 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID255 - 0x62, 0xfc, 0x3c, 0x14, 0x81, 0xc0, 0x00, 0x00, 0x00, 0x10, // IID256 - 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xc2, 0x00, 0x00, 0x00, 0x10, // IID257 - 0x62, 0xd4, 0x14, 0x10, 0x83, 0xe5, 0x01, // IID258 - 0x62, 0xd4, 0x7c, 0x18, 0x83, 0xe5, 0x01, // IID259 - 0x62, 0xfc, 0x04, 0x14, 0x83, 0xe6, 0x01, // IID260 - 0x62, 0xdc, 0x7c, 0x1c, 0x83, 0xe5, 0x01, // IID261 - 0x62, 0xcc, 0x7c, 0x08, 0x69, 0xfd, 0x00, 0x00, 0x01, 0x00, // IID262 - 0x62, 0xd4, 0x7c, 0x08, 0x69, 0xc7, 0x00, 0x00, 0x01, 0x00, // IID263 - 0x62, 0xc4, 0x7c, 0x0c, 0x69, 0xe9, 0x00, 0x00, 0x00, 0x10, // IID264 - 0x62, 0xd4, 0x7c, 0x0c, 0x69, 0xc7, 0x00, 0x00, 0x00, 0x10, // IID265 - 0x62, 0xfc, 0x6c, 0x18, 0x81, 0xca, 0x00, 0x00, 0x01, 0x00, // IID266 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xcf, 0x00, 0x00, 0x01, 0x00, // IID267 - 0x62, 0xd4, 0x3c, 0x1c, 0x81, 0xc9, 0x00, 0x01, 0x00, 0x00, // IID268 - 0x62, 0xdc, 0x7c, 0x1c, 0x81, 0xcb, 0x00, 0x01, 0x00, 0x00, // IID269 - 0x62, 0xd4, 0x34, 0x18, 0xc1, 0xd7, 0x08, // IID270 - 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xd2, 0x08, // IID271 - 0x62, 0xf4, 0x1c, 0x18, 0xc1, 0xc3, 0x10, // IID272 - 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xc3, 0x10, // IID273 - 0x62, 0xd4, 0x2c, 0x1c, 0xc1, 0xc3, 0x10, // IID274 - 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xc2, 0x10, // IID275 - 0x62, 0xd4, 0x6c, 0x18, 0xd1, 0xce, // IID276 - 0x62, 0xfc, 0x7c, 0x18, 0xd1, 0xce, // IID277 - 0x62, 0xdc, 0x34, 0x14, 0xc1, 0xcf, 0x10, // IID278 - 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xcb, 0x10, // IID279 - 0x62, 0xd4, 0x34, 0x18, 0xc1, 0xe7, 0x02, // IID280 - 0x62, 0xd4, 0x7c, 0x18, 0xc1, 0xe5, 0x02, // IID281 - 0x62, 0xfc, 0x54, 0x14, 0xd1, 0xe0, // IID282 - 0x62, 0xfc, 0x7c, 0x1c, 0xd1, 0xe5, // IID283 - 0x62, 0xfc, 0x2c, 0x10, 0xc1, 0xff, 0x08, // IID284 - 0x62, 0xdc, 0x7c, 0x18, 0xc1, 0xfc, 0x08, // IID285 - 0x62, 0xd4, 0x2c, 0x14, 0xc1, 0xfe, 0x04, // IID286 - 0x62, 0xd4, 0x7c, 0x1c, 0xc1, 0xfa, 0x04, // IID287 - 0x62, 0xd4, 0x4c, 0x10, 0xd1, 0xe1, // IID288 - 0x62, 0xfc, 0x7c, 0x18, 0xd1, 0xe2, // IID289 - 0x62, 0xdc, 0x0c, 0x14, 0xc1, 0xe0, 0x10, // IID290 - 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xe7, 0x10, // IID291 - 0x62, 0xd4, 0x24, 0x18, 0xc1, 0xe8, 0x10, // IID292 - 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xe8, 0x10, // IID293 - 0x62, 0xd4, 0x24, 0x1c, 0xc1, 0xec, 0x08, // IID294 - 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xed, 0x08, // IID295 - 0x62, 0xfc, 0x7c, 0x10, 0x81, 0xed, 0x00, 0x00, 0x10, 0x00, // IID296 - 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xef, 0x00, 0x00, 0x10, 0x00, // IID297 - 0x62, 0xfc, 0x34, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x00, 0x01, // IID298 + 0x62, 0xec, 0x7c, 0x08, 0xf5, 0xff, // IID180 + 0x62, 0x44, 0x7c, 0x0c, 0xf5, 0xe0, // IID181 + 0x62, 0x4c, 0x7c, 0x0c, 0xf5, 0xf6, // IID182 + 0x62, 0xd4, 0x44, 0x10, 0xf7, 0xdb, // IID183 + 0x41, 0xf7, 0xdd, // IID184 + 0x62, 0xd4, 0x7c, 0x14, 0xf7, 0xdb, // IID185 + 0x62, 0xd4, 0x24, 0x1c, 0xf7, 0xdb, // IID186 + 0x62, 0x64, 0x7c, 0x08, 0x88, 0xd1, // IID187 #endif // _LP64 - 0x62, 0xf4, 0x7c, 0x1c, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x01, // IID299 + 0x62, 0xf4, 0x7c, 0x08, 0x88, 0xdb, // IID188 #ifdef _LP64 - 0x62, 0xfc, 0x64, 0x10, 0x81, 0xf7, 0x00, 0x00, 0x01, 0x00, // IID300 - 0x62, 0xfc, 0x7c, 0x18, 0x81, 0xf1, 0x00, 0x00, 0x01, 0x00, // IID301 - 0x62, 0xfc, 0x14, 0x14, 0x81, 0xf2, 0x00, 0x00, 0x10, 0x00, // IID302 - 0x62, 0xd4, 0x7c, 0x1c, 0x81, 0xf6, 0x00, 0x00, 0x10, 0x00, // IID303 - 0x62, 0xd4, 0x64, 0x10, 0x81, 0xef, 0x00, 0x00, 0x00, 0x01, // IID304 - 0x62, 0xdc, 0x7c, 0x18, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x01, // IID305 - 0x62, 0xdc, 0x44, 0x14, 0x81, 0xeb, 0x00, 0x00, 0x00, 0x40, // IID306 - 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xef, 0x00, 0x00, 0x00, 0x40, // IID307 - 0x62, 0x1c, 0x38, 0x18, 0x03, 0xa4, 0xc4, 0x98, 0x81, 0x92, 0x92, // IID308 - 0x62, 0x1c, 0x38, 0x14, 0x03, 0xac, 0xc8, 0xfd, 0x73, 0x46, 0x78, // IID309 - 0x62, 0x84, 0x3c, 0x10, 0x23, 0xac, 0xa8, 0x77, 0xc7, 0x99, 0x9c, // IID310 - 0x62, 0x4c, 0x1c, 0x1c, 0x23, 0x86, 0xaa, 0x9a, 0xad, 0x98, // IID311 - 0x62, 0x34, 0x10, 0x18, 0xaf, 0xac, 0x8b, 0x27, 0xb2, 0xc6, 0xa0, // IID312 - 0x62, 0x4c, 0x2c, 0x14, 0xaf, 0x8c, 0xd1, 0x66, 0x08, 0xc6, 0xd1, // IID313 - 0x62, 0x34, 0x18, 0x10, 0x0b, 0x84, 0xc2, 0xac, 0x65, 0x26, 0xf1, // IID314 - 0x62, 0xcc, 0x00, 0x14, 0x0b, 0xb4, 0xe6, 0xbd, 0x1c, 0xc4, 0x3a, // IID315 - 0x62, 0x44, 0x38, 0x10, 0x2b, 0xb4, 0x4d, 0xe3, 0xc2, 0xfd, 0x1e, // IID316 - 0x62, 0x84, 0x7c, 0x14, 0x2b, 0x84, 0x79, 0x34, 0xeb, 0x9f, 0x76, // IID317 - 0x62, 0x44, 0x64, 0x10, 0x33, 0x8a, 0x29, 0xb4, 0x39, 0x22, // IID318 - 0x62, 0xac, 0x30, 0x14, 0x33, 0x9c, 0x40, 0xea, 0xfa, 0x71, 0x1c, // IID319 - 0x62, 0x5c, 0x64, 0x10, 0x32, 0x94, 0x24, 0x03, 0xf3, 0x65, 0xd6, // IID320 - 0x62, 0x2c, 0x60, 0x1c, 0x32, 0xa4, 0x47, 0x27, 0x22, 0x87, 0xa2, // IID321 - 0x62, 0x14, 0x29, 0x18, 0x33, 0x8c, 0xb5, 0x88, 0x11, 0x15, 0x11, // IID322 - 0x62, 0xa4, 0x79, 0x14, 0x33, 0x8c, 0x3a, 0xe7, 0x6c, 0x93, 0x61, // IID323 - 0x62, 0xdc, 0x14, 0x18, 0x03, 0xdc, // IID324 - 0x62, 0x6c, 0x64, 0x1c, 0x03, 0xee, // IID325 - 0x62, 0x54, 0x64, 0x18, 0x23, 0xc0, // IID326 - 0x62, 0xc4, 0x24, 0x1c, 0x23, 0xc5, // IID327 - 0x62, 0x7c, 0x1c, 0x18, 0xaf, 0xf9, // IID328 - 0x62, 0x6c, 0x44, 0x14, 0xaf, 0xfc, // IID329 - 0x62, 0x44, 0x4d, 0x10, 0x0b, 0xd2, // IID330 - 0x62, 0xc4, 0x35, 0x14, 0x0b, 0xdb, // IID331 - 0x62, 0x44, 0x64, 0x10, 0x0b, 0xf0, // IID332 - 0x62, 0x74, 0x1c, 0x1c, 0x0b, 0xd2, // IID333 - 0x62, 0x6c, 0x4c, 0x10, 0xa5, 0xf4, // IID334 - 0x62, 0xec, 0x6c, 0x14, 0xa5, 0xd3, // IID335 - 0x62, 0xfc, 0x34, 0x10, 0xad, 0xca, // IID336 - 0x62, 0x6c, 0x64, 0x14, 0xad, 0xc8, // IID337 - 0x62, 0x4c, 0x24, 0x18, 0x2b, 0xf8, // IID338 - 0x62, 0x6c, 0x0c, 0x1c, 0x2b, 0xf0, // IID339 - 0x62, 0x5c, 0x34, 0x18, 0x33, 0xda, // IID340 - 0x62, 0xdc, 0x24, 0x14, 0x33, 0xd7, // IID341 - 0x62, 0xd4, 0x14, 0x10, 0x24, 0xca, 0x10, // IID342 - 0x62, 0xec, 0x04, 0x1c, 0x24, 0xcf, 0x10, // IID343 - 0x62, 0x54, 0x24, 0x10, 0x2c, 0xfd, 0x08, // IID344 - 0x62, 0x4c, 0x04, 0x1c, 0x2c, 0xd5, 0x10, // IID345 - 0x62, 0x54, 0x6c, 0x10, 0x40, 0xc9, // IID346 - 0x62, 0x6c, 0x4c, 0x10, 0x41, 0xf7, // IID347 - 0x62, 0xc4, 0x24, 0x18, 0x42, 0xe3, // IID348 - 0x62, 0x6c, 0x64, 0x18, 0x43, 0xe0, // IID349 - 0x62, 0xcc, 0x5c, 0x10, 0x44, 0xc8, // IID350 - 0x62, 0xc4, 0x4c, 0x10, 0x45, 0xc7, // IID351 - 0x62, 0x4c, 0x04, 0x18, 0x46, 0xe5, // IID352 - 0x62, 0x4c, 0x7c, 0x10, 0x47, 0xc9, // IID353 - 0x62, 0x7c, 0x74, 0x10, 0x48, 0xe9, // IID354 - 0x62, 0xdc, 0x44, 0x10, 0x49, 0xde, // IID355 - 0x62, 0xc4, 0x04, 0x18, 0x4a, 0xf3, // IID356 - 0x62, 0xfc, 0x24, 0x10, 0x4b, 0xd6, // IID357 - 0x62, 0xcc, 0x34, 0x18, 0x4c, 0xcc, // IID358 - 0x62, 0x5c, 0x3c, 0x10, 0x4d, 0xda, // IID359 - 0x62, 0xf4, 0x1c, 0x18, 0x4e, 0xcb, // IID360 - 0x62, 0xec, 0x1c, 0x10, 0x4f, 0xf6, // IID361 - 0x62, 0x74, 0x28, 0x18, 0x40, 0xb4, 0xc9, 0xc3, 0x4d, 0xa8, 0x87, // IID362 - 0x62, 0x1c, 0x70, 0x10, 0x41, 0xa4, 0xc2, 0x23, 0x22, 0x64, 0x10, // IID363 - 0x62, 0x5c, 0x2c, 0x10, 0x42, 0x87, 0x1c, 0xd4, 0xd2, 0xf4, // IID364 - 0x62, 0xc4, 0x18, 0x18, 0x43, 0xa4, 0xb4, 0xd5, 0x08, 0x80, 0x99, // IID365 - 0x62, 0x5c, 0x48, 0x10, 0x44, 0x8c, 0xbb, 0x22, 0x4d, 0xce, 0x66, // IID366 - 0x62, 0x1c, 0x18, 0x18, 0x45, 0x84, 0xde, 0x1f, 0x89, 0x69, 0xd4, // IID367 - 0x62, 0x84, 0x70, 0x10, 0x46, 0xa4, 0xf1, 0x21, 0xdd, 0xef, 0xca, // IID368 - 0x62, 0x54, 0x6c, 0x18, 0x47, 0x86, 0x59, 0x7a, 0x6b, 0x3d, // IID369 - 0x62, 0x04, 0x74, 0x18, 0x48, 0xbc, 0xb3, 0xf2, 0x85, 0xd5, 0x2c, // IID370 - 0x62, 0x8c, 0x34, 0x10, 0x49, 0x94, 0x98, 0xcc, 0x63, 0x96, 0xc0, // IID371 - 0x62, 0x7c, 0x68, 0x10, 0x4a, 0x84, 0x8b, 0x3b, 0x5b, 0xf2, 0xc6, // IID372 - 0x62, 0x4c, 0x24, 0x18, 0x4b, 0xac, 0x95, 0x3f, 0xa9, 0x94, 0x3a, // IID373 - 0x62, 0x44, 0x10, 0x18, 0x4c, 0xac, 0x7f, 0x32, 0x35, 0xd4, 0x76, // IID374 - 0x62, 0x14, 0x04, 0x18, 0x4d, 0xa4, 0x4d, 0x5b, 0x7a, 0x6f, 0x01, // IID375 - 0x62, 0xfc, 0x30, 0x18, 0x4e, 0x94, 0x79, 0xe1, 0xbf, 0xb6, 0x43, // IID376 - 0x62, 0x8c, 0x1c, 0x10, 0x4f, 0xa4, 0x10, 0xd1, 0x7f, 0x91, 0xcd, // IID377 - 0xd5, 0x4c, 0x13, 0xd9, // IID378 - 0xd5, 0x49, 0x3b, 0xf7, // IID379 - 0xd5, 0xdd, 0xaf, 0xfe, // IID380 - 0xf3, 0xd5, 0xd8, 0xb8, 0xdb, // IID381 - 0xd5, 0x5c, 0x1b, 0xd5, // IID382 - 0xd5, 0x1d, 0x2b, 0xf2, // IID383 - 0xf3, 0xd5, 0xc9, 0xbc, 0xe7, // IID384 - 0xf3, 0x4d, 0x0f, 0xbd, 0xe5, // IID385 - 0xd5, 0x59, 0x03, 0xfc, // IID386 - 0xd5, 0x58, 0x23, 0xe4, // IID387 - 0xd5, 0x4d, 0x0b, 0xc3, // IID388 - 0x4d, 0x33, 0xd7, // IID389 - 0xd5, 0x58, 0x8b, 0xdc, // IID390 - 0xd5, 0xc9, 0xbc, 0xff, // IID391 - 0xd5, 0xdc, 0xbd, 0xd3, // IID392 - 0xd5, 0xd9, 0xa3, 0xf8, // IID393 - 0xd5, 0x4d, 0x87, 0xe3, // IID394 - 0x4d, 0x85, 0xed, // IID395 - 0xd5, 0x39, 0x01, 0x94, 0xff, 0x37, 0x04, 0xda, 0x59, // IID396 - 0xd5, 0x7c, 0x21, 0x9c, 0xe5, 0x57, 0xd5, 0xd0, 0x6f, // IID397 - 0xd5, 0x1c, 0x39, 0x9d, 0x44, 0x67, 0xef, 0x23, // IID398 - 0x49, 0x09, 0x8c, 0xca, 0xab, 0x44, 0x85, 0x7e, // IID399 - 0xd5, 0x2a, 0x31, 0x9c, 0xc1, 0x77, 0xb7, 0x35, 0x86, // IID400 - 0xd5, 0x7f, 0x29, 0x9c, 0x3b, 0x9a, 0x5f, 0xf8, 0x11, // IID401 - 0xd5, 0x78, 0x89, 0x8c, 0xc4, 0xda, 0x8d, 0x15, 0x72, // IID402 - 0xd5, 0x9f, 0xc1, 0xa4, 0x8d, 0xd1, 0xeb, 0x8f, 0x6e, // IID403 - 0x49, 0x81, 0xa7, 0x33, 0xb1, 0x36, 0xb8, 0x00, 0x00, 0x00, 0x10, // IID404 - 0xd5, 0x38, 0x81, 0x84, 0x5f, 0x3f, 0xde, 0xbf, 0x32, 0x00, 0x01, 0x00, 0x00, // IID405 - 0x4b, 0x81, 0xbc, 0xdf, 0x60, 0x75, 0x8e, 0x54, 0x00, 0x10, 0x00, 0x00, // IID406 - 0xd5, 0x1a, 0xc1, 0xbc, 0x74, 0x34, 0xfc, 0x43, 0x1b, 0x02, // IID407 - 0xd5, 0x39, 0xc1, 0xa4, 0x2a, 0x3d, 0xaf, 0x51, 0xc4, 0x08, // IID408 - 0xd5, 0x1a, 0x81, 0x9c, 0xd6, 0x03, 0x14, 0x7e, 0x04, 0x00, 0x00, 0x01, 0x00, // IID409 - 0x48, 0xc1, 0xac, 0x91, 0x4d, 0x92, 0xa3, 0x7e, 0x10, // IID410 - 0xd5, 0x2a, 0x83, 0xac, 0xd1, 0xc2, 0x5a, 0x91, 0xca, 0x10, // IID411 - 0xd5, 0x3b, 0x83, 0xb4, 0x96, 0x5c, 0x2f, 0xa1, 0x78, 0x10, // IID412 - 0x4b, 0x81, 0x8c, 0x53, 0xb5, 0xb5, 0x13, 0x37, 0x00, 0x00, 0x00, 0x10, // IID413 - 0xd5, 0x3b, 0xc7, 0x84, 0xf6, 0x10, 0x1a, 0x54, 0x02, 0x00, 0x00, 0x01, 0x00, // IID414 - 0xd5, 0x1a, 0xf7, 0x84, 0xf8, 0x51, 0x32, 0x8e, 0x55, 0xf0, 0xff, 0xff, 0xff, // IID415 - 0xd5, 0x4f, 0x03, 0x9c, 0x90, 0x2d, 0x73, 0x5f, 0x63, // IID416 - 0xd5, 0x6b, 0x23, 0xac, 0x3c, 0x60, 0x3b, 0x17, 0x8a, // IID417 - 0xd5, 0x78, 0x3b, 0x94, 0x83, 0xe2, 0x17, 0xf5, 0xed, // IID418 - 0xf3, 0xd5, 0xbb, 0xbd, 0x9c, 0x37, 0x5d, 0x26, 0xc3, 0x1e, // IID419 - 0xd5, 0x6a, 0x0b, 0x84, 0x12, 0x1b, 0x83, 0x86, 0x35, // IID420 - 0xd5, 0x1c, 0x13, 0xa2, 0x86, 0x60, 0xc1, 0xc3, // IID421 - 0xd5, 0xa9, 0xaf, 0x8c, 0xe8, 0xab, 0x15, 0x15, 0x6b, // IID422 - 0xf3, 0xd5, 0xec, 0xb8, 0xac, 0xb9, 0x4d, 0x6c, 0xf0, 0x4f, // IID423 - 0xd5, 0x5f, 0x1b, 0x94, 0x50, 0x77, 0x5e, 0x26, 0x8a, // IID424 - 0xd5, 0x48, 0x2b, 0x8c, 0x1b, 0x9c, 0xd5, 0x33, 0x40, // IID425 - 0xf3, 0xd5, 0xda, 0xbc, 0x94, 0xe6, 0x83, 0xcb, 0x6c, 0xc7, // IID426 - 0xd5, 0x3c, 0x33, 0xa4, 0xfc, 0x60, 0x15, 0x31, 0x4b, // IID427 - 0xd5, 0x6f, 0x8b, 0xac, 0xa2, 0x57, 0x26, 0x3a, 0x5c, // IID428 - 0xd5, 0x6b, 0x8d, 0xb4, 0xcd, 0x3f, 0x6f, 0x3d, 0x1a, // IID429 - 0xf2, 0xd5, 0xfe, 0x2c, 0x8c, 0xc1, 0x28, 0x24, 0x52, 0xca, // IID430 - 0xd5, 0x59, 0x87, 0x91, 0xc3, 0x84, 0x21, 0x63, // IID431 - 0xd5, 0x5e, 0x85, 0xac, 0x6a, 0x76, 0x02, 0xc6, 0xaf, // IID432 - 0xd5, 0x18, 0x81, 0xc4, 0x00, 0x10, 0x00, 0x00, // IID433 - 0x49, 0x83, 0xe1, 0x10, // IID434 - 0x48, 0x81, 0xd2, 0x00, 0x01, 0x00, 0x00, // IID435 - 0xd5, 0x18, 0x81, 0xfe, 0x00, 0x00, 0x00, 0x01, // IID436 - 0xd5, 0x18, 0xd1, 0xd1, // IID437 - 0xd5, 0x19, 0xd1, 0xdf, // IID438 - 0xd5, 0x19, 0xc1, 0xc3, 0x04, // IID439 - 0xd5, 0x19, 0xc1, 0xcc, 0x02, // IID440 - 0x48, 0xc1, 0xf9, 0x10, // IID441 - 0xd5, 0x19, 0xc1, 0xe7, 0x08, // IID442 - 0xd5, 0x19, 0x81, 0xdb, 0x00, 0x00, 0x10, 0x00, // IID443 - 0xd5, 0x18, 0xc1, 0xe4, 0x10, // IID444 - 0xd5, 0x19, 0xc1, 0xef, 0x08, // IID445 - 0xd5, 0x19, 0x81, 0xeb, 0x00, 0x00, 0x10, 0x00, // IID446 - 0xd5, 0x18, 0x81, 0xf6, 0x00, 0x10, 0x00, 0x00, // IID447 - 0x49, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, // IID448 - 0xd5, 0x19, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // IID449 - 0x49, 0x0f, 0xba, 0xe5, 0x01, // IID450 - 0xd5, 0x18, 0xf7, 0xc0, 0x00, 0x00, 0xf0, 0xff, // IID451 - 0xd5, 0x18, 0x81, 0xcc, 0x00, 0x00, 0x04, 0x00, // IID452 - 0xd5, 0x18, 0x81, 0xea, 0x00, 0x00, 0x10, 0x00, // IID453 - 0xd5, 0x9b, 0x40, 0x9c, 0x05, 0x15, 0x26, 0x02, 0x1d, // IID454 - 0xd5, 0xab, 0x41, 0x94, 0x64, 0x1e, 0x67, 0x37, 0xcb, // IID455 - 0xd5, 0xcd, 0x42, 0x9c, 0xca, 0x0f, 0x54, 0x08, 0xe1, // IID456 - 0xd5, 0xaf, 0x43, 0xb4, 0xad, 0x97, 0x7c, 0xb3, 0x83, // IID457 - 0xd5, 0x9c, 0x44, 0xbc, 0x8f, 0x31, 0xd3, 0x2d, 0x94, // IID458 - 0xd5, 0xcf, 0x45, 0x84, 0x57, 0xf7, 0xc2, 0x04, 0x80, // IID459 - 0xd5, 0xc9, 0x46, 0xbb, 0x3b, 0x86, 0x6a, 0x27, // IID460 - 0xd5, 0xdd, 0x47, 0xa5, 0x6e, 0x39, 0xb4, 0x3f, // IID461 - 0xd5, 0xdd, 0x48, 0x94, 0xcb, 0x1c, 0xa6, 0xde, 0x4d, // IID462 - 0xd5, 0xbc, 0x49, 0x94, 0x5e, 0x66, 0x69, 0x12, 0x2a, // IID463 - 0x4d, 0x0f, 0x4a, 0xa2, 0x9f, 0xc5, 0xd7, 0x03, // IID464 - 0x4f, 0x0f, 0x4b, 0x94, 0xc0, 0xd3, 0x79, 0x9e, 0xf1, // IID465 - 0xd5, 0xd9, 0x4c, 0xbd, 0x93, 0x26, 0x81, 0x88, // IID466 - 0xd5, 0xa8, 0x4d, 0x8c, 0x5b, 0xcb, 0x01, 0xc6, 0x53, // IID467 - 0xd5, 0x9c, 0x4e, 0xb4, 0x19, 0x8d, 0x0f, 0x74, 0x89, // IID468 - 0xd5, 0xed, 0x4f, 0xac, 0x5a, 0x3c, 0x8d, 0xc9, 0x30, // IID469 - 0x41, 0xff, 0xd2, // IID470 - 0xd5, 0x18, 0xf7, 0xf0, // IID471 - 0xd5, 0x19, 0xf7, 0xfb, // IID472 - 0x49, 0xf7, 0xe9, // IID473 - 0x49, 0xf7, 0xe5, // IID474 - 0x49, 0xf7, 0xde, // IID475 - 0xd5, 0x18, 0xf7, 0xd2, // IID476 - 0xd5, 0x19, 0xd3, 0xc4, // IID477 - 0xd5, 0x19, 0xd3, 0xcc, // IID478 - 0xd5, 0x18, 0xd3, 0xfe, // IID479 - 0x49, 0xd3, 0xe0, // IID480 - 0x49, 0xd3, 0xe4, // IID481 - 0x48, 0xd3, 0xeb, // IID482 - 0x48, 0xff, 0xc1, // IID483 - 0xd5, 0x18, 0xff, 0xcf, // IID484 - 0xd5, 0x08, 0x51, // IID485 - 0xd5, 0x19, 0x5a, // IID486 - 0xd5, 0x13, 0xff, 0x94, 0x15, 0x9f, 0xbc, 0x55, 0x56, // IID487 - 0xd5, 0x28, 0xf7, 0xa4, 0xea, 0xd0, 0x59, 0x67, 0x98, // IID488 - 0xd5, 0x3b, 0xf7, 0x9c, 0x07, 0xfe, 0xe7, 0xf8, 0xdf, // IID489 - 0xd5, 0x18, 0xd3, 0xbc, 0x95, 0x1b, 0x46, 0xc3, 0xcb, // IID490 - 0xd5, 0x3a, 0xd3, 0xa4, 0xc4, 0x74, 0x75, 0x66, 0x0a, // IID491 - 0xd5, 0x19, 0xd3, 0xab, 0x74, 0x79, 0xb7, 0x76, // IID492 - 0xd5, 0x19, 0xff, 0x81, 0xcf, 0x72, 0xb1, 0xac, // IID493 - 0xd5, 0x18, 0xff, 0x8c, 0x24, 0x5f, 0xc1, 0xf2, 0xe7, // IID494 - 0xd5, 0x58, 0x69, 0x88, 0xa8, 0x02, 0x0d, 0xd5, 0x00, 0x10, 0x00, 0x00, // IID495 - 0xd5, 0x5d, 0x6b, 0xe1, 0x10, // IID496 - 0xd5, 0x9d, 0xa4, 0xeb, 0x10, // IID497 - 0x4d, 0x0f, 0xac, 0xd0, 0x10, // IID498 - 0x62, 0xd4, 0x3c, 0x18, 0x8f, 0xc6, // IID499 - 0x62, 0xfc, 0xe4, 0x18, 0x8f, 0xc2, // IID500 - 0x62, 0xfc, 0x64, 0x10, 0xff, 0xf7, // IID501 - 0x62, 0xd4, 0xe4, 0x18, 0xff, 0xf4, // IID502 - 0xd5, 0xad, 0xb6, 0x8c, 0xfe, 0xba, 0xd9, 0x72, 0xbd, // IID503 - 0xd5, 0xcd, 0xb7, 0xa4, 0x89, 0x9f, 0xe9, 0x9e, 0x8d, // IID504 - 0xd5, 0xb9, 0xbe, 0x9c, 0xa8, 0x90, 0xe9, 0x6b, 0x3a, // IID505 - 0xd5, 0xda, 0xbf, 0x84, 0x16, 0xdd, 0x8b, 0xef, 0x07, // IID506 - 0xd5, 0xcd, 0xb6, 0xe6, // IID507 - 0xd5, 0x9d, 0xb7, 0xec, // IID508 - 0x4c, 0x0f, 0xbe, 0xda, // IID509 - 0xd5, 0x9d, 0xbf, 0xe2, // IID510 - 0xd5, 0xc9, 0xb1, 0xa2, 0x26, 0x57, 0x2d, 0xf4, // IID511 - 0x62, 0xd4, 0xfc, 0x08, 0xf7, 0xff, // IID512 - 0x62, 0xfc, 0xfc, 0x0c, 0xf7, 0xff, // IID513 - 0x62, 0xd4, 0xfc, 0x08, 0xf7, 0xf6, // IID514 - 0x62, 0xd4, 0xfc, 0x0c, 0xf7, 0xf6, // IID515 - 0x62, 0xd4, 0xfc, 0x08, 0xf7, 0xef, // IID516 - 0x62, 0xfc, 0xfc, 0x0c, 0xf7, 0xec, // IID517 - 0x62, 0xf4, 0xfc, 0x08, 0xf7, 0xe1, // IID518 - 0x62, 0xfc, 0xfc, 0x0c, 0xf7, 0xe5, // IID519 - 0x62, 0xbc, 0xfc, 0x08, 0xf7, 0xa4, 0xd0, 0x1e, 0xac, 0x66, 0x5f, // IID520 - 0x62, 0xfc, 0xf8, 0x0c, 0xf7, 0xa4, 0xf5, 0x83, 0x7f, 0x43, 0xf4, // IID521 - 0x62, 0xcc, 0xfc, 0x08, 0xaf, 0xf2, // IID522 - 0x62, 0x6c, 0xfc, 0x0c, 0xaf, 0xcd, // IID523 - 0x62, 0xc4, 0xfc, 0x08, 0xf5, 0xe5, // IID524 - 0x62, 0x6c, 0xfc, 0x0c, 0xf5, 0xcb, // IID525 - 0x62, 0xdc, 0xd4, 0x10, 0xf7, 0xde, // IID526 - 0x62, 0xd4, 0x94, 0x14, 0xf7, 0xdb, // IID527 - 0x62, 0xd4, 0xcc, 0x10, 0xf7, 0xd0, // IID528 - 0x62, 0x7c, 0xfc, 0x08, 0x88, 0xe3, // IID529 - 0x62, 0x6c, 0xfc, 0x0c, 0x88, 0xef, // IID530 - 0x62, 0xdc, 0x9c, 0x10, 0xd3, 0xc0, // IID531 - 0x62, 0xfc, 0xec, 0x1c, 0xd3, 0xc4, // IID532 - 0x62, 0xdc, 0xe4, 0x18, 0xd3, 0xce, // IID533 - 0x62, 0xd4, 0xac, 0x1c, 0xd3, 0xcf, // IID534 - 0x62, 0xd4, 0xf4, 0x10, 0xd3, 0xe5, // IID535 - 0x62, 0xdc, 0xd4, 0x14, 0xd3, 0xe0, // IID536 - 0x62, 0xd4, 0x84, 0x10, 0xd3, 0xfc, // IID537 - 0x62, 0xdc, 0xec, 0x1c, 0xd3, 0xf8, // IID538 - 0x62, 0xdc, 0xd4, 0x10, 0xff, 0xc8, // IID539 - 0x62, 0xdc, 0x84, 0x1c, 0xff, 0xcf, // IID540 - 0x62, 0xf4, 0xac, 0x18, 0xff, 0xc3, // IID541 - 0x62, 0xd4, 0xec, 0x14, 0xff, 0xc0, // IID542 - 0x62, 0xdc, 0xac, 0x18, 0xd3, 0xe2, // IID543 - 0x62, 0xd4, 0x9c, 0x14, 0xd3, 0xe6, // IID544 - 0x62, 0xfc, 0xac, 0x18, 0xd3, 0xeb, // IID545 - 0x62, 0xfc, 0x9c, 0x14, 0xd3, 0xed, // IID546 - 0x62, 0xec, 0xfc, 0x08, 0xf4, 0xee, // IID547 - 0x62, 0xec, 0xfc, 0x0c, 0xf4, 0xc7, // IID548 - 0x62, 0x3c, 0xfc, 0x08, 0xaf, 0x9c, 0x8a, 0x5f, 0x7a, 0xdd, 0xec, // IID549 - 0x62, 0x1c, 0xfc, 0x0c, 0xaf, 0xac, 0xf8, 0xa0, 0x0c, 0xf5, 0x48, // IID550 - 0x62, 0x54, 0xfc, 0x08, 0xf5, 0x8d, 0x0e, 0xcf, 0x15, 0x21, // IID551 - 0x62, 0x4c, 0xfc, 0x0c, 0xf5, 0x9e, 0xbb, 0xab, 0x9c, 0x04, // IID552 - 0x62, 0x94, 0xd0, 0x10, 0xf7, 0x9c, 0xbd, 0xd2, 0xf4, 0xa8, 0x50, // IID553 - 0x62, 0xfc, 0xc8, 0x14, 0xf7, 0x9c, 0x62, 0xb4, 0xa7, 0x5f, 0xa2, // IID554 - 0x62, 0x74, 0xf8, 0x08, 0x88, 0xb4, 0xb3, 0x2f, 0xb6, 0x9c, 0x9f, // IID555 - 0x62, 0x6c, 0xf8, 0x0c, 0x88, 0x94, 0xf7, 0xdd, 0x93, 0x39, 0x8d, // IID556 - 0x62, 0xd4, 0xac, 0x10, 0xd3, 0xa1, 0x09, 0xba, 0x4a, 0x33, // IID557 - 0x62, 0x94, 0xb0, 0x1c, 0xd3, 0xa4, 0xf1, 0xfe, 0x9e, 0x65, 0xde, // IID558 - 0x62, 0xfc, 0xb4, 0x10, 0xd3, 0xbc, 0x24, 0x4f, 0x45, 0xce, 0xde, // IID559 - 0x62, 0xdc, 0xf8, 0x14, 0xd3, 0xbc, 0x44, 0xb9, 0x83, 0xc4, 0x48, // IID560 - 0x62, 0xd4, 0x88, 0x10, 0xff, 0x8c, 0x01, 0xb1, 0x17, 0x73, 0xf7, // IID561 - 0x62, 0x9c, 0xa0, 0x1c, 0xff, 0x8c, 0xae, 0xd0, 0x8f, 0xeb, 0x3e, // IID562 - 0x62, 0x9c, 0xac, 0x10, 0xff, 0x84, 0xd5, 0x2e, 0x82, 0xf4, 0x3e, // IID563 - 0x62, 0xfc, 0x90, 0x14, 0xff, 0x84, 0xa3, 0x47, 0xc2, 0xf0, 0xc0, // IID564 - 0x62, 0xdc, 0xb8, 0x18, 0xd3, 0xac, 0x26, 0x17, 0x6a, 0xb5, 0x15, // IID565 - 0x62, 0xd4, 0xac, 0x14, 0xd3, 0xab, 0x9f, 0x9a, 0x17, 0xd2, // IID566 - 0x62, 0x34, 0xf8, 0x08, 0xf4, 0x9c, 0x71, 0x3e, 0x4e, 0x00, 0xcd, // IID567 - 0x62, 0x84, 0xfc, 0x0c, 0xf4, 0xbc, 0x61, 0x97, 0xc1, 0x7d, 0xab, // IID568 - 0x62, 0x54, 0xdc, 0x10, 0x01, 0xbc, 0xcd, 0xf3, 0x93, 0xee, 0xb9, // IID569 - 0x62, 0xc4, 0x90, 0x1c, 0x01, 0x84, 0x79, 0xfb, 0x89, 0x93, 0xd7, // IID570 - 0x62, 0x4c, 0xd0, 0x10, 0x21, 0xac, 0x0e, 0xb2, 0x30, 0x4e, 0x0f, // IID571 - 0x62, 0xac, 0x88, 0x14, 0x21, 0x8c, 0x39, 0xc4, 0xde, 0xb9, 0x3a, // IID572 - 0x62, 0x0c, 0xa8, 0x18, 0x09, 0xa4, 0x73, 0x9a, 0xed, 0x80, 0xe6, // IID573 - 0x62, 0x1c, 0xb0, 0x1c, 0x09, 0x9c, 0x35, 0xf8, 0x64, 0x15, 0xdb, // IID574 - 0x62, 0xc4, 0x84, 0x18, 0x29, 0x86, 0x70, 0x40, 0xbb, 0xb0, // IID575 - 0x62, 0x6c, 0xf0, 0x1c, 0x29, 0xa4, 0x55, 0x71, 0x53, 0x2f, 0xee, // IID576 - 0x62, 0x7c, 0xe0, 0x10, 0x31, 0x84, 0x13, 0x14, 0xaa, 0xa1, 0xf5, // IID577 - 0x62, 0xac, 0x98, 0x14, 0x31, 0x84, 0x61, 0x20, 0xd0, 0x4b, 0x91, // IID578 - 0x62, 0xfc, 0xf4, 0x10, 0x81, 0x82, 0xfb, 0xee, 0x54, 0x9f, 0x00, 0x00, 0x00, 0x01, // IID579 - 0x62, 0xbc, 0xb0, 0x14, 0x81, 0x84, 0x0b, 0xd9, 0x44, 0x24, 0x12, 0x00, 0x00, 0x01, 0x00, // IID580 - 0x62, 0x94, 0x88, 0x10, 0x81, 0xa4, 0x61, 0x0d, 0xf3, 0x4f, 0xda, 0x00, 0x10, 0x00, 0x00, // IID581 - 0x62, 0xfc, 0xb4, 0x1c, 0x81, 0xa4, 0x5e, 0xda, 0xaf, 0xb9, 0x81, 0x00, 0x00, 0x00, 0x10, // IID582 - 0x62, 0x1c, 0xf8, 0x08, 0x6b, 0xa4, 0x49, 0x34, 0x97, 0xd2, 0xbc, 0x01, // IID583 - 0x62, 0x3c, 0xf8, 0x0c, 0x6b, 0xbc, 0xf9, 0xa2, 0xa9, 0x68, 0xd4, 0x10, // IID584 - 0x62, 0xb4, 0x98, 0x10, 0x81, 0x8c, 0x3a, 0xb1, 0x63, 0x13, 0x3f, 0x00, 0x01, 0x00, 0x00, // IID585 - 0x62, 0xd4, 0xf8, 0x14, 0x81, 0x8c, 0xfc, 0xc4, 0x79, 0x7a, 0xe8, 0x00, 0x00, 0x00, 0x01, // IID586 - 0x62, 0x94, 0xb8, 0x18, 0xc1, 0xa4, 0x86, 0x5b, 0x6f, 0xbd, 0x8e, 0x02, // IID587 - 0x62, 0x94, 0xbc, 0x1c, 0xc1, 0xa4, 0xb7, 0x43, 0x32, 0xf1, 0x21, 0x10, // IID588 - 0x62, 0x94, 0xa8, 0x18, 0xc1, 0xbc, 0x2d, 0x72, 0xcb, 0x04, 0x7d, 0x02, // IID589 - 0x62, 0xbc, 0xa0, 0x1c, 0xc1, 0xbc, 0xfd, 0x24, 0x4b, 0x89, 0xde, 0x08, // IID590 - 0x62, 0xbc, 0xf4, 0x18, 0xc1, 0xac, 0x60, 0x38, 0x9a, 0x0c, 0x26, 0x04, // IID591 - 0x62, 0x9c, 0xcc, 0x14, 0xc1, 0xac, 0x0a, 0x9e, 0x44, 0xa9, 0xa1, 0x08, // IID592 - 0x62, 0xb4, 0x80, 0x10, 0x83, 0xac, 0x63, 0x10, 0xbb, 0x00, 0x2b, 0x01, // IID593 - 0x62, 0xdc, 0xd4, 0x14, 0x81, 0xaf, 0x53, 0x0b, 0xef, 0x93, 0x00, 0x10, 0x00, 0x00, // IID594 - 0x62, 0xbc, 0xa0, 0x18, 0x81, 0xb4, 0x77, 0x6b, 0x02, 0xa6, 0x51, 0x00, 0x00, 0x01, 0x00, // IID595 - 0x62, 0x9c, 0x8c, 0x1c, 0x83, 0xb4, 0x93, 0x55, 0x64, 0x52, 0xcb, 0x10, // IID596 - 0x62, 0xfc, 0xdc, 0x10, 0x81, 0xc7, 0x00, 0x00, 0x00, 0x01, // IID597 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xc6, 0x00, 0x00, 0x00, 0x01, // IID598 - 0x62, 0xfc, 0xb4, 0x1c, 0x81, 0xc5, 0x00, 0x10, 0x00, 0x00, // IID599 - 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xc3, 0x00, 0x10, 0x00, 0x00, // IID600 - 0x62, 0xfc, 0xec, 0x18, 0x81, 0xe5, 0x00, 0x00, 0x00, 0x10, // IID601 - 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x10, // IID602 - 0x62, 0xdc, 0xe4, 0x14, 0x81, 0xe7, 0x00, 0x00, 0x01, 0x00, // IID603 - 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xe3, 0x00, 0x00, 0x01, 0x00, // IID604 - 0x62, 0xc4, 0xfc, 0x08, 0x69, 0xe9, 0x00, 0x00, 0x00, 0x01, // IID605 - 0x62, 0xdc, 0xfc, 0x08, 0x69, 0xc6, 0x00, 0x00, 0x00, 0x01, // IID606 - 0x62, 0x6c, 0xfc, 0x0c, 0x69, 0xf2, 0x00, 0x00, 0x01, 0x00, // IID607 - 0x62, 0xfc, 0xfc, 0x0c, 0x69, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID608 - 0x62, 0xfc, 0xdc, 0x10, 0x81, 0xc8, 0x00, 0x00, 0x10, 0x00, // IID609 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xcc, 0x00, 0x00, 0x10, 0x00, // IID610 - 0x62, 0xdc, 0xe4, 0x1c, 0x81, 0xc8, 0x00, 0x10, 0x00, 0x00, // IID611 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xce, 0x00, 0x10, 0x00, 0x00, // IID612 - 0x62, 0xdc, 0xdc, 0x10, 0xc1, 0xd6, 0x04, // IID613 - 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xd6, 0x04, // IID614 - 0x62, 0xdc, 0xf4, 0x18, 0xc1, 0xc4, 0x02, // IID615 - 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xc5, 0x02, // IID616 - 0x62, 0xd4, 0xac, 0x14, 0xc1, 0xc7, 0x04, // IID617 - 0x62, 0xfc, 0xfc, 0x1c, 0xc1, 0xc3, 0x04, // IID618 - 0x62, 0xfc, 0xbc, 0x10, 0xc1, 0xcb, 0x08, // IID619 - 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xcc, 0x08, // IID620 - 0x62, 0xfc, 0xb4, 0x14, 0xc1, 0xca, 0x04, // IID621 - 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xcd, 0x04, // IID622 - 0x62, 0xfc, 0xa4, 0x10, 0xc1, 0xe1, 0x02, // IID623 - 0x62, 0xf4, 0xfc, 0x18, 0xc1, 0xe2, 0x02, // IID624 - 0x62, 0xdc, 0xe4, 0x1c, 0xc1, 0xe4, 0x10, // IID625 - 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xe7, 0x10, // IID626 - 0x62, 0xd4, 0xe4, 0x18, 0xc1, 0xfc, 0x04, // IID627 - 0x62, 0xf4, 0xfc, 0x18, 0xc1, 0xfb, 0x04, // IID628 - 0x62, 0xf4, 0xf4, 0x14, 0xc1, 0xfa, 0x02, // IID629 - 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xff, 0x02, // IID630 - 0x62, 0xf4, 0xd4, 0x10, 0xc1, 0xe3, 0x04, // IID631 - 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xe0, 0x04, // IID632 - 0x62, 0xd4, 0xa4, 0x14, 0xc1, 0xe5, 0x10, // IID633 - 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xe1, 0x10, // IID634 - 0x62, 0xfc, 0xf4, 0x18, 0xc1, 0xee, 0x10, // IID635 - 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xee, 0x10, // IID636 - 0x62, 0xdc, 0xa4, 0x1c, 0xc1, 0xee, 0x04, // IID637 - 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xe8, 0x04, // IID638 - 0x62, 0xfc, 0xdc, 0x10, 0x81, 0xeb, 0x00, 0x01, 0x00, 0x00, // IID639 - 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xe9, 0x00, 0x01, 0x00, 0x00, // IID640 - 0x62, 0xdc, 0x84, 0x14, 0x81, 0xee, 0x00, 0x00, 0x01, 0x00, // IID641 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x01, 0x00, // IID642 - 0x62, 0xd4, 0xec, 0x10, 0x81, 0xf3, 0x00, 0x10, 0x00, 0x00, // IID643 - 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xf2, 0x00, 0x10, 0x00, 0x00, // IID644 - 0x62, 0xfc, 0xbc, 0x14, 0x81, 0xf2, 0x00, 0x00, 0x00, 0x10, // IID645 - 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x10, // IID646 - 0x62, 0xfc, 0xac, 0x10, 0x81, 0xcd, 0x00, 0x00, 0x40, 0x00, // IID647 - 0x62, 0xd4, 0xfc, 0x18, 0x81, 0xc8, 0x00, 0x00, 0x40, 0x00, // IID648 - 0x62, 0xfc, 0xcc, 0x10, 0x81, 0xcd, 0x00, 0x00, 0x04, 0x00, // IID649 - 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xcb, 0x00, 0x00, 0x04, 0x00, // IID650 - 0x62, 0xd4, 0xfc, 0x10, 0x81, 0xe8, 0x00, 0x00, 0x40, 0x00, // IID651 - 0x62, 0xf4, 0xfc, 0x18, 0x81, 0xea, 0x00, 0x00, 0x40, 0x00, // IID652 - 0x62, 0xdc, 0xdc, 0x14, 0x81, 0xef, 0x00, 0x00, 0x10, 0x00, // IID653 - 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xed, 0x00, 0x00, 0x10, 0x00, // IID654 - 0x62, 0x74, 0xd8, 0x10, 0x03, 0xb4, 0x01, 0xd9, 0x54, 0x66, 0x7c, // IID655 - 0x62, 0xd4, 0x90, 0x14, 0x03, 0x8c, 0x3f, 0x2d, 0xf7, 0xb7, 0x45, // IID656 - 0x62, 0xc4, 0xe0, 0x10, 0x23, 0x8c, 0x75, 0x6a, 0xe6, 0xf3, 0x8a, // IID657 - 0x62, 0x5c, 0x90, 0x1c, 0x23, 0x84, 0x7f, 0x4e, 0x49, 0xee, 0xdd, // IID658 - 0x62, 0x04, 0xa4, 0x18, 0x0b, 0xa4, 0xdd, 0xab, 0x13, 0x00, 0x5c, // IID659 - 0x62, 0xec, 0xec, 0x1c, 0x0b, 0x94, 0x0a, 0x71, 0x7e, 0x55, 0x59, // IID660 - 0x62, 0x7c, 0xa4, 0x10, 0xaf, 0x9e, 0xb7, 0x69, 0xb9, 0xd7, // IID661 - 0x62, 0x5c, 0xac, 0x1c, 0xaf, 0x88, 0x54, 0x1d, 0x69, 0x49, // IID662 - 0x62, 0x7c, 0xbc, 0x10, 0x2b, 0xa3, 0xaa, 0x29, 0xd5, 0x22, // IID663 - 0x62, 0x84, 0xdc, 0x14, 0x2b, 0x94, 0x91, 0xb8, 0x85, 0xb5, 0xd9, // IID664 - 0x62, 0x14, 0xe0, 0x18, 0x33, 0x8c, 0x1e, 0x2f, 0xc0, 0x71, 0x0f, // IID665 - 0x62, 0x14, 0xb4, 0x14, 0x33, 0xbc, 0x62, 0xbd, 0x67, 0x23, 0x73, // IID666 - 0x62, 0x54, 0xa4, 0x18, 0x03, 0xca, // IID667 - 0x62, 0x7c, 0xb4, 0x14, 0x03, 0xe8, // IID668 - 0x62, 0xcc, 0xa5, 0x18, 0x66, 0xe9, // IID669 - 0x62, 0xe4, 0xee, 0x18, 0x66, 0xe3, // IID670 - 0x62, 0xcc, 0xb4, 0x10, 0x23, 0xea, // IID671 - 0x62, 0x6c, 0xc4, 0x14, 0x23, 0xdd, // IID672 - 0x62, 0x54, 0xac, 0x18, 0xaf, 0xd4, // IID673 - 0x62, 0x7c, 0x84, 0x14, 0xaf, 0xe7, // IID674 - 0x62, 0x44, 0xfc, 0x10, 0x0b, 0xee, // IID675 - 0x62, 0x6c, 0xe4, 0x14, 0x0b, 0xc7, // IID676 - 0x62, 0xc4, 0x8c, 0x18, 0x2b, 0xef, // IID677 - 0x62, 0x5c, 0xb4, 0x14, 0x2b, 0xcd, // IID678 - 0x62, 0x5c, 0xec, 0x18, 0x33, 0xd9, // IID679 - 0x62, 0x7c, 0xe4, 0x14, 0x33, 0xd0, // IID680 - 0x62, 0x6c, 0xbc, 0x18, 0x24, 0xff, 0x08, // IID681 - 0x62, 0xe4, 0x84, 0x14, 0x24, 0xc3, 0x02, // IID682 - 0x62, 0x54, 0xbc, 0x10, 0x2c, 0xca, 0x02, // IID683 - 0x62, 0xcc, 0x9c, 0x14, 0x2c, 0xd2, 0x10, // IID684 - 0x62, 0xec, 0xb4, 0x10, 0x40, 0xe0, // IID685 - 0x62, 0xdc, 0xd4, 0x10, 0x41, 0xdc, // IID686 - 0x62, 0xc4, 0xcc, 0x10, 0x42, 0xdd, // IID687 - 0x62, 0xd4, 0x84, 0x18, 0x43, 0xd0, // IID688 - 0x62, 0x54, 0xcc, 0x10, 0x44, 0xf4, // IID689 - 0x62, 0x5c, 0xbc, 0x10, 0x45, 0xf0, // IID690 - 0x62, 0xe4, 0x94, 0x18, 0x46, 0xeb, // IID691 - 0x62, 0x44, 0xe4, 0x18, 0x47, 0xde, // IID692 - 0x62, 0x6c, 0xbc, 0x10, 0x48, 0xd9, // IID693 - 0x62, 0x4c, 0xd4, 0x10, 0x49, 0xdb, // IID694 - 0x62, 0x5c, 0xa4, 0x10, 0x4a, 0xf0, // IID695 - 0x62, 0x6c, 0x9c, 0x10, 0x4b, 0xee, // IID696 - 0x62, 0x5c, 0x84, 0x18, 0x4c, 0xef, // IID697 - 0x62, 0x5c, 0xd4, 0x10, 0x4d, 0xfe, // IID698 - 0x62, 0x54, 0xdc, 0x10, 0x4e, 0xc5, // IID699 - 0x62, 0x4c, 0x84, 0x10, 0x4f, 0xcb, // IID700 - 0x62, 0x14, 0x84, 0x10, 0x40, 0xbc, 0x6e, 0xaa, 0x7a, 0x19, 0xf9, // IID701 - 0x62, 0x0c, 0x9c, 0x18, 0x41, 0xa4, 0xfe, 0x9e, 0x3f, 0xa3, 0x3b, // IID702 - 0x62, 0x04, 0xfc, 0x10, 0x42, 0x8c, 0x0c, 0xcd, 0xc4, 0x1f, 0xd7, // IID703 - 0x62, 0x04, 0xb8, 0x18, 0x43, 0x9c, 0xc8, 0x6b, 0x42, 0xbd, 0xe1, // IID704 - 0x62, 0xcc, 0xf4, 0x18, 0x44, 0xa4, 0x9b, 0x58, 0x3c, 0x82, 0x46, // IID705 - 0x62, 0x7c, 0xe4, 0x18, 0x45, 0xa5, 0x38, 0x47, 0xca, 0xf9, // IID706 - 0x62, 0x9c, 0xc0, 0x10, 0x46, 0x9c, 0xd3, 0xc0, 0xbc, 0x22, 0x09, // IID707 - 0x62, 0x7c, 0xb4, 0x10, 0x47, 0x8f, 0xec, 0x14, 0x2a, 0x0d, // IID708 - 0x62, 0xc4, 0xa4, 0x18, 0x48, 0x9b, 0x63, 0xa5, 0x46, 0xf0, // IID709 - 0x62, 0xcc, 0x90, 0x18, 0x49, 0x94, 0x1c, 0x7e, 0x9b, 0x6b, 0x71, // IID710 - 0x62, 0xa4, 0xd0, 0x10, 0x4a, 0x84, 0x29, 0xe2, 0xbb, 0x0f, 0xa5, // IID711 - 0x62, 0x2c, 0x98, 0x18, 0x4b, 0xbc, 0x14, 0xb1, 0x7f, 0x0b, 0x0e, // IID712 - 0x62, 0x4c, 0x84, 0x18, 0x4c, 0x86, 0x4f, 0x7b, 0x3b, 0x2d, // IID713 - 0x62, 0x54, 0x98, 0x18, 0x4d, 0xbc, 0xae, 0x18, 0x51, 0xdd, 0xed, // IID714 - 0x62, 0x6c, 0xe0, 0x18, 0x4e, 0xbc, 0x27, 0x96, 0xb2, 0x91, 0xf6, // IID715 - 0x62, 0xd4, 0xec, 0x18, 0x4f, 0x94, 0xd2, 0x7c, 0xf1, 0x75, 0x38, // IID716 + 0x62, 0x54, 0x7c, 0x0c, 0x88, 0xd6, // IID189 + 0x62, 0x4c, 0x7c, 0x0c, 0x88, 0xed, // IID190 + 0x62, 0xfc, 0x04, 0x18, 0xf7, 0xd4, // IID191 + 0xd5, 0x10, 0xf7, 0xd1, // IID192 + 0x41, 0xd3, 0xc4, // IID193 +#endif // _LP64 + 0xd3, 0xc3, // IID194 +#ifdef _LP64 + 0x62, 0xdc, 0x44, 0x14, 0xd3, 0xc3, // IID195 + 0x62, 0xdc, 0x14, 0x14, 0xd3, 0xc5, // IID196 + 0x62, 0xdc, 0x5c, 0x10, 0xd3, 0xcc, // IID197 +#endif // _LP64 + 0xd3, 0xca, // IID198 +#ifdef _LP64 + 0x62, 0xdc, 0x3c, 0x1c, 0xd3, 0xcb, // IID199 +#endif // _LP64 + 0x62, 0xf4, 0x64, 0x1c, 0xd3, 0xcb, // IID200 +#ifdef _LP64 + 0x62, 0xd4, 0x04, 0x18, 0xd3, 0xe3, // IID201 + 0xd5, 0x11, 0xd3, 0xe3, // IID202 + 0x62, 0xdc, 0x14, 0x14, 0xd3, 0xe1, // IID203 + 0x62, 0xd4, 0x1c, 0x1c, 0xd3, 0xe4, // IID204 + 0x62, 0xd4, 0x3c, 0x18, 0xd3, 0xfb, // IID205 + 0xd5, 0x10, 0xd3, 0xfa, // IID206 + 0x62, 0xd4, 0x6c, 0x1c, 0xd3, 0xfd, // IID207 + 0x62, 0xfc, 0x44, 0x14, 0xd3, 0xff, // IID208 + 0x62, 0xd4, 0x3c, 0x10, 0xff, 0xcf, // IID209 + 0x41, 0xff, 0xcf, // IID210 + 0x62, 0xdc, 0x2c, 0x14, 0xff, 0xcc, // IID211 +#endif // _LP64 + 0x62, 0xf4, 0x64, 0x1c, 0xff, 0xcb, // IID212 +#ifdef _LP64 + 0x62, 0xd4, 0x34, 0x10, 0xff, 0xc6, // IID213 + 0x41, 0xff, 0xc4, // IID214 + 0x62, 0xfc, 0x74, 0x1c, 0xff, 0xc7, // IID215 + 0x62, 0xdc, 0x14, 0x14, 0xff, 0xc5, // IID216 + 0x62, 0xdc, 0x4c, 0x10, 0xd3, 0xe0, // IID217 + 0x41, 0xd3, 0xe7, // IID218 + 0x62, 0xdc, 0x34, 0x1c, 0xd3, 0xe7, // IID219 + 0x62, 0xdc, 0x1c, 0x14, 0xd3, 0xe4, // IID220 + 0x62, 0xfc, 0x54, 0x10, 0xd3, 0xea, // IID221 + 0xd5, 0x11, 0xd3, 0xe8, // IID222 + 0x62, 0xfc, 0x0c, 0x1c, 0xd3, 0xeb, // IID223 + 0x62, 0xd4, 0x3c, 0x1c, 0xd3, 0xe8, // IID224 + 0x62, 0x44, 0x7c, 0x08, 0xf4, 0xc9, // IID225 + 0x62, 0x4c, 0x7c, 0x08, 0xf4, 0xd2, // IID226 + 0x62, 0x5c, 0x7c, 0x0c, 0xf4, 0xc6, // IID227 + 0x62, 0x4c, 0x7c, 0x0c, 0xf4, 0xd2, // IID228 + 0x62, 0x4c, 0x78, 0x08, 0xf5, 0xac, 0xe1, 0x1e, 0xf0, 0x37, 0xf6, // IID229 + 0x62, 0xcc, 0x78, 0x0c, 0xf5, 0xb4, 0x9b, 0x09, 0x7c, 0xf2, 0x38, // IID230 + 0x62, 0x94, 0x50, 0x10, 0xf7, 0x9c, 0xb6, 0x7b, 0x2c, 0xf9, 0x39, // IID231 + 0x62, 0xbc, 0x2c, 0x14, 0xf7, 0x9c, 0xf7, 0xc3, 0xe4, 0xd1, 0x9f, // IID232 + 0x62, 0x4c, 0x78, 0x08, 0x88, 0x8c, 0x7c, 0xef, 0x20, 0xf1, 0x4f, // IID233 + 0x62, 0x4c, 0x78, 0x0c, 0x88, 0xac, 0xc0, 0xbd, 0x44, 0xde, 0x97, // IID234 + 0x62, 0x94, 0x40, 0x10, 0xd3, 0xa4, 0xbb, 0xbb, 0x24, 0x42, 0x7f, // IID235 + 0x62, 0xbc, 0x18, 0x1c, 0xd3, 0xa4, 0x7f, 0x58, 0x78, 0x70, 0xfd, // IID236 + 0x62, 0xbc, 0x60, 0x10, 0xd3, 0xbc, 0x70, 0xf3, 0x61, 0x47, 0xd8, // IID237 + 0x62, 0xdc, 0x2c, 0x14, 0xd3, 0xb9, 0x48, 0x5d, 0x14, 0x3d, // IID238 + 0x62, 0x9c, 0x10, 0x18, 0xff, 0x8c, 0x43, 0x62, 0x38, 0x5f, 0x62, // IID239 + 0x62, 0xfc, 0x24, 0x1c, 0xff, 0x8e, 0xa6, 0x04, 0x59, 0x76, // IID240 + 0x62, 0xf4, 0x30, 0x10, 0xff, 0x84, 0x4a, 0x91, 0xc8, 0xaf, 0x82, // IID241 + 0x62, 0xd4, 0x4c, 0x14, 0xff, 0x84, 0x24, 0x57, 0xa2, 0xcd, 0xaf, // IID242 + 0x62, 0xd4, 0x10, 0x18, 0xd3, 0xac, 0x25, 0x94, 0x17, 0x0c, 0xf4, // IID243 + 0x62, 0xd4, 0x28, 0x14, 0xd3, 0xac, 0x5e, 0x47, 0x63, 0x3a, 0xdb, // IID244 + 0x62, 0xac, 0x78, 0x08, 0xf4, 0x84, 0x9e, 0xd1, 0x6f, 0x7f, 0x80, // IID245 + 0x62, 0xcc, 0x7c, 0x0c, 0xf4, 0xa4, 0xd7, 0x18, 0x48, 0x25, 0x12, // IID246 + 0x62, 0x94, 0x54, 0x10, 0x81, 0x84, 0xd4, 0x06, 0xcf, 0x17, 0x64, 0x00, 0x00, 0x10, 0x00, // IID247 + 0x62, 0xd4, 0x34, 0x1c, 0x81, 0x85, 0xfd, 0xa5, 0xf1, 0x14, 0x00, 0x10, 0x00, 0x00, // IID248 + 0x62, 0x9c, 0x24, 0x10, 0x83, 0xa4, 0x05, 0x99, 0x87, 0x98, 0x37, 0x01, // IID249 + 0x62, 0xd4, 0x24, 0x14, 0x81, 0xa1, 0x3f, 0xd2, 0x92, 0xbb, 0x00, 0x01, 0x00, 0x00, // IID250 + 0x62, 0xac, 0x78, 0x08, 0x6b, 0x8c, 0x0c, 0xdb, 0xb5, 0x57, 0x49, 0x10, // IID251 + 0x62, 0x0c, 0x78, 0x0c, 0x6b, 0x8c, 0x7d, 0x3e, 0xa5, 0x26, 0x3c, 0x01, // IID252 + 0x62, 0xd4, 0x04, 0x18, 0x81, 0x89, 0xe2, 0xb5, 0x68, 0xda, 0x00, 0x00, 0x00, 0x10, // IID253 + 0x62, 0xbc, 0x24, 0x1c, 0x81, 0x8c, 0xb8, 0x9f, 0x32, 0xa0, 0x66, 0x00, 0x10, 0x00, 0x00, // IID254 + 0x62, 0xb4, 0x70, 0x18, 0x80, 0x8c, 0x19, 0x5e, 0x48, 0xc6, 0x38, 0x01, // IID255 + 0x62, 0x94, 0x34, 0x14, 0x80, 0x8c, 0x10, 0x34, 0x1c, 0x13, 0x79, 0x40, // IID256 + 0x62, 0x94, 0x10, 0x18, 0xc1, 0xa4, 0xb9, 0xa9, 0x8b, 0x71, 0x12, 0x02, // IID257 + 0x62, 0xdc, 0x04, 0x1c, 0xc1, 0xa1, 0x0d, 0xc9, 0xa7, 0xaf, 0x10, // IID258 + 0x62, 0xf4, 0x00, 0x18, 0xd1, 0xbc, 0x19, 0x10, 0x15, 0x5c, 0x0c, // IID259 + 0x62, 0xdc, 0x10, 0x1c, 0xc1, 0xbc, 0xad, 0x64, 0xcf, 0x98, 0x93, 0x08, // IID260 + 0x62, 0xf4, 0x24, 0x18, 0xc1, 0xab, 0xd0, 0x67, 0x9f, 0x74, 0x10, // IID261 + 0x62, 0xd4, 0x0c, 0x1c, 0xc1, 0xae, 0x48, 0xc2, 0x07, 0xaa, 0x04, // IID262 + 0x62, 0xbc, 0x08, 0x10, 0x83, 0xac, 0x15, 0xe1, 0x14, 0x4d, 0x3b, 0x01, // IID263 + 0x62, 0xfc, 0x1c, 0x14, 0x81, 0xaa, 0x5f, 0xb7, 0xdc, 0xba, 0x00, 0x00, 0x00, 0x01, // IID264 + 0x62, 0xd4, 0x68, 0x18, 0x81, 0xb4, 0x82, 0xb9, 0xe2, 0xe1, 0xe9, 0x00, 0x00, 0x00, 0x01, // IID265 + 0x62, 0xdc, 0x68, 0x1c, 0x81, 0xb4, 0x7d, 0xf8, 0xe2, 0x34, 0x1b, 0x00, 0x00, 0x00, 0x01, // IID266 + 0x62, 0x0c, 0x60, 0x10, 0x01, 0xac, 0x3b, 0xd8, 0xe7, 0x3c, 0x1f, // IID267 + 0x62, 0x4c, 0x1c, 0x10, 0x01, 0xa4, 0xc8, 0x3e, 0x12, 0xac, 0x9f, // IID268 + 0x62, 0x2c, 0x70, 0x14, 0x01, 0xac, 0xc2, 0x88, 0xe0, 0x08, 0xe4, // IID269 + 0x62, 0x94, 0x70, 0x1c, 0x01, 0x8c, 0x67, 0x16, 0x82, 0x5b, 0x01, // IID270 + 0x62, 0x64, 0x0c, 0x10, 0x09, 0xa4, 0xd3, 0x4c, 0xbf, 0xca, 0xb9, // IID271 + 0x62, 0x8c, 0x6c, 0x10, 0x09, 0x94, 0xd4, 0x3b, 0xa7, 0x23, 0x35, // IID272 + 0x62, 0x84, 0x34, 0x1c, 0x09, 0xac, 0x7f, 0xaa, 0x22, 0xf4, 0xd5, // IID273 + 0x62, 0xec, 0x7c, 0x14, 0x09, 0x87, 0x01, 0x9b, 0xaf, 0xe9, // IID274 + 0x62, 0x8c, 0x1c, 0x10, 0x08, 0xa4, 0x1e, 0x3a, 0x1e, 0x28, 0x17, // IID275 + 0x62, 0xb4, 0x68, 0x18, 0x08, 0x94, 0xbb, 0xbb, 0xb5, 0x77, 0x24, // IID276 + 0x62, 0x44, 0x7c, 0x14, 0x08, 0x84, 0x4b, 0x51, 0x2e, 0x8a, 0xce, // IID277 + 0x62, 0xd4, 0x60, 0x1c, 0x08, 0x9c, 0xe3, 0x2d, 0x84, 0x29, 0xdd, // IID278 + 0x62, 0x9c, 0x28, 0x10, 0x29, 0x94, 0x73, 0xd2, 0x31, 0x64, 0xc2, // IID279 + 0x62, 0x2c, 0x00, 0x10, 0x29, 0xbc, 0x6e, 0x19, 0x85, 0x21, 0x14, // IID280 + 0x62, 0x54, 0x54, 0x14, 0x29, 0xa9, 0x86, 0xed, 0xaf, 0xef, // IID281 + 0x62, 0x04, 0x04, 0x14, 0x29, 0xbc, 0x01, 0x9f, 0x76, 0x1e, 0xf5, // IID282 + 0x62, 0x7c, 0x04, 0x18, 0x31, 0xa2, 0xe5, 0xbc, 0x2b, 0x5c, // IID283 + 0x62, 0x4c, 0x20, 0x10, 0x31, 0x9c, 0x39, 0xb3, 0x78, 0x60, 0x5c, // IID284 + 0x62, 0x54, 0x6c, 0x14, 0x31, 0xb4, 0xd0, 0x7f, 0xc7, 0x12, 0xf6, // IID285 + 0x62, 0x54, 0x34, 0x1c, 0x31, 0x8f, 0xad, 0xcd, 0x5a, 0x77, // IID286 + 0x62, 0xac, 0x50, 0x10, 0x30, 0xbc, 0x52, 0xd5, 0x1f, 0xe3, 0x2f, // IID287 + 0x62, 0x5c, 0x2c, 0x18, 0x30, 0x93, 0xde, 0x50, 0x31, 0x0a, // IID288 + 0x62, 0x2c, 0x68, 0x14, 0x30, 0x84, 0xf6, 0x97, 0xe8, 0xd4, 0x1a, // IID289 + 0x62, 0x7c, 0x38, 0x1c, 0x30, 0x84, 0x20, 0x82, 0xae, 0x6e, 0x62, // IID290 + 0x62, 0xd4, 0x54, 0x10, 0x81, 0xc7, 0x00, 0x00, 0x10, 0x00, // IID291 + 0x62, 0xfc, 0x7c, 0x18, 0x81, 0xc2, 0x00, 0x00, 0x10, 0x00, // IID292 + 0xd5, 0x10, 0x81, 0xc2, 0x00, 0x01, 0x00, 0x00, // IID293 + 0x62, 0xfc, 0x14, 0x1c, 0x83, 0xc3, 0x10, // IID294 + 0x62, 0xfc, 0x7c, 0x1c, 0x83, 0xc7, 0x10, // IID295 + 0x62, 0xdc, 0x34, 0x14, 0x81, 0xc1, 0x00, 0x00, 0x00, 0x01, // IID296 + 0x62, 0xfc, 0x14, 0x10, 0x81, 0xe2, 0x00, 0x00, 0x10, 0x00, // IID297 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xe6, 0x00, 0x00, 0x10, 0x00, // IID298 + 0xd5, 0x10, 0x81, 0xe3, 0x00, 0x00, 0x01, 0x00, // IID299 + 0x62, 0xdc, 0x24, 0x14, 0x81, 0xe1, 0x00, 0x00, 0x10, 0x00, // IID300 + 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xe4, 0x00, 0x00, 0x10, 0x00, // IID301 + 0x62, 0xdc, 0x1c, 0x14, 0x83, 0xe4, 0x10, // IID302 + 0x62, 0x6c, 0x7c, 0x08, 0x69, 0xfe, 0x00, 0x10, 0x00, 0x00, // IID303 +#endif // _LP64 + 0x62, 0xf4, 0x7c, 0x08, 0x69, 0xc3, 0x00, 0x10, 0x00, 0x00, // IID304 +#ifdef _LP64 + 0x62, 0x4c, 0x7c, 0x08, 0x69, 0xc0, 0x00, 0x00, 0x10, 0x00, // IID305 + 0x62, 0xec, 0x7c, 0x0c, 0x69, 0xe8, 0x00, 0x00, 0x01, 0x00, // IID306 + 0x62, 0xdc, 0x7c, 0x0c, 0x69, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID307 + 0x62, 0x54, 0x7c, 0x0c, 0x6b, 0xed, 0x10, // IID308 + 0x62, 0xd4, 0x14, 0x10, 0x81, 0xc8, 0x00, 0x00, 0x00, 0x01, // IID309 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xcc, 0x00, 0x00, 0x00, 0x01, // IID310 + 0xd5, 0x11, 0x81, 0xce, 0x00, 0x10, 0x00, 0x00, // IID311 + 0x62, 0xf4, 0x3c, 0x14, 0x83, 0xca, 0x10, // IID312 + 0x62, 0xd4, 0x7c, 0x1c, 0x83, 0xc8, 0x10, // IID313 + 0x62, 0xd4, 0x14, 0x1c, 0x81, 0xcd, 0x00, 0x10, 0x00, 0x00, // IID314 + 0x62, 0xd4, 0x34, 0x10, 0xd1, 0xd5, // IID315 + 0x62, 0xfc, 0x7c, 0x18, 0xd1, 0xd2, // IID316 + 0x41, 0xc1, 0xd1, 0x10, // IID317 + 0x62, 0xdc, 0x2c, 0x10, 0xc1, 0xc1, 0x08, // IID318 +#endif // _LP64 + 0x62, 0xf4, 0x7c, 0x18, 0xc1, 0xc2, 0x08, // IID319 +#ifdef _LP64 + 0xd5, 0x11, 0xc1, 0xc0, 0x10, // IID320 + 0x62, 0xf4, 0x3c, 0x14, 0xc1, 0xc1, 0x08, // IID321 + 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xc6, 0x08, // IID322 + 0x62, 0xdc, 0x1c, 0x14, 0xc1, 0xc4, 0x10, // IID323 + 0x62, 0xdc, 0x74, 0x10, 0xc1, 0xcc, 0x04, // IID324 +#endif // _LP64 + 0x62, 0xf4, 0x7c, 0x18, 0xc1, 0xca, 0x04, // IID325 +#ifdef _LP64 + 0x41, 0xc1, 0xc8, 0x10, // IID326 + 0x62, 0xf4, 0x64, 0x14, 0xc1, 0xca, 0x10, // IID327 + 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xcf, 0x10, // IID328 + 0x62, 0xfc, 0x4c, 0x14, 0xc1, 0xce, 0x08, // IID329 + 0x62, 0xdc, 0x44, 0x10, 0xc1, 0xe1, 0x10, // IID330 + 0x62, 0xd4, 0x7c, 0x18, 0xc1, 0xe6, 0x10, // IID331 + 0xd5, 0x11, 0xc1, 0xe7, 0x08, // IID332 + 0x62, 0xdc, 0x0c, 0x14, 0xc1, 0xe0, 0x02, // IID333 + 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xe5, 0x02, // IID334 + 0x62, 0xd4, 0x3c, 0x1c, 0xc1, 0xe0, 0x02, // IID335 + 0x62, 0xdc, 0x6c, 0x10, 0xc1, 0xf8, 0x10, // IID336 + 0x62, 0xd4, 0x7c, 0x18, 0xc1, 0xfd, 0x10, // IID337 + 0xd5, 0x11, 0xd1, 0xf8, // IID338 + 0x62, 0xfc, 0x1c, 0x14, 0xc1, 0xf9, 0x10, // IID339 + 0x62, 0xdc, 0x7c, 0x1c, 0xc1, 0xf8, 0x10, // IID340 + 0x62, 0xfc, 0x74, 0x14, 0xc1, 0xf9, 0x04, // IID341 + 0x62, 0xf4, 0x3c, 0x10, 0xc1, 0xe1, 0x04, // IID342 + 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xe0, 0x04, // IID343 + 0x41, 0xc1, 0xe7, 0x02, // IID344 + 0x62, 0xdc, 0x0c, 0x1c, 0xc1, 0xe3, 0x04, // IID345 + 0x62, 0xfc, 0x7c, 0x1c, 0xc1, 0xe7, 0x04, // IID346 + 0x62, 0xdc, 0x0c, 0x14, 0xc1, 0xe6, 0x04, // IID347 + 0x62, 0xf4, 0x24, 0x10, 0xc1, 0xea, 0x02, // IID348 + 0x62, 0xfc, 0x7c, 0x18, 0xc1, 0xeb, 0x02, // IID349 + 0xd5, 0x10, 0xc1, 0xec, 0x02, // IID350 + 0x62, 0xfc, 0x54, 0x14, 0xd1, 0xef, // IID351 + 0x62, 0xdc, 0x7c, 0x1c, 0xd1, 0xee, // IID352 + 0x62, 0xdc, 0x34, 0x14, 0xc1, 0xe9, 0x02, // IID353 + 0x62, 0xfc, 0x3c, 0x10, 0x81, 0xeb, 0x00, 0x00, 0x10, 0x00, // IID354 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xee, 0x00, 0x00, 0x10, 0x00, // IID355 + 0xd5, 0x10, 0x81, 0xee, 0x00, 0x00, 0x00, 0x10, // IID356 + 0x62, 0xdc, 0x3c, 0x14, 0x81, 0xe8, 0x00, 0x00, 0x01, 0x00, // IID357 + 0x62, 0xd4, 0x7c, 0x1c, 0x81, 0xee, 0x00, 0x00, 0x01, 0x00, // IID358 + 0x62, 0xdc, 0x1c, 0x14, 0x81, 0xec, 0x00, 0x00, 0x00, 0x10, // IID359 + 0x62, 0xfc, 0x64, 0x18, 0x81, 0xf4, 0x00, 0x01, 0x00, 0x00, // IID360 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xf7, 0x00, 0x01, 0x00, 0x00, // IID361 +#endif // _LP64 + 0x81, 0xf3, 0x00, 0x10, 0x00, 0x00, // IID362 +#ifdef _LP64 + 0x62, 0xdc, 0x3c, 0x14, 0x81, 0xf6, 0x00, 0x00, 0x01, 0x00, // IID363 + 0x62, 0xdc, 0x7c, 0x1c, 0x81, 0xf7, 0x00, 0x00, 0x01, 0x00, // IID364 + 0x62, 0xdc, 0x04, 0x14, 0x81, 0xf7, 0x00, 0x10, 0x00, 0x00, // IID365 + 0x62, 0xd4, 0x5c, 0x10, 0x81, 0xea, 0x00, 0x00, 0x10, 0x00, // IID366 + 0x62, 0xd4, 0x7c, 0x18, 0x81, 0xed, 0x00, 0x00, 0x10, 0x00, // IID367 + 0xd5, 0x11, 0x81, 0xe9, 0x00, 0x00, 0x10, 0x00, // IID368 + 0x62, 0xd4, 0x44, 0x14, 0x81, 0xec, 0x00, 0x00, 0x00, 0x40, // IID369 + 0x62, 0xfc, 0x7c, 0x1c, 0x81, 0xe8, 0x00, 0x00, 0x00, 0x40, // IID370 + 0x62, 0xdc, 0x04, 0x14, 0x81, 0xef, 0x00, 0x00, 0x01, 0x00, // IID371 + 0x62, 0x54, 0x74, 0x10, 0x03, 0xa9, 0x98, 0x2f, 0xef, 0x7f, // IID372 + 0x62, 0x7c, 0x14, 0x14, 0x03, 0x86, 0x54, 0xf5, 0x08, 0xb2, // IID373 + 0x62, 0x84, 0x14, 0x18, 0x23, 0x8c, 0xfc, 0x02, 0xa9, 0xa8, 0x50, // IID374 + 0x62, 0x0c, 0x4c, 0x14, 0x23, 0x8c, 0x92, 0x54, 0x27, 0xea, 0x70, // IID375 + 0x62, 0x1c, 0x64, 0x10, 0xaf, 0xa4, 0x06, 0x73, 0x0a, 0x1a, 0x6a, // IID376 + 0x62, 0xec, 0x08, 0x14, 0xaf, 0x94, 0x9a, 0x39, 0xd7, 0x32, 0x80, // IID377 + 0x62, 0x0c, 0x7c, 0x10, 0x0b, 0xbc, 0xd9, 0xbc, 0x5d, 0x2d, 0x48, // IID378 + 0x62, 0x44, 0x34, 0x1c, 0x0b, 0x9b, 0x01, 0xee, 0xd5, 0x43, // IID379 + 0x62, 0xac, 0x74, 0x18, 0x2b, 0xbc, 0xbd, 0xbc, 0xc2, 0x25, 0x28, // IID380 + 0x62, 0x84, 0x24, 0x14, 0x2b, 0xb4, 0x7d, 0xa7, 0x0d, 0x1f, 0x77, // IID381 + 0x62, 0x44, 0x30, 0x18, 0x33, 0xb4, 0xf1, 0x72, 0x37, 0x29, 0xb5, // IID382 + 0x62, 0xa4, 0x20, 0x1c, 0x33, 0x84, 0xa3, 0xee, 0x23, 0x02, 0x0b, // IID383 + 0x62, 0x04, 0x00, 0x18, 0x32, 0xac, 0x67, 0x97, 0x85, 0xd6, 0xe0, // IID384 + 0x62, 0x6c, 0x74, 0x14, 0x32, 0xb4, 0x5f, 0x45, 0x75, 0xdc, 0x0a, // IID385 + 0x62, 0x74, 0x21, 0x10, 0x33, 0x8c, 0xb2, 0x9f, 0xf0, 0x26, 0xbc, // IID386 + 0x62, 0xcc, 0x61, 0x1c, 0x33, 0xb4, 0x34, 0x4f, 0x5f, 0xcf, 0x82, // IID387 + 0x62, 0x64, 0x0c, 0x18, 0x03, 0xc1, // IID388 + 0xd5, 0x14, 0x03, 0xc1, // IID389 + 0x62, 0x44, 0x2c, 0x14, 0x03, 0xc4, // IID390 + 0x62, 0x6c, 0x3c, 0x14, 0x03, 0xc7, // IID391 + 0x62, 0x4c, 0x14, 0x18, 0x23, 0xd7, // IID392 + 0x45, 0x23, 0xd8, // IID393 + 0x62, 0xc4, 0x74, 0x1c, 0x23, 0xdf, // IID394 + 0x62, 0x54, 0x1c, 0x1c, 0x23, 0xe4, // IID395 + 0x62, 0xec, 0x4c, 0x10, 0xaf, 0xe3, // IID396 + 0x44, 0x0f, 0xaf, 0xc2, // IID397 + 0x62, 0x6c, 0x4c, 0x14, 0xaf, 0xdf, // IID398 + 0x62, 0x7c, 0x34, 0x1c, 0xaf, 0xca, // IID399 + 0x62, 0x44, 0x75, 0x18, 0x0b, 0xf5, // IID400 + 0x66, 0xd5, 0x54, 0x0b, 0xe3, // IID401 + 0x62, 0x4c, 0x1d, 0x1c, 0x0b, 0xf3, // IID402 + 0x62, 0x7c, 0x3d, 0x1c, 0x0b, 0xc6, // IID403 + 0x62, 0xdc, 0x7c, 0x10, 0x0b, 0xce, // IID404 + 0xd5, 0x15, 0x0b, 0xd1, // IID405 + 0x62, 0xec, 0x04, 0x1c, 0x0b, 0xc9, // IID406 + 0x62, 0x5c, 0x34, 0x1c, 0x0b, 0xce, // IID407 + 0x62, 0x7c, 0x5c, 0x10, 0xa5, 0xc5, // IID408 + 0xd5, 0x95, 0xa5, 0xf2, // IID409 + 0x62, 0x74, 0x7c, 0x14, 0xa5, 0xf2, // IID410 + 0x62, 0x7c, 0x64, 0x14, 0xa5, 0xc3, // IID411 + 0x62, 0x64, 0x24, 0x10, 0xad, 0xd3, // IID412 + 0xd5, 0xd1, 0xad, 0xdc, // IID413 + 0x62, 0x54, 0x74, 0x1c, 0xad, 0xf3, // IID414 + 0x62, 0xcc, 0x04, 0x14, 0xad, 0xdf, // IID415 + 0x62, 0x5c, 0x2c, 0x10, 0x2b, 0xe9, // IID416 + 0xd5, 0x45, 0x2b, 0xc3, // IID417 + 0x62, 0xc4, 0x6c, 0x14, 0x2b, 0xe5, // IID418 + 0x62, 0xec, 0x7c, 0x14, 0x2b, 0xc2, // IID419 + 0x62, 0xc4, 0x64, 0x10, 0x33, 0xc8, // IID420 + 0xd5, 0x41, 0x33, 0xdd, // IID421 + 0x62, 0x54, 0x44, 0x14, 0x33, 0xef, // IID422 + 0x62, 0x5c, 0x24, 0x1c, 0x33, 0xdd, // IID423 + 0x62, 0xec, 0x14, 0x10, 0x24, 0xc9, 0x01, // IID424 + 0xd5, 0xd4, 0xa4, 0xc6, 0x04, // IID425 + 0x62, 0x5c, 0x3c, 0x1c, 0x24, 0xdc, 0x10, // IID426 + 0x62, 0xc4, 0x04, 0x1c, 0x24, 0xff, 0x04, // IID427 + 0x62, 0xec, 0x14, 0x10, 0x2c, 0xc6, 0x04, // IID428 + 0x45, 0x0f, 0xac, 0xcd, 0x04, // IID429 + 0x62, 0x7c, 0x04, 0x1c, 0x2c, 0xe5, 0x02, // IID430 + 0x62, 0xec, 0x74, 0x14, 0x2c, 0xf9, 0x02, // IID431 + 0x62, 0xcc, 0x6c, 0x18, 0x40, 0xc5, // IID432 + 0xd5, 0x94, 0x40, 0xd5, // IID433 + 0x62, 0x6c, 0x74, 0x10, 0x41, 0xea, // IID434 + 0xd5, 0xd5, 0x41, 0xe0, // IID435 + 0x62, 0xcc, 0x2c, 0x18, 0x42, 0xe3, // IID436 + 0x45, 0x0f, 0x42, 0xd6, // IID437 + 0x62, 0x64, 0x24, 0x18, 0x43, 0xd9, // IID438 + 0xd5, 0xc1, 0x43, 0xf7, // IID439 + 0x62, 0x6c, 0x04, 0x10, 0x44, 0xf3, // IID440 + 0xd5, 0xd1, 0x44, 0xda, // IID441 + 0x62, 0x5c, 0x54, 0x10, 0x45, 0xf2, // IID442 + 0xd5, 0xc1, 0x45, 0xe7, // IID443 + 0x62, 0x7c, 0x1c, 0x18, 0x46, 0xef, // IID444 + 0xd5, 0xd4, 0x46, 0xe4, // IID445 + 0x62, 0x44, 0x5c, 0x10, 0x47, 0xc3, // IID446 + 0x45, 0x0f, 0x47, 0xd7, // IID447 + 0x62, 0xec, 0x64, 0x10, 0x48, 0xe7, // IID448 + 0xd5, 0x95, 0x48, 0xfa, // IID449 + 0x62, 0x6c, 0x64, 0x10, 0x49, 0xc7, // IID450 + 0xd5, 0xc5, 0x49, 0xe3, // IID451 + 0x44, 0x0f, 0x4a, 0xea, // IID452 + 0xd5, 0xd4, 0x4a, 0xff, // IID453 + 0x62, 0x5c, 0x44, 0x10, 0x4b, 0xcb, // IID454 + 0xd5, 0xd0, 0x4b, 0xec, // IID455 + 0x62, 0xcc, 0x3c, 0x10, 0x4c, 0xed, // IID456 + 0x41, 0x0f, 0x4c, 0xdb, // IID457 + 0x62, 0xf4, 0x54, 0x10, 0x4d, 0xd9, // IID458 + 0xd5, 0xd4, 0x4d, 0xfd, // IID459 + 0x62, 0x4c, 0x04, 0x18, 0x4e, 0xce, // IID460 + 0xd5, 0xd1, 0x4e, 0xf9, // IID461 + 0x62, 0xd4, 0x6c, 0x10, 0x4f, 0xca, // IID462 + 0xd5, 0x91, 0x4f, 0xcf, // IID463 + 0x62, 0xcc, 0x54, 0x10, 0x40, 0x9a, 0x8d, 0xf7, 0xd6, 0x91, // IID464 + 0x62, 0xec, 0x3c, 0x10, 0x41, 0x9c, 0x0e, 0x9a, 0x5f, 0xf8, 0x11, // IID465 + 0x62, 0x6c, 0x74, 0x10, 0x42, 0x84, 0x24, 0x5e, 0x77, 0x4d, 0x53, // IID466 + 0x62, 0xec, 0x5c, 0x10, 0x43, 0x94, 0x24, 0x33, 0xb1, 0x36, 0xb8, // IID467 + 0x62, 0x7c, 0x34, 0x18, 0x44, 0xaf, 0x9d, 0x3a, 0x7c, 0xb4, // IID468 + 0x62, 0x0c, 0x24, 0x18, 0x45, 0x8c, 0x70, 0x51, 0xf8, 0x9a, 0xbb, // IID469 + 0x62, 0x0c, 0x0c, 0x18, 0x46, 0x84, 0xae, 0x1d, 0x66, 0xd0, 0x00, // IID470 + 0x62, 0x04, 0x10, 0x18, 0x47, 0x8c, 0xde, 0x03, 0x14, 0x7e, 0x04, // IID471 + 0x62, 0xe4, 0x3c, 0x10, 0x48, 0x9c, 0xd1, 0xe8, 0xac, 0xb5, 0x9b, // IID472 + 0x62, 0x6c, 0x28, 0x10, 0x49, 0x84, 0x36, 0x46, 0x24, 0x35, 0x70, // IID473 + 0x62, 0x04, 0x60, 0x10, 0x4a, 0x94, 0xb0, 0x5c, 0x2f, 0xa1, 0x78, // IID474 + 0x62, 0x5c, 0x10, 0x10, 0x4b, 0x9c, 0x21, 0x3a, 0x30, 0xa8, 0x27, // IID475 + 0x62, 0x4c, 0x48, 0x10, 0x4c, 0x84, 0x43, 0x10, 0x1a, 0x54, 0x02, // IID476 + 0x62, 0x54, 0x00, 0x10, 0x4d, 0xbc, 0xc0, 0x51, 0x32, 0x8e, 0x55, // IID477 + 0x62, 0x84, 0x24, 0x10, 0x4e, 0x94, 0x10, 0x49, 0x78, 0xe6, 0xb8, // IID478 + 0x62, 0xec, 0x68, 0x10, 0x4f, 0x84, 0x9a, 0xe2, 0x17, 0xf5, 0xed, // IID479 + 0xd5, 0x19, 0x13, 0xdf, // IID480 + 0xd5, 0x5d, 0x3b, 0xf7, // IID481 + 0xd5, 0xdd, 0xaf, 0xec, // IID482 + 0xf3, 0xd5, 0xcd, 0xb8, 0xca, // IID483 + 0xd5, 0x5c, 0x1b, 0xc4, // IID484 + 0xd5, 0x48, 0x2b, 0xc2, // IID485 + 0xf3, 0xd5, 0xdd, 0xbc, 0xd4, // IID486 + 0xf3, 0xd5, 0xcd, 0xbd, 0xe1, // IID487 + 0xd5, 0x59, 0x03, 0xe0, // IID488 + 0xd5, 0x5d, 0x23, 0xc5, // IID489 + 0xd5, 0x59, 0x0b, 0xfb, // IID490 + 0x4d, 0x33, 0xfc, // IID491 + 0xd5, 0x58, 0x8b, 0xd3, // IID492 + 0xd5, 0xcc, 0xbc, 0xf9, // IID493 + 0x4d, 0x0f, 0xbd, 0xcd, // IID494 + 0xd5, 0x98, 0xa3, 0xcc, // IID495 + 0xd5, 0x1c, 0x87, 0xc5, // IID496 + 0xd5, 0x4d, 0x85, 0xc6, // IID497 + 0xd5, 0x6c, 0x01, 0xac, 0xb9, 0x4d, 0x6c, 0xf0, 0x4f, // IID498 + 0xd5, 0x5f, 0x21, 0x94, 0x50, 0x77, 0x5e, 0x26, 0x8a, // IID499 + 0xd5, 0x48, 0x39, 0x8c, 0x1b, 0x9c, 0xd5, 0x33, 0x40, // IID500 + 0xd5, 0x5a, 0x09, 0x94, 0xe6, 0x83, 0xcb, 0x6c, 0xc7, // IID501 + 0xd5, 0x3c, 0x31, 0xa4, 0xfc, 0x60, 0x15, 0x31, 0x4b, // IID502 + 0xd5, 0x6f, 0x29, 0xac, 0xa2, 0x57, 0x26, 0x3a, 0x5c, // IID503 + 0xd5, 0x6b, 0x89, 0xb4, 0xcd, 0x3f, 0x6f, 0x3d, 0x1a, // IID504 + 0xd5, 0xfe, 0xc1, 0x8c, 0xc1, 0x28, 0x24, 0x52, 0xca, // IID505 + 0xd5, 0x19, 0x81, 0xa1, 0xc3, 0x84, 0x21, 0x63, 0x00, 0x00, 0x00, 0x01, // IID506 + 0x4b, 0x81, 0x84, 0x2d, 0x3a, 0x15, 0x8d, 0xc6, 0x00, 0x00, 0x00, 0x01, // IID507 + 0x49, 0x81, 0xb9, 0xfa, 0x37, 0x4b, 0xec, 0x00, 0x10, 0x00, 0x00, // IID508 + 0xd5, 0x19, 0xd1, 0xbf, 0x51, 0xf5, 0xa7, 0x4f, // IID509 + 0xd5, 0x3a, 0xd1, 0xa4, 0xbd, 0x32, 0x82, 0xaa, 0x31, // IID510 + 0xd5, 0x3b, 0x81, 0x9c, 0xb8, 0x49, 0xc7, 0x9a, 0xb9, 0x00, 0x00, 0x00, 0x10, // IID511 + 0xd5, 0x39, 0xc1, 0xac, 0x34, 0x4f, 0x7a, 0x01, 0xc1, 0x02, // IID512 + 0xd5, 0x18, 0x81, 0xa8, 0x15, 0x5c, 0x76, 0xec, 0x00, 0x00, 0x10, 0x00, // IID513 + 0xd5, 0x1b, 0x83, 0xb4, 0x05, 0x15, 0x26, 0x02, 0x1d, 0x10, // IID514 + 0xd5, 0x2b, 0x83, 0x8c, 0x64, 0x1e, 0x67, 0x37, 0xcb, 0x01, // IID515 + 0xd5, 0x2a, 0xc7, 0x84, 0x81, 0xf8, 0x14, 0xbb, 0xe9, 0x00, 0x01, 0x00, 0x00, // IID516 + 0xd5, 0x19, 0xf7, 0x85, 0xf5, 0x76, 0xdc, 0x82, 0x00, 0x00, 0xff, 0xff, // IID517 + 0xd5, 0x68, 0x03, 0xbc, 0x99, 0x54, 0xc6, 0xea, 0x70, // IID518 + 0xd5, 0x1b, 0x23, 0x94, 0x38, 0x57, 0x25, 0xb2, 0xdf, // IID519 + 0xd5, 0x1a, 0x3b, 0x94, 0xdf, 0xbd, 0x30, 0xc9, 0x32, // IID520 + 0xf3, 0xd5, 0xcc, 0xbd, 0xa2, 0x71, 0x3d, 0xcc, 0xab, // IID521 + 0xd5, 0x5a, 0x0b, 0xb4, 0x73, 0xc8, 0x82, 0x39, 0xd3, // IID522 + 0x4d, 0x13, 0x92, 0x9f, 0xc5, 0xd7, 0x03, // IID523 + 0x4f, 0x0f, 0xaf, 0x94, 0xc0, 0xd3, 0x79, 0x9e, 0xf1, // IID524 + 0xf3, 0xd5, 0xd9, 0xb8, 0xbd, 0x93, 0x26, 0x81, 0x88, // IID525 + 0xd5, 0x28, 0x1b, 0x8c, 0x5b, 0xcb, 0x01, 0xc6, 0x53, // IID526 + 0xd5, 0x1c, 0x2b, 0xb4, 0x19, 0x8d, 0x0f, 0x74, 0x89, // IID527 + 0xf3, 0xd5, 0xed, 0xbc, 0xac, 0x5a, 0x3c, 0x8d, 0xc9, 0x30, // IID528 + 0xd5, 0x3e, 0x33, 0x94, 0x18, 0xfe, 0x29, 0xf7, 0xc2, // IID529 + 0xd5, 0x7b, 0x8b, 0x94, 0xe4, 0x6f, 0x53, 0x04, 0x9d, // IID530 + 0x48, 0x8d, 0x99, 0xa5, 0x02, 0x06, 0x45, // IID531 + 0xf2, 0xd5, 0xbf, 0x2c, 0xa4, 0x3e, 0xd0, 0x59, 0x67, 0x98, // IID532 + 0xd5, 0x5f, 0x87, 0xbc, 0x50, 0x13, 0xed, 0x98, 0x8f, // IID533 + 0xd5, 0x2d, 0x85, 0xb4, 0xe5, 0xf2, 0x81, 0x10, 0x17, // IID534 + 0xd5, 0x19, 0x83, 0xc7, 0x10, // IID535 + 0xd5, 0x19, 0x83, 0xe1, 0x10, // IID536 + 0xd5, 0x18, 0x81, 0xd7, 0x00, 0x01, 0x00, 0x00, // IID537 + 0xd5, 0x18, 0x81, 0xfb, 0x00, 0x00, 0x00, 0x10, // IID538 + 0xd5, 0x19, 0xd1, 0xd7, // IID539 + 0xd5, 0x18, 0xd1, 0xd9, // IID540 + 0xd5, 0x19, 0xc1, 0xc1, 0x02, // IID541 + 0xd5, 0x18, 0xc1, 0xc9, 0x04, // IID542 + 0xd5, 0x19, 0xd1, 0xfc, // IID543 + 0x49, 0xc1, 0xe7, 0x04, // IID544 + 0x48, 0x81, 0xdb, 0x00, 0x00, 0x01, 0x00, // IID545 + 0xd5, 0x18, 0xd1, 0xe5, // IID546 + 0x49, 0xd1, 0xea, // IID547 + 0x49, 0x83, 0xee, 0x10, // IID548 + 0xd5, 0x18, 0x81, 0xf2, 0x00, 0x00, 0x00, 0x10, // IID549 + 0xd5, 0x18, 0xc7, 0xc7, 0x10, 0x00, 0x00, 0x00, // IID550 + 0x49, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // IID551 + 0x49, 0x0f, 0xba, 0xe6, 0x04, // IID552 + 0xd5, 0x19, 0xf7, 0xc0, 0x00, 0xf0, 0xff, 0xff, // IID553 + 0xd5, 0x18, 0x81, 0xcb, 0x00, 0x00, 0x10, 0x00, // IID554 + 0x48, 0x81, 0xe9, 0x00, 0x00, 0x00, 0x10, // IID555 + 0xd5, 0x98, 0x40, 0x94, 0xdb, 0xc4, 0xc8, 0x11, 0x02, // IID556 + 0xd5, 0x98, 0x41, 0x9d, 0x43, 0x77, 0x26, 0x49, // IID557 + 0xd5, 0xeb, 0x42, 0xac, 0x60, 0xba, 0xd6, 0x73, 0xb3, // IID558 + 0xd5, 0xbd, 0x43, 0xa4, 0x22, 0x64, 0x07, 0xb2, 0xd9, // IID559 + 0xd5, 0xdb, 0x44, 0x8c, 0x8c, 0x6b, 0x19, 0x97, 0x34, // IID560 + 0xd5, 0xad, 0x45, 0xac, 0x7f, 0x67, 0xf6, 0x5c, 0xd8, // IID561 + 0xd5, 0xd8, 0x46, 0xb6, 0x05, 0xab, 0x39, 0x0f, // IID562 + 0xd5, 0xba, 0x47, 0x8c, 0xd6, 0xb4, 0x6a, 0x73, 0xfb, // IID563 + 0xd5, 0xfc, 0x48, 0x8c, 0x2b, 0x0b, 0x5b, 0x40, 0x0e, // IID564 + 0xd5, 0xbe, 0x49, 0xa4, 0xeb, 0xb5, 0xfb, 0x9d, 0x88, // IID565 + 0xd5, 0x9b, 0x4a, 0x9c, 0x56, 0xdd, 0x7c, 0x86, 0xe6, // IID566 + 0xd5, 0xfb, 0x4b, 0xac, 0x38, 0xd5, 0x9a, 0xce, 0xa8, // IID567 + 0xd5, 0xcb, 0x4c, 0x94, 0x50, 0x77, 0x41, 0xec, 0xa9, // IID568 + 0xd5, 0xfc, 0x4d, 0xa4, 0xed, 0xc4, 0xfd, 0xa0, 0x65, // IID569 + 0xd5, 0xe9, 0x4e, 0xbc, 0x13, 0xf4, 0x0e, 0xe5, 0xe2, // IID570 + 0xd5, 0xda, 0x4f, 0xb4, 0x62, 0x38, 0x1c, 0x5f, 0x1a, // IID571 + 0xd5, 0x10, 0xff, 0xd7, // IID572 + 0xd5, 0x19, 0xf7, 0xf6, // IID573 + 0xd5, 0x18, 0xf7, 0xfb, // IID574 + 0x49, 0xf7, 0xe9, // IID575 + 0x49, 0xf7, 0xe5, // IID576 + 0xd5, 0x18, 0xf7, 0xd8, // IID577 + 0xd5, 0x19, 0xf7, 0xd5, // IID578 + 0x48, 0xd3, 0xc1, // IID579 + 0xd5, 0x19, 0xd3, 0xc9, // IID580 + 0x49, 0xd3, 0xf8, // IID581 + 0xd5, 0x19, 0xd3, 0xe3, // IID582 + 0xd5, 0x19, 0xd3, 0xe6, // IID583 + 0xd5, 0x18, 0xd3, 0xef, // IID584 + 0x48, 0xff, 0xc3, // IID585 + 0x49, 0xff, 0xce, // IID586 + 0xd5, 0x18, 0x55, // IID587 + 0xd5, 0x18, 0x5d, // IID588 + 0xd5, 0x30, 0xff, 0x94, 0x6c, 0x2f, 0xaf, 0xc6, 0x56, // IID589 + 0xd5, 0x39, 0xf7, 0xa4, 0xdf, 0xdd, 0x14, 0x4b, 0xfe, // IID590 + 0xd5, 0x3b, 0xf7, 0x9c, 0x1b, 0xe1, 0x03, 0x24, 0xa7, // IID591 + 0xd5, 0x28, 0xd3, 0xbc, 0xb3, 0x2f, 0xb6, 0x9c, 0x9f, // IID592 + 0xd5, 0x39, 0xd3, 0xa4, 0xfa, 0x79, 0xa0, 0x95, 0x0b, // IID593 + 0xd5, 0x2b, 0xd3, 0xac, 0x16, 0x09, 0x4e, 0x54, 0x03, // IID594 + 0xd5, 0x19, 0xff, 0x84, 0x13, 0x50, 0x32, 0x0b, 0x12, // IID595 + 0xd5, 0x2b, 0xff, 0x8c, 0x89, 0x35, 0x13, 0x55, 0xcb, // IID596 + 0xd5, 0x7a, 0x69, 0xa4, 0x60, 0x5b, 0xfa, 0x21, 0xa6, 0x00, 0x00, 0x10, 0x00, // IID597 + 0xd5, 0x58, 0x69, 0xcf, 0x00, 0x01, 0x00, 0x00, // IID598 + 0xd5, 0x9c, 0xa4, 0xdb, 0x08, // IID599 + 0xd5, 0x9d, 0xac, 0xd4, 0x08, // IID600 + 0x62, 0xdc, 0x2c, 0x10, 0x8f, 0xc5, // IID601 + 0x62, 0xfc, 0xac, 0x18, 0x8f, 0xc6, // IID602 + 0x62, 0xdc, 0x0c, 0x10, 0xff, 0xf1, // IID603 + 0x62, 0xdc, 0x84, 0x18, 0xff, 0xf4, // IID604 + 0xd5, 0xbd, 0xb6, 0x9c, 0x9d, 0xcc, 0x72, 0xc9, 0xed, // IID605 + 0xd5, 0xaf, 0xb7, 0xb4, 0xb0, 0x22, 0x6d, 0x6c, 0xb5, // IID606 + 0xd5, 0xde, 0xbe, 0xa4, 0x3f, 0x54, 0xcb, 0x89, 0x61, // IID607 + 0xd5, 0xec, 0xbf, 0xa4, 0xfb, 0x9f, 0x9a, 0x17, 0xd2, // IID608 + 0x4c, 0x0f, 0xb6, 0xd9, // IID609 + 0xd5, 0xcd, 0xb7, 0xf7, // IID610 + 0x4c, 0x0f, 0xbe, 0xf1, // IID611 + 0xd5, 0xc9, 0xbf, 0xf9, // IID612 + 0x4f, 0x0f, 0xb1, 0xa4, 0x55, 0xc6, 0xd3, 0x39, 0xf8, // IID613 + 0x62, 0xf4, 0xfc, 0x08, 0xf7, 0xf9, // IID614 + 0x62, 0xd4, 0xfc, 0x0c, 0xf7, 0xff, // IID615 + 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xf7, // IID616 + 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xf0, // IID617 + 0x62, 0xdc, 0xfc, 0x08, 0xf7, 0xeb, // IID618 + 0x62, 0xdc, 0xfc, 0x0c, 0xf7, 0xee, // IID619 + 0x62, 0xd4, 0xfc, 0x08, 0xf7, 0xe4, // IID620 + 0x62, 0xf4, 0xfc, 0x0c, 0xf7, 0xe1, // IID621 + 0x62, 0x94, 0xfc, 0x08, 0xf7, 0xa4, 0xcd, 0x6c, 0x54, 0x95, 0xdd, // IID622 + 0x62, 0x94, 0xf8, 0x0c, 0xf7, 0xa4, 0xc5, 0xfb, 0x89, 0x93, 0xd7, // IID623 + 0x62, 0xcc, 0xfc, 0x08, 0xaf, 0xee, // IID624 + 0xd5, 0x18, 0xf7, 0xe9, // IID625 + 0x62, 0x44, 0xfc, 0x0c, 0xaf, 0xec, // IID626 + 0x62, 0x4c, 0xfc, 0x0c, 0xaf, 0xf6, // IID627 + 0x62, 0x44, 0xfc, 0x08, 0xf5, 0xc7, // IID628 + 0x62, 0x4c, 0xfc, 0x08, 0xf5, 0xc9, // IID629 + 0x62, 0x6c, 0xfc, 0x0c, 0xf5, 0xcd, // IID630 + 0x62, 0xec, 0xfc, 0x0c, 0xf5, 0xf6, // IID631 + 0x62, 0xdc, 0xf4, 0x10, 0xf7, 0xde, // IID632 + 0xd5, 0x18, 0xf7, 0xd9, // IID633 + 0x62, 0xfc, 0x84, 0x14, 0xf7, 0xd9, // IID634 + 0x62, 0xdc, 0x94, 0x14, 0xf7, 0xdd, // IID635 + 0x62, 0xd4, 0xac, 0x18, 0xf7, 0xd1, // IID636 + 0xd5, 0x19, 0xf7, 0xd0, // IID637 + 0x62, 0x44, 0xfc, 0x08, 0x88, 0xe7, // IID638 + 0x62, 0x54, 0xfc, 0x08, 0x88, 0xd2, // IID639 + 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xde, // IID640 + 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xe4, // IID641 + 0x62, 0xd4, 0x9c, 0x10, 0xd3, 0xc6, // IID642 + 0xd5, 0x18, 0xd3, 0xc7, // IID643 + 0x62, 0xdc, 0xc4, 0x14, 0xd3, 0xc0, // IID644 + 0x62, 0xfc, 0xd4, 0x14, 0xd3, 0xc5, // IID645 + 0x62, 0xfc, 0x84, 0x10, 0xd3, 0xce, // IID646 + 0xd5, 0x19, 0xd3, 0xcc, // IID647 + 0x62, 0xd4, 0xf4, 0x14, 0xd3, 0xca, // IID648 + 0x62, 0xd4, 0xb4, 0x1c, 0xd3, 0xc9, // IID649 + 0x62, 0xdc, 0x94, 0x10, 0xd3, 0xe6, // IID650 + 0x49, 0xd3, 0xe3, // IID651 + 0x62, 0xd4, 0xac, 0x14, 0xd3, 0xe3, // IID652 + 0x62, 0xfc, 0xfc, 0x14, 0xd3, 0xe0, // IID653 + 0x62, 0xd4, 0xe4, 0x18, 0xd3, 0xff, // IID654 + 0x49, 0xd3, 0xfe, // IID655 + 0x62, 0xfc, 0xb4, 0x14, 0xd3, 0xf8, // IID656 + 0x62, 0xd4, 0xbc, 0x1c, 0xd3, 0xf8, // IID657 + 0x62, 0xd4, 0xa4, 0x18, 0xff, 0xcd, // IID658 + 0x48, 0xff, 0xc9, // IID659 + 0x62, 0xfc, 0xd4, 0x14, 0xff, 0xca, // IID660 + 0x62, 0xdc, 0x9c, 0x14, 0xff, 0xcc, // IID661 + 0xd5, 0x18, 0xff, 0xc0, // IID662 + 0xd5, 0x19, 0xff, 0xc5, // IID663 + 0x62, 0xd4, 0xec, 0x14, 0xff, 0xc1, // IID664 + 0x62, 0xfc, 0xe4, 0x14, 0xff, 0xc3, // IID665 + 0x62, 0xfc, 0xe4, 0x10, 0xd3, 0xe2, // IID666 + 0x49, 0xd3, 0xe0, // IID667 + 0x62, 0xd4, 0x9c, 0x1c, 0xd3, 0xe7, // IID668 + 0x62, 0xdc, 0x94, 0x14, 0xd3, 0xe5, // IID669 + 0x62, 0xdc, 0x9c, 0x10, 0xd3, 0xe8, // IID670 + 0xd5, 0x18, 0xd3, 0xeb, // IID671 + 0x62, 0xdc, 0xbc, 0x1c, 0xd3, 0xec, // IID672 + 0x62, 0xfc, 0xf4, 0x14, 0xd3, 0xe9, // IID673 + 0x62, 0x6c, 0xfc, 0x08, 0xf4, 0xe0, // IID674 + 0x62, 0x54, 0xfc, 0x08, 0xf4, 0xf6, // IID675 + 0x62, 0x5c, 0xfc, 0x0c, 0xf4, 0xe7, // IID676 + 0x62, 0x54, 0xfc, 0x0c, 0xf4, 0xf6, // IID677 + 0x62, 0x44, 0xfc, 0x08, 0xaf, 0xbd, 0xae, 0x4c, 0x3b, 0x96, // IID678 + 0x62, 0xec, 0xfc, 0x0c, 0xaf, 0x8a, 0xfb, 0xee, 0x54, 0x9f, // IID679 + 0x62, 0x04, 0xf8, 0x08, 0xf5, 0x9c, 0x8e, 0x83, 0xbf, 0x98, 0x27, // IID680 + 0x62, 0x84, 0xfc, 0x0c, 0xf5, 0xbc, 0x1a, 0xa3, 0x9c, 0x71, 0xc8, // IID681 + 0x62, 0xbc, 0xf4, 0x18, 0xf7, 0x9c, 0xcb, 0xc0, 0x2b, 0xb8, 0x97, // IID682 + 0x62, 0xf4, 0xf4, 0x1c, 0xf7, 0x9c, 0x0b, 0x8d, 0xd3, 0x92, 0x6f, // IID683 + 0x62, 0xc4, 0xfc, 0x08, 0x88, 0xa4, 0x24, 0x2a, 0xd8, 0x74, 0xd5, // IID684 + 0x62, 0x4c, 0xfc, 0x0c, 0x88, 0xbe, 0xd0, 0xf6, 0x03, 0x46, // IID685 + 0x62, 0xdc, 0xe4, 0x18, 0xd3, 0xa0, 0xf9, 0x06, 0x7d, 0x56, // IID686 + 0x62, 0x9c, 0x98, 0x1c, 0xd3, 0xa4, 0x20, 0xb2, 0xa7, 0xb3, 0xe3, // IID687 + 0x62, 0xbc, 0x98, 0x18, 0xd3, 0xbc, 0x87, 0x46, 0x43, 0xa8, 0xce, // IID688 + 0x62, 0x94, 0xb8, 0x1c, 0xd3, 0xbc, 0x86, 0x5b, 0x6f, 0xbd, 0x8e, // IID689 + 0x62, 0x94, 0xc4, 0x10, 0xff, 0x8c, 0x78, 0x23, 0x8d, 0x1d, 0xa5, // IID690 + 0x62, 0x9c, 0x94, 0x1c, 0xff, 0x8c, 0xcd, 0x57, 0x8b, 0xae, 0xa4, // IID691 + 0x62, 0xbc, 0xa0, 0x18, 0xff, 0x84, 0xfd, 0x24, 0x4b, 0x89, 0xde, // IID692 + 0x62, 0xf4, 0x90, 0x1c, 0xff, 0x84, 0x01, 0x37, 0xb7, 0x4b, 0xc9, // IID693 + 0x62, 0xdc, 0xac, 0x10, 0xd3, 0xac, 0x89, 0x6d, 0xb6, 0x76, 0xa0, // IID694 + 0x62, 0xd4, 0xb4, 0x14, 0xd3, 0xa9, 0x21, 0x8d, 0x79, 0x51, // IID695 + 0x62, 0x04, 0xf8, 0x08, 0xf4, 0xa4, 0x95, 0xf6, 0x96, 0x71, 0x20, // IID696 + 0x62, 0xbc, 0xfc, 0x0c, 0xf4, 0x9c, 0x2b, 0x2b, 0xc8, 0x26, 0xdb, // IID697 + 0x62, 0x4c, 0xf4, 0x10, 0x01, 0xbe, 0xff, 0xcc, 0x35, 0x39, // IID698 + 0x62, 0x1c, 0x8c, 0x18, 0x01, 0xb4, 0x93, 0x55, 0x64, 0x52, 0xcb, // IID699 + 0x62, 0x6c, 0xe8, 0x14, 0x01, 0xb4, 0x3c, 0x4b, 0xed, 0xd3, 0x5a, // IID700 + 0x62, 0xe4, 0xdc, 0x14, 0x01, 0xa2, 0x1b, 0x66, 0xd5, 0xcd, // IID701 + 0x62, 0xa4, 0x80, 0x10, 0x21, 0x8c, 0xdb, 0xd2, 0x47, 0xe2, 0x4c, // IID702 + 0x62, 0x6c, 0x88, 0x10, 0x21, 0xb4, 0x5a, 0xec, 0xc2, 0x11, 0xfb, // IID703 + 0x62, 0x44, 0x9c, 0x14, 0x21, 0x84, 0xdb, 0x41, 0xb4, 0x66, 0xd7, // IID704 + 0x62, 0x6c, 0x8c, 0x14, 0x21, 0xb6, 0x24, 0x1c, 0xd2, 0x07, // IID705 + 0x62, 0xc4, 0xa8, 0x10, 0x09, 0xa4, 0xdf, 0x92, 0x17, 0xc2, 0x58, // IID706 + 0x62, 0x14, 0x90, 0x18, 0x09, 0xac, 0x9a, 0xcd, 0x2c, 0x8f, 0xd3, // IID707 + 0x62, 0x44, 0xe4, 0x1c, 0x09, 0x94, 0x1c, 0x44, 0x0e, 0x4f, 0xe0, // IID708 + 0x62, 0x0c, 0x80, 0x14, 0x09, 0xbc, 0x7b, 0x56, 0x17, 0x8d, 0x02, // IID709 + 0x62, 0x4c, 0xb8, 0x10, 0x29, 0x9c, 0x7c, 0x10, 0xf6, 0x80, 0x69, // IID710 + 0x62, 0x14, 0x80, 0x18, 0x29, 0xbc, 0xf3, 0x19, 0x88, 0x68, 0xfb, // IID711 + 0x62, 0x0c, 0xf4, 0x14, 0x29, 0xbc, 0xa9, 0x46, 0x9e, 0x61, 0x31, // IID712 + 0x62, 0x84, 0xec, 0x14, 0x29, 0x94, 0x93, 0x1a, 0x86, 0x22, 0x19, // IID713 + 0x62, 0xc4, 0xe4, 0x18, 0x31, 0xab, 0xe0, 0x2b, 0xe9, 0xb8, // IID714 + 0x62, 0x34, 0xbc, 0x18, 0x31, 0x84, 0x8a, 0x64, 0x1c, 0x30, 0xfb, // IID715 + 0x62, 0x04, 0xf8, 0x14, 0x31, 0x8c, 0x1e, 0xd9, 0x54, 0x66, 0x7c, // IID716 + 0x62, 0x44, 0x94, 0x14, 0x31, 0xaf, 0x87, 0x4b, 0x05, 0xa1, // IID717 + 0x62, 0xd4, 0xe0, 0x10, 0x81, 0x84, 0xb5, 0x59, 0x45, 0xb6, 0x68, 0x00, 0x00, 0x00, 0x01, // IID718 + 0x62, 0x94, 0xf8, 0x14, 0x83, 0x84, 0xfd, 0x0b, 0xc5, 0xeb, 0x9a, 0x01, // IID719 + 0x62, 0x9c, 0x84, 0x10, 0x83, 0xa4, 0x68, 0xf2, 0x95, 0x4e, 0xda, 0x01, // IID720 + 0x62, 0xdc, 0xa4, 0x1c, 0x81, 0xa4, 0x24, 0xda, 0xb4, 0x92, 0xf0, 0x00, 0x00, 0x01, 0x00, // IID721 + 0x62, 0xbc, 0xfc, 0x08, 0x69, 0x8c, 0x12, 0xa1, 0x6d, 0xec, 0x46, 0x00, 0x00, 0x00, 0x01, // IID722 + 0x62, 0x14, 0xfc, 0x0c, 0x6b, 0xbc, 0xd1, 0x0d, 0x95, 0x3c, 0x80, 0x10, // IID723 + 0x62, 0x9c, 0xf0, 0x10, 0x83, 0x8c, 0x33, 0x2c, 0xda, 0x4c, 0x1b, 0x01, // IID724 + 0x62, 0x9c, 0xec, 0x1c, 0x81, 0x8c, 0xb1, 0x7b, 0x94, 0x55, 0xa6, 0x00, 0x10, 0x00, 0x00, // IID725 + 0x62, 0xdc, 0xf0, 0x10, 0xc1, 0xa4, 0x6a, 0xa1, 0x0e, 0x4e, 0x95, 0x08, // IID726 + 0x62, 0xfc, 0x98, 0x1c, 0xc1, 0xa4, 0x0e, 0x55, 0xeb, 0x53, 0xbc, 0x02, // IID727 + 0x62, 0xfc, 0x90, 0x10, 0xc1, 0xbc, 0x02, 0x9f, 0xf3, 0x23, 0xa6, 0x04, // IID728 + 0x62, 0xd4, 0xfc, 0x14, 0xc1, 0xbb, 0xec, 0x2c, 0x42, 0xf8, 0x04, // IID729 + 0x62, 0xbc, 0xa8, 0x10, 0xc1, 0xac, 0xdf, 0xec, 0xdc, 0x46, 0xaa, 0x10, // IID730 + 0x62, 0xbc, 0xc0, 0x14, 0xc1, 0xac, 0x68, 0x1d, 0x1a, 0x31, 0x71, 0x02, // IID731 + 0x62, 0xd4, 0xb4, 0x10, 0x81, 0xa9, 0x54, 0xd4, 0xac, 0xf6, 0x00, 0x00, 0x10, 0x00, // IID732 + 0x62, 0xd4, 0xf0, 0x14, 0x81, 0xac, 0x38, 0xa2, 0x6c, 0xd0, 0x55, 0x00, 0x00, 0x10, 0x00, // IID733 + 0x62, 0x94, 0x90, 0x10, 0x81, 0xb4, 0x01, 0x3f, 0xbe, 0x3e, 0xfd, 0x00, 0x00, 0x10, 0x00, // IID734 + 0x62, 0xfc, 0x98, 0x14, 0x83, 0xb4, 0x5e, 0x43, 0x65, 0x62, 0xd2, 0x10, // IID735 + 0x62, 0xd4, 0xcc, 0x10, 0x83, 0xc6, 0x10, // IID736 + 0x62, 0xd4, 0xfc, 0x18, 0x83, 0xc4, 0x10, // IID737 + 0xd5, 0x19, 0x81, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID738 + 0x62, 0xf4, 0xd4, 0x14, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID739 + 0x62, 0xf4, 0xfc, 0x1c, 0x81, 0xc3, 0x00, 0x00, 0x01, 0x00, // IID740 + 0x62, 0xdc, 0xbc, 0x14, 0x81, 0xc0, 0x00, 0x00, 0x01, 0x00, // IID741 + 0x62, 0xdc, 0xd4, 0x10, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x01, // IID742 + 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x01, // IID743 + 0xd5, 0x19, 0x81, 0xe0, 0x00, 0x00, 0x01, 0x00, // IID744 + 0x62, 0xdc, 0x94, 0x1c, 0x81, 0xe7, 0x00, 0x00, 0x10, 0x00, // IID745 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xe5, 0x00, 0x00, 0x10, 0x00, // IID746 + 0x62, 0xdc, 0x8c, 0x14, 0x81, 0xe6, 0x00, 0x00, 0x10, 0x00, // IID747 + 0x62, 0x54, 0xfc, 0x08, 0x69, 0xc5, 0x00, 0x00, 0x00, 0x10, // IID748 + 0x62, 0xdc, 0xfc, 0x08, 0x69, 0xc7, 0x00, 0x00, 0x00, 0x10, // IID749 + 0x62, 0x54, 0xfc, 0x08, 0x69, 0xed, 0x00, 0x00, 0x01, 0x00, // IID750 + 0x62, 0x5c, 0xfc, 0x0c, 0x69, 0xf5, 0x00, 0x00, 0x10, 0x00, // IID751 + 0x62, 0xfc, 0xfc, 0x0c, 0x69, 0xc6, 0x00, 0x00, 0x10, 0x00, // IID752 + 0x62, 0x54, 0xfc, 0x0c, 0x69, 0xc0, 0x00, 0x00, 0x00, 0x10, // IID753 + 0x62, 0xd4, 0x8c, 0x10, 0x81, 0xcf, 0x00, 0x10, 0x00, 0x00, // IID754 + 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xcc, 0x00, 0x10, 0x00, 0x00, // IID755 + 0xd5, 0x19, 0x81, 0xca, 0x00, 0x00, 0x10, 0x00, // IID756 + 0x62, 0xd4, 0xfc, 0x14, 0x81, 0xcc, 0x00, 0x00, 0x00, 0x10, // IID757 + 0x62, 0xd4, 0xfc, 0x1c, 0x81, 0xc9, 0x00, 0x00, 0x00, 0x10, // IID758 + 0x62, 0xfc, 0xc4, 0x14, 0x81, 0xcf, 0x00, 0x01, 0x00, 0x00, // IID759 + 0x62, 0xd4, 0x84, 0x18, 0xc1, 0xd1, 0x10, // IID760 + 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xd0, 0x10, // IID761 + 0xd5, 0x19, 0xd1, 0xd1, // IID762 + 0x62, 0xfc, 0xb4, 0x18, 0xc1, 0xc1, 0x10, // IID763 + 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xc4, 0x10, // IID764 + 0xd5, 0x19, 0xd1, 0xc3, // IID765 + 0x62, 0xdc, 0xdc, 0x14, 0xd1, 0xc7, // IID766 + 0x62, 0xfc, 0xfc, 0x1c, 0xd1, 0xc2, // IID767 + 0x62, 0xdc, 0x9c, 0x14, 0xc1, 0xc4, 0x10, // IID768 + 0x62, 0xfc, 0xac, 0x10, 0xc1, 0xca, 0x10, // IID769 + 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xc8, 0x10, // IID770 + 0xd5, 0x18, 0xc1, 0xce, 0x10, // IID771 + 0x62, 0xdc, 0xa4, 0x14, 0xd1, 0xcd, // IID772 + 0x62, 0xfc, 0xfc, 0x1c, 0xd1, 0xca, // IID773 + 0x62, 0xfc, 0xd4, 0x14, 0xd1, 0xcd, // IID774 + 0x62, 0xf4, 0x9c, 0x18, 0xc1, 0xe1, 0x02, // IID775 + 0x62, 0xdc, 0xfc, 0x18, 0xc1, 0xe0, 0x02, // IID776 + 0xd5, 0x18, 0xc1, 0xe6, 0x08, // IID777 + 0x62, 0xfc, 0xf4, 0x14, 0xc1, 0xe7, 0x08, // IID778 + 0x62, 0xdc, 0xfc, 0x1c, 0xc1, 0xe3, 0x08, // IID779 + 0x62, 0xfc, 0xc4, 0x14, 0xd1, 0xe7, // IID780 + 0x62, 0xdc, 0xbc, 0x18, 0xc1, 0xf9, 0x10, // IID781 + 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xff, 0x10, // IID782 + 0x49, 0xc1, 0xf9, 0x04, // IID783 + 0x62, 0xd4, 0xcc, 0x14, 0xd1, 0xfd, // IID784 + 0x62, 0xd4, 0xfc, 0x1c, 0xd1, 0xfb, // IID785 + 0x62, 0xd4, 0x9c, 0x1c, 0xc1, 0xfc, 0x02, // IID786 + 0x62, 0xdc, 0xf4, 0x18, 0xc1, 0xe6, 0x08, // IID787 + 0x62, 0xfc, 0xfc, 0x18, 0xc1, 0xe3, 0x08, // IID788 + 0x49, 0xc1, 0xe5, 0x02, // IID789 + 0x62, 0xd4, 0xec, 0x14, 0xc1, 0xe3, 0x08, // IID790 + 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xe1, 0x08, // IID791 + 0x62, 0xf4, 0xf4, 0x1c, 0xc1, 0xe1, 0x10, // IID792 + 0x62, 0xfc, 0xac, 0x18, 0xc1, 0xee, 0x04, // IID793 + 0x62, 0xd4, 0xfc, 0x18, 0xc1, 0xe9, 0x04, // IID794 + 0x49, 0xc1, 0xec, 0x02, // IID795 + 0x62, 0xdc, 0xac, 0x14, 0xc1, 0xef, 0x08, // IID796 + 0x62, 0xd4, 0xfc, 0x1c, 0xc1, 0xec, 0x08, // IID797 + 0x62, 0xdc, 0x9c, 0x14, 0xd1, 0xec, // IID798 + 0x62, 0xdc, 0x84, 0x18, 0x81, 0xee, 0x00, 0x00, 0x01, 0x00, // IID799 + 0x62, 0xf4, 0xfc, 0x18, 0x81, 0xe9, 0x00, 0x00, 0x01, 0x00, // IID800 + 0xd5, 0x19, 0x83, 0xea, 0x10, // IID801 + 0x62, 0xd4, 0x9c, 0x1c, 0x83, 0xee, 0x01, // IID802 + 0x62, 0xfc, 0xfc, 0x1c, 0x83, 0xed, 0x01, // IID803 + 0x62, 0xfc, 0xdc, 0x14, 0x81, 0xec, 0x00, 0x00, 0x10, 0x00, // IID804 + 0x62, 0xf4, 0xa4, 0x18, 0x81, 0xf3, 0x00, 0x00, 0x00, 0x01, // IID805 + 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xf7, 0x00, 0x00, 0x00, 0x01, // IID806 + 0xd5, 0x19, 0x81, 0xf7, 0x00, 0x00, 0x00, 0x10, // IID807 + 0x62, 0xdc, 0x94, 0x14, 0x81, 0xf4, 0x00, 0x10, 0x00, 0x00, // IID808 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xf3, 0x00, 0x10, 0x00, 0x00, // IID809 + 0x62, 0xf4, 0xec, 0x1c, 0x81, 0xf2, 0x00, 0x00, 0x00, 0x10, // IID810 + 0x48, 0x81, 0xca, 0x00, 0x00, 0x10, 0x00, // IID811 + 0x62, 0xfc, 0xfc, 0x18, 0x81, 0xce, 0x00, 0x00, 0x10, 0x00, // IID812 + 0xd5, 0x19, 0x81, 0xcd, 0x00, 0x00, 0x10, 0x00, // IID813 + 0x62, 0xf4, 0xf4, 0x10, 0x81, 0xc9, 0x00, 0x00, 0x40, 0x00, // IID814 + 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xc9, 0x00, 0x00, 0x40, 0x00, // IID815 + 0xd5, 0x19, 0x81, 0xcb, 0x00, 0x00, 0x00, 0x40, // IID816 + 0x62, 0xfc, 0xfc, 0x10, 0x81, 0xeb, 0x00, 0x00, 0x40, 0x00, // IID817 + 0x62, 0xdc, 0xfc, 0x18, 0x81, 0xef, 0x00, 0x00, 0x40, 0x00, // IID818 + 0xd5, 0x19, 0x81, 0xea, 0x00, 0x00, 0x04, 0x00, // IID819 + 0x62, 0xfc, 0xf4, 0x14, 0x81, 0xee, 0x00, 0x00, 0x00, 0x40, // IID820 + 0x62, 0xfc, 0xfc, 0x1c, 0x81, 0xea, 0x00, 0x00, 0x00, 0x40, // IID821 + 0x62, 0xfc, 0xc4, 0x14, 0x81, 0xef, 0x00, 0x00, 0x00, 0x10, // IID822 + 0x62, 0x4c, 0x90, 0x18, 0x03, 0xb4, 0x58, 0x3b, 0x3a, 0xea, 0x56, // IID823 + 0x62, 0x1c, 0x90, 0x14, 0x03, 0xbc, 0xda, 0xa8, 0xc6, 0xee, 0xb4, // IID824 + 0x62, 0x4c, 0x9c, 0x18, 0x23, 0xb7, 0x8c, 0xc3, 0xef, 0xb9, // IID825 + 0x62, 0x3c, 0xa0, 0x14, 0x23, 0x94, 0x4e, 0xe5, 0xbe, 0x1e, 0x6a, // IID826 + 0x62, 0x44, 0x88, 0x10, 0x0b, 0x94, 0x93, 0xd7, 0x00, 0x60, 0xd4, // IID827 + 0x62, 0x7c, 0xb0, 0x1c, 0x0b, 0xa4, 0x0a, 0xf6, 0x59, 0x48, 0x0b, // IID828 + 0x62, 0xcc, 0xec, 0x18, 0xaf, 0x8c, 0x90, 0xd8, 0x4c, 0x28, 0x3d, // IID829 + 0x62, 0x0c, 0x94, 0x14, 0xaf, 0x94, 0x66, 0x24, 0x31, 0x81, 0x6e, // IID830 + 0x62, 0x7c, 0xe4, 0x18, 0x2b, 0xae, 0x62, 0xd7, 0xd5, 0x8f, // IID831 + 0x62, 0x4c, 0xc4, 0x14, 0x2b, 0xac, 0x11, 0x13, 0x58, 0xad, 0x9d, // IID832 + 0x62, 0xac, 0xbc, 0x18, 0x33, 0x94, 0xb3, 0x69, 0x59, 0x40, 0xf1, // IID833 + 0x62, 0x4c, 0xac, 0x1c, 0x33, 0xa2, 0xca, 0x81, 0x83, 0x16, // IID834 + 0x62, 0xc4, 0xf4, 0x18, 0x03, 0xd0, // IID835 + 0x49, 0x03, 0xce, // IID836 + 0x62, 0x7c, 0xc4, 0x14, 0x03, 0xd0, // IID837 + 0x62, 0x5c, 0xa4, 0x1c, 0x03, 0xd8, // IID838 + 0x62, 0xe4, 0xb5, 0x18, 0x66, 0xd2, // IID839 + 0x66, 0x4d, 0x0f, 0x38, 0xf6, 0xc7, // IID840 + 0x62, 0xcc, 0x86, 0x18, 0x66, 0xf2, // IID841 + 0xf3, 0x4c, 0x0f, 0x38, 0xf6, 0xda, // IID842 + 0x62, 0xfc, 0xe4, 0x10, 0x23, 0xd6, // IID843 + 0xd5, 0x5c, 0x23, 0xe9, // IID844 + 0x62, 0x44, 0xc4, 0x14, 0x23, 0xdf, // IID845 + 0x62, 0x54, 0xb4, 0x1c, 0x23, 0xcd, // IID846 + 0x62, 0x7c, 0xec, 0x10, 0xaf, 0xf8, // IID847 + 0xd5, 0x98, 0xaf, 0xc9, // IID848 + 0x62, 0x7c, 0xc4, 0x14, 0xaf, 0xe4, // IID849 + 0x62, 0x54, 0xac, 0x1c, 0xaf, 0xd1, // IID850 + 0x62, 0xc4, 0xec, 0x18, 0x0b, 0xde, // IID851 + 0x49, 0x0b, 0xcd, // IID852 + 0x62, 0x4c, 0xb4, 0x1c, 0x0b, 0xcd, // IID853 + 0x62, 0xdc, 0xec, 0x1c, 0x0b, 0xd1, // IID854 + 0x62, 0x7c, 0xc4, 0x10, 0x2b, 0xc0, // IID855 + 0x4d, 0x2b, 0xed, // IID856 + 0x62, 0x54, 0xe4, 0x14, 0x2b, 0xe7, // IID857 + 0x62, 0x74, 0xb4, 0x1c, 0x2b, 0xca, // IID858 + 0x62, 0xcc, 0x94, 0x18, 0x33, 0xc7, // IID859 + 0xd5, 0x59, 0x33, 0xce, // IID860 + 0x62, 0x6c, 0xe4, 0x14, 0x33, 0xf4, // IID861 + 0x62, 0x44, 0x84, 0x14, 0x33, 0xfd, // IID862 + 0x62, 0x54, 0xcc, 0x10, 0x24, 0xea, 0x04, // IID863 + 0xd5, 0xd9, 0xa4, 0xe8, 0x10, // IID864 + 0x62, 0x44, 0xdc, 0x14, 0x24, 0xdd, 0x10, // IID865 + 0x62, 0xcc, 0x84, 0x14, 0x24, 0xdf, 0x02, // IID866 + 0x62, 0x7c, 0x8c, 0x10, 0x2c, 0xdc, 0x08, // IID867 + 0x4c, 0x0f, 0xac, 0xfa, 0x01, // IID868 + 0x62, 0x5c, 0x9c, 0x14, 0x2c, 0xf6, 0x02, // IID869 + 0x62, 0xec, 0xdc, 0x14, 0x2c, 0xc4, 0x01, // IID870 + 0x62, 0xcc, 0xd4, 0x10, 0x40, 0xcc, // IID871 + 0xd5, 0x9d, 0x40, 0xfe, // IID872 + 0x62, 0x54, 0xf4, 0x18, 0x41, 0xff, // IID873 + 0x49, 0x0f, 0x41, 0xcd, // IID874 + 0x62, 0x4c, 0xec, 0x18, 0x42, 0xd2, // IID875 + 0xd5, 0xcd, 0x42, 0xe7, // IID876 + 0x62, 0xf4, 0xbc, 0x18, 0x43, 0xd1, // IID877 + 0x48, 0x0f, 0x43, 0xc9, // IID878 + 0x62, 0x54, 0xac, 0x18, 0x44, 0xe9, // IID879 + 0xd5, 0x9d, 0x44, 0xf3, // IID880 + 0x62, 0xc4, 0xa4, 0x18, 0x45, 0xf9, // IID881 + 0x4c, 0x0f, 0x45, 0xda, // IID882 + 0x62, 0x5c, 0x84, 0x10, 0x46, 0xf1, // IID883 + 0xd5, 0xc9, 0x46, 0xe4, // IID884 + 0x62, 0x5c, 0xec, 0x18, 0x47, 0xd4, // IID885 + 0xd5, 0x9c, 0x47, 0xc1, // IID886 + 0x62, 0x6c, 0xf4, 0x18, 0x48, 0xf7, // IID887 + 0xd5, 0xdc, 0x48, 0xd2, // IID888 + 0x62, 0xfc, 0xec, 0x18, 0x49, 0xda, // IID889 + 0xd5, 0xc9, 0x49, 0xed, // IID890 + 0x62, 0x4c, 0xa4, 0x10, 0x4a, 0xe3, // IID891 + 0xd5, 0x9d, 0x4a, 0xde, // IID892 + 0x62, 0xec, 0xf4, 0x18, 0x4b, 0xea, // IID893 + 0xd5, 0x99, 0x4b, 0xcd, // IID894 + 0x62, 0xc4, 0xec, 0x18, 0x4c, 0xec, // IID895 + 0xd5, 0x99, 0x4c, 0xd2, // IID896 + 0x62, 0xfc, 0xf4, 0x10, 0x4d, 0xde, // IID897 + 0x49, 0x0f, 0x4d, 0xd3, // IID898 + 0x62, 0x54, 0xec, 0x18, 0x4e, 0xf0, // IID899 + 0x4d, 0x0f, 0x4e, 0xf0, // IID900 + 0x62, 0x6c, 0xb4, 0x10, 0x4f, 0xed, // IID901 + 0xd5, 0xdd, 0x4f, 0xd6, // IID902 + 0x62, 0x84, 0xbc, 0x10, 0x40, 0xac, 0x5d, 0x1e, 0x52, 0x9c, 0x43, // IID903 + 0x62, 0xcc, 0xa0, 0x18, 0x41, 0x94, 0x05, 0x7f, 0x12, 0x32, 0x06, // IID904 + 0x62, 0x14, 0xf8, 0x10, 0x42, 0x84, 0x50, 0xef, 0x3d, 0x63, 0x10, // IID905 + 0x62, 0x7c, 0x94, 0x18, 0x43, 0xb2, 0xc8, 0x61, 0x09, 0xab, // IID906 + 0x62, 0x1c, 0x98, 0x18, 0x44, 0x84, 0x57, 0x86, 0xbb, 0xe1, 0x85, // IID907 + 0xd5, 0xde, 0x45, 0xac, 0x9b, 0x2e, 0xd2, 0x27, 0xca, // IID908 + 0x62, 0x8c, 0xf0, 0x18, 0x46, 0x94, 0x21, 0xa0, 0x64, 0xbe, 0x30, // IID909 + 0x62, 0x54, 0x98, 0x10, 0x47, 0xa4, 0x42, 0x06, 0x01, 0x47, 0xdd, // IID910 + 0x62, 0x34, 0xa4, 0x18, 0x48, 0x84, 0xdb, 0x96, 0x9e, 0xcc, 0x25, // IID911 + 0x62, 0x44, 0x9c, 0x18, 0x49, 0x9b, 0x02, 0x8f, 0xd2, 0xf3, // IID912 + 0x62, 0x6c, 0xbc, 0x18, 0x4a, 0x94, 0x5b, 0x16, 0x48, 0x92, 0xb7, // IID913 + 0x62, 0x54, 0x88, 0x10, 0x4b, 0x94, 0xd6, 0x84, 0x48, 0x88, 0x14, // IID914 + 0x62, 0x1c, 0xa4, 0x10, 0x4c, 0x84, 0xb5, 0xa8, 0xb7, 0x92, 0x00, // IID915 + 0x62, 0x6c, 0x8c, 0x18, 0x4d, 0xa4, 0x13, 0x45, 0x2d, 0x9c, 0x00, // IID916 + 0x62, 0x74, 0xb0, 0x10, 0x4e, 0x84, 0x91, 0x6b, 0xc8, 0x55, 0x66, // IID917 + 0x62, 0x84, 0xe0, 0x10, 0x4f, 0xac, 0x0a, 0xf5, 0xbc, 0xfa, 0xef, // IID918 #endif // _LP64 }; @@ -1666,541 +2102,759 @@ 6, // IID181 6, // IID182 6, // IID183 - 6, // IID184 + 3, // IID184 6, // IID185 6, // IID186 6, // IID187 +#endif // _LP64 6, // IID188 +#ifdef _LP64 6, // IID189 6, // IID190 6, // IID191 - 6, // IID192 - 6, // IID193 - 6, // IID194 + 4, // IID192 + 3, // IID193 +#endif // _LP64 + 2, // IID194 +#ifdef _LP64 6, // IID195 6, // IID196 6, // IID197 - 6, // IID198 +#endif // _LP64 + 2, // IID198 +#ifdef _LP64 6, // IID199 +#endif // _LP64 6, // IID200 +#ifdef _LP64 6, // IID201 - 6, // IID202 + 4, // IID202 6, // IID203 - 11, // IID204 - 11, // IID205 - 10, // IID206 - 11, // IID207 - 11, // IID208 - 11, // IID209 - 11, // IID210 - 11, // IID211 - 11, // IID212 - 11, // IID213 - 11, // IID214 - 10, // IID215 - 11, // IID216 - 10, // IID217 - 11, // IID218 - 11, // IID219 - 11, // IID220 - 11, // IID221 - 15, // IID222 - 15, // IID223 - 14, // IID224 - 14, // IID225 - 12, // IID226 - 14, // IID227 - 12, // IID228 - 12, // IID229 + 6, // IID204 + 6, // IID205 + 4, // IID206 + 6, // IID207 + 6, // IID208 + 6, // IID209 + 3, // IID210 + 6, // IID211 +#endif // _LP64 + 6, // IID212 +#ifdef _LP64 + 6, // IID213 + 3, // IID214 + 6, // IID215 + 6, // IID216 + 6, // IID217 + 3, // IID218 + 6, // IID219 + 6, // IID220 + 6, // IID221 + 4, // IID222 + 6, // IID223 + 6, // IID224 + 6, // IID225 + 6, // IID226 + 6, // IID227 + 6, // IID228 + 11, // IID229 11, // IID230 - 12, // IID231 + 11, // IID231 11, // IID232 - 12, // IID233 - 12, // IID234 + 11, // IID233 + 11, // IID234 11, // IID235 11, // IID236 - 12, // IID237 - 15, // IID238 - 15, // IID239 - 12, // IID240 - 14, // IID241 + 11, // IID237 + 10, // IID238 + 11, // IID239 + 10, // IID240 + 11, // IID241 11, // IID242 11, // IID243 11, // IID244 11, // IID245 11, // IID246 - 11, // IID247 - 11, // IID248 - 10, // IID249 - 11, // IID250 - 11, // IID251 - 10, // IID252 - 11, // IID253 - 10, // IID254 - 10, // IID255 - 10, // IID256 - 10, // IID257 - 7, // IID258 - 7, // IID259 - 7, // IID260 - 7, // IID261 - 10, // IID262 - 10, // IID263 - 10, // IID264 - 10, // IID265 - 10, // IID266 - 10, // IID267 - 10, // IID268 - 10, // IID269 - 7, // IID270 - 7, // IID271 - 7, // IID272 - 7, // IID273 - 7, // IID274 - 7, // IID275 - 6, // IID276 - 6, // IID277 - 7, // IID278 - 7, // IID279 - 7, // IID280 - 7, // IID281 - 6, // IID282 - 6, // IID283 - 7, // IID284 - 7, // IID285 - 7, // IID286 - 7, // IID287 - 6, // IID288 - 6, // IID289 - 7, // IID290 - 7, // IID291 - 7, // IID292 - 7, // IID293 + 15, // IID247 + 14, // IID248 + 12, // IID249 + 14, // IID250 + 12, // IID251 + 12, // IID252 + 14, // IID253 + 15, // IID254 + 12, // IID255 + 12, // IID256 + 12, // IID257 + 11, // IID258 + 11, // IID259 + 12, // IID260 + 11, // IID261 + 11, // IID262 + 12, // IID263 + 14, // IID264 + 15, // IID265 + 15, // IID266 + 11, // IID267 + 11, // IID268 + 11, // IID269 + 11, // IID270 + 11, // IID271 + 11, // IID272 + 11, // IID273 + 10, // IID274 + 11, // IID275 + 11, // IID276 + 11, // IID277 + 11, // IID278 + 11, // IID279 + 11, // IID280 + 10, // IID281 + 11, // IID282 + 10, // IID283 + 11, // IID284 + 11, // IID285 + 10, // IID286 + 11, // IID287 + 10, // IID288 + 11, // IID289 + 11, // IID290 + 10, // IID291 + 10, // IID292 + 8, // IID293 7, // IID294 7, // IID295 10, // IID296 10, // IID297 10, // IID298 -#endif // _LP64 - 10, // IID299 -#ifdef _LP64 + 8, // IID299 10, // IID300 10, // IID301 - 10, // IID302 + 7, // IID302 10, // IID303 +#endif // _LP64 10, // IID304 +#ifdef _LP64 10, // IID305 10, // IID306 10, // IID307 - 11, // IID308 - 11, // IID309 - 11, // IID310 - 10, // IID311 - 11, // IID312 - 11, // IID313 - 11, // IID314 - 11, // IID315 - 11, // IID316 - 11, // IID317 - 10, // IID318 - 11, // IID319 - 11, // IID320 - 11, // IID321 - 11, // IID322 - 11, // IID323 - 6, // IID324 - 6, // IID325 - 6, // IID326 - 6, // IID327 - 6, // IID328 - 6, // IID329 - 6, // IID330 - 6, // IID331 - 6, // IID332 - 6, // IID333 - 6, // IID334 - 6, // IID335 - 6, // IID336 - 6, // IID337 - 6, // IID338 - 6, // IID339 - 6, // IID340 - 6, // IID341 + 7, // IID308 + 10, // IID309 + 10, // IID310 + 8, // IID311 + 7, // IID312 + 7, // IID313 + 10, // IID314 + 6, // IID315 + 6, // IID316 + 4, // IID317 + 7, // IID318 +#endif // _LP64 + 7, // IID319 +#ifdef _LP64 + 5, // IID320 + 7, // IID321 + 7, // IID322 + 7, // IID323 + 7, // IID324 +#endif // _LP64 + 7, // IID325 +#ifdef _LP64 + 4, // IID326 + 7, // IID327 + 7, // IID328 + 7, // IID329 + 7, // IID330 + 7, // IID331 + 5, // IID332 + 7, // IID333 + 7, // IID334 + 7, // IID335 + 7, // IID336 + 7, // IID337 + 4, // IID338 + 7, // IID339 + 7, // IID340 + 7, // IID341 7, // IID342 7, // IID343 - 7, // IID344 + 4, // IID344 7, // IID345 - 6, // IID346 - 6, // IID347 - 6, // IID348 - 6, // IID349 - 6, // IID350 + 7, // IID346 + 7, // IID347 + 7, // IID348 + 7, // IID349 + 5, // IID350 6, // IID351 6, // IID352 - 6, // IID353 - 6, // IID354 - 6, // IID355 - 6, // IID356 - 6, // IID357 - 6, // IID358 - 6, // IID359 - 6, // IID360 - 6, // IID361 - 11, // IID362 - 11, // IID363 + 7, // IID353 + 10, // IID354 + 10, // IID355 + 8, // IID356 + 10, // IID357 + 10, // IID358 + 10, // IID359 + 10, // IID360 + 10, // IID361 +#endif // _LP64 + 6, // IID362 +#ifdef _LP64 + 10, // IID363 10, // IID364 - 11, // IID365 - 11, // IID366 - 11, // IID367 - 11, // IID368 + 10, // IID365 + 10, // IID366 + 10, // IID367 + 8, // IID368 10, // IID369 - 11, // IID370 - 11, // IID371 - 11, // IID372 - 11, // IID373 + 10, // IID370 + 10, // IID371 + 10, // IID372 + 10, // IID373 11, // IID374 11, // IID375 11, // IID376 11, // IID377 - 4, // IID378 - 4, // IID379 - 4, // IID380 - 5, // IID381 - 4, // IID382 - 4, // IID383 - 5, // IID384 - 5, // IID385 - 4, // IID386 - 4, // IID387 - 4, // IID388 - 3, // IID389 - 4, // IID390 - 4, // IID391 - 4, // IID392 - 4, // IID393 - 4, // IID394 - 3, // IID395 - 9, // IID396 - 9, // IID397 - 8, // IID398 - 8, // IID399 - 9, // IID400 - 9, // IID401 - 9, // IID402 - 9, // IID403 - 11, // IID404 - 13, // IID405 - 12, // IID406 - 10, // IID407 - 10, // IID408 - 13, // IID409 - 9, // IID410 - 10, // IID411 - 10, // IID412 - 12, // IID413 - 13, // IID414 - 13, // IID415 - 9, // IID416 - 9, // IID417 - 9, // IID418 - 10, // IID419 - 9, // IID420 - 8, // IID421 - 9, // IID422 - 10, // IID423 - 9, // IID424 - 9, // IID425 - 10, // IID426 - 9, // IID427 - 9, // IID428 - 9, // IID429 - 10, // IID430 - 8, // IID431 - 9, // IID432 - 8, // IID433 - 4, // IID434 - 7, // IID435 - 8, // IID436 + 11, // IID378 + 10, // IID379 + 11, // IID380 + 11, // IID381 + 11, // IID382 + 11, // IID383 + 11, // IID384 + 11, // IID385 + 11, // IID386 + 11, // IID387 + 6, // IID388 + 4, // IID389 + 6, // IID390 + 6, // IID391 + 6, // IID392 + 3, // IID393 + 6, // IID394 + 6, // IID395 + 6, // IID396 + 4, // IID397 + 6, // IID398 + 6, // IID399 + 6, // IID400 + 5, // IID401 + 6, // IID402 + 6, // IID403 + 6, // IID404 + 4, // IID405 + 6, // IID406 + 6, // IID407 + 6, // IID408 + 4, // IID409 + 6, // IID410 + 6, // IID411 + 6, // IID412 + 4, // IID413 + 6, // IID414 + 6, // IID415 + 6, // IID416 + 4, // IID417 + 6, // IID418 + 6, // IID419 + 6, // IID420 + 4, // IID421 + 6, // IID422 + 6, // IID423 + 7, // IID424 + 5, // IID425 + 7, // IID426 + 7, // IID427 + 7, // IID428 + 5, // IID429 + 7, // IID430 + 7, // IID431 + 6, // IID432 + 4, // IID433 + 6, // IID434 + 4, // IID435 + 6, // IID436 4, // IID437 - 4, // IID438 - 5, // IID439 - 5, // IID440 + 6, // IID438 + 4, // IID439 + 6, // IID440 4, // IID441 - 5, // IID442 - 8, // IID443 - 5, // IID444 - 5, // IID445 - 8, // IID446 - 8, // IID447 - 7, // IID448 - 11, // IID449 - 5, // IID450 - 8, // IID451 - 8, // IID452 - 8, // IID453 - 9, // IID454 - 9, // IID455 - 9, // IID456 - 9, // IID457 - 9, // IID458 - 9, // IID459 - 8, // IID460 - 8, // IID461 - 9, // IID462 - 9, // IID463 - 8, // IID464 - 9, // IID465 - 8, // IID466 - 9, // IID467 - 9, // IID468 - 9, // IID469 - 3, // IID470 - 4, // IID471 - 4, // IID472 - 3, // IID473 - 3, // IID474 - 3, // IID475 - 4, // IID476 - 4, // IID477 - 4, // IID478 - 4, // IID479 - 3, // IID480 - 3, // IID481 - 3, // IID482 - 3, // IID483 + 6, // IID442 + 4, // IID443 + 6, // IID444 + 4, // IID445 + 6, // IID446 + 4, // IID447 + 6, // IID448 + 4, // IID449 + 6, // IID450 + 4, // IID451 + 4, // IID452 + 4, // IID453 + 6, // IID454 + 4, // IID455 + 6, // IID456 + 4, // IID457 + 6, // IID458 + 4, // IID459 + 6, // IID460 + 4, // IID461 + 6, // IID462 + 4, // IID463 + 10, // IID464 + 11, // IID465 + 11, // IID466 + 11, // IID467 + 10, // IID468 + 11, // IID469 + 11, // IID470 + 11, // IID471 + 11, // IID472 + 11, // IID473 + 11, // IID474 + 11, // IID475 + 11, // IID476 + 11, // IID477 + 11, // IID478 + 11, // IID479 + 4, // IID480 + 4, // IID481 + 4, // IID482 + 5, // IID483 4, // IID484 - 3, // IID485 - 3, // IID486 - 9, // IID487 - 9, // IID488 - 9, // IID489 - 9, // IID490 - 9, // IID491 - 8, // IID492 - 8, // IID493 - 9, // IID494 - 12, // IID495 - 5, // IID496 - 5, // IID497 - 5, // IID498 - 6, // IID499 - 6, // IID500 - 6, // IID501 - 6, // IID502 + 4, // IID485 + 5, // IID486 + 5, // IID487 + 4, // IID488 + 4, // IID489 + 4, // IID490 + 3, // IID491 + 4, // IID492 + 4, // IID493 + 4, // IID494 + 4, // IID495 + 4, // IID496 + 4, // IID497 + 9, // IID498 + 9, // IID499 + 9, // IID500 + 9, // IID501 + 9, // IID502 9, // IID503 9, // IID504 9, // IID505 - 9, // IID506 - 4, // IID507 - 4, // IID508 - 4, // IID509 - 4, // IID510 - 8, // IID511 - 6, // IID512 - 6, // IID513 - 6, // IID514 - 6, // IID515 - 6, // IID516 - 6, // IID517 - 6, // IID518 - 6, // IID519 - 11, // IID520 - 11, // IID521 - 6, // IID522 - 6, // IID523 - 6, // IID524 - 6, // IID525 - 6, // IID526 - 6, // IID527 - 6, // IID528 - 6, // IID529 - 6, // IID530 - 6, // IID531 - 6, // IID532 - 6, // IID533 - 6, // IID534 - 6, // IID535 - 6, // IID536 - 6, // IID537 - 6, // IID538 - 6, // IID539 - 6, // IID540 - 6, // IID541 - 6, // IID542 - 6, // IID543 - 6, // IID544 - 6, // IID545 - 6, // IID546 - 6, // IID547 - 6, // IID548 - 11, // IID549 - 11, // IID550 + 12, // IID506 + 12, // IID507 + 11, // IID508 + 8, // IID509 + 9, // IID510 + 13, // IID511 + 10, // IID512 + 12, // IID513 + 10, // IID514 + 10, // IID515 + 13, // IID516 + 12, // IID517 + 9, // IID518 + 9, // IID519 + 9, // IID520 + 9, // IID521 + 9, // IID522 + 7, // IID523 + 9, // IID524 + 9, // IID525 + 9, // IID526 + 9, // IID527 + 10, // IID528 + 9, // IID529 + 9, // IID530 + 7, // IID531 + 10, // IID532 + 9, // IID533 + 9, // IID534 + 5, // IID535 + 5, // IID536 + 8, // IID537 + 8, // IID538 + 4, // IID539 + 4, // IID540 + 5, // IID541 + 5, // IID542 + 4, // IID543 + 4, // IID544 + 7, // IID545 + 4, // IID546 + 3, // IID547 + 4, // IID548 + 8, // IID549 + 8, // IID550 10, // IID551 - 10, // IID552 - 11, // IID553 - 11, // IID554 - 11, // IID555 - 11, // IID556 - 10, // IID557 - 11, // IID558 - 11, // IID559 - 11, // IID560 - 11, // IID561 - 11, // IID562 - 11, // IID563 - 11, // IID564 - 11, // IID565 - 10, // IID566 - 11, // IID567 - 11, // IID568 - 11, // IID569 - 11, // IID570 - 11, // IID571 - 11, // IID572 - 11, // IID573 - 11, // IID574 - 10, // IID575 - 11, // IID576 - 11, // IID577 - 11, // IID578 - 14, // IID579 - 15, // IID580 - 15, // IID581 - 15, // IID582 - 12, // IID583 - 12, // IID584 - 15, // IID585 - 15, // IID586 - 12, // IID587 - 12, // IID588 - 12, // IID589 - 12, // IID590 - 12, // IID591 - 12, // IID592 - 12, // IID593 - 14, // IID594 - 15, // IID595 - 12, // IID596 - 10, // IID597 - 10, // IID598 - 10, // IID599 - 10, // IID600 - 10, // IID601 - 10, // IID602 - 10, // IID603 - 10, // IID604 - 10, // IID605 - 10, // IID606 - 10, // IID607 - 10, // IID608 - 10, // IID609 - 10, // IID610 - 10, // IID611 - 10, // IID612 - 7, // IID613 - 7, // IID614 - 7, // IID615 - 7, // IID616 - 7, // IID617 - 7, // IID618 - 7, // IID619 - 7, // IID620 - 7, // IID621 - 7, // IID622 - 7, // IID623 - 7, // IID624 - 7, // IID625 - 7, // IID626 - 7, // IID627 - 7, // IID628 - 7, // IID629 - 7, // IID630 - 7, // IID631 - 7, // IID632 - 7, // IID633 - 7, // IID634 - 7, // IID635 - 7, // IID636 - 7, // IID637 - 7, // IID638 - 10, // IID639 - 10, // IID640 - 10, // IID641 - 10, // IID642 - 10, // IID643 - 10, // IID644 - 10, // IID645 - 10, // IID646 - 10, // IID647 - 10, // IID648 - 10, // IID649 - 10, // IID650 - 10, // IID651 - 10, // IID652 - 10, // IID653 - 10, // IID654 - 11, // IID655 - 11, // IID656 - 11, // IID657 - 11, // IID658 - 11, // IID659 - 11, // IID660 - 10, // IID661 - 10, // IID662 - 10, // IID663 - 11, // IID664 - 11, // IID665 - 11, // IID666 - 6, // IID667 + 5, // IID552 + 8, // IID553 + 8, // IID554 + 7, // IID555 + 9, // IID556 + 8, // IID557 + 9, // IID558 + 9, // IID559 + 9, // IID560 + 9, // IID561 + 8, // IID562 + 9, // IID563 + 9, // IID564 + 9, // IID565 + 9, // IID566 + 9, // IID567 + 9, // IID568 + 9, // IID569 + 9, // IID570 + 9, // IID571 + 4, // IID572 + 4, // IID573 + 4, // IID574 + 3, // IID575 + 3, // IID576 + 4, // IID577 + 4, // IID578 + 3, // IID579 + 4, // IID580 + 3, // IID581 + 4, // IID582 + 4, // IID583 + 4, // IID584 + 3, // IID585 + 3, // IID586 + 3, // IID587 + 3, // IID588 + 9, // IID589 + 9, // IID590 + 9, // IID591 + 9, // IID592 + 9, // IID593 + 9, // IID594 + 9, // IID595 + 9, // IID596 + 13, // IID597 + 8, // IID598 + 5, // IID599 + 5, // IID600 + 6, // IID601 + 6, // IID602 + 6, // IID603 + 6, // IID604 + 9, // IID605 + 9, // IID606 + 9, // IID607 + 9, // IID608 + 4, // IID609 + 4, // IID610 + 4, // IID611 + 4, // IID612 + 9, // IID613 + 6, // IID614 + 6, // IID615 + 6, // IID616 + 6, // IID617 + 6, // IID618 + 6, // IID619 + 6, // IID620 + 6, // IID621 + 11, // IID622 + 11, // IID623 + 6, // IID624 + 4, // IID625 + 6, // IID626 + 6, // IID627 + 6, // IID628 + 6, // IID629 + 6, // IID630 + 6, // IID631 + 6, // IID632 + 4, // IID633 + 6, // IID634 + 6, // IID635 + 6, // IID636 + 4, // IID637 + 6, // IID638 + 6, // IID639 + 6, // IID640 + 6, // IID641 + 6, // IID642 + 4, // IID643 + 6, // IID644 + 6, // IID645 + 6, // IID646 + 4, // IID647 + 6, // IID648 + 6, // IID649 + 6, // IID650 + 3, // IID651 + 6, // IID652 + 6, // IID653 + 6, // IID654 + 3, // IID655 + 6, // IID656 + 6, // IID657 + 6, // IID658 + 3, // IID659 + 6, // IID660 + 6, // IID661 + 4, // IID662 + 4, // IID663 + 6, // IID664 + 6, // IID665 + 6, // IID666 + 3, // IID667 6, // IID668 6, // IID669 6, // IID670 - 6, // IID671 + 4, // IID671 6, // IID672 6, // IID673 6, // IID674 6, // IID675 6, // IID676 6, // IID677 - 6, // IID678 - 6, // IID679 - 6, // IID680 - 7, // IID681 - 7, // IID682 - 7, // IID683 - 7, // IID684 - 6, // IID685 - 6, // IID686 - 6, // IID687 - 6, // IID688 - 6, // IID689 - 6, // IID690 - 6, // IID691 - 6, // IID692 - 6, // IID693 - 6, // IID694 - 6, // IID695 - 6, // IID696 - 6, // IID697 - 6, // IID698 - 6, // IID699 - 6, // IID700 - 11, // IID701 + 10, // IID678 + 10, // IID679 + 11, // IID680 + 11, // IID681 + 11, // IID682 + 11, // IID683 + 11, // IID684 + 10, // IID685 + 10, // IID686 + 11, // IID687 + 11, // IID688 + 11, // IID689 + 11, // IID690 + 11, // IID691 + 11, // IID692 + 11, // IID693 + 11, // IID694 + 10, // IID695 + 11, // IID696 + 11, // IID697 + 10, // IID698 + 11, // IID699 + 11, // IID700 + 10, // IID701 11, // IID702 11, // IID703 11, // IID704 - 11, // IID705 - 10, // IID706 + 10, // IID705 + 11, // IID706 11, // IID707 - 10, // IID708 - 10, // IID709 + 11, // IID708 + 11, // IID709 11, // IID710 11, // IID711 11, // IID712 - 10, // IID713 - 11, // IID714 + 11, // IID713 + 10, // IID714 11, // IID715 11, // IID716 + 10, // IID717 + 15, // IID718 + 12, // IID719 + 12, // IID720 + 15, // IID721 + 15, // IID722 + 12, // IID723 + 12, // IID724 + 15, // IID725 + 12, // IID726 + 12, // IID727 + 12, // IID728 + 11, // IID729 + 12, // IID730 + 12, // IID731 + 14, // IID732 + 15, // IID733 + 15, // IID734 + 12, // IID735 + 7, // IID736 + 7, // IID737 + 8, // IID738 + 10, // IID739 + 10, // IID740 + 10, // IID741 + 10, // IID742 + 10, // IID743 + 8, // IID744 + 10, // IID745 + 10, // IID746 + 10, // IID747 + 10, // IID748 + 10, // IID749 + 10, // IID750 + 10, // IID751 + 10, // IID752 + 10, // IID753 + 10, // IID754 + 10, // IID755 + 8, // IID756 + 10, // IID757 + 10, // IID758 + 10, // IID759 + 7, // IID760 + 7, // IID761 + 4, // IID762 + 7, // IID763 + 7, // IID764 + 4, // IID765 + 6, // IID766 + 6, // IID767 + 7, // IID768 + 7, // IID769 + 7, // IID770 + 5, // IID771 + 6, // IID772 + 6, // IID773 + 6, // IID774 + 7, // IID775 + 7, // IID776 + 5, // IID777 + 7, // IID778 + 7, // IID779 + 6, // IID780 + 7, // IID781 + 7, // IID782 + 4, // IID783 + 6, // IID784 + 6, // IID785 + 7, // IID786 + 7, // IID787 + 7, // IID788 + 4, // IID789 + 7, // IID790 + 7, // IID791 + 7, // IID792 + 7, // IID793 + 7, // IID794 + 4, // IID795 + 7, // IID796 + 7, // IID797 + 6, // IID798 + 10, // IID799 + 10, // IID800 + 5, // IID801 + 7, // IID802 + 7, // IID803 + 10, // IID804 + 10, // IID805 + 10, // IID806 + 8, // IID807 + 10, // IID808 + 10, // IID809 + 10, // IID810 + 7, // IID811 + 10, // IID812 + 8, // IID813 + 10, // IID814 + 10, // IID815 + 8, // IID816 + 10, // IID817 + 10, // IID818 + 8, // IID819 + 10, // IID820 + 10, // IID821 + 10, // IID822 + 11, // IID823 + 11, // IID824 + 10, // IID825 + 11, // IID826 + 11, // IID827 + 11, // IID828 + 11, // IID829 + 11, // IID830 + 10, // IID831 + 11, // IID832 + 11, // IID833 + 10, // IID834 + 6, // IID835 + 3, // IID836 + 6, // IID837 + 6, // IID838 + 6, // IID839 + 6, // IID840 + 6, // IID841 + 6, // IID842 + 6, // IID843 + 4, // IID844 + 6, // IID845 + 6, // IID846 + 6, // IID847 + 4, // IID848 + 6, // IID849 + 6, // IID850 + 6, // IID851 + 3, // IID852 + 6, // IID853 + 6, // IID854 + 6, // IID855 + 3, // IID856 + 6, // IID857 + 6, // IID858 + 6, // IID859 + 4, // IID860 + 6, // IID861 + 6, // IID862 + 7, // IID863 + 5, // IID864 + 7, // IID865 + 7, // IID866 + 7, // IID867 + 5, // IID868 + 7, // IID869 + 7, // IID870 + 6, // IID871 + 4, // IID872 + 6, // IID873 + 4, // IID874 + 6, // IID875 + 4, // IID876 + 6, // IID877 + 4, // IID878 + 6, // IID879 + 4, // IID880 + 6, // IID881 + 4, // IID882 + 6, // IID883 + 4, // IID884 + 6, // IID885 + 4, // IID886 + 6, // IID887 + 4, // IID888 + 6, // IID889 + 4, // IID890 + 6, // IID891 + 4, // IID892 + 6, // IID893 + 4, // IID894 + 6, // IID895 + 4, // IID896 + 6, // IID897 + 4, // IID898 + 6, // IID899 + 4, // IID900 + 6, // IID901 + 4, // IID902 + 11, // IID903 + 11, // IID904 + 11, // IID905 + 10, // IID906 + 11, // IID907 + 9, // IID908 + 11, // IID909 + 11, // IID910 + 11, // IID911 + 10, // IID912 + 11, // IID913 + 11, // IID914 + 11, // IID915 + 11, // IID916 + 11, // IID917 + 11, // IID918 #endif // _LP64 }; @@ -2397,545 +3051,763 @@ "__ emull(Address(r22, r10, (Address::ScaleFactor)1, -0x3d379b56), false);", // IID177 "__ emull(Address(r11, -0x3249efaf), true);", // IID178 "__ elzcntl(r9, r16, false);", // IID179 - "__ elzcntl(r23, r28, true);", // IID180 - "__ enegl(r8, r30, false);", // IID181 - "__ enegl(r23, r11, true);", // IID182 - "__ epopcntl(r13, r16, false);", // IID183 - "__ epopcntl(r11, r11, true);", // IID184 - "__ enotl(r26, rcx);", // IID185 - "__ eroll(rbx, r10, false);", // IID186 - "__ eroll(r14, r29, true);", // IID187 - "__ erorl(r15, r20, false);", // IID188 - "__ erorl(r17, r12, true);", // IID189 - "__ esall(r12, rbx, false);", // IID190 - "__ esall(r23, r27, true);", // IID191 - "__ esarl(r29, r20, false);", // IID192 - "__ esarl(r28, rdx, true);", // IID193 - "__ edecl(r8, r27, false);", // IID194 - "__ edecl(rbx, r15, true);", // IID195 - "__ eincl(r11, r27, false);", // IID196 - "__ eincl(r29, r25, true);", // IID197 - "__ eshll(r12, r8, false);", // IID198 - "__ eshll(r11, r18, true);", // IID199 - "__ eshrl(rdx, r13, false);", // IID200 - "__ eshrl(r23, r24, true);", // IID201 - "__ etzcntl(r15, r15, false);", // IID202 - "__ etzcntl(r26, r28, true);", // IID203 - "__ elzcntl(rbx, Address(r25, r14, (Address::ScaleFactor)0, +0x1c13fdb6), false);", // IID204 - "__ elzcntl(r9, Address(r31, r28, (Address::ScaleFactor)3, -0x30bf8b7f), true);", // IID205 - "__ enegl(r8, Address(r25, -0x9c80fe2), false);", // IID206 - "__ enegl(r22, Address(r27, r19, (Address::ScaleFactor)2, +0x38f27c09), true);", // IID207 - "__ epopcntl(r21, Address(r14, r30, (Address::ScaleFactor)2, +0x39f92c7b), false);", // IID208 - "__ epopcntl(r26, Address(r23, r14, (Address::ScaleFactor)3, -0x602e1b3d), true);", // IID209 - "__ esall(r25, Address(r28, r23, (Address::ScaleFactor)1, +0x4ff120ef), false);", // IID210 - "__ esall(r29, Address(r24, r16, (Address::ScaleFactor)3, -0x6821bb43), true);", // IID211 - "__ esarl(r23, Address(r11, r31, (Address::ScaleFactor)2, +0x7f4224bb), false);", // IID212 - "__ esarl(r12, Address(r23, r31, (Address::ScaleFactor)1, -0x28f87a8), true);", // IID213 - "__ edecl(r19, Address(r16, r30, (Address::ScaleFactor)1, -0x27b89e0d), false);", // IID214 - "__ edecl(r26, Address(r25, +0x3d145d48), true);", // IID215 - "__ eincl(r13, Address(r27, r24, (Address::ScaleFactor)1, +0x625f3862), false);", // IID216 - "__ eincl(r11, Address(r22, +0x765904a6), true);", // IID217 - "__ eshrl(r25, Address(rdx, r17, (Address::ScaleFactor)1, -0x7d50376f), false);", // IID218 - "__ eshrl(r22, Address(r12, -0x50325da9), true);", // IID219 - "__ etzcntl(r13, Address(r13, r20, (Address::ScaleFactor)0, -0xbf3e86c), false);", // IID220 - "__ etzcntl(r26, Address(r14, r19, (Address::ScaleFactor)1, -0x24c59cb9), true);", // IID221 - "__ eaddl(r22, Address(r27, r31, (Address::ScaleFactor)2, -0x7f80902f), 1048576, false);", // IID222 - "__ eaddl(r31, Address(rdx, r21, (Address::ScaleFactor)3, -0x557cc036), 268435456, true);", // IID223 - "__ eandl(r10, Address(r26, +0x4e6bebf9), 4096, false);", // IID224 - "__ eandl(r13, Address(r30, +0x14f1a5fd), 256, true);", // IID225 - "__ eimull(r27, Address(r29, r8, (Address::ScaleFactor)0, +0x37988799), 1, false);", // IID226 - "__ eimull(r27, Address(r9, -0x446d2dc1), 256, true);", // IID227 - "__ eorl(r17, Address(r20, r25, (Address::ScaleFactor)0, +0x4957b5db), 16, false);", // IID228 - "__ eorl(r25, Address(r29, r31, (Address::ScaleFactor)1, +0x3c26a53e), 1, true);", // IID229 - "__ eorb(r15, Address(r9, -0x25974a1e), 64, false);", // IID230 - "__ eorb(r11, Address(r16, r15, (Address::ScaleFactor)2, +0x66a0329f), 4, true);", // IID231 - "__ esall(rcx, Address(rcx, r27, (Address::ScaleFactor)0, +0x38c6485e), 1, false);", // IID232 - "__ esall(r25, Address(r8, r10, (Address::ScaleFactor)0, +0x79131c34), 8, true);", // IID233 - "__ esarl(r13, Address(r9, r31, (Address::ScaleFactor)2, +0x12718ba9), 2, false);", // IID234 - "__ esarl(r15, Address(r25, -0x505836f3), 16, true);", // IID235 - "__ eshrl(r15, Address(rcx, r19, (Address::ScaleFactor)0, +0xc5c1510), 1, false);", // IID236 - "__ eshrl(r13, Address(r29, r21, (Address::ScaleFactor)2, -0x6c67309c), 8, true);", // IID237 - "__ esubl(rbx, Address(r12, r8, (Address::ScaleFactor)1, -0x3575087f), 4096, false);", // IID238 - "__ esubl(r28, Address(rbx, r21, (Address::ScaleFactor)3, -0x55f83db8), 65536, true);", // IID239 - "__ exorl(r30, Address(r21, r26, (Address::ScaleFactor)0, +0x3b4d14e1), 1, false);", // IID240 - "__ exorl(r28, Address(r18, -0x452348a1), 16777216, true);", // IID241 - "__ eaddl(r18, Address(rdx, r10, (Address::ScaleFactor)2, -0x161e1d47), r16, false);", // IID242 - "__ eaddl(r27, Address(r25, r18, (Address::ScaleFactor)3, -0x679bb823), rdx, true);", // IID243 - "__ eorl(r27, Address(r31, r29, (Address::ScaleFactor)3, +0x19ed7934), r9, false);", // IID244 - "__ eorl(r22, Address(r8, r16, (Address::ScaleFactor)2, -0x1bf71f78), r17, true);", // IID245 - "__ eorb(rcx, Address(r15, r28, (Address::ScaleFactor)3, -0x6a4a3934), r16, false);", // IID246 - "__ eorb(r28, Address(r23, r12, (Address::ScaleFactor)2, +0x3c2449f7), r16, true);", // IID247 - "__ esubl(r22, Address(r27, r10, (Address::ScaleFactor)1, -0x3c29396f), r9, false);", // IID248 - "__ esubl(r10, Address(r16, -0x165064ff), r17, true);", // IID249 - "__ exorl(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false);", // IID250 - "__ exorl(rdx, Address(rbx, r31, (Address::ScaleFactor)3, +0x7753d0dc), r17, true);", // IID251 - "__ exorb(r9, Address(r31, +0x72a4f58e), r30, false);", // IID252 - "__ exorb(r24, Address(r25, r15, (Address::ScaleFactor)0, +0x20fc1a0a), r16, true);", // IID253 - "__ eaddl(r12, rbx, 65536, false);", // IID254 - "__ eaddl(rax, r11, 65536, false);", // IID255 - "__ eaddl(r24, r16, 268435456, true);", // IID256 - "__ eaddl(rax, r18, 268435456, true);", // IID257 - "__ eandl(r29, r13, 1, false);", // IID258 - "__ eandl(rax, r13, 1, false);", // IID259 - "__ eandl(r31, r22, 1, true);", // IID260 - "__ eandl(rax, r29, 1, true);", // IID261 - "__ eimull(r23, r29, 65536, false);", // IID262 - "__ eimull(rax, r15, 65536, false);", // IID263 - "__ eimull(r21, r9, 268435456, true);", // IID264 - "__ eimull(rax, r15, 268435456, true);", // IID265 - "__ eorl(rdx, r18, 65536, false);", // IID266 - "__ eorl(rax, r15, 65536, false);", // IID267 - "__ eorl(r8, r9, 256, true);", // IID268 - "__ eorl(rax, r27, 256, true);", // IID269 - "__ ercll(r9, r15, 8);", // IID270 - "__ ercll(rax, r18, 8);", // IID271 - "__ eroll(r12, rbx, 16, false);", // IID272 - "__ eroll(rax, r19, 16, false);", // IID273 - "__ eroll(r10, r11, 16, true);", // IID274 - "__ eroll(rax, r18, 16, true);", // IID275 - "__ erorl(rdx, r14, 1, false);", // IID276 - "__ erorl(rax, r22, 1, false);", // IID277 - "__ erorl(r25, r31, 16, true);", // IID278 - "__ erorl(rax, r19, 16, true);", // IID279 - "__ esall(r9, r15, 2, false);", // IID280 - "__ esall(rax, r13, 2, false);", // IID281 - "__ esall(r21, r16, 1, true);", // IID282 - "__ esall(rax, r21, 1, true);", // IID283 - "__ esarl(r26, r23, 8, false);", // IID284 - "__ esarl(rax, r28, 8, false);", // IID285 - "__ esarl(r26, r14, 4, true);", // IID286 - "__ esarl(rax, r10, 4, true);", // IID287 - "__ eshll(r22, r9, 1, false);", // IID288 - "__ eshll(rax, r18, 1, false);", // IID289 - "__ eshll(r30, r24, 16, true);", // IID290 - "__ eshll(rax, r23, 16, true);", // IID291 - "__ eshrl(r11, r8, 16, false);", // IID292 - "__ eshrl(rax, r16, 16, false);", // IID293 - "__ eshrl(r11, r12, 8, true);", // IID294 - "__ eshrl(rax, r29, 8, true);", // IID295 - "__ esubl(r16, r21, 1048576, false);", // IID296 - "__ esubl(rax, r15, 1048576, false);", // IID297 - "__ esubl(r9, r18, 16777216, true);", // IID298 + "__ elzcntl(r23, r23, false);", // IID180 + "__ elzcntl(r28, r8, true);", // IID181 + "__ elzcntl(r30, r30, true);", // IID182 + "__ enegl(r23, r11, false);", // IID183 + "__ enegl(r13, r13, false);", // IID184 + "__ enegl(r16, r11, true);", // IID185 + "__ enegl(r11, r11, true);", // IID186 + "__ epopcntl(r26, rcx, false);", // IID187 #endif // _LP64 - "__ esubl(rax, rbx, 16777216, true);", // IID299 + "__ epopcntl(rbx, rbx, false);", // IID188 #ifdef _LP64 - "__ exorl(r19, r23, 65536, false);", // IID300 - "__ exorl(rax, r17, 65536, false);", // IID301 - "__ exorl(r29, r18, 1048576, true);", // IID302 - "__ exorl(rax, r14, 1048576, true);", // IID303 - "__ esubl_imm32(r19, r15, 16777216, false);", // IID304 - "__ esubl_imm32(rax, r27, 16777216, false);", // IID305 - "__ esubl_imm32(r23, r27, 1073741824, true);", // IID306 - "__ esubl_imm32(rax, r23, 1073741824, true);", // IID307 - "__ eaddl(r8, r12, Address(r28, r24, (Address::ScaleFactor)3, -0x6d6d7e68), false);", // IID308 - "__ eaddl(r24, r13, Address(r24, r25, (Address::ScaleFactor)3, +0x784673fd), true);", // IID309 - "__ eandl(r24, r21, Address(r8, r13, (Address::ScaleFactor)2, -0x63663889), false);", // IID310 - "__ eandl(r12, r24, Address(r30, -0x67526556), true);", // IID311 - "__ eimull(r13, r13, Address(rbx, r25, (Address::ScaleFactor)2, -0x5f394dd9), false);", // IID312 - "__ eimull(r26, r25, Address(r25, rdx, (Address::ScaleFactor)3, -0x2e39f79a), true);", // IID313 - "__ eorl(r28, r8, Address(rdx, r24, (Address::ScaleFactor)3, -0xed99a54), false);", // IID314 - "__ eorl(r31, r22, Address(r30, r20, (Address::ScaleFactor)3, +0x3ac41cbd), true);", // IID315 - "__ esubl(r24, r30, Address(r13, r17, (Address::ScaleFactor)1, +0x1efdc2e3), false);", // IID316 - "__ esubl(r16, r16, Address(r9, r15, (Address::ScaleFactor)1, +0x769feb34), true);", // IID317 - "__ exorl(r19, r25, Address(r10, +0x2239b429), false);", // IID318 - "__ exorl(r25, r19, Address(r16, r24, (Address::ScaleFactor)1, +0x1c71faea), true);", // IID319 - "__ exorb(r19, r10, Address(r28, -0x299a0cfd), false);", // IID320 - "__ exorb(rbx, r28, Address(r23, r24, (Address::ScaleFactor)1, -0x5d78ddd9), true);", // IID321 - "__ exorw(r10, r9, Address(r13, r30, (Address::ScaleFactor)2, +0x11151188), false);", // IID322 - "__ exorw(r16, r17, Address(rdx, r31, (Address::ScaleFactor)0, +0x61936ce7), true);", // IID323 - "__ eaddl(r13, rbx, r28, false);", // IID324 - "__ eaddl(rbx, r29, r22, true);", // IID325 - "__ eandl(rbx, r8, r8, false);", // IID326 - "__ eandl(r11, r16, r13, true);", // IID327 - "__ eimull(r12, r15, r17, false);", // IID328 - "__ eimull(r23, r31, r20, true);", // IID329 - "__ eorw(r22, r26, r10, false);", // IID330 - "__ eorw(r25, r19, r11, true);", // IID331 - "__ eorl(r19, r30, r8, false);", // IID332 - "__ eorl(r12, r10, rdx, true);", // IID333 - "__ eshldl(r22, r20, r30, false);", // IID334 - "__ eshldl(r18, r19, r18, true);", // IID335 - "__ eshrdl(r25, r18, rcx, false);", // IID336 - "__ eshrdl(r19, r16, r25, true);", // IID337 - "__ esubl(r11, r31, r24, false);", // IID338 - "__ esubl(r14, r30, r16, true);", // IID339 - "__ exorl(r9, r11, r26, false);", // IID340 - "__ exorl(r27, rdx, r31, true);", // IID341 - "__ eshldl(r29, r10, rcx, 16, false);", // IID342 - "__ eshldl(r15, r23, r17, 16, true);", // IID343 - "__ eshrdl(r27, r13, r15, 8, false);", // IID344 - "__ eshrdl(r15, r29, r26, 16, true);", // IID345 - "__ ecmovl (Assembler::Condition::overflow, r18, r9, r9);", // IID346 - "__ ecmovl (Assembler::Condition::noOverflow, r22, r30, r23);", // IID347 - "__ ecmovl (Assembler::Condition::below, r11, r20, r11);", // IID348 - "__ ecmovl (Assembler::Condition::aboveEqual, rbx, r28, r16);", // IID349 - "__ ecmovl (Assembler::Condition::zero, r20, r17, r24);", // IID350 - "__ ecmovl (Assembler::Condition::notZero, r22, r16, r15);", // IID351 - "__ ecmovl (Assembler::Condition::belowEqual, r15, r28, r29);", // IID352 - "__ ecmovl (Assembler::Condition::above, r16, r25, r25);", // IID353 - "__ ecmovl (Assembler::Condition::negative, r17, r13, r17);", // IID354 - "__ ecmovl (Assembler::Condition::positive, r23, rbx, r30);", // IID355 - "__ ecmovl (Assembler::Condition::parity, r15, r22, r11);", // IID356 - "__ ecmovl (Assembler::Condition::noParity, r27, rdx, r22);", // IID357 - "__ ecmovl (Assembler::Condition::less, r9, r17, r28);", // IID358 - "__ ecmovl (Assembler::Condition::greaterEqual, r24, r11, r26);", // IID359 - "__ ecmovl (Assembler::Condition::lessEqual, r12, rcx, rbx);", // IID360 - "__ ecmovl (Assembler::Condition::greater, r28, r22, r22);", // IID361 - "__ ecmovl (Assembler::Condition::overflow, r10, r14, Address(rcx, r17, (Address::ScaleFactor)3, -0x7857b23d));", // IID362 - "__ ecmovl (Assembler::Condition::noOverflow, r17, r12, Address(r26, r24, (Address::ScaleFactor)3, +0x10642223));", // IID363 - "__ ecmovl (Assembler::Condition::below, r26, r8, Address(r31, -0xb2d2be4));", // IID364 - "__ ecmovl (Assembler::Condition::aboveEqual, r12, r20, Address(r12, r22, (Address::ScaleFactor)2, -0x667ff72b));", // IID365 - "__ ecmovl (Assembler::Condition::zero, r22, r9, Address(r27, r23, (Address::ScaleFactor)2, +0x66ce4d22));", // IID366 - "__ ecmovl (Assembler::Condition::notZero, r12, r8, Address(r30, r27, (Address::ScaleFactor)3, -0x2b9676e1));", // IID367 - "__ ecmovl (Assembler::Condition::belowEqual, r17, r20, Address(r9, r30, (Address::ScaleFactor)3, -0x351022df));", // IID368 - "__ ecmovl (Assembler::Condition::above, rdx, r8, Address(r14, +0x3d6b7a59));", // IID369 - "__ ecmovl (Assembler::Condition::negative, rcx, r31, Address(r11, r14, (Address::ScaleFactor)2, +0x2cd585f2));", // IID370 - "__ ecmovl (Assembler::Condition::positive, r25, r18, Address(r24, r11, (Address::ScaleFactor)2, -0x3f699c34));", // IID371 - "__ ecmovl (Assembler::Condition::parity, r18, r8, Address(r19, r17, (Address::ScaleFactor)2, -0x390da4c5));", // IID372 - "__ ecmovl (Assembler::Condition::noParity, r11, r29, Address(r29, rdx, (Address::ScaleFactor)2, +0x3a94a93f));", // IID373 - "__ ecmovl (Assembler::Condition::less, r13, r29, Address(r15, r23, (Address::ScaleFactor)1, +0x76d43532));", // IID374 - "__ ecmovl (Assembler::Condition::greaterEqual, r15, r12, Address(r13, r9, (Address::ScaleFactor)1, +0x16f7a5b));", // IID375 - "__ ecmovl (Assembler::Condition::lessEqual, r9, rdx, Address(r17, r23, (Address::ScaleFactor)1, +0x43b6bfe1));", // IID376 - "__ ecmovl (Assembler::Condition::greater, r28, r20, Address(r24, r10, (Address::ScaleFactor)0, -0x326e802f));", // IID377 - "__ adcq(r27, rcx);", // IID378 - "__ cmpq(r22, r15);", // IID379 - "__ imulq(r31, r30);", // IID380 - "__ popcntq(r19, r19);", // IID381 - "__ sbbq(r26, r21);", // IID382 - "__ subq(r14, r26);", // IID383 - "__ tzcntq(r20, r15);", // IID384 - "__ lzcntq(r12, r13);", // IID385 - "__ addq(r23, r28);", // IID386 - "__ andq(r20, r20);", // IID387 - "__ orq(r24, r11);", // IID388 - "__ xorq(r10, r15);", // IID389 - "__ movq(r19, r20);", // IID390 - "__ bsfq(r23, r15);", // IID391 - "__ bsrq(r26, r19);", // IID392 - "__ btq(r24, r23);", // IID393 - "__ xchgq(r28, r11);", // IID394 - "__ testq(r13, r13);", // IID395 - "__ addq(Address(r31, r23, (Address::ScaleFactor)3, +0x59da0437), rdx);", // IID396 - "__ andq(Address(r21, r20, (Address::ScaleFactor)3, +0x6fd0d557), r27);", // IID397 - "__ cmpq(Address(r21, +0x23ef6744), r11);", // IID398 - "__ orq(Address(r10, rcx, (Address::ScaleFactor)3, +0x7e8544ab), rcx);", // IID399 - "__ xorq(Address(rcx, r24, (Address::ScaleFactor)3, -0x79ca4889), rbx);", // IID400 - "__ subq(Address(r27, r31, (Address::ScaleFactor)0, +0x11f85f9a), r27);", // IID401 - "__ movq(Address(r20, r16, (Address::ScaleFactor)3, +0x72158dda), r17);", // IID402 - "__ xaddq(Address(r29, r9, (Address::ScaleFactor)2, +0x6e8febd1), r12);", // IID403 - "__ andq(Address(r15, -0x47c94ecd), 268435456);", // IID404 - "__ addq(Address(r23, r19, (Address::ScaleFactor)1, +0x32bfde3f), 256);", // IID405 - "__ cmpq(Address(r15, r11, (Address::ScaleFactor)3, +0x548e7560), 4096);", // IID406 - "__ sarq(Address(r20, r14, (Address::ScaleFactor)1, +0x1b43fc34), 2);", // IID407 - "__ salq(Address(r26, r21, (Address::ScaleFactor)0, -0x3bae50c3), 8);", // IID408 - "__ sbbq(Address(r22, r10, (Address::ScaleFactor)3, +0x47e1403), 65536);", // IID409 - "__ shrq(Address(rcx, rdx, (Address::ScaleFactor)2, +0x7ea3924d), 16);", // IID410 - "__ subq(Address(rcx, r26, (Address::ScaleFactor)3, -0x356ea53e), 16);", // IID411 - "__ xorq(Address(r30, r26, (Address::ScaleFactor)2, +0x78a12f5c), 16);", // IID412 - "__ orq(Address(r11, r10, (Address::ScaleFactor)1, +0x3713b5b5), 268435456);", // IID413 - "__ movq(Address(r30, r30, (Address::ScaleFactor)3, +0x2541a10), 65536);", // IID414 - "__ testq(Address(r16, r15, (Address::ScaleFactor)3, +0x558e3251), -16);", // IID415 - "__ addq(r27, Address(r8, r10, (Address::ScaleFactor)2, +0x635f732d));", // IID416 - "__ andq(r21, Address(r12, r31, (Address::ScaleFactor)0, -0x75e8c4a0));", // IID417 - "__ cmpq(r18, Address(r19, r16, (Address::ScaleFactor)2, -0x120ae81e));", // IID418 - "__ lzcntq(rbx, Address(r31, r30, (Address::ScaleFactor)0, +0x1ec3265d));", // IID419 - "__ orq(r16, Address(rdx, r26, (Address::ScaleFactor)0, +0x3586831b));", // IID420 - "__ adcq(r12, Address(r18, -0x3c3e9f7a));", // IID421 - "__ imulq(rcx, Address(r8, r21, (Address::ScaleFactor)3, +0x6b1515ab));", // IID422 - "__ popcntq(r29, Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d));", // IID423 - "__ sbbq(r26, Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189));", // IID424 - "__ subq(r17, Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c));", // IID425 - "__ tzcntq(r18, Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d));", // IID426 - "__ xorq(r12, Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560));", // IID427 - "__ movq(r29, Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657));", // IID428 - "__ leaq(r22, Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f));", // IID429 - "__ cvttsd2siq(r25, Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8));", // IID430 - "__ xchgq(r18, Address(r25, +0x632184c3));", // IID431 - "__ testq(r29, Address(r18, r13, (Address::ScaleFactor)1, -0x5039fd8a));", // IID432 - "__ addq(r20, 4096);", // IID433 - "__ andq(r9, 16);", // IID434 - "__ adcq(rdx, 256);", // IID435 - "__ cmpq(r22, 16777216);", // IID436 - "__ rclq(r17, 1);", // IID437 - "__ rcrq(r31, 1);", // IID438 - "__ rolq(r27, 4);", // IID439 - "__ rorq(r28, 2);", // IID440 - "__ sarq(rcx, 16);", // IID441 - "__ salq(r31, 8);", // IID442 - "__ sbbq(r27, 1048576);", // IID443 - "__ shlq(r20, 16);", // IID444 - "__ shrq(r31, 8);", // IID445 - "__ subq(r27, 1048576);", // IID446 - "__ xorq(r22, 4096);", // IID447 - "__ movq(r8, 4096);", // IID448 - "__ mov64(r28, 1099511627776);", // IID449 - "__ btq(r13, 1);", // IID450 - "__ testq(r16, -1048576);", // IID451 - "__ orq_imm32(r20, 262144);", // IID452 - "__ subq_imm32(r18, 1048576);", // IID453 - "__ cmovq(Assembler::Condition::overflow, rbx, Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615));", // IID454 - "__ cmovq(Assembler::Condition::noOverflow, rdx, Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2));", // IID455 - "__ cmovq(Assembler::Condition::below, r27, Address(r10, rcx, (Address::ScaleFactor)3, -0x1ef7abf1));", // IID456 - "__ cmovq(Assembler::Condition::aboveEqual, r14, Address(r13, r29, (Address::ScaleFactor)2, -0x7c4c8369));", // IID457 - "__ cmovq(Assembler::Condition::zero, r15, Address(r23, rcx, (Address::ScaleFactor)2, -0x6bd22ccf));", // IID458 - "__ cmovq(Assembler::Condition::notZero, r24, Address(r15, r10, (Address::ScaleFactor)1, -0x7ffb3d09));", // IID459 - "__ cmovq(Assembler::Condition::belowEqual, r23, Address(r11, +0x276a863b));", // IID460 - "__ cmovq(Assembler::Condition::above, r28, Address(r29, +0x3fb4396e));", // IID461 - "__ cmovq(Assembler::Condition::negative, r26, Address(r27, rcx, (Address::ScaleFactor)3, +0x4ddea61c));", // IID462 - "__ cmovq(Assembler::Condition::positive, r10, Address(r22, r19, (Address::ScaleFactor)1, +0x2a126966));", // IID463 - "__ cmovq(Assembler::Condition::parity, r12, Address(r10, +0x3d7c59f));", // IID464 - "__ cmovq(Assembler::Condition::noParity, r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d));", // IID465 - "__ cmovq(Assembler::Condition::less, r23, Address(r29, -0x777ed96d));", // IID466 - "__ cmovq(Assembler::Condition::greaterEqual, rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb));", // IID467 - "__ cmovq(Assembler::Condition::lessEqual, r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073));", // IID468 - "__ cmovq(Assembler::Condition::greater, r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c));", // IID469 - "__ call(r10);", // IID470 - "__ divq(r16);", // IID471 - "__ idivq(r27);", // IID472 - "__ imulq(r9);", // IID473 - "__ mulq(r13);", // IID474 - "__ negq(r14);", // IID475 - "__ notq(r18);", // IID476 - "__ rolq(r28);", // IID477 - "__ rorq(r28);", // IID478 - "__ sarq(r22);", // IID479 - "__ salq(r8);", // IID480 - "__ shlq(r12);", // IID481 - "__ shrq(rbx);", // IID482 - "__ incrementq(rcx);", // IID483 - "__ decrementq(r23);", // IID484 - "__ pushp(rcx);", // IID485 - "__ popp(r26);", // IID486 - "__ call(Address(r29, r10, (Address::ScaleFactor)0, +0x5655bc9f));", // IID487 - "__ mulq(Address(rdx, r21, (Address::ScaleFactor)3, -0x6798a630));", // IID488 - "__ negq(Address(r31, r24, (Address::ScaleFactor)0, -0x20071802));", // IID489 - "__ sarq(Address(r21, rdx, (Address::ScaleFactor)2, -0x343cb9e5));", // IID490 - "__ salq(Address(r20, r24, (Address::ScaleFactor)3, +0xa667574));", // IID491 - "__ shrq(Address(r27, +0x76b77974));", // IID492 - "__ incrementq(Address(r25, -0x534e8d31));", // IID493 - "__ decrementq(Address(r20, -0x180d3ea1));", // IID494 - "__ imulq(r17, Address(r16, -0x2af2fd58), 4096);", // IID495 - "__ imulq(r28, r25, 16);", // IID496 - "__ shldq(r27, r13, 16);", // IID497 - "__ shrdq(r8, r10, 16);", // IID498 - "__ pop2(r14, r8);", // IID499 - "__ pop2p(r18, rbx);", // IID500 - "__ push2(r23, r19);", // IID501 - "__ push2p(r12, rbx);", // IID502 - "__ movzbq(r9, Address(r14, r23, (Address::ScaleFactor)3, -0x428d2646));", // IID503 - "__ movzwq(r28, Address(r9, rcx, (Address::ScaleFactor)2, -0x72611661));", // IID504 - "__ movsbq(rbx, Address(r24, r21, (Address::ScaleFactor)2, +0x3a6be990));", // IID505 - "__ movswq(r16, Address(r22, r10, (Address::ScaleFactor)0, +0x7ef8bdd));", // IID506 - "__ movzbq(r28, r14);", // IID507 - "__ movzwq(r13, r28);", // IID508 - "__ movsbq(r11, rdx);", // IID509 - "__ movswq(r12, r26);", // IID510 - "__ cmpxchgq(r20, Address(r10, -0xbd2a8da));", // IID511 - "__ eidivq(r15, false);", // IID512 - "__ eidivq(r23, true);", // IID513 - "__ edivq(r14, false);", // IID514 - "__ edivq(r14, true);", // IID515 - "__ eimulq(r15, false);", // IID516 - "__ eimulq(r20, true);", // IID517 - "__ emulq(rcx, false);", // IID518 - "__ emulq(r21, true);", // IID519 - "__ emulq(Address(r16, r10, (Address::ScaleFactor)3, +0x5f66ac1e), false);", // IID520 - "__ emulq(Address(r21, r22, (Address::ScaleFactor)3, -0xbbc807d), true);", // IID521 - "__ eimulq(r22, r26, false);", // IID522 - "__ eimulq(r25, r21, true);", // IID523 - "__ elzcntq(r20, r13, false);", // IID524 - "__ elzcntq(r25, r19, true);", // IID525 - "__ enegq(r21, r30, false);", // IID526 - "__ enegq(r29, r11, true);", // IID527 - "__ enotq(r22, r8);", // IID528 - "__ epopcntq(r12, r19, false);", // IID529 - "__ epopcntq(r29, r23, true);", // IID530 - "__ erolq(r28, r24, false);", // IID531 - "__ erolq(rdx, r20, true);", // IID532 - "__ erorq(rbx, r30, false);", // IID533 - "__ erorq(r10, r15, true);", // IID534 - "__ esalq(r17, r13, false);", // IID535 - "__ esalq(r21, r24, true);", // IID536 - "__ esarq(r31, r12, false);", // IID537 - "__ esarq(rdx, r24, true);", // IID538 - "__ edecq(r21, r24, false);", // IID539 - "__ edecq(r15, r31, true);", // IID540 - "__ eincq(r10, rbx, false);", // IID541 - "__ eincq(r18, r8, true);", // IID542 - "__ eshlq(r10, r26, false);", // IID543 - "__ eshlq(r28, r14, true);", // IID544 - "__ eshrq(r10, r19, false);", // IID545 - "__ eshrq(r28, r21, true);", // IID546 - "__ etzcntq(r21, r22, false);", // IID547 - "__ etzcntq(r16, r23, true);", // IID548 - "__ eimulq(r11, Address(r18, r9, (Address::ScaleFactor)2, -0x132285a1), false);", // IID549 - "__ eimulq(r13, Address(r24, r15, (Address::ScaleFactor)3, +0x48f50ca0), true);", // IID550 - "__ elzcntq(r9, Address(r13, +0x2115cf0e), false);", // IID551 - "__ elzcntq(r27, Address(r30, +0x49cabbb), true);", // IID552 - "__ enegq(r21, Address(r13, r31, (Address::ScaleFactor)2, +0x50a8f4d2), false);", // IID553 - "__ enegq(r22, Address(r18, r20, (Address::ScaleFactor)1, -0x5da0584c), true);", // IID554 - "__ epopcntq(r14, Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1), false);", // IID555 - "__ epopcntq(r26, Address(r23, r22, (Address::ScaleFactor)3, -0x72c66c23), true);", // IID556 - "__ esalq(r26, Address(r9, +0x334aba09), false);", // IID557 - "__ esalq(r9, Address(r9, r30, (Address::ScaleFactor)3, -0x219a6102), true);", // IID558 - "__ esarq(r25, Address(r20, -0x2131bab1), false);", // IID559 - "__ esarq(r16, Address(r28, r16, (Address::ScaleFactor)1, +0x48c483b9), true);", // IID560 - "__ edecq(r30, Address(r9, r16, (Address::ScaleFactor)0, -0x88ce84f), false);", // IID561 - "__ edecq(r11, Address(r30, r29, (Address::ScaleFactor)2, +0x3eeb8fd0), true);", // IID562 - "__ eincq(r26, Address(r29, r10, (Address::ScaleFactor)3, +0x3ef4822e), false);", // IID563 - "__ eincq(r29, Address(r19, r20, (Address::ScaleFactor)2, -0x3f0f3db9), true);", // IID564 - "__ eshrq(r8, Address(r30, r20, (Address::ScaleFactor)0, +0x15b56a17), false);", // IID565 - "__ eshrq(r26, Address(r11, -0x2de86561), true);", // IID566 - "__ etzcntq(r11, Address(rcx, r30, (Address::ScaleFactor)1, -0x32ffb1c2), false);", // IID567 - "__ etzcntq(r23, Address(r9, r12, (Address::ScaleFactor)1, -0x54823e69), true);", // IID568 - "__ eaddq(r20, Address(r13, rcx, (Address::ScaleFactor)3, -0x46116c0d), r15, false);", // IID569 - "__ eaddq(r13, Address(r9, r23, (Address::ScaleFactor)1, -0x286c7605), r16, true);", // IID570 - "__ eandq(r21, Address(r30, r17, (Address::ScaleFactor)0, +0xf4e30b2), r29, false);", // IID571 - "__ eandq(r30, Address(r17, r31, (Address::ScaleFactor)0, +0x3ab9dec4), r17, true);", // IID572 - "__ eorq(r10, Address(r27, r30, (Address::ScaleFactor)1, -0x197f1266), r28, false);", // IID573 - "__ eorq(r9, Address(r29, r30, (Address::ScaleFactor)0, -0x24ea9b08), r11, true);", // IID574 - "__ esubq(r15, Address(r14, -0x4f44bf90), r16, false);", // IID575 - "__ esubq(rcx, Address(r21, r18, (Address::ScaleFactor)1, -0x11d0ac8f), r28, true);", // IID576 - "__ exorq(r19, Address(r19, r18, (Address::ScaleFactor)0, -0xa5e55ec), r8, false);", // IID577 - "__ exorq(r28, Address(r17, r28, (Address::ScaleFactor)1, -0x6eb42fe0), r16, true);", // IID578 - "__ eaddq(r17, Address(r18, -0x60ab1105), 16777216, false);", // IID579 - "__ eaddq(r25, Address(r19, r25, (Address::ScaleFactor)0, +0x122444d9), 65536, true);", // IID580 - "__ eandq(r30, Address(r9, r28, (Address::ScaleFactor)1, -0x25b00cf3), 4096, false);", // IID581 - "__ eandq(r9, Address(r22, rbx, (Address::ScaleFactor)1, -0x7e465026), 268435456, true);", // IID582 - "__ eimulq(r12, Address(r25, r25, (Address::ScaleFactor)1, -0x432d68cc), 1, false);", // IID583 - "__ eimulq(r15, Address(r17, r31, (Address::ScaleFactor)3, -0x2b97565e), 16, true);", // IID584 - "__ eorq(r28, Address(rdx, r31, (Address::ScaleFactor)0, +0x3f1363b1), 256, false);", // IID585 - "__ eorq(r16, Address(r12, r23, (Address::ScaleFactor)3, -0x1785863c), 16777216, true);", // IID586 - "__ esalq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), 2, false);", // IID587 - "__ esalq(r8, Address(r15, r14, (Address::ScaleFactor)2, +0x21f13243), 16, true);", // IID588 - "__ esarq(r10, Address(r13, r29, (Address::ScaleFactor)0, +0x7d04cb72), 2, false);", // IID589 - "__ esarq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), 8, true);", // IID590 - "__ eshrq(rcx, Address(r16, r12, (Address::ScaleFactor)1, +0x260c9a38), 4, false);", // IID591 - "__ eshrq(r22, Address(r26, r9, (Address::ScaleFactor)0, -0x5e56bb62), 8, true);", // IID592 - "__ esubq(r31, Address(rbx, r28, (Address::ScaleFactor)1, +0x2b00bb10), 1, false);", // IID593 - "__ esubq(r21, Address(r31, -0x6c10f4ad), 4096, true);", // IID594 - "__ exorq(r11, Address(r23, r30, (Address::ScaleFactor)1, +0x51a6026b), 65536, false);", // IID595 - "__ exorq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), 16, true);", // IID596 - "__ eaddq(r20, r23, 16777216, false);", // IID597 - "__ eaddq(rax, r30, 16777216, false);", // IID598 - "__ eaddq(r9, r21, 4096, true);", // IID599 - "__ eaddq(rax, rbx, 4096, true);", // IID600 - "__ eandq(rdx, r21, 268435456, false);", // IID601 - "__ eandq(rax, r8, 268435456, false);", // IID602 - "__ eandq(r19, r31, 65536, true);", // IID603 - "__ eandq(rax, rbx, 65536, true);", // IID604 - "__ eimulq(r21, r9, 16777216, false);", // IID605 - "__ eimulq(rax, r30, 16777216, false);", // IID606 - "__ eimulq(r30, r18, 65536, true);", // IID607 - "__ eimulq(rax, r19, 65536, true);", // IID608 - "__ eorq(r20, r16, 1048576, false);", // IID609 - "__ eorq(rax, r28, 1048576, false);", // IID610 - "__ eorq(rbx, r24, 4096, true);", // IID611 - "__ eorq(rax, r22, 4096, true);", // IID612 - "__ erclq(r20, r30, 4);", // IID613 - "__ erclq(rax, r22, 4);", // IID614 - "__ erolq(rcx, r28, 2, false);", // IID615 - "__ erolq(rax, r21, 2, false);", // IID616 - "__ erolq(r26, r15, 4, true);", // IID617 - "__ erolq(rax, r19, 4, true);", // IID618 - "__ erorq(r24, r19, 8, false);", // IID619 - "__ erorq(rax, r28, 8, false);", // IID620 - "__ erorq(r25, r18, 4, true);", // IID621 - "__ erorq(rax, r13, 4, true);", // IID622 - "__ esalq(r27, r17, 2, false);", // IID623 - "__ esalq(rax, rdx, 2, false);", // IID624 - "__ esalq(rbx, r28, 16, true);", // IID625 - "__ esalq(rax, r15, 16, true);", // IID626 - "__ esarq(rbx, r12, 4, false);", // IID627 - "__ esarq(rax, rbx, 4, false);", // IID628 - "__ esarq(r17, rdx, 2, true);", // IID629 - "__ esarq(rax, r31, 2, true);", // IID630 - "__ eshlq(r21, rbx, 4, false);", // IID631 - "__ eshlq(rax, r24, 4, false);", // IID632 - "__ eshlq(r27, r13, 16, true);", // IID633 - "__ eshlq(rax, r25, 16, true);", // IID634 - "__ eshrq(rcx, r22, 16, false);", // IID635 - "__ eshrq(rax, r14, 16, false);", // IID636 - "__ eshrq(r11, r30, 4, true);", // IID637 - "__ eshrq(rax, r24, 4, true);", // IID638 - "__ esubq(r20, r19, 256, false);", // IID639 - "__ esubq(rax, r17, 256, false);", // IID640 - "__ esubq(r31, r30, 65536, true);", // IID641 - "__ esubq(rax, r18, 65536, true);", // IID642 - "__ exorq(r18, r11, 4096, false);", // IID643 - "__ exorq(rax, r10, 4096, false);", // IID644 - "__ exorq(r24, r18, 268435456, true);", // IID645 - "__ exorq(rax, rbx, 268435456, true);", // IID646 - "__ eorq_imm32(r26, r21, 4194304, false);", // IID647 - "__ eorq_imm32(rax, r8, 4194304, false);", // IID648 - "__ eorq_imm32(r22, r21, 262144, false);", // IID649 - "__ eorq_imm32(rax, r27, 262144, false);", // IID650 - "__ esubq_imm32(r16, r8, 4194304, false);", // IID651 - "__ esubq_imm32(rax, rdx, 4194304, false);", // IID652 - "__ esubq_imm32(r20, r31, 1048576, true);", // IID653 - "__ esubq_imm32(rax, r21, 1048576, true);", // IID654 - "__ eaddq(r20, r14, Address(rcx, r16, (Address::ScaleFactor)0, +0x7c6654d9), false);", // IID655 - "__ eaddq(r29, rcx, Address(r15, r23, (Address::ScaleFactor)0, +0x45b7f72d), true);", // IID656 - "__ eandq(r19, r17, Address(r13, r22, (Address::ScaleFactor)1, -0x750c1996), false);", // IID657 - "__ eandq(r13, r8, Address(r31, r23, (Address::ScaleFactor)1, -0x2211b6b2), true);", // IID658 - "__ eorq(r11, r28, Address(r13, r11, (Address::ScaleFactor)3, +0x5c0013ab), false);", // IID659 - "__ eorq(rdx, r18, Address(r18, rcx, (Address::ScaleFactor)0, +0x59557e71), true);", // IID660 - "__ eimulq(r27, r11, Address(r22, -0x28469649), false);", // IID661 - "__ eimulq(r10, r9, Address(r24, +0x49691d54), true);", // IID662 - "__ esubq(r24, r12, Address(r19, +0x22d529aa), false);", // IID663 - "__ esubq(r20, r18, Address(r9, r10, (Address::ScaleFactor)2, -0x264a7a48), true);", // IID664 - "__ exorq(rbx, r9, Address(r14, r27, (Address::ScaleFactor)0, +0xf71c02f), false);", // IID665 - "__ exorq(r25, r15, Address(r10, r12, (Address::ScaleFactor)1, +0x732367bd), true);", // IID666 - "__ eaddq(r11, r9, r10, false);", // IID667 - "__ eaddq(r25, r13, r16, true);", // IID668 - "__ eadcxq(r11, r21, r25);", // IID669 - "__ eadoxq(rdx, r20, rbx);", // IID670 - "__ eandq(r25, r21, r26, false);", // IID671 - "__ eandq(r23, r27, r21, true);", // IID672 - "__ eimulq(r10, r10, r12, false);", // IID673 - "__ eimulq(r31, r12, r23, true);", // IID674 - "__ eorq(r16, r29, r14, false);", // IID675 - "__ eorq(r19, r24, r23, true);", // IID676 - "__ esubq(r14, r21, r15, false);", // IID677 - "__ esubq(r25, r9, r29, true);", // IID678 - "__ exorq(rdx, r11, r25, false);", // IID679 - "__ exorq(r19, r10, r16, true);", // IID680 - "__ eshldq(r8, r23, r31, 8, false);", // IID681 - "__ eshldq(r31, rbx, r16, 2, true);", // IID682 - "__ eshrdq(r24, r10, r9, 2, false);", // IID683 - "__ eshrdq(r28, r26, r18, 16, true);", // IID684 - "__ ecmovq (Assembler::Condition::overflow, r25, r20, r16);", // IID685 - "__ ecmovq (Assembler::Condition::noOverflow, r21, rbx, r28);", // IID686 - "__ ecmovq (Assembler::Condition::below, r22, r19, r13);", // IID687 - "__ ecmovq (Assembler::Condition::aboveEqual, r15, rdx, r8);", // IID688 - "__ ecmovq (Assembler::Condition::zero, r22, r14, r12);", // IID689 - "__ ecmovq (Assembler::Condition::notZero, r24, r14, r24);", // IID690 - "__ ecmovq (Assembler::Condition::belowEqual, r13, r21, rbx);", // IID691 - "__ ecmovq (Assembler::Condition::above, rbx, r27, r14);", // IID692 - "__ ecmovq (Assembler::Condition::negative, r24, r27, r17);", // IID693 - "__ ecmovq (Assembler::Condition::positive, r21, r27, r27);", // IID694 - "__ ecmovq (Assembler::Condition::parity, r27, r14, r24);", // IID695 - "__ ecmovq (Assembler::Condition::noParity, r28, r29, r22);", // IID696 - "__ ecmovq (Assembler::Condition::less, r15, r13, r31);", // IID697 - "__ ecmovq (Assembler::Condition::greaterEqual, r21, r15, r30);", // IID698 - "__ ecmovq (Assembler::Condition::lessEqual, r20, r8, r13);", // IID699 - "__ ecmovq (Assembler::Condition::greater, r31, r25, r27);", // IID700 - "__ ecmovq (Assembler::Condition::overflow, r31, r15, Address(r14, r13, (Address::ScaleFactor)1, -0x6e68556));", // IID701 - "__ ecmovq (Assembler::Condition::noOverflow, r12, r28, Address(r30, r15, (Address::ScaleFactor)3, +0x3ba33f9e));", // IID702 - "__ ecmovq (Assembler::Condition::below, r16, r25, Address(r12, r9, (Address::ScaleFactor)0, -0x28e03b33));", // IID703 - "__ ecmovq (Assembler::Condition::aboveEqual, r8, r27, Address(r8, r25, (Address::ScaleFactor)3, -0x1e42bd95));", // IID704 - "__ ecmovq (Assembler::Condition::zero, rcx, r20, Address(r27, rbx, (Address::ScaleFactor)2, +0x46823c58));", // IID705 - "__ ecmovq (Assembler::Condition::notZero, rbx, r12, Address(r21, -0x635b8c8));", // IID706 - "__ ecmovq (Assembler::Condition::belowEqual, r23, rbx, Address(r27, r26, (Address::ScaleFactor)3, +0x922bcc0));", // IID707 - "__ ecmovq (Assembler::Condition::above, r25, r9, Address(r23, +0xd2a14ec));", // IID708 - "__ ecmovq (Assembler::Condition::negative, r11, r19, Address(r11, -0xfb95a9d));", // IID709 - "__ ecmovq (Assembler::Condition::positive, r13, r18, Address(r28, r19, (Address::ScaleFactor)0, +0x716b9b7e));", // IID710 - "__ ecmovq (Assembler::Condition::parity, r21, r16, Address(rcx, r29, (Address::ScaleFactor)0, -0x5af0441e));", // IID711 - "__ ecmovq (Assembler::Condition::noParity, r12, r31, Address(r20, r26, (Address::ScaleFactor)0, +0xe0b7fb1));", // IID712 - "__ ecmovq (Assembler::Condition::less, r15, r24, Address(r30, +0x2d3b7b4f));", // IID713 - "__ ecmovq (Assembler::Condition::greaterEqual, r12, r15, Address(r14, r21, (Address::ScaleFactor)2, -0x1222aee8));", // IID714 - "__ ecmovq (Assembler::Condition::lessEqual, rbx, r31, Address(r23, r20, (Address::ScaleFactor)0, -0x96e4d6a));", // IID715 - "__ ecmovq (Assembler::Condition::greater, rdx, rdx, Address(r10, rdx, (Address::ScaleFactor)3, +0x3875f17c));", // IID716 + "__ epopcntl(r10, r14, true);", // IID189 + "__ epopcntl(r29, r29, true);", // IID190 + "__ enotl(r15, r20);", // IID191 + "__ enotl(r17, r17);", // IID192 + "__ eroll(r12, r12, false);", // IID193 +#endif // _LP64 + "__ eroll(rbx, rbx, false);", // IID194 +#ifdef _LP64 + "__ eroll(r23, r27, true);", // IID195 + "__ eroll(r29, r29, true);", // IID196 + "__ erorl(r20, r28, false);", // IID197 +#endif // _LP64 + "__ erorl(rdx, rdx, false);", // IID198 +#ifdef _LP64 + "__ erorl(r8, r27, true);", // IID199 +#endif // _LP64 + "__ erorl(rbx, rbx, true);", // IID200 +#ifdef _LP64 + "__ esall(r15, r11, false);", // IID201 + "__ esall(r27, r27, false);", // IID202 + "__ esall(r29, r25, true);", // IID203 + "__ esall(r12, r12, true);", // IID204 + "__ esarl(r8, r11, false);", // IID205 + "__ esarl(r18, r18, false);", // IID206 + "__ esarl(rdx, r13, true);", // IID207 + "__ esarl(r23, r23, true);", // IID208 + "__ edecl(r24, r15, false);", // IID209 + "__ edecl(r15, r15, false);", // IID210 + "__ edecl(r26, r28, true);", // IID211 +#endif // _LP64 + "__ edecl(rbx, rbx, true);", // IID212 +#ifdef _LP64 + "__ eincl(r25, r14, false);", // IID213 + "__ eincl(r12, r12, false);", // IID214 + "__ eincl(rcx, r23, true);", // IID215 + "__ eincl(r29, r29, true);", // IID216 + "__ eshll(r22, r24, false);", // IID217 + "__ eshll(r15, r15, false);", // IID218 + "__ eshll(r9, r31, true);", // IID219 + "__ eshll(r28, r28, true);", // IID220 + "__ eshrl(r21, r18, false);", // IID221 + "__ eshrl(r24, r24, false);", // IID222 + "__ eshrl(r14, r19, true);", // IID223 + "__ eshrl(r8, r8, true);", // IID224 + "__ etzcntl(r25, r9, false);", // IID225 + "__ etzcntl(r26, r26, false);", // IID226 + "__ etzcntl(r8, r30, true);", // IID227 + "__ etzcntl(r26, r26, true);", // IID228 + "__ elzcntl(r29, Address(r25, r20, (Address::ScaleFactor)3, -0x9c80fe2), false);", // IID229 + "__ elzcntl(r22, Address(r27, r19, (Address::ScaleFactor)2, +0x38f27c09), true);", // IID230 + "__ enegl(r21, Address(r14, r30, (Address::ScaleFactor)2, +0x39f92c7b), false);", // IID231 + "__ enegl(r26, Address(r23, r14, (Address::ScaleFactor)3, -0x602e1b3d), true);", // IID232 + "__ epopcntl(r25, Address(r28, r23, (Address::ScaleFactor)1, +0x4ff120ef), false);", // IID233 + "__ epopcntl(r29, Address(r24, r16, (Address::ScaleFactor)3, -0x6821bb43), true);", // IID234 + "__ esall(r23, Address(r11, r31, (Address::ScaleFactor)2, +0x7f4224bb), false);", // IID235 + "__ esall(r12, Address(r23, r31, (Address::ScaleFactor)1, -0x28f87a8), true);", // IID236 + "__ esarl(r19, Address(r16, r30, (Address::ScaleFactor)1, -0x27b89e0d), false);", // IID237 + "__ esarl(r26, Address(r25, +0x3d145d48), true);", // IID238 + "__ edecl(r13, Address(r27, r24, (Address::ScaleFactor)1, +0x625f3862), false);", // IID239 + "__ edecl(r11, Address(r22, +0x765904a6), true);", // IID240 + "__ eincl(r25, Address(rdx, r17, (Address::ScaleFactor)1, -0x7d50376f), false);", // IID241 + "__ eincl(r22, Address(r12, -0x50325da9), true);", // IID242 + "__ eshrl(r13, Address(r13, r20, (Address::ScaleFactor)0, -0xbf3e86c), false);", // IID243 + "__ eshrl(r26, Address(r14, r19, (Address::ScaleFactor)1, -0x24c59cb9), true);", // IID244 + "__ etzcntl(r16, Address(r22, r27, (Address::ScaleFactor)2, -0x7f80902f), false);", // IID245 + "__ etzcntl(r20, Address(r31, rdx, (Address::ScaleFactor)3, +0x12254818), true);", // IID246 + "__ eaddl(r21, Address(r12, r10, (Address::ScaleFactor)3, +0x6417cf06), 1048576, false);", // IID247 + "__ eaddl(r9, Address(r13, +0x14f1a5fd), 4096, true);", // IID248 + "__ eandl(r27, Address(r29, r8, (Address::ScaleFactor)0, +0x37988799), 1, false);", // IID249 + "__ eandl(r27, Address(r9, -0x446d2dc1), 256, true);", // IID250 + "__ eimull(r17, Address(r20, r25, (Address::ScaleFactor)0, +0x4957b5db), 16, false);", // IID251 + "__ eimull(r25, Address(r29, r31, (Address::ScaleFactor)1, +0x3c26a53e), 1, true);", // IID252 + "__ eorl(r15, Address(r9, -0x25974a1e), 268435456, false);", // IID253 + "__ eorl(r11, Address(r16, r15, (Address::ScaleFactor)2, +0x66a0329f), 4096, true);", // IID254 + "__ eorb(rcx, Address(rcx, r27, (Address::ScaleFactor)0, +0x38c6485e), 1, false);", // IID255 + "__ eorb(r25, Address(r8, r10, (Address::ScaleFactor)0, +0x79131c34), 64, true);", // IID256 + "__ esall(r13, Address(r9, r31, (Address::ScaleFactor)2, +0x12718ba9), 2, false);", // IID257 + "__ esall(r15, Address(r25, -0x505836f3), 16, true);", // IID258 + "__ esarl(r15, Address(rcx, r19, (Address::ScaleFactor)0, +0xc5c1510), 1, false);", // IID259 + "__ esarl(r13, Address(r29, r21, (Address::ScaleFactor)2, -0x6c67309c), 8, true);", // IID260 + "__ eshrl(r11, Address(rbx, +0x749f67d0), 16, false);", // IID261 + "__ eshrl(r14, Address(r14, -0x55f83db8), 4, true);", // IID262 + "__ esubl(r30, Address(r21, r26, (Address::ScaleFactor)0, +0x3b4d14e1), 1, false);", // IID263 + "__ esubl(r28, Address(r18, -0x452348a1), 16777216, true);", // IID264 + "__ exorl(rdx, Address(r10, r16, (Address::ScaleFactor)2, -0x161e1d47), 16777216, false);", // IID265 + "__ exorl(rdx, Address(r29, r23, (Address::ScaleFactor)1, +0x1b34e2f8), 16777216, true);", // IID266 + "__ eaddl(r19, Address(r27, r31, (Address::ScaleFactor)0, +0x1f3ce7d8), r29, false);", // IID267 + "__ eaddl(r28, Address(r24, rcx, (Address::ScaleFactor)3, -0x6053edc2), r28, false);", // IID268 + "__ eaddl(r17, Address(r18, r24, (Address::ScaleFactor)3, -0x1bf71f78), r29, true);", // IID269 + "__ eaddl(rcx, Address(r15, r28, (Address::ScaleFactor)1, +0x15b8216), rcx, true);", // IID270 + "__ eorl(r30, Address(rbx, rdx, (Address::ScaleFactor)3, -0x463540b4), r28, false);", // IID271 + "__ eorl(r18, Address(r28, r10, (Address::ScaleFactor)3, +0x3523a73b), r18, false);", // IID272 + "__ eorl(r9, Address(r15, r15, (Address::ScaleFactor)1, -0x2a0bdd56), r21, true);", // IID273 + "__ eorl(r16, Address(r23, -0x165064ff), r16, true);", // IID274 + "__ eorb(r28, Address(r30, r11, (Address::ScaleFactor)0, +0x17281e3a), r20, false);", // IID275 + "__ eorb(rdx, Address(rbx, r31, (Address::ScaleFactor)2, +0x2477b5bb), rdx, false);", // IID276 + "__ eorb(r16, Address(r11, rcx, (Address::ScaleFactor)1, -0x3175d1af), r24, true);", // IID277 + "__ eorb(rbx, Address(r11, r20, (Address::ScaleFactor)3, -0x22d67bd3), rbx, true);", // IID278 + "__ esubl(r26, Address(r27, r30, (Address::ScaleFactor)1, -0x3d9bce2e), rdx, false);", // IID279 + "__ esubl(r31, Address(r22, r29, (Address::ScaleFactor)1, +0x14218519), r31, false);", // IID280 + "__ esubl(r21, Address(r9, -0x1050127a), r13, true);", // IID281 + "__ esubl(r31, Address(r9, r8, (Address::ScaleFactor)0, -0xae18961), r31, true);", // IID282 + "__ exorl(r15, Address(r18, +0x5c2bbce5), r12, false);", // IID283 + "__ exorl(r27, Address(r25, r23, (Address::ScaleFactor)0, +0x5c6078b3), r27, false);", // IID284 + "__ exorl(r18, Address(r8, rdx, (Address::ScaleFactor)3, -0x9ed3881), r14, true);", // IID285 + "__ exorl(r9, Address(r15, +0x775acdad), r9, true);", // IID286 + "__ exorb(r21, Address(r18, r26, (Address::ScaleFactor)1, +0x2fe31fd5), r23, false);", // IID287 + "__ exorb(r10, Address(r27, +0xa3150de), r10, false);", // IID288 + "__ exorb(r18, Address(r22, r30, (Address::ScaleFactor)3, +0x1ad4e897), r24, true);", // IID289 + "__ exorb(r8, Address(r16, r20, (Address::ScaleFactor)0, +0x626eae82), r8, true);", // IID290 + "__ eaddl(r21, r15, 1048576, false);", // IID291 + "__ eaddl(rax, r18, 1048576, false);", // IID292 + "__ eaddl(r18, r18, 256, false);", // IID293 + "__ eaddl(r13, r19, 16, true);", // IID294 + "__ eaddl(rax, r23, 16, true);", // IID295 + "__ eaddl(r25, r25, 16777216, true);", // IID296 + "__ eandl(r29, r18, 1048576, false);", // IID297 + "__ eandl(rax, r14, 1048576, false);", // IID298 + "__ eandl(r19, r19, 65536, false);", // IID299 + "__ eandl(r27, r25, 1048576, true);", // IID300 + "__ eandl(rax, r20, 1048576, true);", // IID301 + "__ eandl(r28, r28, 16, true);", // IID302 + "__ eimull(r31, r22, 4096, false);", // IID303 +#endif // _LP64 + "__ eimull(rax, rbx, 4096, false);", // IID304 +#ifdef _LP64 + "__ eimull(r24, r24, 1048576, false);", // IID305 + "__ eimull(r21, r16, 65536, true);", // IID306 + "__ eimull(rax, r24, 65536, true);", // IID307 + "__ eimull(r13, r13, 16, true);", // IID308 + "__ eorl(r29, r8, 16777216, false);", // IID309 + "__ eorl(rax, r12, 16777216, false);", // IID310 + "__ eorl(r30, r30, 4096, false);", // IID311 + "__ eorl(r24, rdx, 16, true);", // IID312 + "__ eorl(rax, r8, 16, true);", // IID313 + "__ eorl(r13, r13, 4096, true);", // IID314 + "__ ercll(r25, r13, 1);", // IID315 + "__ ercll(rax, r18, 1);", // IID316 + "__ ercll(r9, r9, 16);", // IID317 + "__ eroll(r26, r25, 8, false);", // IID318 +#endif // _LP64 + "__ eroll(rax, rdx, 8, false);", // IID319 +#ifdef _LP64 + "__ eroll(r24, r24, 16, false);", // IID320 + "__ eroll(r24, rcx, 8, true);", // IID321 + "__ eroll(rax, r30, 8, true);", // IID322 + "__ eroll(r28, r28, 16, true);", // IID323 + "__ erorl(r17, r28, 4, false);", // IID324 +#endif // _LP64 + "__ erorl(rax, rdx, 4, false);", // IID325 +#ifdef _LP64 + "__ erorl(r8, r8, 16, false);", // IID326 + "__ erorl(r19, rdx, 16, true);", // IID327 + "__ erorl(rax, r31, 16, true);", // IID328 + "__ erorl(r22, r22, 8, true);", // IID329 + "__ esall(r23, r25, 16, false);", // IID330 + "__ esall(rax, r14, 16, false);", // IID331 + "__ esall(r31, r31, 8, false);", // IID332 + "__ esall(r30, r24, 2, true);", // IID333 + "__ esall(rax, r29, 2, true);", // IID334 + "__ esall(r8, r8, 2, true);", // IID335 + "__ esarl(r18, r24, 16, false);", // IID336 + "__ esarl(rax, r13, 16, false);", // IID337 + "__ esarl(r24, r24, 1, false);", // IID338 + "__ esarl(r28, r17, 16, true);", // IID339 + "__ esarl(rax, r24, 16, true);", // IID340 + "__ esarl(r17, r17, 4, true);", // IID341 + "__ eshll(r24, rcx, 4, false);", // IID342 + "__ eshll(rax, r16, 4, false);", // IID343 + "__ eshll(r15, r15, 2, false);", // IID344 + "__ eshll(r14, r27, 4, true);", // IID345 + "__ eshll(rax, r23, 4, true);", // IID346 + "__ eshll(r30, r30, 4, true);", // IID347 + "__ eshrl(r27, rdx, 2, false);", // IID348 + "__ eshrl(rax, r19, 2, false);", // IID349 + "__ eshrl(r20, r20, 2, false);", // IID350 + "__ eshrl(r21, r23, 1, true);", // IID351 + "__ eshrl(rax, r30, 1, true);", // IID352 + "__ eshrl(r25, r25, 2, true);", // IID353 + "__ esubl(r24, r19, 1048576, false);", // IID354 + "__ esubl(rax, r14, 1048576, false);", // IID355 + "__ esubl(r22, r22, 268435456, false);", // IID356 + "__ esubl(r24, r24, 65536, true);", // IID357 + "__ esubl(rax, r14, 65536, true);", // IID358 + "__ esubl(r28, r28, 268435456, true);", // IID359 + "__ exorl(rbx, r20, 256, false);", // IID360 + "__ exorl(rax, r15, 256, false);", // IID361 +#endif // _LP64 + "__ exorl(rbx, rbx, 4096, false);", // IID362 +#ifdef _LP64 + "__ exorl(r24, r30, 65536, true);", // IID363 + "__ exorl(rax, r31, 65536, true);", // IID364 + "__ exorl(r31, r31, 4096, true);", // IID365 + "__ esubl_imm32(r20, r10, 1048576, false);", // IID366 + "__ esubl_imm32(rax, r13, 1048576, false);", // IID367 + "__ esubl_imm32(r25, r25, 1048576, false);", // IID368 + "__ esubl_imm32(r23, r12, 1073741824, true);", // IID369 + "__ esubl_imm32(rax, r16, 1073741824, true);", // IID370 + "__ esubl_imm32(r31, r31, 65536, true);", // IID371 + "__ eaddl(r17, r13, Address(r9, +0x7fef2f98), false);", // IID372 + "__ eaddl(r29, r8, Address(r22, -0x4df70aac), true);", // IID373 + "__ eandl(r13, r17, Address(r12, r15, (Address::ScaleFactor)3, +0x50a8a902), false);", // IID374 + "__ eandl(r22, r25, Address(r26, r10, (Address::ScaleFactor)2, +0x70ea2754), true);", // IID375 + "__ eimull(r19, r12, Address(r30, r8, (Address::ScaleFactor)0, +0x6a1a0a73), false);", // IID376 + "__ eimull(r30, r18, Address(r18, r19, (Address::ScaleFactor)2, -0x7fcd28c7), true);", // IID377 + "__ eorl(r16, r31, Address(r25, r11, (Address::ScaleFactor)3, +0x482d5dbc), false);", // IID378 + "__ eorl(r9, r27, Address(r11, +0x43d5ee01), true);", // IID379 + "__ esubl(rcx, r23, Address(r21, r15, (Address::ScaleFactor)2, +0x2825c2bc), false);", // IID380 + "__ esubl(r27, r22, Address(r13, r15, (Address::ScaleFactor)1, +0x771f0da7), true);", // IID381 + "__ exorl(r9, r30, Address(r9, r22, (Address::ScaleFactor)3, -0x4ad6c88e), false);", // IID382 + "__ exorl(r11, r16, Address(rbx, r28, (Address::ScaleFactor)2, +0xb0223ee), true);", // IID383 + "__ exorb(r15, r29, Address(r15, r28, (Address::ScaleFactor)1, -0x1f297a69), false);", // IID384 + "__ exorb(r17, r30, Address(r23, rbx, (Address::ScaleFactor)1, +0xadc7545), true);", // IID385 + "__ exorw(r27, r9, Address(rdx, r22, (Address::ScaleFactor)2, -0x43d90f61), false);", // IID386 + "__ exorw(rbx, r22, Address(r28, r22, (Address::ScaleFactor)0, -0x7d30a0b1), true);", // IID387 + "__ eaddl(r14, r24, rcx, false);", // IID388 + "__ eaddl(r8, r8, r17, false);", // IID389 + "__ eaddl(r26, r24, r12, true);", // IID390 + "__ eaddl(r24, r24, r23, true);", // IID391 + "__ eandl(r13, r26, r31, false);", // IID392 + "__ eandl(r11, r11, r8, false);", // IID393 + "__ eandl(rcx, r19, r15, true);", // IID394 + "__ eandl(r12, r12, r12, true);", // IID395 + "__ eimull(r22, r20, r19, false);", // IID396 + "__ eimull(r8, r8, rdx, false);", // IID397 + "__ eimull(r22, r27, r23, true);", // IID398 + "__ eimull(r9, r9, r18, true);", // IID399 + "__ eorw(rcx, r30, r13, false);", // IID400 + "__ eorw(r28, r28, r19, false);", // IID401 + "__ eorw(r12, r30, r27, true);", // IID402 + "__ eorw(r8, r8, r22, true);", // IID403 + "__ eorl(r16, rcx, r30, false);", // IID404 + "__ eorl(r10, r10, r25, false);", // IID405 + "__ eorl(r15, r17, r17, true);", // IID406 + "__ eorl(r9, r9, r30, true);", // IID407 + "__ eshldl(r20, r21, r8, false);", // IID408 + "__ eshldl(r26, r26, r14, false);", // IID409 + "__ eshldl(r16, rdx, r14, true);", // IID410 + "__ eshldl(r19, r19, r8, true);", // IID411 + "__ eshrdl(r27, rbx, r26, false);", // IID412 + "__ eshrdl(r28, r28, r19, false);", // IID413 + "__ eshrdl(rcx, r11, r14, true);", // IID414 + "__ eshrdl(r31, r31, r19, true);", // IID415 + "__ esubl(r26, r13, r25, false);", // IID416 + "__ esubl(r24, r24, r11, false);", // IID417 + "__ esubl(r18, r20, r13, true);", // IID418 + "__ esubl(r16, r16, r18, true);", // IID419 + "__ exorl(r19, r17, r8, false);", // IID420 + "__ exorl(r19, r19, r13, false);", // IID421 + "__ exorl(r23, r13, r15, true);", // IID422 + "__ exorl(r11, r11, r29, true);", // IID423 + "__ eshldl(r29, r17, r17, 1, false);", // IID424 + "__ eshldl(r22, r22, r24, 4, false);", // IID425 + "__ eshldl(r8, r28, r11, 16, true);", // IID426 + "__ eshldl(r15, r15, r23, 4, true);", // IID427 + "__ eshrdl(r29, r22, r16, 4, false);", // IID428 + "__ eshrdl(r13, r13, r9, 4, false);", // IID429 + "__ eshrdl(r15, r21, r12, 2, true);", // IID430 + "__ eshrdl(r17, r17, r23, 2, true);", // IID431 + "__ ecmovl (Assembler::Condition::overflow, rdx, r16, r29);", // IID432 + "__ ecmovl (Assembler::Condition::overflow, r10, r10, r21);", // IID433 + "__ ecmovl (Assembler::Condition::noOverflow, r17, r29, r18);", // IID434 + "__ ecmovl (Assembler::Condition::noOverflow, r28, r28, r24);", // IID435 + "__ ecmovl (Assembler::Condition::below, r10, r20, r27);", // IID436 + "__ ecmovl (Assembler::Condition::below, r10, r10, r14);", // IID437 + "__ ecmovl (Assembler::Condition::aboveEqual, r11, r27, rcx);", // IID438 + "__ ecmovl (Assembler::Condition::aboveEqual, r22, r22, r15);", // IID439 + "__ ecmovl (Assembler::Condition::zero, r31, r30, r19);", // IID440 + "__ ecmovl (Assembler::Condition::zero, r19, r19, r26);", // IID441 + "__ ecmovl (Assembler::Condition::notZero, r21, r14, r26);", // IID442 + "__ ecmovl (Assembler::Condition::notZero, r20, r20, r15);", // IID443 + "__ ecmovl (Assembler::Condition::belowEqual, r12, r13, r23);", // IID444 + "__ ecmovl (Assembler::Condition::belowEqual, r28, r28, r20);", // IID445 + "__ ecmovl (Assembler::Condition::above, r20, r24, r11);", // IID446 + "__ ecmovl (Assembler::Condition::above, r10, r10, r15);", // IID447 + "__ ecmovl (Assembler::Condition::negative, r19, r20, r23);", // IID448 + "__ ecmovl (Assembler::Condition::negative, r15, r15, r26);", // IID449 + "__ ecmovl (Assembler::Condition::positive, r19, r24, r23);", // IID450 + "__ ecmovl (Assembler::Condition::positive, r28, r28, r11);", // IID451 + "__ ecmovl (Assembler::Condition::parity, r13, r13, rdx);", // IID452 + "__ ecmovl (Assembler::Condition::parity, r31, r31, r23);", // IID453 + "__ ecmovl (Assembler::Condition::noParity, r23, r9, r27);", // IID454 + "__ ecmovl (Assembler::Condition::noParity, r21, r21, r20);", // IID455 + "__ ecmovl (Assembler::Condition::less, r24, r21, r29);", // IID456 + "__ ecmovl (Assembler::Condition::less, rbx, rbx, r11);", // IID457 + "__ ecmovl (Assembler::Condition::greaterEqual, r21, rbx, rcx);", // IID458 + "__ ecmovl (Assembler::Condition::greaterEqual, r31, r31, r21);", // IID459 + "__ ecmovl (Assembler::Condition::lessEqual, r15, r25, r30);", // IID460 + "__ ecmovl (Assembler::Condition::lessEqual, r23, r23, r25);", // IID461 + "__ ecmovl (Assembler::Condition::greater, r18, rcx, r10);", // IID462 + "__ ecmovl (Assembler::Condition::greater, rcx, rcx, r31);", // IID463 + "__ ecmovl (Assembler::Condition::overflow, r21, r19, Address(r26, -0x6e290873));", // IID464 + "__ ecmovl (Assembler::Condition::noOverflow, r24, r19, Address(r22, rcx, (Address::ScaleFactor)0, +0x11f85f9a));", // IID465 + "__ ecmovl (Assembler::Condition::below, r17, r24, Address(r20, +0x534d775e));", // IID466 + "__ ecmovl (Assembler::Condition::aboveEqual, r20, r18, Address(r20, -0x47c94ecd));", // IID467 + "__ ecmovl (Assembler::Condition::zero, r9, r13, Address(r23, -0x4b83c563));", // IID468 + "__ ecmovl (Assembler::Condition::notZero, r11, r25, Address(r24, r14, (Address::ScaleFactor)1, -0x446507af));", // IID469 + "__ ecmovl (Assembler::Condition::belowEqual, r14, r24, Address(r30, r13, (Address::ScaleFactor)2, +0xd0661d));", // IID470 + "__ ecmovl (Assembler::Condition::above, r13, r25, Address(r14, r27, (Address::ScaleFactor)3, +0x47e1403));", // IID471 + "__ ecmovl (Assembler::Condition::negative, r24, r19, Address(rcx, rdx, (Address::ScaleFactor)3, -0x644a5318));", // IID472 + "__ ecmovl (Assembler::Condition::positive, r26, r24, Address(r22, r22, (Address::ScaleFactor)0, +0x70352446));", // IID473 + "__ ecmovl (Assembler::Condition::parity, r19, r26, Address(r8, r30, (Address::ScaleFactor)2, +0x78a12f5c));", // IID474 + "__ ecmovl (Assembler::Condition::noParity, r29, r11, Address(r25, r20, (Address::ScaleFactor)0, +0x27a8303a));", // IID475 + "__ ecmovl (Assembler::Condition::less, r22, r24, Address(r27, r16, (Address::ScaleFactor)1, +0x2541a10));", // IID476 + "__ ecmovl (Assembler::Condition::greaterEqual, r31, r15, Address(r8, r16, (Address::ScaleFactor)3, +0x558e3251));", // IID477 + "__ ecmovl (Assembler::Condition::lessEqual, r27, r18, Address(r8, r10, (Address::ScaleFactor)0, -0x471987b7));", // IID478 + "__ ecmovl (Assembler::Condition::greater, r18, r16, Address(r18, r19, (Address::ScaleFactor)2, -0x120ae81e));", // IID479 + "__ adcq(rbx, r31);", // IID480 + "__ cmpq(r30, r31);", // IID481 + "__ imulq(r29, r28);", // IID482 + "__ popcntq(r25, r10);", // IID483 + "__ sbbq(r24, r20);", // IID484 + "__ subq(r16, rdx);", // IID485 + "__ tzcntq(r26, r28);", // IID486 + "__ lzcntq(r28, r9);", // IID487 + "__ addq(r20, r24);", // IID488 + "__ andq(r24, r29);", // IID489 + "__ orq(r23, r27);", // IID490 + "__ xorq(r15, r12);", // IID491 + "__ movq(r18, r19);", // IID492 + "__ bsfq(r31, rcx);", // IID493 + "__ bsrq(r9, r13);", // IID494 + "__ btq(r20, rcx);", // IID495 + "__ xchgq(r8, r21);", // IID496 + "__ testq(r24, r14);", // IID497 + "__ addq(Address(rcx, r23, (Address::ScaleFactor)2, +0x4ff06c4d), r29);", // IID498 + "__ andq(Address(r24, r10, (Address::ScaleFactor)1, -0x75d9a189), r26);", // IID499 + "__ cmpq(Address(rbx, rbx, (Address::ScaleFactor)0, +0x4033d59c), r17);", // IID500 + "__ orq(Address(r22, r12, (Address::ScaleFactor)3, -0x3893347d), r18);", // IID501 + "__ xorq(Address(r20, r23, (Address::ScaleFactor)3, +0x4b311560), r12);", // IID502 + "__ subq(Address(r10, r28, (Address::ScaleFactor)2, +0x5c3a2657), r29);", // IID503 + "__ movq(Address(r13, r25, (Address::ScaleFactor)3, +0x1a3d6f3f), r22);", // IID504 + "__ xaddq(Address(r17, r24, (Address::ScaleFactor)3, -0x35addbd8), r25);", // IID505 + "__ andq(Address(r25, +0x632184c3), 16777216);", // IID506 + "__ addq(Address(r13, r13, (Address::ScaleFactor)0, -0x3972eac6), 16777216);", // IID507 + "__ cmpq(Address(r9, -0x13b4c806), 4096);", // IID508 + "__ sarq(Address(r31, +0x4fa7f551), 1);", // IID509 + "__ salq(Address(r21, r31, (Address::ScaleFactor)2, +0x31aa8232), 1);", // IID510 + "__ sbbq(Address(r24, r31, (Address::ScaleFactor)2, -0x466538b7), 268435456);", // IID511 + "__ shrq(Address(r28, r22, (Address::ScaleFactor)0, -0x3efe85b1), 2);", // IID512 + "__ subq(Address(r16, -0x1389a3eb), 1048576);", // IID513 + "__ xorq(Address(r29, r8, (Address::ScaleFactor)0, +0x1d022615), 16);", // IID514 + "__ orq(Address(r12, r28, (Address::ScaleFactor)1, -0x34c898e2), 1);", // IID515 + "__ movq(Address(rcx, r24, (Address::ScaleFactor)2, -0x1644eb08), 256);", // IID516 + "__ testq(Address(r29, -0x7d23890b), -65536);", // IID517 + "__ addq(r23, Address(rcx, r19, (Address::ScaleFactor)2, +0x70eac654));", // IID518 + "__ andq(rdx, Address(r24, r15, (Address::ScaleFactor)0, -0x204ddaa9));", // IID519 + "__ cmpq(rdx, Address(r23, r11, (Address::ScaleFactor)3, +0x32c930bd));", // IID520 + "__ lzcntq(r28, Address(rdx, -0x5433c28f));", // IID521 + "__ orq(r22, Address(r19, r14, (Address::ScaleFactor)1, -0x2cc67d38));", // IID522 + "__ adcq(r10, Address(r10, +0x3d7c59f));", // IID523 + "__ imulq(r10, Address(r8, r8, (Address::ScaleFactor)3, -0xe61862d));", // IID524 + "__ popcntq(r23, Address(r29, -0x777ed96d));", // IID525 + "__ sbbq(rcx, Address(rbx, r19, (Address::ScaleFactor)1, +0x53c601cb));", // IID526 + "__ subq(r14, Address(r17, rbx, (Address::ScaleFactor)0, -0x768bf073));", // IID527 + "__ tzcntq(r29, Address(r10, r19, (Address::ScaleFactor)1, +0x30c98d3c));", // IID528 + "__ xorq(r10, Address(r16, r27, (Address::ScaleFactor)0, -0x3d08d602));", // IID529 + "__ movq(r18, Address(r28, r28, (Address::ScaleFactor)3, -0x62fbac91));", // IID530 + "__ leaq(rbx, Address(rcx, +0x450602a5));", // IID531 + "__ cvttsd2siq(r12, Address(r30, r31, (Address::ScaleFactor)0, -0x6798a630));", // IID532 + "__ xchgq(r31, Address(r24, r10, (Address::ScaleFactor)1, -0x706712ed));", // IID533 + "__ testq(r14, Address(r13, r20, (Address::ScaleFactor)3, +0x171081f2));", // IID534 + "__ addq(r31, 16);", // IID535 + "__ andq(r25, 16);", // IID536 + "__ adcq(r23, 256);", // IID537 + "__ cmpq(r19, 268435456);", // IID538 + "__ rclq(r31, 1);", // IID539 + "__ rcrq(r17, 1);", // IID540 + "__ rolq(r25, 2);", // IID541 + "__ rorq(r17, 4);", // IID542 + "__ sarq(r28, 1);", // IID543 + "__ salq(r15, 4);", // IID544 + "__ sbbq(rbx, 65536);", // IID545 + "__ shlq(r21, 1);", // IID546 + "__ shrq(r10, 1);", // IID547 + "__ subq(r14, 16);", // IID548 + "__ xorq(r18, 268435456);", // IID549 + "__ movq(r23, 16);", // IID550 + "__ mov64(r12, 1099511627776);", // IID551 + "__ btq(r14, 4);", // IID552 + "__ testq(r24, -4096);", // IID553 + "__ orq_imm32(r19, 1048576);", // IID554 + "__ subq_imm32(rcx, 268435456);", // IID555 + "__ cmovq(Assembler::Condition::overflow, rdx, Address(r19, rbx, (Address::ScaleFactor)3, +0x211c8c4));", // IID556 + "__ cmovq(Assembler::Condition::noOverflow, rbx, Address(r21, +0x49267743));", // IID557 + "__ cmovq(Assembler::Condition::below, r21, Address(r8, r28, (Address::ScaleFactor)1, -0x4c8c2946));", // IID558 + "__ cmovq(Assembler::Condition::aboveEqual, r12, Address(r26, r20, (Address::ScaleFactor)0, -0x264df89c));", // IID559 + "__ cmovq(Assembler::Condition::zero, r17, Address(r28, r9, (Address::ScaleFactor)2, +0x3497196b));", // IID560 + "__ cmovq(Assembler::Condition::notZero, r13, Address(r15, r23, (Address::ScaleFactor)1, -0x27a30999));", // IID561 + "__ cmovq(Assembler::Condition::belowEqual, r22, Address(r22, +0xf39ab05));", // IID562 + "__ cmovq(Assembler::Condition::above, rcx, Address(r22, r26, (Address::ScaleFactor)3, -0x48c954c));", // IID563 + "__ cmovq(Assembler::Condition::negative, r25, Address(r19, r21, (Address::ScaleFactor)0, +0xe405b0b));", // IID564 + "__ cmovq(Assembler::Condition::positive, r12, Address(r19, r29, (Address::ScaleFactor)3, -0x7762044b));", // IID565 + "__ cmovq(Assembler::Condition::parity, rbx, Address(r30, r10, (Address::ScaleFactor)1, -0x19798323));", // IID566 + "__ cmovq(Assembler::Condition::noParity, r21, Address(r24, r31, (Address::ScaleFactor)0, -0x5731652b));", // IID567 + "__ cmovq(Assembler::Condition::less, r18, Address(r8, r10, (Address::ScaleFactor)1, -0x5613be89));", // IID568 + "__ cmovq(Assembler::Condition::greaterEqual, r28, Address(r21, r21, (Address::ScaleFactor)3, +0x65a0fdc4));", // IID569 + "__ cmovq(Assembler::Condition::lessEqual, r23, Address(r11, r18, (Address::ScaleFactor)0, -0x1d1af10c));", // IID570 + "__ cmovq(Assembler::Condition::greater, r22, Address(r18, r12, (Address::ScaleFactor)1, +0x1a5f1c38));", // IID571 + "__ call(r23);", // IID572 + "__ divq(r30);", // IID573 + "__ idivq(r19);", // IID574 + "__ imulq(r9);", // IID575 + "__ mulq(r13);", // IID576 + "__ negq(r16);", // IID577 + "__ notq(r29);", // IID578 + "__ rolq(rcx);", // IID579 + "__ rorq(r25);", // IID580 + "__ sarq(r8);", // IID581 + "__ salq(r27);", // IID582 + "__ shlq(r30);", // IID583 + "__ shrq(r23);", // IID584 + "__ incrementq(rbx);", // IID585 + "__ decrementq(r14);", // IID586 + "__ pushp(r21);", // IID587 + "__ popp(r21);", // IID588 + "__ call(Address(r20, r21, (Address::ScaleFactor)1, +0x56c6af2f));", // IID589 + "__ mulq(Address(r31, r19, (Address::ScaleFactor)3, -0x1b4eb23));", // IID590 + "__ negq(Address(r27, r27, (Address::ScaleFactor)0, -0x58dbfc1f));", // IID591 + "__ sarq(Address(rbx, r22, (Address::ScaleFactor)2, -0x606349d1));", // IID592 + "__ salq(Address(r26, r23, (Address::ScaleFactor)3, +0xb95a079));", // IID593 + "__ shrq(Address(r14, r26, (Address::ScaleFactor)0, +0x3544e09));", // IID594 + "__ incrementq(Address(r27, rdx, (Address::ScaleFactor)0, +0x120b3250));", // IID595 + "__ decrementq(Address(r9, r25, (Address::ScaleFactor)2, -0x34aaeccb));", // IID596 + "__ imulq(r20, Address(r16, r28, (Address::ScaleFactor)1, -0x59de05a5), 1048576);", // IID597 + "__ imulq(r17, r23, 256);", // IID598 + "__ shldq(r19, r11, 8);", // IID599 + "__ shrdq(r28, r10, 8);", // IID600 + "__ pop2(r29, r26);", // IID601 + "__ pop2p(r22, r10);", // IID602 + "__ push2(r25, r30);", // IID603 + "__ push2p(r28, r15);", // IID604 + "__ movzbq(r11, Address(r29, r19, (Address::ScaleFactor)2, -0x12368d34));", // IID605 + "__ movzwq(r14, Address(r8, r30, (Address::ScaleFactor)2, -0x4a9392de));", // IID606 + "__ movsbq(r28, Address(r23, r15, (Address::ScaleFactor)0, +0x6189cb54));", // IID607 + "__ movswq(r28, Address(rbx, r23, (Address::ScaleFactor)3, -0x2de86561));", // IID608 + "__ movzbq(r11, rcx);", // IID609 + "__ movzwq(r30, r15);", // IID610 + "__ movsbq(r14, rcx);", // IID611 + "__ movswq(r23, r9);", // IID612 + "__ cmpxchgq(r12, Address(r13, r10, (Address::ScaleFactor)1, -0x7c62c3a));", // IID613 + "__ eidivq(rcx, false);", // IID614 + "__ eidivq(r15, true);", // IID615 + "__ edivq(r23, false);", // IID616 + "__ edivq(r24, true);", // IID617 + "__ eimulq(r27, false);", // IID618 + "__ eimulq(r30, true);", // IID619 + "__ emulq(r12, false);", // IID620 + "__ emulq(rcx, true);", // IID621 + "__ emulq(Address(r13, r9, (Address::ScaleFactor)3, -0x226aab94), false);", // IID622 + "__ emulq(Address(r13, r24, (Address::ScaleFactor)3, -0x286c7605), true);", // IID623 + "__ eimulq(r21, r30, false);", // IID624 + "__ eimulq(r17, r17, false);", // IID625 + "__ eimulq(r29, r12, true);", // IID626 + "__ eimulq(r30, r30, true);", // IID627 + "__ elzcntq(r24, r15, false);", // IID628 + "__ elzcntq(r25, r25, false);", // IID629 + "__ elzcntq(r25, r21, true);", // IID630 + "__ elzcntq(r22, r22, true);", // IID631 + "__ enegq(r17, r30, false);", // IID632 + "__ enegq(r17, r17, false);", // IID633 + "__ enegq(r31, r17, true);", // IID634 + "__ enegq(r29, r29, true);", // IID635 + "__ enotq(r10, r9);", // IID636 + "__ enotq(r24, r24);", // IID637 + "__ epopcntq(r28, r15, false);", // IID638 + "__ epopcntq(r10, r10, false);", // IID639 + "__ epopcntq(r27, r30, true);", // IID640 + "__ epopcntq(r28, r28, true);", // IID641 + "__ erolq(r28, r14, false);", // IID642 + "__ erolq(r23, r23, false);", // IID643 + "__ erolq(r23, r24, true);", // IID644 + "__ erolq(r21, r21, true);", // IID645 + "__ erorq(r31, r22, false);", // IID646 + "__ erorq(r28, r28, false);", // IID647 + "__ erorq(r17, r10, true);", // IID648 + "__ erorq(r9, r9, true);", // IID649 + "__ esalq(r29, r30, false);", // IID650 + "__ esalq(r11, r11, false);", // IID651 + "__ esalq(r26, r11, true);", // IID652 + "__ esalq(r16, r16, true);", // IID653 + "__ esarq(rbx, r15, false);", // IID654 + "__ esarq(r14, r14, false);", // IID655 + "__ esarq(r25, r16, true);", // IID656 + "__ esarq(r8, r8, true);", // IID657 + "__ edecq(r11, r13, false);", // IID658 + "__ edecq(rcx, rcx, false);", // IID659 + "__ edecq(r21, r18, true);", // IID660 + "__ edecq(r28, r28, true);", // IID661 + "__ eincq(r16, r16, false);", // IID662 + "__ eincq(r29, r29, false);", // IID663 + "__ eincq(r18, r9, true);", // IID664 + "__ eincq(r19, r19, true);", // IID665 + "__ eshlq(r19, r18, false);", // IID666 + "__ eshlq(r8, r8, false);", // IID667 + "__ eshlq(r12, r15, true);", // IID668 + "__ eshlq(r29, r29, true);", // IID669 + "__ eshrq(r28, r24, false);", // IID670 + "__ eshrq(r19, r19, false);", // IID671 + "__ eshrq(r8, r28, true);", // IID672 + "__ eshrq(r17, r17, true);", // IID673 + "__ etzcntq(r28, r16, false);", // IID674 + "__ etzcntq(r14, r14, false);", // IID675 + "__ etzcntq(r12, r31, true);", // IID676 + "__ etzcntq(r14, r14, true);", // IID677 + "__ eimulq(r31, Address(r13, -0x69c4b352), false);", // IID678 + "__ eimulq(r17, Address(r18, -0x60ab1105), true);", // IID679 + "__ elzcntq(r27, Address(r14, r25, (Address::ScaleFactor)2, +0x2798bf83), false);", // IID680 + "__ elzcntq(r23, Address(r10, r11, (Address::ScaleFactor)0, -0x378e635d), true);", // IID681 + "__ enegq(rcx, Address(r19, r9, (Address::ScaleFactor)3, -0x6847d440), false);", // IID682 + "__ enegq(rcx, Address(rbx, rcx, (Address::ScaleFactor)0, +0x6f92d38d), true);", // IID683 + "__ epopcntq(r20, Address(r12, -0x2a8b27d6), false);", // IID684 + "__ epopcntq(r31, Address(r30, +0x4603f6d0), true);", // IID685 + "__ esalq(rbx, Address(r24, +0x567d06f9), false);", // IID686 + "__ esalq(r12, Address(r24, r28, (Address::ScaleFactor)0, -0x1c4c584e), true);", // IID687 + "__ esarq(r12, Address(r23, r24, (Address::ScaleFactor)2, -0x3157bcba), false);", // IID688 + "__ esarq(r8, Address(r14, r24, (Address::ScaleFactor)2, -0x714290a5), true);", // IID689 + "__ edecq(r23, Address(r8, r15, (Address::ScaleFactor)1, -0x5ae272dd), false);", // IID690 + "__ edecq(r13, Address(r29, r9, (Address::ScaleFactor)3, -0x5b5174a9), true);", // IID691 + "__ eincq(r11, Address(r21, r31, (Address::ScaleFactor)3, -0x2176b4dc), false);", // IID692 + "__ eincq(r13, Address(rcx, r16, (Address::ScaleFactor)0, -0x36b448c9), true);", // IID693 + "__ eshrq(r26, Address(r25, rcx, (Address::ScaleFactor)2, -0x5f894993), false);", // IID694 + "__ eshrq(r25, Address(r9, +0x51798d21), true);", // IID695 + "__ etzcntq(r28, Address(r13, r26, (Address::ScaleFactor)2, +0x207196f6), false);", // IID696 + "__ etzcntq(rbx, Address(r19, r13, (Address::ScaleFactor)0, -0x24d937d5), true);", // IID697 + "__ eaddq(r17, Address(r30, +0x3935ccff), r31, false);", // IID698 + "__ eaddq(r14, Address(r27, r10, (Address::ScaleFactor)2, -0x34ad9bab), r14, false);", // IID699 + "__ eaddq(r18, Address(r20, r23, (Address::ScaleFactor)0, +0x5ad3ed4b), r30, true);", // IID700 + "__ eaddq(r20, Address(rdx, -0x322a99e5), r20, true);", // IID701 + "__ eandq(r31, Address(rbx, r27, (Address::ScaleFactor)3, +0x4ce247d2), r17, false);", // IID702 + "__ eandq(r30, Address(r18, r19, (Address::ScaleFactor)1, -0x4ee3d14), r30, false);", // IID703 + "__ eandq(r28, Address(r11, rbx, (Address::ScaleFactor)3, -0x28994bbf), r24, true);", // IID704 + "__ eandq(r30, Address(r22, +0x7d21c24), r30, true);", // IID705 + "__ eorq(r26, Address(r15, r19, (Address::ScaleFactor)3, +0x58c21792), r20, false);", // IID706 + "__ eorq(r13, Address(r10, r27, (Address::ScaleFactor)2, -0x2c70d333), r13, false);", // IID707 + "__ eorq(rbx, Address(r12, rbx, (Address::ScaleFactor)0, -0x1fb0f1bc), r26, true);", // IID708 + "__ eorq(r31, Address(r27, r31, (Address::ScaleFactor)1, +0x28d1756), r31, true);", // IID709 + "__ esubq(r24, Address(r28, r23, (Address::ScaleFactor)1, +0x6980f610), r27, false);", // IID710 + "__ esubq(r15, Address(r11, r30, (Address::ScaleFactor)3, -0x49777e7), r15, false);", // IID711 + "__ esubq(r17, Address(r25, r13, (Address::ScaleFactor)2, +0x31619e46), r31, true);", // IID712 + "__ esubq(r18, Address(r11, r10, (Address::ScaleFactor)2, +0x1922861a), r18, true);", // IID713 + "__ exorq(rbx, Address(r11, -0x4716d420), r21, false);", // IID714 + "__ exorq(r8, Address(rdx, r9, (Address::ScaleFactor)2, -0x4cfe39c), r8, false);", // IID715 + "__ exorq(r16, Address(r14, r27, (Address::ScaleFactor)0, +0x7c6654d9), r25, true);", // IID716 + "__ exorq(r29, Address(r15, -0x5efab479), r29, true);", // IID717 + "__ eaddq(r19, Address(r13, r22, (Address::ScaleFactor)2, +0x68b64559), 16777216, false);", // IID718 + "__ eaddq(r16, Address(r13, r31, (Address::ScaleFactor)3, -0x65143af5), 1, true);", // IID719 + "__ eandq(r31, Address(r24, r13, (Address::ScaleFactor)1, -0x25b16a0e), 1, false);", // IID720 + "__ eandq(r11, Address(r28, -0xf6d4b26), 65536, true);", // IID721 + "__ eimulq(rcx, Address(r18, r10, (Address::ScaleFactor)0, +0x46ec6da1), 16777216, false);", // IID722 + "__ eimulq(r15, Address(r9, r10, (Address::ScaleFactor)3, -0x7fc36af3), 16, true);", // IID723 + "__ eorq(r17, Address(r27, r30, (Address::ScaleFactor)0, +0x1b4cda2c), 1, false);", // IID724 + "__ eorq(rdx, Address(r25, r14, (Address::ScaleFactor)2, -0x59aa6b85), 4096, true);", // IID725 + "__ esalq(r17, Address(r26, r21, (Address::ScaleFactor)1, -0x6ab1f15f), 8, false);", // IID726 + "__ esalq(r12, Address(r22, r17, (Address::ScaleFactor)0, -0x43ac14ab), 2, true);", // IID727 + "__ esarq(r29, Address(r18, r16, (Address::ScaleFactor)0, -0x59dc0c61), 4, false);", // IID728 + "__ esarq(r16, Address(r11, -0x7bdd314), 4, true);", // IID729 + "__ eshrq(r26, Address(r23, r27, (Address::ScaleFactor)3, -0x55b92314), 16, false);", // IID730 + "__ eshrq(r23, Address(r16, r29, (Address::ScaleFactor)1, +0x71311a1d), 2, true);", // IID731 + "__ esubq(r25, Address(r9, -0x9532bac), 1048576, false);", // IID732 + "__ esubq(r17, Address(r8, r23, (Address::ScaleFactor)0, +0x55d06ca2), 1048576, true);", // IID733 + "__ exorq(r29, Address(r9, r24, (Address::ScaleFactor)0, -0x2c141c1), 1048576, false);", // IID734 + "__ exorq(r28, Address(r22, r19, (Address::ScaleFactor)1, -0x2d9d9abd), 16, true);", // IID735 + "__ eaddq(r22, r14, 16, false);", // IID736 + "__ eaddq(rax, r12, 16, false);", // IID737 + "__ eaddq(r24, r24, 65536, false);", // IID738 + "__ eaddq(r21, rbx, 65536, true);", // IID739 + "__ eaddq(rax, rbx, 65536, true);", // IID740 + "__ eaddq(r24, r24, 65536, true);", // IID741 + "__ eandq(r21, r27, 16777216, false);", // IID742 + "__ eandq(rax, r27, 16777216, false);", // IID743 + "__ eandq(r24, r24, 65536, false);", // IID744 + "__ eandq(r13, r31, 1048576, true);", // IID745 + "__ eandq(rax, r21, 1048576, true);", // IID746 + "__ eandq(r30, r30, 1048576, true);", // IID747 + "__ eimulq(r8, r13, 268435456, false);", // IID748 + "__ eimulq(rax, r31, 268435456, false);", // IID749 + "__ eimulq(r13, r13, 65536, false);", // IID750 + "__ eimulq(r14, r29, 1048576, true);", // IID751 + "__ eimulq(rax, r22, 1048576, true);", // IID752 + "__ eimulq(r8, r8, 268435456, true);", // IID753 + "__ eorq(r30, r15, 4096, false);", // IID754 + "__ eorq(rax, r28, 4096, false);", // IID755 + "__ eorq(r26, r26, 1048576, false);", // IID756 + "__ eorq(r16, r12, 268435456, true);", // IID757 + "__ eorq(rax, r9, 268435456, true);", // IID758 + "__ eorq(r23, r23, 256, true);", // IID759 + "__ erclq(r15, r9, 16);", // IID760 + "__ erclq(rax, r8, 16);", // IID761 + "__ erclq(r25, r25, 1);", // IID762 + "__ erolq(r9, r17, 16, false);", // IID763 + "__ erolq(rax, r20, 16, false);", // IID764 + "__ erolq(r27, r27, 1, false);", // IID765 + "__ erolq(r20, r31, 1, true);", // IID766 + "__ erolq(rax, r18, 1, true);", // IID767 + "__ erolq(r28, r28, 16, true);", // IID768 + "__ erorq(r26, r18, 16, false);", // IID769 + "__ erorq(rax, r24, 16, false);", // IID770 + "__ erorq(r22, r22, 16, false);", // IID771 + "__ erorq(r27, r29, 1, true);", // IID772 + "__ erorq(rax, r18, 1, true);", // IID773 + "__ erorq(r21, r21, 1, true);", // IID774 + "__ esalq(r12, rcx, 2, false);", // IID775 + "__ esalq(rax, r24, 2, false);", // IID776 + "__ esalq(r22, r22, 8, false);", // IID777 + "__ esalq(r17, r23, 8, true);", // IID778 + "__ esalq(rax, r27, 8, true);", // IID779 + "__ esalq(r23, r23, 1, true);", // IID780 + "__ esarq(r8, r25, 16, false);", // IID781 + "__ esarq(rax, r23, 16, false);", // IID782 + "__ esarq(r9, r9, 4, false);", // IID783 + "__ esarq(r22, r13, 1, true);", // IID784 + "__ esarq(rax, r11, 1, true);", // IID785 + "__ esarq(r12, r12, 2, true);", // IID786 + "__ eshlq(rcx, r30, 8, false);", // IID787 + "__ eshlq(rax, r19, 8, false);", // IID788 + "__ eshlq(r13, r13, 2, false);", // IID789 + "__ eshlq(r18, r11, 8, true);", // IID790 + "__ eshlq(rax, r9, 8, true);", // IID791 + "__ eshlq(rcx, rcx, 16, true);", // IID792 + "__ eshrq(r10, r22, 4, false);", // IID793 + "__ eshrq(rax, r9, 4, false);", // IID794 + "__ eshrq(r12, r12, 2, false);", // IID795 + "__ eshrq(r26, r31, 8, true);", // IID796 + "__ eshrq(rax, r12, 8, true);", // IID797 + "__ eshrq(r28, r28, 1, true);", // IID798 + "__ esubq(r15, r30, 65536, false);", // IID799 + "__ esubq(rax, rcx, 65536, false);", // IID800 + "__ esubq(r26, r26, 16, false);", // IID801 + "__ esubq(r12, r14, 1, true);", // IID802 + "__ esubq(rax, r21, 1, true);", // IID803 + "__ esubq(r20, r20, 1048576, true);", // IID804 + "__ exorq(r11, rbx, 16777216, false);", // IID805 + "__ exorq(rax, r23, 16777216, false);", // IID806 + "__ exorq(r31, r31, 268435456, false);", // IID807 + "__ exorq(r29, r28, 4096, true);", // IID808 + "__ exorq(rax, r19, 4096, true);", // IID809 + "__ exorq(rdx, rdx, 268435456, true);", // IID810 + "__ eorq_imm32(rdx, rdx, 1048576, false);", // IID811 + "__ eorq_imm32(rax, r22, 1048576, false);", // IID812 + "__ eorq_imm32(r29, r29, 1048576, false);", // IID813 + "__ eorq_imm32(r17, rcx, 4194304, false);", // IID814 + "__ eorq_imm32(rax, r25, 4194304, false);", // IID815 + "__ eorq_imm32(r27, r27, 1073741824, false);", // IID816 + "__ esubq_imm32(r16, r19, 4194304, false);", // IID817 + "__ esubq_imm32(rax, r31, 4194304, false);", // IID818 + "__ esubq_imm32(r26, r26, 262144, false);", // IID819 + "__ esubq_imm32(r17, r22, 1073741824, true);", // IID820 + "__ esubq_imm32(rax, r18, 1073741824, true);", // IID821 + "__ esubq_imm32(r23, r23, 268435456, true);", // IID822 + "__ eaddq(r13, r30, Address(r24, r19, (Address::ScaleFactor)1, +0x56ea3a3b), false);", // IID823 + "__ eaddq(r29, r15, Address(r26, r27, (Address::ScaleFactor)3, -0x4b113958), true);", // IID824 + "__ eandq(r12, r30, Address(r31, -0x46103c74), false);", // IID825 + "__ eandq(r27, r10, Address(r22, r25, (Address::ScaleFactor)1, +0x6a1ebee5), true);", // IID826 + "__ eorq(r30, r26, Address(r11, r18, (Address::ScaleFactor)2, -0x2b9fff29), false);", // IID827 + "__ eorq(r9, r12, Address(r18, r17, (Address::ScaleFactor)0, +0xb4859f6), true);", // IID828 + "__ eimulq(rdx, r17, Address(r24, rdx, (Address::ScaleFactor)2, +0x3d284cd8), false);", // IID829 + "__ eimulq(r29, r26, Address(r30, r12, (Address::ScaleFactor)1, +0x6e813124), true);", // IID830 + "__ esubq(rbx, r13, Address(r22, -0x702a289e), false);", // IID831 + "__ esubq(r23, r29, Address(r25, rdx, (Address::ScaleFactor)0, -0x6252a7ed), true);", // IID832 + "__ exorq(r8, r18, Address(r19, r14, (Address::ScaleFactor)2, -0xebfa697), false);", // IID833 + "__ exorq(r10, r28, Address(r26, +0x168381ca), true);", // IID834 + "__ eaddq(rcx, r18, r8, false);", // IID835 + "__ eaddq(rcx, rcx, r14, false);", // IID836 + "__ eaddq(r23, r10, r16, true);", // IID837 + "__ eaddq(r11, r11, r24, true);", // IID838 + "__ eadcxq(r9, r18, rdx);", // IID839 + "__ eadcxq(r8, r8, r15);", // IID840 + "__ eadoxq(r15, r22, r26);", // IID841 + "__ eadoxq(r11, r11, rdx);", // IID842 + "__ eandq(r19, rdx, r22, false);", // IID843 + "__ eandq(r29, r29, r17, false);", // IID844 + "__ eandq(r23, r27, r15, true);", // IID845 + "__ eandq(r9, r9, r13, true);", // IID846 + "__ eimulq(r18, r15, r16, false);", // IID847 + "__ eimulq(rcx, rcx, r17, false);", // IID848 + "__ eimulq(r23, r12, r20, true);", // IID849 + "__ eimulq(r10, r10, r9, true);", // IID850 + "__ eorq(rdx, r19, r14, false);", // IID851 + "__ eorq(rcx, rcx, r13, false);", // IID852 + "__ eorq(r9, r25, r29, true);", // IID853 + "__ eorq(rdx, rdx, r25, true);", // IID854 + "__ esubq(r23, r8, r16, false);", // IID855 + "__ esubq(r13, r13, r13, false);", // IID856 + "__ esubq(r19, r12, r15, true);", // IID857 + "__ esubq(r9, r9, rdx, true);", // IID858 + "__ exorq(r13, r16, r31, false);", // IID859 + "__ exorq(r17, r17, r30, false);", // IID860 + "__ exorq(r19, r30, r20, true);", // IID861 + "__ exorq(r31, r31, r13, true);", // IID862 + "__ eshldq(r22, r10, r13, 4, false);", // IID863 + "__ eshldq(r24, r24, r21, 16, false);", // IID864 + "__ eshldq(r20, r13, r27, 16, true);", // IID865 + "__ eshldq(r31, r31, r19, 2, true);", // IID866 + "__ eshrdq(r30, r20, r11, 8, false);", // IID867 + "__ eshrdq(rdx, rdx, r15, 1, false);", // IID868 + "__ eshrdq(r28, r30, r14, 2, true);", // IID869 + "__ eshrdq(r20, r20, r16, 1, true);", // IID870 + "__ ecmovq (Assembler::Condition::overflow, r21, r17, r28);", // IID871 + "__ ecmovq (Assembler::Condition::overflow, r15, r15, r30);", // IID872 + "__ ecmovq (Assembler::Condition::noOverflow, rcx, r15, r15);", // IID873 + "__ ecmovq (Assembler::Condition::noOverflow, rcx, rcx, r13);", // IID874 + "__ ecmovq (Assembler::Condition::below, rdx, r26, r26);", // IID875 + "__ ecmovq (Assembler::Condition::below, r28, r28, r15);", // IID876 + "__ ecmovq (Assembler::Condition::aboveEqual, r8, rdx, rcx);", // IID877 + "__ ecmovq (Assembler::Condition::aboveEqual, rcx, rcx, rcx);", // IID878 + "__ ecmovq (Assembler::Condition::zero, r10, r13, r9);", // IID879 + "__ ecmovq (Assembler::Condition::zero, r14, r14, r27);", // IID880 + "__ ecmovq (Assembler::Condition::notZero, r11, r23, r9);", // IID881 + "__ ecmovq (Assembler::Condition::notZero, r11, r11, rdx);", // IID882 + "__ ecmovq (Assembler::Condition::belowEqual, r31, r14, r25);", // IID883 + "__ ecmovq (Assembler::Condition::belowEqual, r20, r20, r12);", // IID884 + "__ ecmovq (Assembler::Condition::above, rdx, r10, r28);", // IID885 + "__ ecmovq (Assembler::Condition::above, r8, r8, r17);", // IID886 + "__ ecmovq (Assembler::Condition::negative, rcx, r30, r23);", // IID887 + "__ ecmovq (Assembler::Condition::negative, r26, r26, r18);", // IID888 + "__ ecmovq (Assembler::Condition::positive, rdx, rbx, r18);", // IID889 + "__ ecmovq (Assembler::Condition::positive, r21, r21, r13);", // IID890 + "__ ecmovq (Assembler::Condition::parity, r27, r28, r27);", // IID891 + "__ ecmovq (Assembler::Condition::parity, r11, r11, r30);", // IID892 + "__ ecmovq (Assembler::Condition::noParity, rcx, r21, r18);", // IID893 + "__ ecmovq (Assembler::Condition::noParity, rcx, rcx, r29);", // IID894 + "__ ecmovq (Assembler::Condition::less, rdx, r21, r12);", // IID895 + "__ ecmovq (Assembler::Condition::less, rdx, rdx, r26);", // IID896 + "__ ecmovq (Assembler::Condition::greaterEqual, r17, rbx, r22);", // IID897 + "__ ecmovq (Assembler::Condition::greaterEqual, rdx, rdx, r11);", // IID898 + "__ ecmovq (Assembler::Condition::lessEqual, rdx, r14, r8);", // IID899 + "__ ecmovq (Assembler::Condition::lessEqual, r14, r14, r8);", // IID900 + "__ ecmovq (Assembler::Condition::greater, r25, r29, r21);", // IID901 + "__ ecmovq (Assembler::Condition::greater, r26, r26, r30);", // IID902 + "__ ecmovq (Assembler::Condition::overflow, r24, r21, Address(r13, r11, (Address::ScaleFactor)1, +0x439c521e));", // IID903 + "__ ecmovq (Assembler::Condition::noOverflow, r11, r18, Address(r29, r16, (Address::ScaleFactor)0, +0x632127f));", // IID904 + "__ ecmovq (Assembler::Condition::below, r16, r8, Address(r8, r26, (Address::ScaleFactor)1, +0x10633def));", // IID905 + "__ ecmovq (Assembler::Condition::aboveEqual, r13, r14, Address(r18, -0x54f69e38));", // IID906 + "__ ecmovq (Assembler::Condition::zero, r12, r8, Address(r31, r26, (Address::ScaleFactor)1, -0x7a1e447a));", // IID907 + "__ ecmovq (Assembler::Condition::notZero, r29, r29, Address(r19, r11, (Address::ScaleFactor)2, -0x35d82dd2));", // IID908 + "__ ecmovq (Assembler::Condition::belowEqual, rcx, r18, Address(r25, r28, (Address::ScaleFactor)0, +0x30be64a0));", // IID909 + "__ ecmovq (Assembler::Condition::above, r28, r12, Address(r10, r16, (Address::ScaleFactor)1, -0x22b8fefa));", // IID910 + "__ ecmovq (Assembler::Condition::negative, r11, r8, Address(rbx, r11, (Address::ScaleFactor)3, +0x25cc9e96));", // IID911 + "__ ecmovq (Assembler::Condition::positive, r12, r27, Address(r11, -0xc2d70fe));", // IID912 + "__ ecmovq (Assembler::Condition::parity, r8, r26, Address(r19, rbx, (Address::ScaleFactor)1, -0x486db7ea));", // IID913 + "__ ecmovq (Assembler::Condition::noParity, r30, r10, Address(r14, r18, (Address::ScaleFactor)3, +0x14884884));", // IID914 + "__ ecmovq (Assembler::Condition::less, r27, r8, Address(r29, r14, (Address::ScaleFactor)2, +0x92b7a8));", // IID915 + "__ ecmovq (Assembler::Condition::greaterEqual, r14, r28, Address(r19, rdx, (Address::ScaleFactor)0, +0x9c2d45));", // IID916 + "__ ecmovq (Assembler::Condition::lessEqual, r25, r8, Address(rcx, r18, (Address::ScaleFactor)2, +0x6655c86b));", // IID917 + "__ ecmovq (Assembler::Condition::greater, r19, r21, Address(r10, r25, (Address::ScaleFactor)0, -0x1005430b));", // IID918 #endif // _LP64 }; // END Generated code -- do not edit diff --git a/test/hotspot/gtest/x86/test_assembler_x86.cpp b/test/hotspot/gtest/x86/test_assembler_x86.cpp index 32315e06fde..1382d0c243f 100644 --- a/test/hotspot/gtest/x86/test_assembler_x86.cpp +++ b/test/hotspot/gtest/x86/test_assembler_x86.cpp @@ -71,7 +71,7 @@ TEST_VM(AssemblerX86, validate) { VM_Version::set_evex_cpuFeatures(); VM_Version::set_avx_cpuFeatures(); VM_Version::set_apx_cpuFeatures(); - BufferBlob* b = BufferBlob::create("x64Test", 500000); + BufferBlob* b = BufferBlob::create("x64Test", 5000000); CodeBuffer code(b); MacroAssembler _masm(&code); address entry = __ pc(); diff --git a/test/hotspot/gtest/x86/x86-asmtest.py b/test/hotspot/gtest/x86/x86-asmtest.py index 51932988fb2..7081c64e604 100644 --- a/test/hotspot/gtest/x86/x86-asmtest.py +++ b/test/hotspot/gtest/x86/x86-asmtest.py @@ -30,6 +30,7 @@ OBJDUMP = "objdump" X86_AS = "as" X86_OBJCOPY = "objcopy" SEED = 1327 +TEST_DEMOTION = True random.seed(SEED) @@ -301,12 +302,18 @@ class CondRegRegRegInstruction(Instruction): self.reg3 = Register().generate(reg3, width) self.cond = cond self.generate_operands(self.reg1, self.reg2, self.reg3) + self.demote = True def cstr(self): return f'__ {self._name} (' + 'Assembler::Condition::' + self.cond + ', ' + ', '.join([reg.cstr() for reg in self.operands]) + ');' def astr(self): - return f'{self._aname}' + cond_to_suffix[self.cond] + ' ' + ', '.join([reg.astr() for reg in self.operands]) + operands = self.operands + if self.demote: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1]: + operands = operands[1:] + return f'{self._aname}' + cond_to_suffix[self.cond] + ' ' + ', '.join([reg.astr() for reg in operands]) class CondRegRegMemInstruction(Instruction): def __init__(self, name, aname, width, cond, reg1, reg2, mem_base, mem_idx): @@ -316,12 +323,18 @@ class CondRegRegMemInstruction(Instruction): self.mem = Address().generate(mem_base, mem_idx, width) self.cond = cond self.generate_operands(self.reg1, self.reg2, self.mem) + self.demote = True def cstr(self): return f'__ {self._name} (' + 'Assembler::Condition::' + self.cond + ', ' + ', '.join([reg.cstr() for reg in self.operands]) + ');' def astr(self): - return f'{self._aname}' + cond_to_suffix[self.cond] + ' ' + ', '.join([reg.astr() for reg in self.operands]) + operands = self.operands + if self.demote: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1]: + operands = operands[1:] + return f'{self._aname}' + cond_to_suffix[self.cond] + ' ' + ', '.join([reg.astr() for reg in operands]) class MoveRegMemInstruction(Instruction): def __init__(self, name, aname, width, mem_width, reg, mem_base, mem_idx): @@ -355,6 +368,15 @@ class RegRegNddInstruction(NFInstruction): self.reg1 = Register().generate(reg1, width) self.reg2 = Register().generate(reg2, width) self.generate_operands(self.reg1, self.reg2) + self.demote = True + + def astr(self): + if self.demote and self._aname not in ['popcnt', 'lzcnt', 'tzcnt']: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1] and (not self.no_flag): + cl_str = (', cl' if self._name in shift_rot_ops and len(self.operands) == 2 else '') + return f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]]) + cl_str + return super().astr() class RegMemNddInstruction(NFInstruction): def __init__(self, name, aname, width, no_flag, reg, mem_base, mem_idx): @@ -386,6 +408,14 @@ class RegRegImmNddInstruction(NFInstruction): self.reg2 = Register().generate(reg2, width) self.imm = Immediate().generate(imm) self.generate_operands(self.reg1, self.reg2, self.imm) + self.demote = True + + def astr(self): + if self.demote and self._aname not in ['imul']: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1] and (not self.no_flag): + return f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]]) + return super().astr() class RegRegMemNddInstruction(NFInstruction): def __init__(self, name, aname, width, no_flag, reg1, reg2, mem_base, mem_idx): @@ -394,6 +424,14 @@ class RegRegMemNddInstruction(NFInstruction): self.reg2 = Register().generate(reg2, width) self.mem = Address().generate(mem_base, mem_idx, width) self.generate_operands(self.reg1, self.reg2, self.mem) + self.demote = True + + def astr(self): + if self.demote: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1] and (not self.no_flag): + return f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]]) + return super().astr() class RegRegRegNddInstruction(NFInstruction): def __init__(self, name, aname, width, no_flag, reg1, reg2, reg3): @@ -402,9 +440,15 @@ class RegRegRegNddInstruction(NFInstruction): self.reg2 = Register().generate(reg2, width) self.reg3 = Register().generate(reg3, width) self.generate_operands(self.reg1, self.reg2, self.reg3) + self.demote = True def astr(self): - return f'{{load}}' + super().astr() + hdr = f'{{load}}' + if self.demote: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1] and (not self.no_flag): + return hdr + f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]]) + return hdr + super().astr() class RegRegRegImmNddInstruction(NFInstruction): def __init__(self, name, aname, width, no_flag, reg1, reg2, reg3, imm): @@ -414,6 +458,15 @@ class RegRegRegImmNddInstruction(NFInstruction): self.reg3 = Register().generate(reg3, width) self.imm = Immediate().generate(imm) self.generate_operands(self.reg1, self.reg2, self.reg3, self.imm) + self.demote = True + + def astr(self): + if self.demote: + ops = [op.cstr() for op in self.operands] + if ops[0] == ops[1] and (not self.no_flag): + return (f'{self._aname} ' + ', '.join([op.astr() for op in self.operands[1:]])) + return super().astr() + test_regs = [key for key in registers_mapping.keys() if key != 'rax'] @@ -499,36 +552,28 @@ def generate(RegOp, ops, print_lp64_flag=True, full_set=False): print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [TwoRegInstruction, MoveRegRegInstruction, RegRegNddInstruction]: - if full_set: - for i in range(len(test_regs)): - test_reg1 = test_regs[i] - test_reg2 = test_regs[(i + 1) % len(test_regs)] + demote_options = [False, True] if TEST_DEMOTION and RegOp in [RegRegNddInstruction] else [False] + for demote in demote_options: + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_reg2 = test_reg1 if demote \ + else test_regs[(i + 1) % len(test_regs)] if full_set \ + else random.choice(test_regs) lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2) print_instruction(instr, lp64_flag, print_lp64_flag) - else: - test_reg1 = random.choice(test_regs) - test_reg2 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) - instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2) - print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [RegRegRegNddInstruction, CondRegRegRegInstruction]: - if full_set: - for i in range(len(test_regs)): - test_reg1 = test_regs[i] - test_reg2 = test_regs[(i + 1) % len(test_regs)] - test_reg3 = test_regs[(i + 2) % len(test_regs)] + for demote in [False, True] if TEST_DEMOTION else [False]: + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_reg2 = test_reg1 if demote \ + else test_regs[(i + 1) % len(test_regs)] if full_set \ + else random.choice(test_regs) + test_reg3 = test_regs[(i + 2) % len(test_regs)] if full_set else random.choice(test_regs) lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3) print_instruction(instr, lp64_flag, print_lp64_flag) - else: - test_reg1 = random.choice(test_regs) - test_reg2 = random.choice(test_regs) - test_reg3 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) - instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3) - print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [MemRegInstruction, RegMemInstruction, MoveRegMemInstruction, CmpxchgInstruction, CondRegMemInstruction, RegMemNddInstruction]: if full_set: @@ -607,30 +652,28 @@ def generate(RegOp, ops, print_lp64_flag=True, full_set=False): print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [RegRegImmInstruction, RegRegImmNddInstruction]: - if full_set: + demote_options = [False, True] if TEST_DEMOTION and RegOp in [RegRegImmNddInstruction] else [False] + for demote in demote_options: imm_list = get_immediate_list(op_name, width) - for i in range(len(test_regs)): - test_reg1 = test_regs[i] - test_reg2 = test_regs[(i + 1) % len(test_regs)] + if not full_set: + imm_list = [random.choice(imm_list)] + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_reg2 = test_reg1 if demote \ + else test_regs[(i + 1) % len(test_regs)] if full_set \ + else random.choice(test_regs) lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) for imm in imm_list: instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, imm=imm) print_instruction(instr, lp64_flag, print_lp64_flag) - else: - imm = random.choice(get_immediate_list(op_name, width)) - test_reg1 = random.choice(test_regs) - test_reg2 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) - instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, imm=imm) - print_instruction(instr, lp64_flag, print_lp64_flag) - # additional tests with rax as destination - if RegOp in [RegRegImmNddInstruction]: - test_reg1 = 'rax' - test_reg2 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) - instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, imm=imm) - print_instruction(instr, lp64_flag, print_lp64_flag) + # additional tests with rax as destination + if RegOp in [RegRegImmNddInstruction] and not demote and not full_set: + test_reg1 = 'rax' + test_reg2 = random.choice(test_regs) + lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2) + instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, imm=imm) + print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [RegMemImmInstruction, RegMemImmNddInstruction]: if full_set: @@ -656,46 +699,37 @@ def generate(RegOp, ops, print_lp64_flag=True, full_set=False): print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [RegMemRegNddInstruction, RegRegMemNddInstruction, CondRegRegMemInstruction]: - if full_set: - for i in range(len(test_regs)): - test_reg1 = test_regs[i] - test_mem_base = test_regs[(i + 1) % len(test_regs)] - test_mem_idx = test_regs[(i + 2) % len(test_regs)] - test_reg2 = test_regs[(i + 3) % len(test_regs)] + demote_options = [False] if TEST_DEMOTION and RegOp not in [RegMemRegNddInstruction] else [False, True] + for demote in demote_options: + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_mem_base = test_regs[(i + 1) % len(test_regs)] if full_set else random.choice(test_regs) + test_mem_idx = test_regs[(i + 2) % len(test_regs)] if full_set \ + else random.choice([reg for reg in test_regs if reg != 'rsp']) + test_reg2 = test_reg1 if demote \ + else test_regs[(i + 3) % len(test_regs)] if full_set \ + else random.choice(test_regs) if test_mem_idx == 'rsp': continue lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_mem_base, test_mem_idx, test_reg2) instr = RegOp(*op, reg1=test_reg1, mem_base=test_mem_base, mem_idx=test_mem_idx, reg2=test_reg2) print_instruction(instr, lp64_flag, print_lp64_flag) - else: - filtered_regs = [reg for reg in test_regs if reg != 'rsp'] - test_reg1 = random.choice(test_regs) - test_mem_base = random.choice(test_regs) - test_mem_idx = random.choice(filtered_regs) - test_reg2 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_mem_base, test_mem_idx, test_reg2) - instr = RegOp(*op, reg1=test_reg1, mem_base=test_mem_base, mem_idx=test_mem_idx, reg2=test_reg2) - print_instruction(instr, lp64_flag, print_lp64_flag) - + elif RegOp in [RegRegRegImmNddInstruction]: - if full_set: + for demote in [False, True] if TEST_DEMOTION else [False]: imm_list = get_immediate_list(op_name, width) - for i in range(len(test_regs)): - test_reg1 = test_regs[i] - test_reg2 = test_regs[(i + 1) % len(test_regs)] - test_reg3 = test_regs[(i + 2) % len(test_regs)] + if not full_set: + imm_list = [random.choice(imm_list)] + for i in range(len(test_regs) if full_set else 1): + test_reg1 = test_regs[i] if full_set else random.choice(test_regs) + test_reg2 = test_reg1 if demote \ + else test_regs[(i + 1) % len(test_regs)] if full_set \ + else random.choice(test_regs) + test_reg3 = test_regs[(i + 2) % len(test_regs)] if full_set else random.choice(test_regs) lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) for imm in imm_list: instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3, imm=imm) print_instruction(instr, lp64_flag, print_lp64_flag) - else: - imm = random.choice(get_immediate_list(op_name, width)) - test_reg1 = random.choice(test_regs) - test_reg2 = random.choice(test_regs) - test_reg3 = random.choice(test_regs) - lp64_flag = handle_lp64_flag(lp64_flag, print_lp64_flag, test_reg1, test_reg2, test_reg3) - instr = RegOp(*op, reg1=test_reg1, reg2=test_reg2, reg3=test_reg3, imm=imm) - print_instruction(instr, lp64_flag, print_lp64_flag) elif RegOp in [Push2Instruction, Pop2Instruction]: if full_set: @@ -936,7 +970,7 @@ instruction_set = { ('edecl', 'dec', 32, False), ('edecl', 'dec', 32, True), ('eincl', 'inc', 32, False), - ('eincl', 'inc', 32, True), + ('eincl', 'inc', 32, True), ('eshll', 'shl', 32, False), ('eshll', 'shl', 32, True), ('eshrl', 'shr', 32, False), @@ -1357,8 +1391,8 @@ instruction_set64 = { ('exorq', 'xor', 64, True), ('eorq_imm32', 'or', 64, False), ('eorq_imm32', 'or', 64, False), - ('esubq_imm32', 'sub', 64, False), - ('esubq_imm32', 'sub', 64, True), + ('esubq_imm32', 'sub', 64, False), + ('esubq_imm32', 'sub', 64, True), ], RegRegMemNddInstruction: [ ('eaddq', 'add', 64, False), @@ -1422,7 +1456,7 @@ if __name__ == "__main__": for RegOp, ops in instruction_set.items(): generate(RegOp, ops, True, full_set) - + if lp64_flag: lp64_flag = False print("#endif // _LP64") From 59dc849909c1edc892c94a27b0340fcf53db3a98 Mon Sep 17 00:00:00 2001 From: Ashutosh Mehra Date: Sun, 1 Jun 2025 01:04:54 +0000 Subject: [PATCH 048/216] 8358230: Incorrect location for the assert for blob != nullptr in CodeBlob::create Reviewed-by: kvn --- src/hotspot/share/code/codeBlob.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index da0408d1270..185b6c06598 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -301,6 +301,8 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, name, archived_reloc_data, archived_oop_maps); + assert(blob != nullptr, "sanity check"); + #ifndef PRODUCT blob->use_remarks(archived_asm_remarks); archived_asm_remarks.clear(); @@ -308,7 +310,6 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, archived_dbg_strings.clear(); #endif // PRODUCT - assert(blob != nullptr, "sanity check"); // Flush the code block ICache::invalidate_range(blob->code_begin(), blob->code_size()); CodeCache::commit(blob); // Count adapters From 470ffeedda45b6f75ce0c794a965428b7859be6f Mon Sep 17 00:00:00 2001 From: Mikhail Yankelevich Date: Sun, 1 Jun 2025 03:50:39 +0000 Subject: [PATCH 049/216] 8230016: re-visit test sun/security/pkcs11/Serialize/SerializeProvider.java Reviewed-by: rhalade --- .../sun/security/pkcs11/Serialize/SerializeProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/security/pkcs11/Serialize/SerializeProvider.java b/test/jdk/sun/security/pkcs11/Serialize/SerializeProvider.java index 495da8e6f38..2b268fe8fea 100644 --- a/test/jdk/sun/security/pkcs11/Serialize/SerializeProvider.java +++ b/test/jdk/sun/security/pkcs11/Serialize/SerializeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -41,9 +41,9 @@ import java.security.Security; public class SerializeProvider extends PKCS11Test { public void main(Provider p) throws Exception { + if (Security.getProvider(p.getName()) != p) { - System.out.println("Provider not installed in Security, skipping"); - return; + Security.addProvider(p); } ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -57,7 +57,7 @@ public class SerializeProvider extends PKCS11Test { InputStream in = new ByteArrayInputStream(data); ObjectInputStream oin = new ObjectInputStream(in); - Provider p2 = (Provider)oin.readObject(); + Provider p2 = (Provider) oin.readObject(); System.out.println("Reconstituted: " + p2); From e3eb089d47d62ae6feeba3dc6b3752a025e27bed Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Sun, 1 Jun 2025 03:57:28 +0000 Subject: [PATCH 050/216] 8357175: Failure to generate or load AOT code should be handled gracefully Reviewed-by: iveresov, asmehra --- src/hotspot/share/code/aotCodeCache.cpp | 160 ++++++++++++------------ src/hotspot/share/code/aotCodeCache.hpp | 15 +-- 2 files changed, 85 insertions(+), 90 deletions(-) diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index 4db16fdbc70..674d71d1bfc 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -125,6 +125,8 @@ uint AOTCodeCache::max_aot_code_size() { return _max_aot_code_size; } +// This method is called during universe_init() +// and does final AOT state and flags settings. void AOTCodeCache::initialize() { #if defined(ZERO) || !(defined(AMD64) || defined(AARCH64)) log_info(aot, codecache, init)("AOT Code Cache is not supported on this platform."); @@ -197,31 +199,40 @@ void AOTCodeCache::initialize() { #endif // defined(AMD64) || defined(AARCH64) } +static AOTCodeCache* opened_cache = nullptr; // Use this until we verify the cache +AOTCodeCache* AOTCodeCache::_cache = nullptr; + +// This method is called after universe_init() +// when all GC settings are finalized. void AOTCodeCache::init2() { - if (!is_on()) { + if (opened_cache == nullptr) { return; } - if (!verify_vm_config()) { - close(); + if (!opened_cache->verify_config()) { + delete opened_cache; + opened_cache = nullptr; report_load_failure(); + return; } // initialize the table of external routines so we can save // generated code blobs that reference them - init_extrs_table(); - init_early_stubs_table(); + AOTCodeAddressTable* table = opened_cache->_table; + assert(table != nullptr, "should be initialized already"); + table->init_extrs(); + table->init_early_stubs(); + + // Now cache and address table are ready for AOT code generation + _cache = opened_cache; } -AOTCodeCache* AOTCodeCache::_cache = nullptr; - bool AOTCodeCache::open_cache(bool is_dumping, bool is_using) { - AOTCodeCache* cache = new AOTCodeCache(is_dumping, is_using); - if (cache->failed()) { - delete cache; - _cache = nullptr; + opened_cache = new AOTCodeCache(is_dumping, is_using); + if (opened_cache->failed()) { + delete opened_cache; + opened_cache = nullptr; return false; } - _cache = cache; return true; } @@ -229,6 +240,7 @@ void AOTCodeCache::close() { if (is_on()) { delete _cache; // Free memory _cache = nullptr; + opened_cache = nullptr; } } @@ -276,7 +288,7 @@ AOTCodeCache::AOTCodeCache(bool is_dumping, bool is_using) : log_debug(aot, codecache, init)("Mapped %u bytes at address " INTPTR_FORMAT " at AOT Code Cache", _load_size, p2i(_load_buffer)); _load_header = (Header*)addr(0); - if (!_load_header->verify_config(_load_size)) { + if (!_load_header->verify(_load_size)) { set_failed(); return; } @@ -300,20 +312,6 @@ AOTCodeCache::AOTCodeCache(bool is_dumping, bool is_using) : _table = new AOTCodeAddressTable(); } -void AOTCodeCache::init_extrs_table() { - AOTCodeAddressTable* table = addr_table(); - if (table != nullptr) { - table->init_extrs(); - } -} - -void AOTCodeCache::init_early_stubs_table() { - AOTCodeAddressTable* table = addr_table(); - if (table != nullptr) { - table->init_early_stubs(); - } -} - void AOTCodeCache::init_shared_blobs_table() { AOTCodeAddressTable* table = addr_table(); if (table != nullptr) { @@ -381,11 +379,11 @@ void AOTCodeCache::Config::record() { _compressedOopBase = CompressedOops::base(); _compressedKlassShift = CompressedKlassPointers::shift(); _contendedPaddingWidth = ContendedPaddingWidth; - _objectAlignment = ObjectAlignmentInBytes; _gc = (uint)Universe::heap()->kind(); } bool AOTCodeCache::Config::verify() const { + // First checks affect all cached AOT code #ifdef ASSERT if ((_flags & debugVM) == 0) { log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created by product VM, it can't be used by debug VM"); @@ -404,47 +402,24 @@ bool AOTCodeCache::Config::verify() const { return false; } - if (((_flags & compressedOops) != 0) != UseCompressedOops) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedOops = %s", UseCompressedOops ? "false" : "true"); - return false; - } if (((_flags & compressedClassPointers) != 0) != UseCompressedClassPointers) { log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedClassPointers = %s", UseCompressedClassPointers ? "false" : "true"); return false; } - - if (((_flags & systemClassAssertions) != 0) != JavaAssertions::systemClassDefault()) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::systemClassDefault() = %s", JavaAssertions::systemClassDefault() ? "disabled" : "enabled"); - return false; - } - if (((_flags & userClassAssertions) != 0) != JavaAssertions::userClassDefault()) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with JavaAssertions::userClassDefault() = %s", JavaAssertions::userClassDefault() ? "disabled" : "enabled"); - return false; - } - - if (((_flags & enableContendedPadding) != 0) != EnableContended) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with EnableContended = %s", EnableContended ? "false" : "true"); - return false; - } - if (((_flags & restrictContendedPadding) != 0) != RestrictContended) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with RestrictContended = %s", RestrictContended ? "false" : "true"); - return false; - } - if (_compressedOopShift != (uint)CompressedOops::shift()) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with different CompressedOops::shift(): %d vs current %d", _compressedOopShift, CompressedOops::shift()); - return false; - } if (_compressedKlassShift != (uint)CompressedKlassPointers::shift()) { log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with CompressedKlassPointers::shift() = %d vs current %d", _compressedKlassShift, CompressedKlassPointers::shift()); return false; } - if (_contendedPaddingWidth != (uint)ContendedPaddingWidth) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ContendedPaddingWidth = %d vs current %d", _contendedPaddingWidth, ContendedPaddingWidth); - return false; + + // The following checks do not affect AOT adapters caching + + if (((_flags & compressedOops) != 0) != UseCompressedOops) { + log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with UseCompressedOops = %s", UseCompressedOops ? "false" : "true"); + AOTStubCaching = false; } - if (_objectAlignment != (uint)ObjectAlignmentInBytes) { - log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with ObjectAlignmentInBytes = %d vs current %d", _objectAlignment, ObjectAlignmentInBytes); - return false; + if (_compressedOopShift != (uint)CompressedOops::shift()) { + log_debug(aot, codecache, init)("AOT Code Cache disabled: it was created with different CompressedOops::shift(): %d vs current %d", _compressedOopShift, CompressedOops::shift()); + AOTStubCaching = false; } // This should be the last check as it only disables AOTStubCaching @@ -456,7 +431,7 @@ bool AOTCodeCache::Config::verify() const { return true; } -bool AOTCodeCache::Header::verify_config(uint load_size) const { +bool AOTCodeCache::Header::verify(uint load_size) const { if (_version != AOT_CODE_VERSION) { log_debug(aot, codecache, init)("AOT Code Cache disabled: different AOT Code version %d vs %d recorded in AOT Code header", AOT_CODE_VERSION, _version); return false; @@ -857,6 +832,10 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind #endif /* PRODUCT */ if (!cache->write_relocations(blob)) { + if (!cache->failed()) { + // We may miss an address in AOT table - skip this code blob. + cache->set_write_position(entry_position); + } return false; } @@ -985,6 +964,10 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co // ------------ process code and data -------------- +// Can't use -1. It is valid value for jump to iteself destination +// used by static call stub: see NativeJump::jump_destination(). +#define BAD_ADDRESS_ID -2 + bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { GrowableArray reloc_data; RelocIterator iter(&code_blob); @@ -1001,16 +984,24 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { if (dest == r->addr()) { // possible call via trampoline on Aarch64 dest = (address)-1; // do nothing in this case when loading this relocation } - reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob)); + int id = _table->id_for_address(dest, iter, &code_blob); + if (id == BAD_ADDRESS_ID) { + return false; + } + reloc_data.at_put(idx, id); break; } case relocInfo::runtime_call_w_cp_type: - fatal("runtime_call_w_cp_type unimplemented"); - break; + log_debug(aot, codecache, reloc)("runtime_call_w_cp_type relocation is not implemented"); + return false; case relocInfo::external_word_type: { // Record offset of runtime target address target = ((external_word_Relocation*)iter.reloc())->target(); - reloc_data.at_put(idx, _table->id_for_address(target, iter, &code_blob)); + int id = _table->id_for_address(target, iter, &code_blob); + if (id == BAD_ADDRESS_ID) { + return false; + } + reloc_data.at_put(idx, id); break; } case relocInfo::internal_word_type: @@ -1020,7 +1011,8 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { case relocInfo::post_call_nop_type: break; default: - fatal("relocation %d unimplemented", (int)iter.type()); + log_debug(aot, codecache, reloc)("relocation %d unimplemented", (int)iter.type()); + return false; break; } if (log.is_enabled()) { @@ -1069,7 +1061,8 @@ void AOTCodeReader::fix_relocations(CodeBlob* code_blob) { break; } case relocInfo::runtime_call_w_cp_type: - fatal("runtime_call_w_cp_type unimplemented"); + // this relocation should not be in cache (see write_relocations) + assert(false, "runtime_call_w_cp_type relocation is not implemented"); break; case relocInfo::external_word_type: { address target = _cache->address_for_id(reloc_data[j]); @@ -1095,7 +1088,7 @@ void AOTCodeReader::fix_relocations(CodeBlob* code_blob) { case relocInfo::post_call_nop_type: break; default: - fatal("relocation %d unimplemented", (int)iter.type()); + assert(false,"relocation %d unimplemented", (int)iter.type()); break; } if (log.is_enabled()) { @@ -1397,9 +1390,13 @@ void AOTCodeAddressTable::init_shared_blobs() { if (_complete || initializing_shared_blobs) return; // Done already initializing_shared_blobs = true; address* blobs_addr = NEW_C_HEAP_ARRAY(address, _blobs_max, mtCode); + + // Divide _shared_blobs_addr array to chunks because they could be initialized in parrallel _shared_blobs_addr = blobs_addr; _C1_blobs_addr = _shared_blobs_addr + _shared_blobs_max; - _shared_blobs_length = _C1_blobs_length = 0; + + _shared_blobs_length = 0; + _C1_blobs_length = 0; // clear the address table memset(blobs_addr, 0, sizeof(address)* _blobs_max); @@ -1556,7 +1553,7 @@ const char* AOTCodeAddressTable::add_C_string(const char* str) { } return dup; } else { - fatal("Number of C strings >= MAX_STR_COUNT"); + assert(false, "Number of C strings >= MAX_STR_COUNT"); } } return str; @@ -1595,13 +1592,11 @@ static int search_address(address addr, address* table, uint length) { return i; } } - return -1; + return BAD_ADDRESS_ID; } address AOTCodeAddressTable::address_for_id(int idx) { - if (!_extrs_complete) { - fatal("AOT Code Cache VM runtime addresses table is not complete"); - } + assert(_extrs_complete, "AOT Code Cache VM runtime addresses table is not complete"); if (idx == -1) { return (address)-1; } @@ -1612,6 +1607,7 @@ address AOTCodeAddressTable::address_for_id(int idx) { } if (idx < 0) { fatal("Incorrect id %d for AOT Code Cache addresses table", id); + return nullptr; } // no need to compare unsigned id against 0 if (/* id >= _extrs_base && */ id < _extrs_length) { @@ -1634,9 +1630,7 @@ address AOTCodeAddressTable::address_for_id(int idx) { } int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeBlob* code_blob) { - if (!_extrs_complete) { - fatal("AOT Code Cache VM runtime addresses table is not complete"); - } + assert(_extrs_complete, "AOT Code Cache VM runtime addresses table is not complete"); int id = -1; if (addr == (address)-1) { // Static call stub has jump to itself return id; @@ -1655,7 +1649,7 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset); } const char* sub_name = (desc != nullptr) ? desc->name() : ""; - fatal("Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name); + assert(false, "Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name); } else { return id + _stubs_base; } @@ -1666,7 +1660,7 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB int id_base = _shared_blobs_base; id = search_address(addr, _shared_blobs_addr, _blobs_max); if (id < 0) { - fatal("Address " INTPTR_FORMAT " for Blob:%s is missing in AOT Code Cache addresses table", p2i(addr), cb->name()); + assert(false, "Address " INTPTR_FORMAT " for Blob:%s is missing in AOT Code Cache addresses table", p2i(addr), cb->name()); } else { return id_base + id; } @@ -1687,16 +1681,20 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB assert(dist > (uint)(_all_max + MAX_STR_COUNT), "change encoding of distance"); return dist; } +#ifdef ASSERT reloc.print_current_on(tty); code_blob->print_on(tty); code_blob->print_code_on(tty); - fatal("Address " INTPTR_FORMAT " for runtime target '%s+%d' is missing in AOT Code Cache addresses table", p2i(addr), func_name, offset); + assert(false, "Address " INTPTR_FORMAT " for runtime target '%s+%d' is missing in AOT Code Cache addresses table", p2i(addr), func_name, offset); +#endif } else { +#ifdef ASSERT reloc.print_current_on(tty); code_blob->print_on(tty); code_blob->print_code_on(tty); os::find(addr, tty); - fatal("Address " INTPTR_FORMAT " for /('%s') is missing in AOT Code Cache addresses table", p2i(addr), (const char*)addr); + assert(false, "Address " INTPTR_FORMAT " for /('%s') is missing in AOT Code Cache addresses table", p2i(addr), (const char*)addr); +#endif } } else { return _extrs_base + id; diff --git a/src/hotspot/share/code/aotCodeCache.hpp b/src/hotspot/share/code/aotCodeCache.hpp index 0956a37d3b9..e7b056ac974 100644 --- a/src/hotspot/share/code/aotCodeCache.hpp +++ b/src/hotspot/share/code/aotCodeCache.hpp @@ -169,7 +169,6 @@ protected: uint _compressedOopShift; uint _compressedKlassShift; uint _contendedPaddingWidth; - uint _objectAlignment; uint _gc; enum Flags { none = 0, @@ -206,7 +205,7 @@ protected: uint _C2_blobs_count; Config _config; -public: + public: void init(uint cache_size, uint strings_count, uint strings_offset, uint entries_count, uint entries_offset, @@ -236,8 +235,8 @@ public: uint C1_blobs_count() const { return _C1_blobs_count; } uint C2_blobs_count() const { return _C2_blobs_count; } - bool verify_config(uint load_size) const; - bool verify_vm_config() const { // Called after Universe initialized + bool verify(uint load_size) const; + bool verify_config() const { // Called after Universe initialized return _config.verify(); } }; @@ -298,8 +297,6 @@ public: void load_strings(); int store_strings(); - static void init_extrs_table() NOT_CDS_RETURN; - static void init_early_stubs_table() NOT_CDS_RETURN; static void init_shared_blobs_table() NOT_CDS_RETURN; static void init_early_c1_table() NOT_CDS_RETURN; @@ -352,9 +349,9 @@ private: static AOTCodeCache* _cache; static bool open_cache(bool is_dumping, bool is_using); - static bool verify_vm_config() { - if (is_on_for_use()) { - return _cache->_load_header->verify_vm_config(); + bool verify_config() { + if (for_use()) { + return _load_header->verify_config(); } return true; } From ac9af69eee9636ff98c2b60224964e518aebb421 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 1 Jun 2025 06:17:50 +0000 Subject: [PATCH 051/216] 8357637: Native resources cached in thread locals not released when FJP common pool threads clears thread locals Reviewed-by: vklang --- .../java/lang/InheritableThreadLocal.java | 6 +-- .../share/classes/java/lang/System.java | 4 -- .../share/classes/java/lang/Thread.java | 35 ++++++++++-- .../share/classes/java/lang/ThreadLocal.java | 36 +++++-------- .../jdk/internal/access/JavaLangAccess.java | 6 --- .../jdk/internal/misc/CarrierThreadLocal.java | 6 +-- .../internal/misc/TerminatingThreadLocal.java | 23 ++++---- .../classes/sun/nio/ch/IOVecWrapper.java | 3 +- .../TestTerminatingThreadLocal.java | 53 ++++++++++++++++++- 9 files changed, 112 insertions(+), 60 deletions(-) diff --git a/src/java.base/share/classes/java/lang/InheritableThreadLocal.java b/src/java.base/share/classes/java/lang/InheritableThreadLocal.java index 10543314ead..ebc95e58418 100644 --- a/src/java.base/share/classes/java/lang/InheritableThreadLocal.java +++ b/src/java.base/share/classes/java/lang/InheritableThreadLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, 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 @@ -80,7 +80,7 @@ public class InheritableThreadLocal extends ThreadLocal { */ @Override ThreadLocalMap getMap(Thread t) { - return t.inheritableThreadLocals; + return t.inheritableThreadLocals(); } /** @@ -91,6 +91,6 @@ public class InheritableThreadLocal extends ThreadLocal { */ @Override void createMap(Thread t, T firstValue) { - t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue); + t.setInheritableThreadLocals(new ThreadLocalMap(this, firstValue)); } } diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 882b5f6945f..bcdbc39e665 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2254,10 +2254,6 @@ public final class System { ((ThreadLocal)local).removeCarrierThreadLocal(); } - public boolean isCarrierThreadLocalPresent(CarrierThreadLocal local) { - return ((ThreadLocal)local).isCarrierThreadLocalPresent(); - } - public Object[] scopedValueCache() { return Thread.scopedValueCache(); } diff --git a/src/java.base/share/classes/java/lang/Thread.java b/src/java.base/share/classes/java/lang/Thread.java index 9daae01676f..2fc20a94f1d 100644 --- a/src/java.base/share/classes/java/lang/Thread.java +++ b/src/java.base/share/classes/java/lang/Thread.java @@ -235,7 +235,7 @@ public class Thread implements Runnable { private volatile ClassLoader contextClassLoader; // Additional fields for platform threads. - // All fields, except task, are accessed directly by the VM. + // All fields, except task and terminatingThreadLocals, are accessed directly by the VM. private static class FieldHolder { final ThreadGroup group; final Runnable task; @@ -244,6 +244,9 @@ public class Thread implements Runnable { volatile boolean daemon; volatile int threadStatus; + // This map is maintained by the ThreadLocal class + ThreadLocal.ThreadLocalMap terminatingThreadLocals; + FieldHolder(ThreadGroup group, Runnable task, long stackSize, @@ -259,17 +262,41 @@ public class Thread implements Runnable { } private final FieldHolder holder; + ThreadLocal.ThreadLocalMap terminatingThreadLocals() { + return holder.terminatingThreadLocals; + } + + void setTerminatingThreadLocals(ThreadLocal.ThreadLocalMap map) { + holder.terminatingThreadLocals = map; + } + /* * ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ - ThreadLocal.ThreadLocalMap threadLocals; + private ThreadLocal.ThreadLocalMap threadLocals; + + ThreadLocal.ThreadLocalMap threadLocals() { + return threadLocals; + } + + void setThreadLocals(ThreadLocal.ThreadLocalMap map) { + threadLocals = map; + } /* * InheritableThreadLocal values pertaining to this thread. This map is * maintained by the InheritableThreadLocal class. */ - ThreadLocal.ThreadLocalMap inheritableThreadLocals; + private ThreadLocal.ThreadLocalMap inheritableThreadLocals; + + ThreadLocal.ThreadLocalMap inheritableThreadLocals() { + return inheritableThreadLocals; + } + + void setInheritableThreadLocals(ThreadLocal.ThreadLocalMap map) { + inheritableThreadLocals = map; + } /* * Scoped value bindings are maintained by the ScopedValue class. @@ -1492,7 +1519,7 @@ public class Thread implements Runnable { } try { - if (threadLocals != null && TerminatingThreadLocal.REGISTRY.isPresent()) { + if (terminatingThreadLocals() != null) { TerminatingThreadLocal.threadTerminated(); } } finally { diff --git a/src/java.base/share/classes/java/lang/ThreadLocal.java b/src/java.base/share/classes/java/lang/ThreadLocal.java index fae322d2b73..2fb427d8611 100644 --- a/src/java.base/share/classes/java/lang/ThreadLocal.java +++ b/src/java.base/share/classes/java/lang/ThreadLocal.java @@ -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 @@ -193,27 +193,6 @@ public class ThreadLocal { return setInitialValue(t); } - /** - * Returns {@code true} if there is a value in the current carrier thread's copy of - * this thread-local variable, even if that values is {@code null}. - * - * @return {@code true} if current carrier thread has associated value in this - * thread-local variable; {@code false} if not - */ - boolean isCarrierThreadLocalPresent() { - assert this instanceof CarrierThreadLocal; - return isPresent(Thread.currentCarrierThread()); - } - - private boolean isPresent(Thread t) { - ThreadLocalMap map = getMap(t); - if (map != null) { - return map.getEntry(this) != null; - } else { - return false; - } - } - /** * Variant of set() to establish initialValue. Used instead * of set() in case user has overridden the set() method. @@ -302,7 +281,11 @@ public class ThreadLocal { * @return the map */ ThreadLocalMap getMap(Thread t) { - return t.threadLocals; + if (this instanceof TerminatingThreadLocal) { + return t.terminatingThreadLocals(); + } else { + return t.threadLocals(); + } } /** @@ -313,7 +296,12 @@ public class ThreadLocal { * @param firstValue value for the initial entry of the map */ void createMap(Thread t, T firstValue) { - t.threadLocals = new ThreadLocalMap(this, firstValue); + var map = new ThreadLocalMap(this, firstValue); + if (this instanceof TerminatingThreadLocal) { + t.setTerminatingThreadLocals(map); + } else { + t.setThreadLocals(map); + } } /** diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 1f60f85464b..5109e7b2a5b 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -546,12 +546,6 @@ public interface JavaLangAccess { */ void removeCarrierThreadLocal(CarrierThreadLocal local); - /** - * Returns {@code true} if there is a value in the current carrier thread's copy of - * thread-local, even if that values is {@code null}. - */ - boolean isCarrierThreadLocalPresent(CarrierThreadLocal local); - /** * Returns the current thread's scoped values cache */ diff --git a/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java b/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java index b14ecaffa2e..9396521cad5 100644 --- a/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java +++ b/src/java.base/share/classes/jdk/internal/misc/CarrierThreadLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,9 +49,5 @@ public class CarrierThreadLocal extends ThreadLocal { JLA.removeCarrierThreadLocal(this); } - public boolean isPresent() { - return JLA.isCarrierThreadLocalPresent(this); - } - private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); } diff --git a/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java b/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java index eeb1a77e226..beee5b78d1a 100644 --- a/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java +++ b/src/java.base/share/classes/jdk/internal/misc/TerminatingThreadLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -29,10 +29,9 @@ import java.util.Collections; import java.util.IdentityHashMap; /** - * A per-carrier-thread-local variable that is notified when a thread terminates and - * it has been initialized in the terminating carrier thread or a virtual thread - * that had the terminating carrier thread as its carrier thread (even if it was - * initialized with a null value). + * A platform thread-local variable that is notified when a platform thread terminates, + * and it has been initialized in the terminating thread (or a mounted virtual thread in + * the case of a carrier thread), and even if it was initialized with a null value. */ public class TerminatingThreadLocal extends CarrierThreadLocal { @@ -44,8 +43,8 @@ public class TerminatingThreadLocal extends CarrierThreadLocal { @Override public void remove() { - super.remove(); unregister(this); + super.remove(); } /** @@ -80,7 +79,9 @@ public class TerminatingThreadLocal extends CarrierThreadLocal { * @param tl the ThreadLocal to register */ public static void register(TerminatingThreadLocal tl) { - REGISTRY.get().add(tl); + if (tl != REGISTRY) { + REGISTRY.get().add(tl); + } } /** @@ -93,11 +94,11 @@ public class TerminatingThreadLocal extends CarrierThreadLocal { } /** - * a per-carrier-thread registry of TerminatingThreadLocal(s) that have been registered - * but later not unregistered in a particular carrier-thread. + * A per-platform-thread registry of TerminatingThreadLocal(s). The registry is + * itself a TerminatingThreadLocal to keep it reachable until the thread terminates. */ - public static final CarrierThreadLocal>> REGISTRY = - new CarrierThreadLocal<>() { + public static final TerminatingThreadLocal>> REGISTRY = + new TerminatingThreadLocal<>() { @Override protected Collection> initialValue() { return Collections.newSetFromMap(new IdentityHashMap<>(4)); diff --git a/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java b/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java index 1c78e45a2d8..6d551462ce8 100644 --- a/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java +++ b/src/java.base/share/classes/sun/nio/ch/IOVecWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -79,6 +79,7 @@ class IOVecWrapper { protected void threadTerminated(IOVecWrapper[] cache) { IOVecWrapper wrapper = cache[0]; if (wrapper != null) { + cache[0] = null; wrapper.vecArray.free(); } } diff --git a/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java b/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java index 00bddec6b56..cf46c5b1d22 100644 --- a/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java +++ b/test/jdk/jdk/internal/misc/TerminatingThreadLocal/TestTerminatingThreadLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -24,6 +24,7 @@ import jdk.internal.misc.TerminatingThreadLocal; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; @@ -31,6 +32,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; @@ -41,7 +43,7 @@ import static org.testng.Assert.*; /* * @test - * @bug 8202788 8291897 + * @bug 8202788 8291897 8357637 * @summary TerminatingThreadLocal unit test * @modules java.base/java.lang:+open java.base/jdk.internal.misc * @requires vm.continuations @@ -154,6 +156,53 @@ public class TestTerminatingThreadLocal { assertEquals(terminatedValues, expectedTerminatedValues); } + /** + * Test TerminatingThreadLocal when thread locals are "cleared" by null'ing the + * threadLocal field of the current Thread. + */ + @Test + public void testClearingThreadLocals() throws Throwable { + var terminatedValues = new CopyOnWriteArrayList(); + + var tl = new ThreadLocal(); + var ttl = new TerminatingThreadLocal() { + @Override + protected void threadTerminated(String value) { + terminatedValues.add(value); + } + }; + var throwableRef = new AtomicReference(); + + String tlValue = "abc"; + String ttlValue = "xyz"; + + Thread thread = Thread.ofPlatform().start(() -> { + try { + tl.set(tlValue); + ttl.set(ttlValue); + + assertEquals(tl.get(), tlValue); + assertEquals(ttl.get(), ttlValue); + + // set Thread.threadLocals to null + Field f = Thread.class.getDeclaredField("threadLocals"); + f.setAccessible(true); + f.set(Thread.currentThread(), null); + + assertNull(tl.get()); + assertEquals(ttl.get(), ttlValue); + } catch (Throwable t) { + throwableRef.set(t); + } + }); + thread.join(); + if (throwableRef.get() instanceof Throwable t) { + throw t; + } + + assertEquals(terminatedValues, List.of(ttlValue)); + } + /** * Returns a builder to create virtual threads that use the given scheduler. */ From c1b5f62a8c30038d3b1a14d184535ba0642d51c9 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Sun, 1 Jun 2025 09:06:04 +0000 Subject: [PATCH 052/216] 8358136: Make langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java intermittent Reviewed-by: jpai, nbenalla, syan --- .../jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java b/test/langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java index a6a04c80834..9a80ca4d089 100644 --- a/test/langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java +++ b/test/langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java @@ -24,6 +24,7 @@ /* * @test * @bug 8190312 + * @key intermittent * @summary test redirected URLs for -link * @library /tools/lib ../../lib /test/lib * @modules jdk.compiler/com.sun.tools.javac.api From 85e36d79246913abb8b85c2be719670655d619ab Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Sun, 1 Jun 2025 21:21:27 +0000 Subject: [PATCH 053/216] 8358236: [AOT] Graal crashes when trying to use persisted MDOs Reviewed-by: kvn --- src/hotspot/share/oops/methodData.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 0f8b8a8275a..deb67e2e90b 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -1996,6 +1996,9 @@ void MethodData::release_C_heap_structures() { #if INCLUDE_CDS void MethodData::remove_unshareable_info() { _extra_data_lock = nullptr; +#if INCLUDE_JVMCI + _failed_speculations = nullptr; +#endif } void MethodData::restore_unshareable_info(TRAPS) { From 3193a28c532d8536d621c99bb661304c49ca13e1 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Sun, 1 Jun 2025 23:36:25 +0000 Subject: [PATCH 054/216] 8358259: ProblemList compiler/startup/StartupOutput.java on Windows Reviewed-by: darcy --- test/hotspot/jtreg/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 1f10d38240b..62fdbdbaa06 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -79,6 +79,8 @@ compiler/ciReplay/TestIncrementalInlining.java 8349191 generic-all compiler/c2/TestVerifyConstraintCasts.java 8355574 generic-all +compiler/startup/StartupOutput.java 8358129 windows-all + ############################################################################# # :hotspot_gc From 90d6ad015714b81064dd16d0e64f1b774e68d4f3 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 2 Jun 2025 02:06:06 +0000 Subject: [PATCH 055/216] 8356594: JSplitPane loses divider location when reopened via JOptionPane.createDialog() Reviewed-by: kizune --- .../share/classes/javax/swing/JSplitPane.java | 35 ++-- .../TestSplitPaneResetDividerLoc.java | 185 ++++++++++++++++++ 2 files changed, 204 insertions(+), 16 deletions(-) create mode 100644 test/jdk/javax/swing/JSplitPane/TestSplitPaneResetDividerLoc.java diff --git a/src/java.desktop/share/classes/javax/swing/JSplitPane.java b/src/java.desktop/share/classes/javax/swing/JSplitPane.java index 90f3efb3e69..f21b2b3339a 100644 --- a/src/java.desktop/share/classes/javax/swing/JSplitPane.java +++ b/src/java.desktop/share/classes/javax/swing/JSplitPane.java @@ -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 @@ -369,22 +369,25 @@ public class JSplitPane extends JComponent implements Accessible */ @Override public void setComponentOrientation(ComponentOrientation orientation) { + ComponentOrientation curOrn = this.getComponentOrientation(); super.setComponentOrientation(orientation); - Component leftComponent = this.getLeftComponent(); - Component rightComponent = this.getRightComponent(); - if (!this.getComponentOrientation().isLeftToRight()) { - if (rightComponent != null) { - setLeftComponent(rightComponent); - } - if (leftComponent != null) { - setRightComponent(leftComponent); - } - } else { - if (leftComponent != null) { - setLeftComponent(leftComponent); - } - if (rightComponent != null) { - setRightComponent(rightComponent); + if (!orientation.equals(curOrn)) { + Component leftComponent = this.getLeftComponent(); + Component rightComponent = this.getRightComponent(); + if (!this.getComponentOrientation().isLeftToRight()) { + if (rightComponent != null) { + setLeftComponent(rightComponent); + } + if (leftComponent != null) { + setRightComponent(leftComponent); + } + } else { + if (leftComponent != null) { + setLeftComponent(leftComponent); + } + if (rightComponent != null) { + setRightComponent(rightComponent); + } } } } diff --git a/test/jdk/javax/swing/JSplitPane/TestSplitPaneResetDividerLoc.java b/test/jdk/javax/swing/JSplitPane/TestSplitPaneResetDividerLoc.java new file mode 100644 index 00000000000..e43691f243c --- /dev/null +++ b/test/jdk/javax/swing/JSplitPane/TestSplitPaneResetDividerLoc.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8356594 + * @key headful + * @summary Verifies if JSplitPane loses divider location when + * reopened via JOptionPane.createDialog() + * @run main TestSplitPaneResetDividerLoc + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class TestSplitPaneResetDividerLoc { + + private static JPanel lazyPanel; + private static JSplitPane splitPane; + private static JButton openDialogButton; + private static JDialog dialog; + private static JFrame frame; + private static volatile Point point; + private static volatile Rectangle size; + private static volatile int setLoc; + private static volatile int curLoc; + + private static boolean setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + return true; + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported LAF: " + laf.getClassName()); + return false; + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + System.out.println("Testing LAF : " + laf.getClassName()); + try { + if (!setLookAndFeel(laf)) { + continue; + } + SwingUtilities.invokeAndWait(TestSplitPaneResetDividerLoc::createAndShowUI); + + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + point = openDialogButton.getLocationOnScreen(); + size = openDialogButton.getBounds(); + }); + robot.mouseMove(point.x + size.width / 2, point.y + size.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + int divLoc = splitPane.getDividerLocation(); + splitPane.setDividerLocation(divLoc + 200); + }); + robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + + SwingUtilities.invokeAndWait(() -> { + setLoc = splitPane.getDividerLocation(); + System.out.println(setLoc); + }); + + robot.waitForIdle(); + robot.delay(1000); + robot.mouseMove(point.x + size.width / 2, point.y + size.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + curLoc = splitPane.getDividerLocation(); + System.out.println(curLoc); + }); + + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + + if (curLoc != setLoc) { + throw new RuntimeException("Divider location is not preserved"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + lazyPanel = null; + }); + } + } + } + + private static void createAndShowUI() { + frame = new JFrame("JSplitPane Divider Location"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + openDialogButton = new JButton(new AbstractAction("Open Dialog") { + public void actionPerformed(ActionEvent e) { + openDialogFromOptionPane(frame); + } + }); + + frame.getContentPane().add(openDialogButton, BorderLayout.CENTER); + frame.setSize(400, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void openDialogFromOptionPane(JFrame parent) { + if (lazyPanel == null) { + System.out.println("Creating lazy panel..."); + lazyPanel = new JPanel(new BorderLayout()); + + JPanel left = new JPanel(); + left.setBackground(Color.ORANGE); + JPanel right = new JPanel(); + right.setBackground(Color.LIGHT_GRAY); + + splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right); + splitPane.setPreferredSize(new Dimension(400, 200)); + + // Set initial divider location — not preserved across dialog openings in OpenJDK 24 + splitPane.setDividerLocation(120); + + lazyPanel.add(splitPane, BorderLayout.CENTER); + } + + JOptionPane optionPane = new JOptionPane(lazyPanel, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION); + dialog = optionPane.createDialog(parent, "SplitPane Dialog (JOptionPane)"); + dialog.setModal(false); + dialog.setVisible(true); + } +} From c5a1543ee3e68775f09ca29fb07efd9aebfdb33e Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Mon, 2 Jun 2025 05:43:20 +0000 Subject: [PATCH 056/216] 8357968: RISC-V: Interpreter volatile reference stores with G1 are not sequentially consistent Reviewed-by: eosterlund, fbredberg, shade, fyang --- src/hotspot/cpu/riscv/templateTable_riscv.cpp | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index 547a1ad35c5..f6bf1e79f92 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -125,24 +125,6 @@ static inline Address at_tos_p5() { return Address(esp, Interpreter::expr_offset_in_bytes(5)); } -// Miscellaneous helper routines -// Store an oop (or null) at the Address described by obj. -// If val == noreg this means store a null -static void do_oop_store(InterpreterMacroAssembler* _masm, - Address dst, - Register val, - DecoratorSet decorators) { - assert(val == noreg || val == x10, "parameter is just for looks"); - __ store_heap_oop(dst, val, x28, x29, x13, decorators); -} - -static void do_oop_load(InterpreterMacroAssembler* _masm, - Address src, - Register dst, - DecoratorSet decorators) { - __ load_heap_oop(dst, src, x28, x29, decorators); -} - Address TemplateTable::at_bcp(int offset) { assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); return Address(xbcp, offset); @@ -787,7 +769,7 @@ void TemplateTable::aaload() { index_check(x10, x11); // leaves index in x11 __ addi(x11, x11, arrayOopDesc::base_offset_in_bytes(T_OBJECT) >> LogBytesPerHeapOop); __ shadd(x10, x11, x10, t0, LogBytesPerHeapOop); - do_oop_load(_masm, Address(x10), x10, IS_ARRAY); + __ load_heap_oop(x10, Address(x10), x28, x29, IS_ARRAY); } void TemplateTable::baload() { @@ -1099,7 +1081,7 @@ void TemplateTable::aastore() { // Get the value we will store __ ld(x10, at_tos()); // Now store using the appropriate barrier - do_oop_store(_masm, element_address, x10, IS_ARRAY); + __ store_heap_oop(element_address, x10, x28, x29, x13, IS_ARRAY); __ j(done); // Have a null in x10, x13=array, x12=index. Store null at ary[idx] @@ -1107,7 +1089,7 @@ void TemplateTable::aastore() { __ profile_null_seen(x12); // Store a null - do_oop_store(_masm, element_address, noreg, IS_ARRAY); + __ store_heap_oop(element_address, noreg, x28, x29, x13, IS_ARRAY); // Pop stack arguments __ bind(done); @@ -2565,7 +2547,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr __ subi(t0, tos_state, (u1)atos); __ bnez(t0, notObj); // atos - do_oop_load(_masm, field, x10, IN_HEAP); + __ load_heap_oop(x10, field, x28, x29, IN_HEAP); __ push(atos); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_agetfield, bc, x11); @@ -2809,7 +2791,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ add(off, obj, off); // if static, obj from cache, else obj from stack. const Address field(off, 0); // Store into the field - do_oop_store(_masm, field, x10, IN_HEAP); + __ store_heap_oop(field, x10, x28, x29, x13, IN_HEAP); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_aputfield, bc, x11, true, byte_no); } @@ -3051,10 +3033,10 @@ void TemplateTable::fast_storefield(TosState state) { __ add(x11, x12, x11); const Address field(x11, 0); - // access field + // access field, must not clobber x13 - flags switch (bytecode()) { case Bytecodes::_fast_aputfield: - do_oop_store(_masm, field, x10, IN_HEAP); + __ store_heap_oop(field, x10, x28, x29, x15, IN_HEAP); break; case Bytecodes::_fast_lputfield: __ access_store_at(T_LONG, IN_HEAP, field, x10, noreg, noreg, noreg); @@ -3133,7 +3115,7 @@ void TemplateTable::fast_accessfield(TosState state) { // access field switch (bytecode()) { case Bytecodes::_fast_agetfield: - do_oop_load(_masm, field, x10, IN_HEAP); + __ load_heap_oop(x10, field, x28, x29, IN_HEAP); __ verify_oop(x10); break; case Bytecodes::_fast_lgetfield: @@ -3191,7 +3173,7 @@ void TemplateTable::fast_xaccess(TosState state) { break; case atos: __ add(x10, x10, x11); - do_oop_load(_masm, Address(x10, 0), x10, IN_HEAP); + __ load_heap_oop(x10, Address(x10, 0), x28, x29, IN_HEAP); __ verify_oop(x10); break; case ftos: From 3f59bfd2e1b35e10fe736e2fa6886cff74ecd35d Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 2 Jun 2025 07:59:10 +0000 Subject: [PATCH 057/216] 8334759: gc/g1/TestMixedGCLiveThreshold.java fails on Windows with JTREG_TEST_THREAD_FACTORY=Virtual due to extra memory allocation Reviewed-by: ayang, iwalulya --- test/hotspot/jtreg/ProblemList-Virtual.txt | 5 ----- test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index 2239a10f3e7..cb5b92b96cf 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -83,11 +83,6 @@ vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemor # to make progress when all other threads are currently suspended. vmTestbase/nsk/jdi/ThreadReference/isSuspended/issuspended002/TestDescription.java 8338713 generic-all -### -# Fails on Windows because of additional memory allocation. - -gc/g1/TestMixedGCLiveThreshold.java#25percent 8334759 windows-x64 - ########## ## Tests incompatible with with virtual test thread factory. ## There is no goal to run all test with virtual test thread factory. diff --git a/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java b/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java index efaea7a097e..66b726223cc 100644 --- a/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java +++ b/test/hotspot/jtreg/gc/g1/TestMixedGCLiveThreshold.java @@ -28,6 +28,7 @@ package gc.g1; * @summary Test G1MixedGCLiveThresholdPercent=0. Fill up a region to at least 33 percent, * the region should not be selected for mixed GC cycle. * @requires vm.gc.G1 + * @requires test.thread.factory != "Virtual" * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -39,6 +40,7 @@ package gc.g1; * @summary Test G1MixedGCLiveThresholdPercent=25. Fill up a region to at least 33 percent, * the region should not be selected for mixed GC cycle. * @requires vm.gc.G1 + * @requires test.thread.factory != "Virtual" * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox @@ -50,6 +52,7 @@ package gc.g1; * @summary Test G1MixedGCLiveThresholdPercent=100. Fill up a region to at least 33 percent, * the region should be selected for mixed GC cycle. * @requires vm.gc.G1 + * @requires test.thread.factory != "Virtual" * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox From 6418306211be47063a9b06bad8003dee1d81570c Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 2 Jun 2025 08:23:06 +0000 Subject: [PATCH 058/216] 8357944: Remove unused CollectedHeap::is_maximal_no_gc Reviewed-by: jsikstro, tschatzl --- src/hotspot/share/gc/epsilon/epsilonHeap.hpp | 5 ----- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 2 +- src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp | 6 ------ src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp | 5 ----- src/hotspot/share/gc/parallel/psOldGen.hpp | 4 ---- src/hotspot/share/gc/serial/serialHeap.cpp | 5 ----- src/hotspot/share/gc/serial/serialHeap.hpp | 5 ----- src/hotspot/share/gc/serial/tenuredGeneration.hpp | 6 ------ src/hotspot/share/gc/shared/collectedHeap.hpp | 5 ----- src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp | 2 -- src/hotspot/share/gc/z/zCollectedHeap.cpp | 6 ------ src/hotspot/share/gc/z/zCollectedHeap.hpp | 1 - 12 files changed, 1 insertion(+), 51 deletions(-) diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp index 129e81c1c34..0022d50cbb9 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp @@ -80,11 +80,6 @@ public: bool requires_barriers(stackChunkOop obj) const override { return false; } - bool is_maximal_no_gc() const override { - // No GC is going to happen. Return "we are at max", when we are about to fail. - return used() == capacity(); - } - // Allocation HeapWord* allocate_work(size_t size, bool verbose = true); HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) override; diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 71aab49864e..965d01c7089 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -966,7 +966,7 @@ public: // end fields defining the extent of the contiguous allocation region.) // But G1CollectedHeap doesn't yet support this. - bool is_maximal_no_gc() const override { + bool is_maximal_no_gc() const { return _hrm.num_inactive_regions() == 0; } diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 683f4e13b47..0235864992f 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -207,12 +207,6 @@ size_t ParallelScavengeHeap::used() const { return value; } -bool ParallelScavengeHeap::is_maximal_no_gc() const { - // We don't expand young-gen except at a GC. - return old_gen()->is_maximal_no_gc(); -} - - size_t ParallelScavengeHeap::max_capacity() const { size_t estimated = reserved_region().byte_size(); if (UseAdaptiveSizePolicy) { diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index 887b78758cf..2ce36a6f961 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -158,11 +158,6 @@ public: size_t capacity() const override; size_t used() const override; - // Return "true" if all generations have reached the - // maximal committed limit that they can reach, without a garbage - // collection. - bool is_maximal_no_gc() const override; - void register_nmethod(nmethod* nm) override; void unregister_nmethod(nmethod* nm) override; void verify_nmethod(nmethod* nm) override; diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index f4815e67179..c1bfe2f1972 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -109,10 +109,6 @@ class PSOldGen : public CHeapObj { size_t capacity_in_bytes() const { return object_space()->capacity_in_bytes(); } size_t used_in_bytes() const { return object_space()->used_in_bytes(); } - bool is_maximal_no_gc() const { - return virtual_space()->uncommitted_size() == 0; - } - void complete_loaded_archive_space(MemRegion archive_space); // Calculating new sizes diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 5b2ce8d0415..27d94593765 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -766,11 +766,6 @@ void SerialHeap::prepare_for_verify() { ensure_parsability(false); // no need to retire TLABs } -bool SerialHeap::is_maximal_no_gc() const { - // We don't expand young-gen except at a GC. - return _old_gen->is_maximal_no_gc(); -} - void SerialHeap::save_marks() { _young_gen_saved_top = _young_gen->to()->top(); _old_gen_saved_top = _old_gen->space()->top(); diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 30b7b9a0085..34c79ac0a18 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -216,11 +216,6 @@ public: void print_heap_change(const PreGenGCValues& pre_gc_values) const; - // Return "true" if all generations have reached the - // maximal committed limit that they can reach, without a garbage - // collection. - virtual bool is_maximal_no_gc() const override; - // This function returns the CardTableRS object that allows us to scan // generations in a fully generational heap. CardTableRS* rem_set() { return _rem_set; } diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index 88bfe6ecf46..1f6871d8ee2 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -102,12 +102,6 @@ public: MemRegion prev_used_region() const { return _prev_used_region; } void save_used_region() { _prev_used_region = used_region(); } - // Returns true if this generation cannot be expanded further - // without a GC. - bool is_maximal_no_gc() const { - return _virtual_space.uncommitted_size() == 0; - } - HeapWord* block_start(const void* addr) const; void scan_old_to_young_refs(HeapWord* saved_top_in_old_gen); diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 30ee35a34a7..d50c09f70a7 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -259,11 +259,6 @@ protected: size_t used_at_last_gc() const { return _used_at_last_gc; } void update_capacity_and_used_at_gc(); - // Return "true" if the part of the heap that allocates Java - // objects has reached the maximal committed limit that it can - // reach, without a garbage collection. - virtual bool is_maximal_no_gc() const = 0; - // Support for java.lang.Runtime.maxMemory(): return the maximum amount of // memory that the vm could make available for storing 'normal' java objects. // This is based on the reserved address space, but should not include space diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 78d507c0f7d..4124bf8be7f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -614,8 +614,6 @@ private: // and can be stubbed out. // public: - bool is_maximal_no_gc() const override shenandoah_not_implemented_return(false); - // Check the pointer is in active part of Java heap. // Use is_in_reserved to check if object is within heap bounds. bool is_in(const void* p) const override; diff --git a/src/hotspot/share/gc/z/zCollectedHeap.cpp b/src/hotspot/share/gc/z/zCollectedHeap.cpp index f69f8492eed..87cfeb012ec 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.cpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp @@ -126,12 +126,6 @@ size_t ZCollectedHeap::unused() const { return _heap.unused(); } -bool ZCollectedHeap::is_maximal_no_gc() const { - // Not supported - ShouldNotReachHere(); - return false; -} - bool ZCollectedHeap::is_in(const void* p) const { return _heap.is_in((uintptr_t)p); } diff --git a/src/hotspot/share/gc/z/zCollectedHeap.hpp b/src/hotspot/share/gc/z/zCollectedHeap.hpp index 9ae3da39dd9..871ff81bfdf 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.hpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp @@ -70,7 +70,6 @@ public: size_t used() const override; size_t unused() const override; - bool is_maximal_no_gc() const override; bool is_in(const void* p) const override; bool requires_barriers(stackChunkOop obj) const override; From 40ce05d4080a9a2b4876c21f83a184f9b8a580a2 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 2 Jun 2025 08:28:10 +0000 Subject: [PATCH 059/216] 8358231: Template interpreter generator crashes with ShouldNotReachHere on some platforms after 8353686 Reviewed-by: shade, amitkumar, mbaesken, kvn --- src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp | 1 + src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp | 1 + src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index 30d88a4db91..db4a5c8625c 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -175,6 +175,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M case Interpreter::java_lang_math_fmaD: case Interpreter::java_lang_math_fmaF: case Interpreter::java_lang_math_tanh: + case Interpreter::java_lang_math_cbrt: // TODO: Implement intrinsic break; default: diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 020590d414f..ab4f35f4d8c 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -1090,6 +1090,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break; case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break; case Interpreter::java_lang_math_tanh : /* run interpreted */ break; + case Interpreter::java_lang_math_cbrt : /* run interpreted */ break; case Interpreter::java_lang_math_abs : /* run interpreted */ break; case Interpreter::java_lang_math_sqrt : /* run interpreted */ break; case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break; diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index c953ab38713..e387d60b594 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1240,6 +1240,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M case Interpreter::java_lang_math_cos : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break; case Interpreter::java_lang_math_tan : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break; case Interpreter::java_lang_math_tanh : /* run interpreted */ break; + case Interpreter::java_lang_math_cbrt : /* run interpreted */ break; case Interpreter::java_lang_math_abs : /* run interpreted */ break; case Interpreter::java_lang_math_sqrt : /* runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt); not available */ break; case Interpreter::java_lang_math_log : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break; From ba9f44c90fe8da2d97d67b6878ac2c0c14e35bd0 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 2 Jun 2025 08:31:10 +0000 Subject: [PATCH 060/216] 8357793: [PPC64] VM crashes with -XX:-UseSIGTRAP -XX:-ImplicitNullChecks Reviewed-by: shade, dbriemann --- src/hotspot/cpu/ppc/methodHandles_ppc.cpp | 4 +++- src/hotspot/cpu/ppc/templateTable_ppc_64.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp index 13fb8ef79d6..803bb6bfe69 100644 --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp @@ -359,7 +359,9 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm, ? -1 // enforce receiver null check : oopDesc::klass_offset_in_bytes(); // regular null-checking behavior - __ null_check_throw(receiver_reg, klass_offset, temp1, Interpreter::throw_NullPointerException_entry()); + address NullPointerException_entry = for_compiler_entry ? SharedRuntime::throw_NullPointerException_at_call_entry() + : Interpreter::throw_NullPointerException_entry(); + __ null_check_throw(receiver_reg, klass_offset, temp1, NullPointerException_entry); if (iid != vmIntrinsics::_linkToSpecial || VerifyMethodHandles) { __ load_klass(temp1_recv_klass, receiver_reg); diff --git a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp index 1667fa3aba3..7431f77aeff 100644 --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp @@ -1035,7 +1035,7 @@ void TemplateTable::bastore() { // Need to check whether array is boolean or byte // since both types share the bastore bytecode. - __ load_klass(Rscratch, Rarray); + __ load_klass_check_null_throw(Rscratch, Rarray, Rscratch); __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch); int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit()); __ testbitdi(CR0, R0, Rscratch, diffbit); From a9e7a74d00fe1c8d3179392738bb15d8e3508b3a Mon Sep 17 00:00:00 2001 From: Guoxiong Li Date: Mon, 2 Jun 2025 08:47:36 +0000 Subject: [PATCH 061/216] 8357109: Parallel: Fix typo in YoungedGeneration Reviewed-by: ayang, zgu, tschatzl --- src/hotspot/share/gc/shared/gc_globals.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 56b8bc4e4ff..f693ab910ba 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -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 @@ -362,11 +362,11 @@ range(0, 100) \ \ product(uint, YoungGenerationSizeSupplement, 80, \ - "Supplement to YoungedGenerationSizeIncrement used at startup") \ + "Supplement to YoungGenerationSizeIncrement used at startup") \ range(0, 100) \ \ product(uintx, YoungGenerationSizeSupplementDecay, 8, \ - "Decay factor to YoungedGenerationSizeSupplement") \ + "Decay factor to YoungGenerationSizeSupplement") \ range(1, max_uintx) \ \ product(uint, TenuredGenerationSizeIncrement, 20, \ From eb9badd8a4ea6dca834525fd49429e2ce771a76c Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Mon, 2 Jun 2025 08:57:16 +0000 Subject: [PATCH 062/216] 8358169: Shenandoah/JVMCI: Export GC state constants Reviewed-by: dnsimon, shade --- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index cf9e6ed46d5..4302c0ce6ad 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -54,6 +54,7 @@ #include "gc/z/zThreadLocalData.hpp" #endif #if INCLUDE_SHENANDOAHGC +#include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" #endif @@ -969,6 +970,13 @@ declare_constant_with_value("ShenandoahThreadLocalData::satb_mark_queue_index_offset", in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset())) \ declare_constant_with_value("ShenandoahThreadLocalData::satb_mark_queue_buffer_offset", in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset())) \ declare_constant_with_value("ShenandoahThreadLocalData::card_table_offset", in_bytes(ShenandoahThreadLocalData::card_table_offset())) \ + declare_constant_with_value("ShenandoahHeap::HAS_FORWARDED", ShenandoahHeap::HAS_FORWARDED) \ + declare_constant_with_value("ShenandoahHeap::MARKING", ShenandoahHeap::MARKING) \ + declare_constant_with_value("ShenandoahHeap::EVACUATION", ShenandoahHeap::EVACUATION) \ + declare_constant_with_value("ShenandoahHeap::UPDATE_REFS", ShenandoahHeap::UPDATE_REFS) \ + declare_constant_with_value("ShenandoahHeap::WEAK_ROOTS", ShenandoahHeap::WEAK_ROOTS) \ + declare_constant_with_value("ShenandoahHeap::YOUNG_MARKING", ShenandoahHeap::YOUNG_MARKING) \ + declare_constant_with_value("ShenandoahHeap::OLD_MARKING", ShenandoahHeap::OLD_MARKING) \ #endif From 612f2c0c0b75466c60d4b54dab6aa793a810c846 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Mon, 2 Jun 2025 09:21:31 +0000 Subject: [PATCH 063/216] 8357981: [PPC64] Remove old instructions from VM_Version::determine_features() Reviewed-by: dbriemann, mbaesken --- src/hotspot/cpu/ppc/vm_version_ppc.cpp | 40 ++------------------------ src/hotspot/cpu/ppc/vm_version_ppc.hpp | 39 ++----------------------- 2 files changed, 4 insertions(+), 75 deletions(-) diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 79efc9a05c1..6a3d88c48ae 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -479,29 +479,10 @@ void VM_Version::determine_features() { // Emit code. void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->function_entry(); uint32_t *code = (uint32_t *)a->pc(); - // Don't use R0 in ldarx. // Keep R3_ARG1 unmodified, it contains &field (see below). // Keep R4_ARG2 unmodified, it contains offset = 0 (see below). - a->fsqrt(F3, F4); // code[0] -> fsqrt_m - a->fsqrts(F3, F4); // code[1] -> fsqrts_m - a->isel(R7, R5, R6, 0); // code[2] -> isel_m - a->ldarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[3] -> lxarx_m - a->cmpb(R7, R5, R6); // code[4] -> cmpb - a->popcntb(R7, R5); // code[5] -> popcntb - a->popcntw(R7, R5); // code[6] -> popcntw - a->fcfids(F3, F4); // code[7] -> fcfids - a->vand(VR0, VR0, VR0); // code[8] -> vand - // arg0 of lqarx must be an even register, (arg1 + arg2) must be a multiple of 16 - a->lqarx_unchecked(R6, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m - a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher - a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb - a->mfdscr(R0); // code[12] -> mfdscr - a->lxvd2x(VSR0, R3_ARG1); // code[13] -> vsx - a->ldbrx(R7, R3_ARG1, R4_ARG2); // code[14] -> ldbrx - a->stdbrx(R7, R3_ARG1, R4_ARG2); // code[15] -> stdbrx - a->vshasigmaw(VR0, VR1, 1, 0xF); // code[16] -> vshasig - a->darn(R7); // code[17] -> darn - a->brw(R5, R6); // code[18] -> brw + a->darn(R7); + a->brw(R5, R6); a->blr(); // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. @@ -536,23 +517,6 @@ void VM_Version::determine_features() { // determine which instructions are legal. int feature_cntr = 0; - if (code[feature_cntr++]) features |= fsqrt_m; - if (code[feature_cntr++]) features |= fsqrts_m; - if (code[feature_cntr++]) features |= isel_m; - if (code[feature_cntr++]) features |= lxarxeh_m; - if (code[feature_cntr++]) features |= cmpb_m; - if (code[feature_cntr++]) features |= popcntb_m; - if (code[feature_cntr++]) features |= popcntw_m; - if (code[feature_cntr++]) features |= fcfids_m; - if (code[feature_cntr++]) features |= vand_m; - if (code[feature_cntr++]) features |= lqarx_m; - if (code[feature_cntr++]) features |= vcipher_m; - if (code[feature_cntr++]) features |= vpmsumb_m; - if (code[feature_cntr++]) features |= mfdscr_m; - if (code[feature_cntr++]) features |= vsx_m; - if (code[feature_cntr++]) features |= ldbrx_m; - if (code[feature_cntr++]) features |= stdbrx_m; - if (code[feature_cntr++]) features |= vshasig_m; if (code[feature_cntr++]) features |= darn_m; if (code[feature_cntr++]) features |= brw_m; diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp index a92aa5ca5e3..18dfd843c19 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2024 SAP SE. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -32,46 +32,12 @@ class VM_Version: public Abstract_VM_Version { protected: enum Feature_Flag { - fsqrt, - fsqrts, - isel, - lxarxeh, - cmpb, - popcntb, - popcntw, - fcfids, - vand, - lqarx, - vcipher, - vpmsumb, - mfdscr, - vsx, - ldbrx, - stdbrx, - vshasig, darn, brw, num_features // last entry to count features }; enum Feature_Flag_Set { unknown_m = 0, - fsqrt_m = (1 << fsqrt ), - fsqrts_m = (1 << fsqrts ), - isel_m = (1 << isel ), - lxarxeh_m = (1 << lxarxeh), - cmpb_m = (1 << cmpb ), - popcntb_m = (1 << popcntb), - popcntw_m = (1 << popcntw), - fcfids_m = (1 << fcfids ), - vand_m = (1 << vand ), - lqarx_m = (1 << lqarx ), - vcipher_m = (1 << vcipher), - vpmsumb_m = (1 << vpmsumb), - mfdscr_m = (1 << mfdscr ), - vsx_m = (1 << vsx ), - ldbrx_m = (1 << ldbrx ), - stdbrx_m = (1 << stdbrx ), - vshasig_m = (1 << vshasig), darn_m = (1 << darn ), brw_m = (1 << brw ), all_features_m = (unsigned long)-1 @@ -101,7 +67,6 @@ public: static bool is_determine_features_test_running() { return _is_determine_features_test_running; } // CPU instruction support - static bool has_mfdscr() { return (_features & mfdscr_m) != 0; } static bool has_darn() { return (_features & darn_m) != 0; } static bool has_brw() { return (_features & brw_m) != 0; } From 83cb0c6de5988de526545d0926c2c6ef60efc1c7 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Mon, 2 Jun 2025 09:22:37 +0000 Subject: [PATCH 064/216] 8358151: Harden JSR166 Test case testShutdownNow_delayedTasks Reviewed-by: alanb, shade --- test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java | 8 +++++--- .../concurrent/tck/ScheduledExecutorSubclassTest.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java b/test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java index 9e26ec11d72..69073ef9dab 100644 --- a/test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java +++ b/test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java @@ -546,11 +546,13 @@ public class ForkJoinPool20Test extends JSR166TestCase { public void testShutdownNow_delayedTasks() throws InterruptedException { final ForkJoinPool p = new ForkJoinPool(2); List> tasks = new ArrayList<>(); + final int DELAY = 100; + for (int i = 0; i < 3; i++) { Runnable r = new NoOpRunnable(); - tasks.add(p.schedule(r, 9, SECONDS)); - tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS)); - tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS)); + tasks.add(p.schedule(r, DELAY, SECONDS)); + tasks.add(p.scheduleAtFixedRate(r, DELAY, DELAY, SECONDS)); + tasks.add(p.scheduleWithFixedDelay(r, DELAY, DELAY, SECONDS)); } p.shutdownNow(); assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); diff --git a/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java b/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java index 43091f9e8f7..588eeabb35f 100644 --- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java +++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java @@ -741,11 +741,13 @@ public class ScheduledExecutorSubclassTest extends JSR166TestCase { public void testShutdownNow_delayedTasks() throws InterruptedException { final CustomExecutor p = new CustomExecutor(1); List> tasks = new ArrayList<>(); + final int DELAY = 100; + for (int i = 0; i < 3; i++) { Runnable r = new NoOpRunnable(); - tasks.add(p.schedule(r, 9, SECONDS)); - tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS)); - tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS)); + tasks.add(p.schedule(r, DELAY, SECONDS)); + tasks.add(p.scheduleAtFixedRate(r, DELAY, DELAY, SECONDS)); + tasks.add(p.scheduleWithFixedDelay(r, DELAY, DELAY, SECONDS)); } if (testImplementationDetails) assertEquals(new HashSet(tasks), new HashSet(p.getQueue())); From c22af0c29ea89857c5cf57dd127b5c739130b2f1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 2 Jun 2025 11:50:50 +0000 Subject: [PATCH 065/216] 8358205: Remove unused JFR array allocation code Reviewed-by: kbarrett, mgronlun --- src/hotspot/share/jfr/jni/jfrJavaCall.cpp | 17 ++--------- src/hotspot/share/jfr/jni/jfrJavaCall.hpp | 6 +--- src/hotspot/share/jfr/jni/jfrJavaSupport.cpp | 30 +------------------- src/hotspot/share/jfr/jni/jfrJavaSupport.hpp | 1 - src/hotspot/share/memory/oopFactory.cpp | 1 - 5 files changed, 5 insertions(+), 50 deletions(-) diff --git a/src/hotspot/share/jfr/jni/jfrJavaCall.cpp b/src/hotspot/share/jfr/jni/jfrJavaCall.cpp index 9c0bcb415b4..5f4489ce745 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaCall.cpp +++ b/src/hotspot/share/jfr/jni/jfrJavaCall.cpp @@ -179,7 +179,7 @@ void JfrJavaArguments::Parameters::copy(JavaCallArguments& args, TRAPS) const { } } -JfrJavaArguments::JfrJavaArguments(JavaValue* result) : _result(result), _klass(nullptr), _name(nullptr), _signature(nullptr), _array_length(-1) { +JfrJavaArguments::JfrJavaArguments(JavaValue* result) : _result(result), _klass(nullptr), _name(nullptr), _signature(nullptr) { assert(result != nullptr, "invariant"); } @@ -187,8 +187,7 @@ JfrJavaArguments::JfrJavaArguments(JavaValue* result, const char* klass_name, co _result(result), _klass(nullptr), _name(nullptr), - _signature(nullptr), - _array_length(-1) { + _signature(nullptr) { assert(result != nullptr, "invariant"); if (klass_name != nullptr) { set_klass(klass_name, CHECK); @@ -204,8 +203,7 @@ JfrJavaArguments::JfrJavaArguments(JavaValue* result, const char* klass_name, co JfrJavaArguments::JfrJavaArguments(JavaValue* result, const Klass* klass, const Symbol* name, const Symbol* signature) : _result(result), _klass(nullptr), _name(nullptr), - _signature(nullptr), - _array_length(-1) { + _signature(nullptr) { assert(result != nullptr, "invariant"); if (klass != nullptr) { set_klass(klass); @@ -268,15 +266,6 @@ void JfrJavaArguments::set_signature(const Symbol* signature) { _signature = signature; } -int JfrJavaArguments::array_length() const { - return _array_length; -} - -void JfrJavaArguments::set_array_length(int length) { - assert(length >= 0, "invariant"); - _array_length = length; -} - JavaValue* JfrJavaArguments::result() const { assert(_result != nullptr, "invariant"); return const_cast(_result); diff --git a/src/hotspot/share/jfr/jni/jfrJavaCall.hpp b/src/hotspot/share/jfr/jni/jfrJavaCall.hpp index 8ea69559427..f5f33100c10 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaCall.hpp +++ b/src/hotspot/share/jfr/jni/jfrJavaCall.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,9 +55,6 @@ class JfrJavaArguments : public StackObj { void set_signature(const char* signature); void set_signature(const Symbol* signature); - int array_length() const; - void set_array_length(int length); - JavaValue* result() const; bool has_receiver() const; @@ -117,7 +114,6 @@ class JfrJavaArguments : public StackObj { const Klass* _klass; const Symbol* _name; const Symbol* _signature; - int _array_length; int java_call_arg_slots() const; void copy(JavaCallArguments& args, TRAPS); diff --git a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp index 1dd7168e9e5..3b566868f07 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp +++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp @@ -178,19 +178,6 @@ static void object_construction(JfrJavaArguments* args, JavaValue* result, Insta result->set_oop(h_obj()); } -static void array_construction(JfrJavaArguments* args, JavaValue* result, InstanceKlass* klass, int array_length, TRAPS) { - assert(args != nullptr, "invariant"); - assert(result != nullptr, "invariant"); - assert(klass != nullptr, "invariant"); - assert(klass->is_initialized(), "invariant"); - - Klass* const ak = klass->array_klass(THREAD); - ObjArrayKlass::cast(ak)->initialize(THREAD); - HandleMark hm(THREAD); - objArrayOop arr = ObjArrayKlass::cast(ak)->allocate(array_length, CHECK); - result->set_oop(arr); -} - static void create_object(JfrJavaArguments* args, JavaValue* result, TRAPS) { assert(args != nullptr, "invariant"); assert(result != nullptr, "invariant"); @@ -200,13 +187,7 @@ static void create_object(JfrJavaArguments* args, JavaValue* result, TRAPS) { InstanceKlass* const klass = static_cast(args->klass()); klass->initialize(CHECK); - const int array_length = args->array_length(); - - if (array_length >= 0) { - array_construction(args, result, klass, array_length, CHECK); - } else { - object_construction(args, result, klass, THREAD); - } + object_construction(args, result, klass, THREAD); } static void handle_result(JavaValue* result, bool global_ref, JavaThread* t) { @@ -252,15 +233,6 @@ jstring JfrJavaSupport::new_string(const char* c_str, TRAPS) { return (jstring)local_jni_handle(result, THREAD); } -jobjectArray JfrJavaSupport::new_string_array(int length, TRAPS) { - DEBUG_ONLY(check_java_thread_in_vm(THREAD)); - JavaValue result(T_OBJECT); - JfrJavaArguments args(&result, "java/lang/String", "", "()V", CHECK_NULL); - args.set_array_length(length); - new_object_local_ref(&args, THREAD); - return (jobjectArray)args.result()->get_jobject(); -} - jobject JfrJavaSupport::new_java_lang_Boolean(bool value, TRAPS) { DEBUG_ONLY(check_java_thread_in_vm(THREAD)); JavaValue result(T_OBJECT); diff --git a/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp b/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp index 118782bc61e..35c2414168f 100644 --- a/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp +++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp @@ -69,7 +69,6 @@ class JfrJavaSupport : public AllStatic { static void get_field_local_ref(JfrJavaArguments* args, TRAPS); static jstring new_string(const char* c_str, TRAPS); - static jobjectArray new_string_array(int length, TRAPS); static jobject new_java_lang_Boolean(bool value, TRAPS); static jobject new_java_lang_Integer(jint value, TRAPS); diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp index 83140aa44f5..949b4fe134b 100644 --- a/src/hotspot/share/memory/oopFactory.cpp +++ b/src/hotspot/share/memory/oopFactory.cpp @@ -107,7 +107,6 @@ typeArrayOop oopFactory::new_typeArray_nozero(BasicType type, int length, TRAPS) objArrayOop oopFactory::new_objArray(Klass* klass, int length, TRAPS) { - assert(klass->is_klass(), "must be instance class"); if (klass->is_array_klass()) { return ArrayKlass::cast(klass)->allocate_arrayArray(1, length, THREAD); } else { From 83b15da2eb3cb6c8937f517c9b75eaa9eeece314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Mon, 2 Jun 2025 12:26:08 +0000 Subject: [PATCH 066/216] 8351997: AArch64: Interpreter volatile reference stores with G1 are not sequentially consistent Reviewed-by: shade, aph, fbredberg --- src/hotspot/cpu/aarch64/templateTable_aarch64.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index 4c1e4ce3a05..fcfe153a9a5 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1144,6 +1144,7 @@ void TemplateTable::aastore() { // Get the value we will store __ ldr(r0, at_tos()); // Now store using the appropriate barrier + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, r0, IS_ARRAY); __ b(done); @@ -1152,6 +1153,7 @@ void TemplateTable::aastore() { __ profile_null_seen(r2); // Store a null + // Clobbers: r10, r11, r3 do_oop_store(_masm, element_address, noreg, IS_ARRAY); // Pop stack arguments @@ -2882,6 +2884,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr __ pop(atos); if (!is_static) pop_and_check_object(obj); // Store into the field + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); if (rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_aputfield, bc, r1, true, byte_no); @@ -3077,12 +3080,12 @@ void TemplateTable::fast_storefield(TosState state) // access constant pool cache __ load_field_entry(r2, r1); - // R1: field offset, R2: field holder, R3: flags - load_resolved_field_entry(r2, r2, noreg, r1, r3); + // R1: field offset, R2: field holder, R5: flags + load_resolved_field_entry(r2, r2, noreg, r1, r5); { Label notVolatile; - __ tbz(r3, ResolvedFieldEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ResolvedFieldEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); __ bind(notVolatile); } @@ -3098,6 +3101,7 @@ void TemplateTable::fast_storefield(TosState state) // access field switch (bytecode()) { case Bytecodes::_fast_aputfield: + // Clobbers: r10, r11, r3 do_oop_store(_masm, field, r0, IN_HEAP); break; case Bytecodes::_fast_lputfield: @@ -3130,7 +3134,7 @@ void TemplateTable::fast_storefield(TosState state) { Label notVolatile; - __ tbz(r3, ResolvedFieldEntry::is_volatile_shift, notVolatile); + __ tbz(r5, ResolvedFieldEntry::is_volatile_shift, notVolatile); __ membar(MacroAssembler::StoreLoad | MacroAssembler::StoreStore); __ bind(notVolatile); } From b3594c9e5508101a39d10099830f04b0c09ad41f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 2 Jun 2025 13:08:41 +0000 Subject: [PATCH 067/216] 8357481: Excessive CompileTask wait/notify monitor creation Reviewed-by: vlivanov, kvn --- src/hotspot/share/compiler/compileBroker.cpp | 12 ++++++------ src/hotspot/share/compiler/compileTask.cpp | 3 --- src/hotspot/share/compiler/compileTask.hpp | 16 +++++----------- src/hotspot/share/runtime/mutexLocker.cpp | 5 ++++- src/hotspot/share/runtime/mutexLocker.hpp | 1 + 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index d23d2e4febe..b5f02b2d9a2 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -231,7 +231,7 @@ CompileTaskWrapper::~CompileTaskWrapper() { if (task->is_blocking()) { bool free_task = false; { - MutexLocker notifier(thread, task->lock()); + MutexLocker notifier(thread, CompileTaskWait_lock); task->mark_complete(); #if INCLUDE_JVMCI if (CompileBroker::compiler(task->comp_level())->is_jvmci()) { @@ -245,7 +245,7 @@ CompileTaskWrapper::~CompileTaskWrapper() { if (!free_task) { // Notify the waiting thread that the compilation has completed // so that it can free the task. - task->lock()->notify_all(); + CompileTaskWait_lock->notify_all(); } } if (free_task) { @@ -375,12 +375,12 @@ void CompileQueue::free_all() { next = current->next(); bool found_waiter = false; { - MutexLocker ct_lock(current->lock()); + MutexLocker ct_lock(CompileTaskWait_lock); assert(current->waiting_for_completion_count() <= 1, "more than one thread are waiting for task"); if (current->waiting_for_completion_count() > 0) { // If another thread waits for this task, we must wake them up // so they will stop waiting and free the task. - current->lock()->notify(); + CompileTaskWait_lock->notify_all(); found_waiter = true; } } @@ -1655,7 +1655,7 @@ static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 10; */ bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask* task, JavaThread* thread) { assert(UseJVMCICompiler, "sanity"); - MonitorLocker ml(thread, task->lock()); + MonitorLocker ml(thread, CompileTaskWait_lock); int progress_wait_attempts = 0; jint thread_jvmci_compilation_ticks = 0; jint global_jvmci_compilation_ticks = jvmci->global_compilation_ticks(); @@ -1723,7 +1723,7 @@ void CompileBroker::wait_for_completion(CompileTask* task) { } else #endif { - MonitorLocker ml(thread, task->lock()); + MonitorLocker ml(thread, CompileTaskWait_lock); free_task = true; task->inc_waiting_for_completion(); while (!task->is_complete() && !is_compilation_disabled_forever()) { diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index 4f91984f7a5..b955a250fae 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -65,7 +65,6 @@ CompileTask* CompileTask::allocate() { void CompileTask::free(CompileTask* task) { MutexLocker locker(CompileTaskAlloc_lock); if (!task->is_free()) { - assert(!task->lock()->is_locked(), "Should not be locked when freed"); if ((task->_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_method_holder))) { JNIHandles::destroy_weak_global(task->_method_holder); } else { @@ -90,8 +89,6 @@ void CompileTask::initialize(int compile_id, int hot_count, CompileTask::CompileReason compile_reason, bool is_blocking) { - assert(!_lock->is_locked(), "bad locking"); - Thread* thread = Thread::current(); _compile_id = compile_id; _method = method(); diff --git a/src/hotspot/share/compiler/compileTask.hpp b/src/hotspot/share/compiler/compileTask.hpp index d615885e51c..166f6497f2b 100644 --- a/src/hotspot/share/compiler/compileTask.hpp +++ b/src/hotspot/share/compiler/compileTask.hpp @@ -29,6 +29,7 @@ #include "code/nmethod.hpp" #include "compiler/compileLog.hpp" #include "memory/allocation.hpp" +#include "runtime/mutexLocker.hpp" #include "utilities/xmlstream.hpp" class CompileTrainingData; @@ -82,7 +83,6 @@ class CompileTask : public CHeapObj { private: static CompileTask* _task_free_list; - Monitor* _lock; int _compile_id; Method* _method; jobject _method_holder; @@ -116,11 +116,7 @@ class CompileTask : public CHeapObj { size_t _arena_bytes; // peak size of temporary memory during compilation (e.g. node arenas) public: - CompileTask() : _failure_reason(nullptr), _failure_reason_on_C_heap(false) { - // May hold MethodCompileQueue_lock - _lock = new Monitor(Mutex::safepoint-1, "CompileTask_lock"); - } - + CompileTask() : _failure_reason(nullptr), _failure_reason_on_C_heap(false) {} void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level, int hot_count, CompileTask::CompileReason compile_reason, bool is_blocking); @@ -172,21 +168,19 @@ class CompileTask : public CHeapObj { } #endif - Monitor* lock() const { return _lock; } - // See how many threads are waiting for this task. Must have lock to read this. int waiting_for_completion_count() { - assert(_lock->owned_by_self(), "must have lock to use waiting_for_completion_count()"); + assert(CompileTaskWait_lock->owned_by_self(), "must have lock to use waiting_for_completion_count()"); return _waiting_count; } // Indicates that a thread is waiting for this task to complete. Must have lock to use this. void inc_waiting_for_completion() { - assert(_lock->owned_by_self(), "must have lock to use inc_waiting_for_completion()"); + assert(CompileTaskWait_lock->owned_by_self(), "must have lock to use inc_waiting_for_completion()"); _waiting_count++; } // Indicates that a thread stopped waiting for this task to complete. Must have lock to use this. void dec_waiting_for_completion() { - assert(_lock->owned_by_self(), "must have lock to use dec_waiting_for_completion()"); + assert(CompileTaskWait_lock->owned_by_self(), "must have lock to use dec_waiting_for_completion()"); assert(_waiting_count > 0, "waiting count is not positive"); _waiting_count--; } diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index eb57d0f9744..36e0cfe1125 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -79,6 +79,7 @@ Mutex* MarkStackChunkList_lock = nullptr; Mutex* MonitoringSupport_lock = nullptr; Monitor* ConcurrentGCBreakpoints_lock = nullptr; Mutex* Compile_lock = nullptr; +Monitor* CompileTaskWait_lock = nullptr; Monitor* MethodCompileQueue_lock = nullptr; Monitor* CompileThread_lock = nullptr; Monitor* Compilation_lock = nullptr; @@ -342,7 +343,9 @@ void mutex_init() { MUTEX_DEFL(G1RareEvent_lock , PaddedMutex , Threads_lock, true); } - MUTEX_DEFL(CompileTaskAlloc_lock , PaddedMutex , MethodCompileQueue_lock); + MUTEX_DEFL(CompileTaskAlloc_lock , PaddedMutex , MethodCompileQueue_lock); + MUTEX_DEFL(CompileTaskWait_lock , PaddedMonitor, MethodCompileQueue_lock); + #if INCLUDE_PARALLELGC if (UseParallelGC) { MUTEX_DEFL(PSOldGenExpand_lock , PaddedMutex , Heap_lock, true); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index bc36db00dc3..6baa93b2579 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -86,6 +86,7 @@ extern Monitor* Compilation_lock; // a lock used to pause compila 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* 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 extern Monitor* Terminator_lock; // a lock used to guard termination of the vm From a4eb15195ceeadf311fe81e622a54f4733b90df2 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 2 Jun 2025 15:24:09 +0000 Subject: [PATCH 068/216] 8357672: Extreme font sizes can cause font substitution Reviewed-by: dmarkov, jdv --- .../classes/sun/font/FileFontStrike.java | 1 - .../native/libfontmanager/freetypeScaler.c | 1 - .../awt/FontMetrics/ExtremeFontSizeTest.java | 112 ++++++++++++++++-- 3 files changed, 102 insertions(+), 12 deletions(-) diff --git a/src/java.desktop/share/classes/sun/font/FileFontStrike.java b/src/java.desktop/share/classes/sun/font/FileFontStrike.java index 37910a41272..01e682e8390 100644 --- a/src/java.desktop/share/classes/sun/font/FileFontStrike.java +++ b/src/java.desktop/share/classes/sun/font/FileFontStrike.java @@ -193,7 +193,6 @@ public class FileFontStrike extends PhysicalStrike { this.disposer = new FontStrikeDisposer(fileFont, desc); initGlyphCache(); pScalerContext = NullFontScaler.getNullScalerContext(); - SunFontManager.getInstance().deRegisterBadFont(fileFont); return; } /* First, see if native code should be used to create the glyph. diff --git a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c index 8b7e147c72c..f46b8a45aca 100644 --- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c +++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c @@ -532,7 +532,6 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative( if (context == NULL) { free(context); - invalidateJavaScaler(env, scaler, NULL); return (jlong) 0; } (*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat); diff --git a/test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java b/test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java index caa365a3f21..f596f710831 100644 --- a/test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java +++ b/test/jdk/java/awt/FontMetrics/ExtremeFontSizeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,16 +24,19 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.Map; /* * @test - * @bug 8328896 + * @bug 8328896 8357672 * @summary test that using very large font sizes used don't break later uses */ @@ -49,34 +52,106 @@ public class ExtremeFontSizeTest { static double[] scales = { 1.0, 900.0}; static boolean[] fms = { false, true }; + static class Key { + int fontSize; + double scale; + boolean fm; + String str; + + + Key(int fs, double sc, boolean f, String s) { + fontSize = fs; + scale = sc; + fm = f; + str = s; + } + + public boolean equals(Object o) { + return + (o instanceof Key k) && + this.fontSize == k.fontSize && + this.scale == k.scale && + this.fm == k.fm && + this.str.equals(k.str); + } + + public int hashCode() { + return fontSize + (int)scale + (fm ? 1 : 0) + str.hashCode(); + } + } + + static class Value { + int height; + double strBounds; + Rectangle pixelBounds; + Rectangle2D visualBounds; + + Value(int h, double sb, Rectangle pb, Rectangle2D vb) { + height = h; + strBounds = sb; + pixelBounds = pb; + visualBounds = vb; + } + + public boolean equals(Object o) { + return + (o instanceof Value v) && + this.height == v.height && + this.strBounds == v.strBounds && + this.pixelBounds.equals(v.pixelBounds) && + this.visualBounds.equals(v.visualBounds); + } + + public int hashCode() { + return height + (int)strBounds + pixelBounds.hashCode() + visualBounds.hashCode(); + } + } + + static Map metricsMap = new HashMap(); + public static void main(String[] args) { + Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); + for (Font f : fonts) { + font = f.deriveFont(Font.PLAIN, 12); + System.out.println("Test font : " + font); + if (font.canDisplayUpTo(testString) != -1) { + System.out.println("Skipping since cannot display test string"); + continue; + } + metricsMap = new HashMap(); + testFont(); + } + } + + static void testFont() { /* run tests validating bounds etc are non-zero * then run with extreme scales for which zero is allowed - but not required * then run the first tests again to be sure they are still reasonable. */ - runTests(); - test(5_000_000, 10_000, false, testString, false); - test(5_000_000, 10_000, true, testString, false); - test(0, 0.00000001, false, testString, false); - runTests(); + runTests(true, false); + test(5_000_000, 10_000, false, testString, false, false, false); + test(5_000_000, 10_000, true, testString, false, false, false); + test(0, 0.00000001, false, testString, false, false, false); + runTests(false, true); if (failed) { throw new RuntimeException("Test failed. Check stdout log."); } } - static void runTests() { + static void runTests(boolean add, boolean check) { for (int fontSize : fontSizes) { for (double scale : scales) { for (boolean fm : fms) { - test(fontSize, scale, fm, testString, true); + test(fontSize, scale, fm, testString, true, add, check); } } } } - static void test(int size, double scale, boolean fm, String str, boolean checkAll) { + static void test(int size, double scale, boolean fm, String str, + boolean checkAll, boolean add, boolean check) { AffineTransform at = AffineTransform.getScaleInstance(scale, scale); FontRenderContext frc = new FontRenderContext(at, false, fm); @@ -114,5 +189,22 @@ public class ExtremeFontSizeTest { System.out.println(" *** RESULTS NOT AS EXPECTED *** "); } System.out.println(); + + Key k = null; + Value v = null; + if (add || check) { + k = new Key(size, scale, fm, str); + v = new Value(height, width, pixelBounds, visualBounds); + } + if (add) { + metricsMap.put(k, v); + } + if (check) { + Value vmap = metricsMap.get(k); + if (!v.equals(vmap)) { + failed = true; + System.out.println("Values differ"); + } + } } } From daab7b5ceeb12222bda709e35699e620b98cb74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Mon, 2 Jun 2025 15:27:14 +0000 Subject: [PATCH 069/216] 8357796: Stylesheet adjustments after JDK-8357452 Reviewed-by: rriggs --- .../internal/doclets/formats/html/resources/stylesheet.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index 08cd78dad78..2c10cb3bc6f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -23,7 +23,7 @@ /* Base font sizes for body and code elements */ --body-font-size: 14.2px; --block-font-size: 14.4px; - --code-font-size: 13.9px; + --code-font-size: 14px; --nav-font-size: 13.4px; /* Line height for continuous text blocks */ --block-line-height: 1.5; @@ -606,6 +606,7 @@ ul.tag-list li:not(:last-child):after, ul.tag-list-long li:not(:last-child):after { content: ", "; + white-space: pre-wrap; } ul.preview-feature-list { list-style: none; From 1b6ae2059b0475ec78559d2d6612f3b6ec68309f Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Mon, 2 Jun 2025 15:29:30 +0000 Subject: [PATCH 070/216] 8357576: FieldInfo::_index is not initialized by the constructor Reviewed-by: coleenp, dholmes --- src/hotspot/share/oops/fieldInfo.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/oops/fieldInfo.hpp b/src/hotspot/share/oops/fieldInfo.hpp index d2fd79332a9..8740d539c8f 100644 --- a/src/hotspot/share/oops/fieldInfo.hpp +++ b/src/hotspot/share/oops/fieldInfo.hpp @@ -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 @@ -137,7 +137,8 @@ class FieldInfo { public: - FieldInfo() : _name_index(0), + FieldInfo() : _index(0), + _name_index(0), _signature_index(0), _offset(0), _access_flags(AccessFlags(0)), @@ -147,6 +148,7 @@ class FieldInfo { _contention_group(0) { } FieldInfo(AccessFlags access_flags, u2 name_index, u2 signature_index, u2 initval_index, FieldInfo::FieldFlags fflags) : + _index(0), _name_index(name_index), _signature_index(signature_index), _offset(0), From 99a4b22ae7dc2755df1780cc7d74c5d6e3cd4cd4 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Mon, 2 Jun 2025 16:48:16 +0000 Subject: [PATCH 071/216] 8358102: GenShen: Age tables could be seeded with cumulative values Reviewed-by: ysr --- src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp b/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp index d393c17f64a..b1d474fa78d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahEvacTracker.cpp @@ -154,7 +154,7 @@ ShenandoahCycleStats ShenandoahEvacuationTracker::flush_cycle_to_global() { // for use in the next cycle. // The first argument is used for any age 0 cohort population that we may otherwise have // missed during the census. This is non-zero only when census happens at marking. - ShenandoahGenerationalHeap::heap()->age_census()->update_census(0, _mutators_global.age_table(), _workers_global.age_table()); + ShenandoahGenerationalHeap::heap()->age_census()->update_census(0, mutators.age_table(), workers.age_table()); } return {workers, mutators}; From ab5de45636f0bf96e52c0ae0dcf080f279d9caee Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 2 Jun 2025 16:50:10 +0000 Subject: [PATCH 072/216] 8357991: make bootcycle-images is broken after JDK-8349665 Reviewed-by: erikj --- make/Main.gmk | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/make/Main.gmk b/make/Main.gmk index 6a800a2edd5..c1b84dc1855 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -417,12 +417,22 @@ $(eval $(call SetupTarget, create-source-revision-tracker, \ )) BOOTCYCLE_TARGET := product-images +BOOTCYCLE_SPEC := $(dir $(SPEC))bootcycle-spec.gmk + bootcycle-images: ifneq ($(COMPILE_TYPE), cross) $(call LogWarn, Boot cycle build step 2: Building a new JDK image using previously built image) $(call MakeDir, $(OUTPUTDIR)/bootcycle-build) + # We need to create essential files for the bootcycle spec dir + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -f make/GenerateFindTests.gmk \ + SPEC=$(BOOTCYCLE_SPEC)) + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Main.gmk \ + SPEC=$(BOOTCYCLE_SPEC) UPDATE_MODULE_DEPS=true NO_RECIPES=true \ + create-main-targets-include ) +$(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \ - LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(dir $(SPEC))bootcycle-spec.gmk main + LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(BOOTCYCLE_SPEC) main else $(call LogWarn, Boot cycle build disabled when cross compiling) endif From 8b6a11f7e05ee0cece798c5ff6646bddbee04900 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Mon, 2 Jun 2025 16:51:44 +0000 Subject: [PATCH 073/216] 8352187: Don't start management agent during AOT cache creation Reviewed-by: shade, iklam, kvn --- src/hotspot/share/runtime/threads.cpp | 21 ++++-- .../cds/appcds/aotCache/ManagementAgent.java | 64 +++++++++++++++++++ 2 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 987db37e9d5..8d8d4782e94 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -847,13 +847,22 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { JFR_ONLY(Jfr::on_create_vm_3();) #if INCLUDE_MANAGEMENT - Management::initialize(THREAD); + bool start_agent = true; +#if INCLUDE_CDS + start_agent = !CDSConfig::is_dumping_final_static_archive(); + if (!start_agent) { + log_info(aot)("Not starting management agent during creation of AOT cache."); + } +#endif // INCLUDE_CDS + if (start_agent) { + Management::initialize(THREAD); - if (HAS_PENDING_EXCEPTION) { - // management agent fails to start possibly due to - // configuration problem and is responsible for printing - // stack trace if appropriate. Simply exit VM. - vm_exit(1); + if (HAS_PENDING_EXCEPTION) { + // management agent fails to start possibly due to + // configuration problem and is responsible for printing + // stack trace if appropriate. Simply exit VM. + vm_exit(1); + } } #endif // INCLUDE_MANAGEMENT diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java new file mode 100644 index 00000000000..abbdd3551b7 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + + +/* + * @test + * @bug 8352187 + * @summary ManagementAgent will not be started during AOT cache creation. + * @requires vm.cds.supports.aot.class.linking + * @comment work around JDK-8345635 + * @requires !vm.jvmci.enabled + * @library /test/lib + * @build HelloAOTCache + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloAOTCacheApp + * @run driver ManagementAgent + */ + +import jdk.test.lib.cds.SimpleCDSAppTester; +import jdk.test.lib.process.OutputAnalyzer; + +public class ManagementAgent { + public static void main(String... args) throws Exception { + SimpleCDSAppTester.of("HelloAOTCache-with-management-agent") + // test with the initialization of a management agent + .addVmArgs("-Xlog:class+load", "-Dcom.sun.management.jmxremote=true") + .classpath("app.jar") + .appCommandLine("HelloAOTCacheApp") + .setAssemblyChecker((OutputAnalyzer out) -> { + out.shouldContain("Not starting management agent during creation of AOT cache."); + }) + .setProductionChecker((OutputAnalyzer out) -> { + out.shouldMatch("class,load.*HelloAOTCacheApp.*shared objects"); + out.shouldContain("HelloWorld"); + }) + .runAOTWorkflow(); + } +} + +class HelloAOTCacheApp { + public static void main(String[] args) { + System.out.println("HelloWorld"); + } +} From bce2bd24ef64e71d895bbf4d91693b30a285746b Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 2 Jun 2025 16:52:05 +0000 Subject: [PATCH 074/216] 8356308: Assert with -Xlog:class+path when classpath has an empty element Reviewed-by: dholmes, ccheung --- src/hotspot/share/cds/aotClassLocation.cpp | 37 ++++++++--- src/hotspot/share/cds/aotClassLocation.hpp | 3 +- src/hotspot/share/cds/filemap.cpp | 2 +- .../share/utilities/classpathStream.cpp | 40 +++++++++--- .../share/utilities/classpathStream.hpp | 23 +++---- .../cds/appcds/PrintSharedArchiveAndExit.java | 6 +- .../cds/appcds/aotCache/ClassPathLogging.java | 64 +++++++++++++++++++ 7 files changed, 139 insertions(+), 36 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/ClassPathLogging.java diff --git a/src/hotspot/share/cds/aotClassLocation.cpp b/src/hotspot/share/cds/aotClassLocation.cpp index 192791ebd9c..b662c5a1b47 100644 --- a/src/hotspot/share/cds/aotClassLocation.cpp +++ b/src/hotspot/share/cds/aotClassLocation.cpp @@ -464,6 +464,7 @@ void AOTClassLocationConfig::dumptime_init_helper(TRAPS) { AOTClassLocation* jrt = AOTClassLocation::allocate(THREAD, ClassLoader::get_jrt_entry()->name(), 0, Group::MODULES_IMAGE, /*from_cpattr*/false, /*is_jrt*/true); + log_info(class, path)("path [%d] = (modules image)", tmp_array.length()); tmp_array.append(jrt); parse(THREAD, tmp_array, all_css.boot_cp(), Group::BOOT_CLASSPATH, /*parse_manifest*/true); @@ -573,6 +574,7 @@ void AOTClassLocationConfig::parse(JavaThread* current, GrowableClassLocationArr void AOTClassLocationConfig::add_class_location(JavaThread* current, GrowableClassLocationArray& tmp_array, const char* path, Group group, bool parse_manifest, bool from_cpattr) { AOTClassLocation* cs = AOTClassLocation::allocate(current, path, tmp_array.length(), group, from_cpattr); + log_info(class, path)("path [%d] = %s%s", tmp_array.length(), path, from_cpattr ? " (from cpattr)" : ""); tmp_array.append(cs); if (!parse_manifest) { @@ -726,6 +728,8 @@ bool AOTClassLocationConfig::is_valid_classpath_index(int classpath_index, Insta } AOTClassLocationConfig* AOTClassLocationConfig::write_to_archive() const { + log_locations(CDSConfig::output_archive_path(), /*is_write=*/true); + Array* archived_copy = ArchiveBuilder::new_ro_array(_class_locations->length()); for (int i = 0; i < _class_locations->length(); i++) { archived_copy->at_put(i, _class_locations->at(i)->write_to_archive()); @@ -773,7 +777,7 @@ bool AOTClassLocationConfig::check_classpaths(bool is_boot_classpath, bool has_a effective_dumptime_path = substitute(effective_dumptime_path, _dumptime_lcp_len, runtime_lcp, runtime_lcp_len); } - log_info(class, path)("Checking '%s' %s%s", effective_dumptime_path, cs->file_type_string(), + log_info(class, path)("Checking [%d] '%s' %s%s", i, effective_dumptime_path, cs->file_type_string(), cs->from_cpattr() ? " (from JAR manifest ClassPath attribute)" : ""); if (!cs->from_cpattr() && file_exists(effective_dumptime_path)) { if (!runtime_css.has_next()) { @@ -961,11 +965,14 @@ bool AOTClassLocationConfig::need_lcp_match_helper(int start, int end, ClassLoca return true; } -bool AOTClassLocationConfig::validate(bool has_aot_linked_classes, bool* has_extra_module_paths) const { +bool AOTClassLocationConfig::validate(const char* cache_filename, bool has_aot_linked_classes, bool* has_extra_module_paths) const { ResourceMark rm; AllClassLocationStreams all_css; + log_locations(cache_filename, /*is_write=*/false); + const char* jrt = ClassLoader::get_jrt_entry()->name(); + log_info(class, path)("Checking [0] (modules image)"); bool success = class_location_at(0)->check(jrt, has_aot_linked_classes); log_info(class, path)("Modules image %s validation: %s", jrt, success ? "passed" : "failed"); if (!success) { @@ -1036,6 +1043,17 @@ bool AOTClassLocationConfig::validate(bool has_aot_linked_classes, bool* has_ext return success; } +void AOTClassLocationConfig::log_locations(const char* cache_filename, bool is_write) const { + if (log_is_enabled(Info, class, path)) { + LogStreamHandle(Info, class, path) st; + st.print_cr("%s classpath(s) %s %s (size = %d)", + is_write ? "Writing" : "Reading", + is_write ? "into" : "from", + cache_filename, class_locations()->length()); + print_on(&st); + } +} + void AOTClassLocationConfig::print() { if (CDSConfig::is_dumping_archive()) { tty->print_cr("AOTClassLocationConfig::_dumptime_instance = %p", _dumptime_instance); @@ -1052,8 +1070,15 @@ void AOTClassLocationConfig::print() { } void AOTClassLocationConfig::print_on(outputStream* st) const { + const char* type = "boot"; int n = class_locations()->length(); for (int i = 0; i < n; i++) { + if (i >= boot_cp_end_index()) { + type = "app"; + } + if (i >= app_cp_end_index()) { + type = "module"; + } const AOTClassLocation* cs = class_location_at(i); const char* path; if (i == 0) { @@ -1061,12 +1086,6 @@ void AOTClassLocationConfig::print_on(outputStream* st) const { } else { path = cs->path(); } - st->print_cr("[%d] = %s", i, path); - if (i == boot_cp_end_index() && i < n) { - st->print_cr("--- end of boot"); - } - if (i == app_cp_end_index() && i < n) { - st->print_cr("--- end of app"); - } + st->print_cr("(%-6s) [%d] = %s", type, i, path); } } diff --git a/src/hotspot/share/cds/aotClassLocation.hpp b/src/hotspot/share/cds/aotClassLocation.hpp index f93bb899a4c..460788930a4 100644 --- a/src/hotspot/share/cds/aotClassLocation.hpp +++ b/src/hotspot/share/cds/aotClassLocation.hpp @@ -204,6 +204,7 @@ class AOTClassLocationConfig : public CHeapObj { const char* prepend, size_t prepend_len) const; void print_on(outputStream* st) const; + void log_locations(const char* cache_filename, bool is_writing) const; public: static AOTClassLocationConfig* dumptime() { @@ -269,7 +270,7 @@ public: AOTClassLocationConfig* write_to_archive() const; // Functions used only during runtime - bool validate(bool has_aot_linked_classes, bool* has_extra_module_paths) const; + bool validate(const char* cache_filename, bool has_aot_linked_classes, bool* has_extra_module_paths) const; bool is_valid_classpath_index(int classpath_index, InstanceKlass* ik); diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 723b5298646..a413aa2d8e8 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -325,7 +325,7 @@ bool FileMapInfo::validate_class_location() { AOTClassLocationConfig* config = header()->class_location_config(); bool has_extra_module_paths = false; - if (!config->validate(header()->has_aot_linked_classes(), &has_extra_module_paths)) { + if (!config->validate(full_path(), header()->has_aot_linked_classes(), &has_extra_module_paths)) { if (PrintSharedArchiveAndExit) { MetaspaceShared::set_archive_loading_failed(); return true; diff --git a/src/hotspot/share/utilities/classpathStream.cpp b/src/hotspot/share/utilities/classpathStream.cpp index cf0b84b18fb..8581c7831ab 100644 --- a/src/hotspot/share/utilities/classpathStream.cpp +++ b/src/hotspot/share/utilities/classpathStream.cpp @@ -26,18 +26,40 @@ #include "runtime/os.hpp" #include "utilities/classpathStream.hpp" -const char* ClasspathStream::get_next() { - while (_class_path[_end] != '\0' && _class_path[_end] != os::path_separator()[0]) { - _end++; +ClasspathStream::ClasspathStream(const char* classpath) { + _cp = classpath; + skip_blank_paths(); +} + +char ClasspathStream::separator() { + // All supported platforms have a single character path separator. + return os::path_separator()[0]; +} + +void ClasspathStream::skip_blank_paths() { + while (*_cp == separator()) { + _cp++; } - int path_len = _end - _start; +} + +const char* ClasspathStream::get_next() { + assert(has_next(), "call this only after you checked has_next()"); + assert(*_cp != separator(), "ensured by constructor and get_next()"); + + const char* end = _cp + 1; + while (*end != separator() && *end != '\0') { + end++; + } + + int path_len = end - _cp; char* path = NEW_RESOURCE_ARRAY(char, path_len + 1); - strncpy(path, &_class_path[_start], path_len); + strncpy(path, _cp, path_len); path[path_len] = '\0'; - while (_class_path[_end] == os::path_separator()[0]) { - _end++; - } - _start = _end; + assert(strlen(path) > 0, "must be"); + + _cp = end; + skip_blank_paths(); + return path; } diff --git a/src/hotspot/share/utilities/classpathStream.hpp b/src/hotspot/share/utilities/classpathStream.hpp index 3c29a07262d..87f7649872d 100644 --- a/src/hotspot/share/utilities/classpathStream.hpp +++ b/src/hotspot/share/utilities/classpathStream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,23 +26,20 @@ #define SHARE_UTILITIES_CLASSPATHSTREAM_HPP class ClasspathStream : public StackObj { - const char* _class_path; - int _len; - int _start; - int _end; - + const char* _cp; + static char separator(); + void skip_blank_paths(); public: - ClasspathStream(const char* class_path) { - _class_path = class_path; - _len = (int)strlen(class_path); - _start = 0; - _end = 0; - } + // The caller should ensure that class_path is alive during the + // lifetime of this ClasspathStream. + ClasspathStream(const char* class_path); bool has_next() { - return _start < _len; + return *_cp != '\0'; } + // Call this only after you checked has_next(). + // Returns a resource-allocated string. const char* get_next(); }; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java b/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java index c0dce14ab82..23dcc7e5fcf 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/PrintSharedArchiveAndExit.java @@ -59,9 +59,9 @@ public class PrintSharedArchiveAndExit { String appJar = JarBuilder.getOrCreateHelloJar(); String appJar2 = JarBuilder.build("PrintSharedArchiveAndExit-more", "HelloMore"); String cp = appJar + File.pathSeparator + appJar2; - String firstCheckShortMsg = "Checking 'hello.jar' file"; // the first JAR to check (without directory prefix) - String firstCheckMsg = "Checking '" + appJar + "' file"; // the first JAR to check - String lastCheckMsg = "Checking '" + appJar2 + "' file"; // the last JAR to check + String firstCheckShortMsg = "Checking [1] 'hello.jar' file"; // the first JAR to check (without directory prefix) + String firstCheckMsg = "Checking [1] '" + appJar + "' file"; // the first JAR to check + String lastCheckMsg = "Checking [2] '" + appJar2 + "' file"; // the last JAR to check TestCommon.testDump(cp, TestCommon.list("Hello", "HelloMore")); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ClassPathLogging.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ClassPathLogging.java new file mode 100644 index 00000000000..0d5bca34d68 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ClassPathLogging.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + + +/* + * @test + * @summary verify the output of -Xlog:class+path when using AOT cache + * @bug 8356308 + * @requires vm.cds.supports.aot.class.linking + * @requires vm.flagless + * @library /test/lib + * @build ClassPathLogging + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar ClassPathLoggingApp + * @run driver ClassPathLogging + */ + +import java.io.File; +import jdk.test.lib.cds.SimpleCDSAppTester; +import jdk.test.lib.process.OutputAnalyzer; + +public class ClassPathLogging { + public static void main(String... args) throws Exception { + String sep = File.pathSeparator; + SimpleCDSAppTester.of("ClassPathLogging") + .addVmArgs("-Xlog:class+path=debug") + .classpath(sep + "foo.jar" + sep + sep + sep + "app.jar" + sep) // all empty paths should be skipped. + .appCommandLine("ClassPathLoggingApp") + .setProductionChecker((OutputAnalyzer out) -> { + out.shouldContain("HelloWorld") + .shouldContain("Reading classpath(s) from ClassPathLogging.aot (size = 3)") + .shouldMatch("boot.*0.*=.*modules") + .shouldContain("(app ) [1] = foo.jar") + .shouldContain("(app ) [2] = app.jar"); + }) + .runAOTWorkflow(); + } +} + +class ClassPathLoggingApp { + public static void main(String[] args) { + System.out.println("HelloWorld"); + } +} From a7671e7360ce23df9577110266e66a1c1a790196 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 2 Jun 2025 17:06:45 +0000 Subject: [PATCH 075/216] 8358337: JDK-8357991 was committed with incorrect indentation Reviewed-by: shade --- make/Main.gmk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/make/Main.gmk b/make/Main.gmk index c1b84dc1855..386bd226842 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -425,12 +425,12 @@ bootcycle-images: $(call MakeDir, $(OUTPUTDIR)/bootcycle-build) # We need to create essential files for the bootcycle spec dir ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -f make/GenerateFindTests.gmk \ - SPEC=$(BOOTCYCLE_SPEC)) + $(MAKE) $(MAKE_ARGS) -f make/GenerateFindTests.gmk \ + SPEC=$(BOOTCYCLE_SPEC)) ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Main.gmk \ - SPEC=$(BOOTCYCLE_SPEC) UPDATE_MODULE_DEPS=true NO_RECIPES=true \ - create-main-targets-include ) + $(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Main.gmk \ + SPEC=$(BOOTCYCLE_SPEC) UPDATE_MODULE_DEPS=true NO_RECIPES=true \ + create-main-targets-include ) +$(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \ LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(BOOTCYCLE_SPEC) main else From ec02a87aeef008f6b2f94001fa33bac66bf24627 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Mon, 2 Jun 2025 18:13:24 +0000 Subject: [PATCH 076/216] 8345745: Update mode of the Attach API communication pipe. Reviewed-by: sspitsyn, kevinw --- .../windows/native/libattach/VirtualMachineImpl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c index dc1b0f6e79a..b5b87b2cc91 100644 --- a/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -291,11 +291,12 @@ JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_createPipe hPipe = CreateNamedPipe( name, // pipe name - ver == 1 ? PIPE_ACCESS_INBOUND // read access - : PIPE_ACCESS_DUPLEX, // read-write access + (ver == 1 ? PIPE_ACCESS_INBOUND : PIPE_ACCESS_DUPLEX) | // read or read-write access + FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_TYPE_BYTE | // byte mode PIPE_READMODE_BYTE | - PIPE_WAIT, // blocking mode + PIPE_WAIT | // blocking mode + PIPE_REJECT_REMOTE_CLIENTS, 1, // max. instances 128, // output buffer size 8192, // input buffer size From 1373ceb7f3040a03ae142cfaab0f74894fc6a0a3 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 2 Jun 2025 18:22:35 +0000 Subject: [PATCH 077/216] 8356698: JFR: @Contextual Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/Contextual.java | 67 +++ .../jdk/jfr/events/MethodTraceEvent.java | 2 + .../jdk/jfr/internal/MetadataRepository.java | 6 +- .../jdk/jfr/internal/tool/PrettyWriter.java | 184 +++++++- .../jdk/jfr/snippet-files/Snippets.java | 34 ++ .../jdk/jdk/jfr/tool/TestPrintContextual.java | 420 ++++++++++++++++++ 6 files changed, 704 insertions(+), 9 deletions(-) create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/Contextual.java create mode 100644 test/jdk/jdk/jfr/tool/TestPrintContextual.java diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Contextual.java b/src/jdk.jfr/share/classes/jdk/jfr/Contextual.java new file mode 100644 index 00000000000..92deeb8d562 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/Contextual.java @@ -0,0 +1,67 @@ +package jdk.jfr; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Event field annotation, specifies that the value carries contextual + * information. + *

      + * Contextual information is data that applies to all events happening in the + * same thread from the beginning to the end of the event with a field annotated + * with {@code Contextual}. + *

      + * For example, to trace requests or transactions in a system, a trace event can + * be created to provide context. + * {@snippet class = "Snippets" region = "ContextualTrace"} + *

      + * To track details within an order service, an order event can be created where + * only the order ID provides context. + * {@snippet class = "Snippets" region = "ContextualOrder"} + *

      + * If an order in the order service stalls due to lock contention, a user + * interface can display contextual information together with the + * JavaMonitorEnter event to simplify troubleshooting, for example: + * {@snippet lang=text : + * $ jfr print --events JavaMonitorEnter recording.jfr + * jdk.JavaMonitorEnter { + * Context: Trace.id = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" + * Context: Trace.name = "POST /checkout/place-order" + * Context: Order.id = 314159 + * startTime = 17:51:29.038 (2025-02-07) + * duration = 50.56 ms + * monitorClass = java.util.ArrayDeque (classLoader = bootstrap) + * previousOwner = "Order Thread" (javaThreadId = 56209, virtual = true) + * address = 0x60000232ECB0 + * eventThread = "Order Thread" (javaThreadId = 52613, virtual = true) + * stackTrace = [ + * java.util.zip.ZipFile$CleanableResource.getInflater() line: 685 + * java.util.zip.ZipFile$ZipFileInflaterInputStream.(ZipFile) line: 388 + * java.util.zip.ZipFile.getInputStream(ZipEntry) line: 355 + * java.util.jar.JarFile.getInputStream(ZipEntry) line: 833 + * ... + * ] + * } + * } + *

      + * The difference between {@link Relational} and {@link Contextual} annotations + * is that {@link Relational} ties event data together to form a global data + * structure, similar to a foreign key in a relational database, but + * {@link Contextual} represents a state that applies to all events that happen + * at the same time, in the same thread. A field can be both contextual and + * relational at the same time. + *

      + * A contextual field may incur overhead on a parser reading a recording file, + * since it must track active context, so it should be used sparingly and only + * where appropriate. + * + * @since 25 + */ +@MetadataDefinition +@Label("Context") +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface Contextual { +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTraceEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTraceEvent.java index b76c6c41738..a56de3e6fca 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTraceEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTraceEvent.java @@ -25,6 +25,7 @@ package jdk.jfr.events; import jdk.jfr.Category; +import jdk.jfr.Contextual; import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.StackTrace; @@ -35,6 +36,7 @@ import jdk.jfr.StackTrace; @StackTrace(true) public final class MethodTraceEvent extends AbstractJDKEvent { + @Contextual @Label("Method") private long method; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 1c9c985fb26..5dcf07f719d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -205,7 +205,11 @@ public final class MetadataRepository { nativeEventTypes.remove(n); nativeControls.remove(n); TypeLibrary.removeType(nativeType.getId()); - pEventType.setFields(nativeType.getFields()); + PrivateAccess access = PrivateAccess.getInstance(); + for (int i = 0; i < nativeFields.size(); i++) { + access.setAnnotations(nativeFields.get(i), eventFields.get(i).getAnnotationElements()); + } + pEventType.setFields(nativeFields); } } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java index faa4a8ec23a..274a21d9b49 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,15 +25,26 @@ package jdk.jfr.internal.tool; +import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Path; import java.time.Duration; +import java.time.Instant; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.SequencedSet; import java.util.StringJoiner; +import jdk.jfr.Contextual; import jdk.jfr.DataAmount; +import jdk.jfr.EventType; import jdk.jfr.Frequency; import jdk.jfr.MemoryAddress; import jdk.jfr.Percentage; @@ -46,7 +57,7 @@ import jdk.jfr.consumer.RecordedMethod; import jdk.jfr.consumer.RecordedObject; import jdk.jfr.consumer.RecordedStackTrace; import jdk.jfr.consumer.RecordedThread; -import jdk.jfr.internal.Type; +import jdk.jfr.consumer.RecordingFile; import jdk.jfr.internal.util.ValueFormatter; /** @@ -55,10 +66,60 @@ import jdk.jfr.internal.util.ValueFormatter; * This class is also used by {@link RecordedObject#toString()} */ public final class PrettyWriter extends EventPrintWriter { - private static final String TYPE_OLD_OBJECT = Type.TYPES_PREFIX + "OldObject"; + private static record Timestamp(RecordedEvent event, long seconds, int nanosCompare, boolean contextual) implements Comparable { + // If the start timestamp from a contextual event has the same start timestamp + // as an ordinary instant event, the contextual event should be processed first + // One way to ensure this is to multiply the nanos value and add 1 ns to the end + // timestamp so the context event always comes first in a comparison. + // This also prevents a contextual start time to be processed after a contextual + // end time, if the event is instantaneous. + public static Timestamp createStart(RecordedEvent event, boolean contextual) { + Instant time = event.getStartTime(); // Method allocates, so store seconds and nanos + return new Timestamp(event, time.getEpochSecond(), 2 * time.getNano(), contextual); + } + + public static Timestamp createEnd(RecordedEvent event, boolean contextual) { + Instant time = event.getEndTime(); // Method allocates, so store seconds and nanos + return new Timestamp(event, time.getEpochSecond(), 2 * time.getNano() + 1, contextual); + } + + public boolean start() { + return (nanosCompare & 1L) == 0; + } + + @Override + public int compareTo(Timestamp that) { + // This is taken from Instant::compareTo + int cmp = Long.compare(seconds, that.seconds); + if (cmp != 0) { + return cmp; + } + return nanosCompare - that.nanosCompare; + } + } + + private static record TypeInformation(Long id, List contextualFields, boolean contextual, String simpleName) { + } + + private static final SequencedSet EMPTY_SET = new LinkedHashSet<>(); + private static final String TYPE_OLD_OBJECT = "jdk.types.OldObject"; private static final DateTimeFormatter TIME_FORMAT_EXACT = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSSSS (yyyy-MM-dd)"); private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss.SSS (yyyy-MM-dd)"); private static final Long ZERO = 0L; + // Rationale for using one million events in the window. + // Events in JFR arrive in batches. The commit time (end time) of an + // event in batch N typically doesn't come before any events in batch N - 1, + // but it can't be ruled out completely. Data is also partitioned into chunks, + // typically 16 MB each. Within a chunk, there must be at least one batch. + // The size of an event is typically more than 16 bytes, so an + // EVENT_WINDOW_SIZE of 1 000 000 events will likely cover more than one batch. + // Having at least two batches in a window avoids boundary issues. + // At the same time, a too large window, means it will take more time + // before the first event is printed and the tool will feel unresponsive. + private static final int EVENT_WINDOW_SIZE = 1_000_000; + private final PriorityQueue timeline = new PriorityQueue<>(EVENT_WINDOW_SIZE + 4); + private final Map typeInformation = new HashMap<>(); + private final Map> contexts = new HashMap<>(); private final boolean showExact; private RecordedEvent currentEvent; @@ -71,19 +132,110 @@ public final class PrettyWriter extends EventPrintWriter { this(destination, false); } - @Override - protected void print(List events) { - for (RecordedEvent e : events) { - print(e); - flush(false); + void print(Path source) throws IOException { + printBegin(); + int counter = 0; + try (RecordingFile file = new RecordingFile(source)) { + while (file.hasMoreEvents()) { + RecordedEvent event = file.readEvent(); + if (typeInformation(event).contextual()) { + timeline.add(Timestamp.createStart(event, true)); + timeline.add(Timestamp.createEnd(event, true)); + } + if (acceptEvent(event)) { + timeline.add(Timestamp.createEnd(event, false)); + } + // There should not be a limit on the size of the recording files that + // the 'jfr' tool can process. To avoid OutOfMemoryError and time complexity + // issues on large recordings, a window size must be set when sorting + // and processing contextual events. + while (timeline.size() > EVENT_WINDOW_SIZE) { + print(timeline.remove()); + flush(false); + } + if ((++counter % EVENT_WINDOW_SIZE) == 0) { + contexts.entrySet().removeIf(c -> c.getValue().isEmpty()); + } + } + while (!timeline.isEmpty()) { + print(timeline.remove()); + } + } + printEnd(); + flush(true); + } + + private TypeInformation typeInformation(RecordedEvent event) { + long id = event.getEventType().getId(); + TypeInformation ti = typeInformation.get(id); + if (ti == null) { + ti = createTypeInformation(event.getEventType()); + typeInformation.put(ti.id(), ti); + } + return ti; + } + + private TypeInformation createTypeInformation(EventType eventType) { + ArrayList contextualFields = new ArrayList<>(); + for (ValueDescriptor v : eventType.getFields()) { + if (v.getAnnotation(Contextual.class) != null) { + contextualFields.add(v); + } + } + contextualFields.trimToSize(); + String name = eventType.getName(); + String simpleName = name.substring(name.lastIndexOf(".") + 1); + boolean contextual = contextualFields.size() > 0; + return new TypeInformation(eventType.getId(), contextualFields, contextual, simpleName); + } + + private void print(Timestamp t) { + RecordedEvent event = t.event(); + RecordedThread rt = event.getThread(); + if (rt != null) { + processThreadedTimestamp(rt, t); + } else { + if (!t.contextual()) { + print(event); + } } } + public void processThreadedTimestamp(RecordedThread thread, Timestamp t) { + RecordedEvent event = t.event(); + var contextEvents = contexts.computeIfAbsent(thread.getId(), k -> new LinkedHashSet<>(1)); + if (t.contextual) { + if (t.start()) { + contextEvents.add(event); + } else { + contextEvents.remove(event); + } + return; + } + if (typeInformation(event).contextual()) { + print(event); + } else { + print(event, contextEvents); + } + } + + @Override + protected void print(List events) { + throw new InternalError("Should not reach here!"); + } + public void print(RecordedEvent event) { + print(event, EMPTY_SET); + } + + public void print(RecordedEvent event, SequencedSet context) { currentEvent = event; print(event.getEventType().getName(), " "); println("{"); indent(); + if (!context.isEmpty()) { + printContexts(context); + } for (ValueDescriptor v : event.getFields()) { String name = v.getName(); if (!isZeroDuration(event, name) && !isLateField(name)) { @@ -106,6 +258,22 @@ public final class PrettyWriter extends EventPrintWriter { println(); } + private void printContexts(SequencedSet contextEvents) { + for (RecordedEvent e : contextEvents) { + printContextFields(e); + } + } + + private void printContextFields(RecordedEvent contextEvent) { + TypeInformation ti = typeInformation(contextEvent); + for (ValueDescriptor v : ti.contextualFields()) { + printIndent(); + String name = "Context: " + ti.simpleName() + "." + v.getName(); + print(name, " = "); + printValue(getValue(contextEvent, v), v, ""); + } + } + private boolean isZeroDuration(RecordedEvent event, String name) { return name.equals("duration") && ZERO.equals(event.getValue("duration")); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java index a8cb6f0111d..e89d69f4668 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java @@ -26,6 +26,7 @@ package jdk.jfr.snippets; import jdk.jfr.AnnotationElement; import jdk.jfr.BooleanFlag; +import jdk.jfr.Contextual; import jdk.jfr.ValueDescriptor; import jdk.jfr.EventFactory; import jdk.jfr.EventType; @@ -251,6 +252,39 @@ public class Snippets { } // @end + // @start region="ContextualTrace" + @Label("Trace") + @Name("com.example.Trace") + class TraceEvent extends Event { + @Label("ID") + @Contextual + String id; + + @Label("Name") + @Contextual + String name; + } + // @end + + void hello() { + // @start region="ContextualOrder" + @Label("Order") + @Name("com.example.Order") + class OrderEvent extends Event { + @Label("Order ID") + @Contextual + long id; + + @Label("Order Date") + @Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH) + long date; + + @Label("Payment Method") + String paymentMethod; + } + // @end + } + // @start region="DataAmountOverview" @Name("com.example.ImageRender") @Label("Image Render") diff --git a/test/jdk/jdk/jfr/tool/TestPrintContextual.java b/test/jdk/jdk/jfr/tool/TestPrintContextual.java new file mode 100644 index 00000000000..efecc31cb16 --- /dev/null +++ b/test/jdk/jdk/jfr/tool/TestPrintContextual.java @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.tool; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import jdk.jfr.Contextual; +import jdk.jfr.Event; +import jdk.jfr.Name; +import jdk.jfr.Recording; +import jdk.jfr.StackTrace; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +/** + * @test + * @requires vm.flagless + * @requires vm.hasJFR + * @library /test/lib + * @run main/othervm jdk.jfr.tool.TestPrintContextual + */ +public class TestPrintContextual { + private static final int WINDOW_SIZE = 1_000_000; + private static final String CONTEXT_MARKER = "Context: "; + + private static final class PrintedEvent { + private final List> contextValues = new ArrayList<>(); + private final List> values = new ArrayList<>(); + private final String name; + + public PrintedEvent(String name) { + this.name = name; + } + + public void addValue(String key, String value) { + values.add(new AbstractMap.SimpleEntry<>(key, value)); + } + + public void addContextValue(String key, String value) { + contextValues.add(new AbstractMap.SimpleEntry<>(key, value)); + } + + public List> getContextValues() { + return contextValues; + } + + public String getContextValue(String key) { + for (var entry : contextValues) { + if (entry.getKey().equals(key)) { + return entry.getValue(); + } + } + return null; + } + } + + @Name("Span") + static class SpanEvent extends Event { + @Contextual + String name; + @Contextual + long spanId; + } + + @Name("Trace") + static class TraceEvent extends Event { + long traceId; + @Contextual + String name; + } + + @Name("Filler") + @StackTrace(false) + static class FillerEvent extends Event { + } + + + public static void main(String[] args) throws Exception { + testContextValues(); + testInterleaved(); + testDeepContext(); + testThreadedContext(); + testFiltered(); + } + + // Tests that context values are injected into non-contextual events + private static void testContextValues() throws Exception { + try (Recording r = new Recording()) { + r.enable("Trace").withoutStackTrace(); + r.enable("Span").withoutStackTrace(); + r.enable("jdk.SystemGC").withoutStackTrace(); + r.start(); + + SpanEvent span = new SpanEvent(); + span.name = "span"; + span.spanId = 4711; + span.begin(); + System.gc(); + span.commit(); + + TraceEvent trace = new TraceEvent(); + trace.name = "trace"; + trace.traceId = 17; + trace.begin(); + System.gc(); + trace.commit(); + + r.stop(); + + List events = dumpPrintedEvents(r, Path.of("context-values.jfr")); + + PrintedEvent e0 = events.get(0); + assertName(e0, "jdk.SystemGC"); + assertContextValue(e0, "Span.name", "span"); + assertContextValue(e0, "Span.spanId", "4711"); + + PrintedEvent e1 = events.get(1); + assertName(e1, "Span"); + assertMissingContextValues(e1); + + PrintedEvent e2 = events.get(2); + assertName(e2, "jdk.SystemGC"); + assertContextValue(e2, "Trace.name", "trace"); + assertMissingContextValue(e2, "Trace.traceId"); + + PrintedEvent e3 = events.get(3); + assertName(e3, "Trace"); + assertMissingContextValues(e3); + } + } + + // Tests that two contexts can interleave and injection still works + private static void testInterleaved() throws Exception { + try (Recording r = new Recording()) { + r.enable("Trace").withoutStackTrace(); + r.enable("Span").withoutStackTrace(); + r.enable("jdk.SystemGC").withoutStackTrace(); + r.start(); + + System.gc(); // Event 0 + SpanEvent span = new SpanEvent(); + span.name = "span"; + span.spanId = 56; + span.begin(); + System.gc(); // Event 1 + TraceEvent trace = new TraceEvent(); + trace.name = "trace"; + trace.traceId = 58; + trace.begin(); + System.gc(); // Event 2 + span.commit(); // Event 3 + System.gc(); // Event 4 + trace.commit(); // Event 5 + System.gc(); // Event 6 + + r.stop(); + + List events = dumpPrintedEvents(r, Path.of("interleaved.jfr")); + + PrintedEvent e0 = events.get(0); + assertName(e0, "jdk.SystemGC"); + assertMissingContextValues(e0); + + PrintedEvent e1 = events.get(1); + assertName(e1, "jdk.SystemGC"); + assertContextValue(e1, "Span.name", "span"); + assertContextValue(e1, "Span.spanId", "56"); + assertMissingContextValue(e1, "trace.name"); + + PrintedEvent e2 = events.get(2); + assertName(e2, "jdk.SystemGC"); + assertContextValue(e2, "Span.name", "span"); + assertContextValue(e2, "Span.spanId", "56"); + assertContextValue(e2, "Trace.name", "trace"); + + PrintedEvent e3 = events.get(3); + assertName(e3, "Span"); + + PrintedEvent e4 = events.get(4); + assertName(e4, "jdk.SystemGC"); + assertMissingContextValue(e4, "Span.name"); + assertMissingContextValue(e4, "Span.spanId"); + assertContextValue(e4, "Trace.name", "trace"); + + PrintedEvent e5 = events.get(5); + assertName(e5, "Trace"); + + PrintedEvent e6 = events.get(6); + assertName(e6, "jdk.SystemGC"); + assertMissingContextValues(e6); + } + } + + // Tests hundred nested contexts in one event + private static void testDeepContext() throws Exception { + try (Recording r = new Recording()) { + r.enable("Trace").withoutStackTrace(); + r.enable("Span").withoutStackTrace(); + r.enable("jdk.SystemGC").withoutStackTrace(); + r.start(); + TraceEvent trace = new TraceEvent(); + trace.name = "trace"; + trace.traceId = 58; + trace.begin(); + span(99); + trace.commit(); + r.stop(); + List events = dumpPrintedEvents(r, Path.of("deep-context.jfr")); + + PrintedEvent e0 = events.get(0); + assertName(e0, "jdk.SystemGC"); + int counter = 100; + for (var e : e0.getContextValues()) { + String key = e.getKey(); + String value = e.getValue(); + if (counter == 100) { + if (!key.equals("Trace.name")) { + throw new Exception("Expected trace context to be printed first, but name was " + key); + } + if ("name".equals(value)) { + throw new Exception("Expected trace context name to be 'trace', but was " + value); + } + counter--; + continue; + } + if (key.equals("Span.spanId")) { + if (!String.valueOf(counter).equals(value)) { + throw new Exception("Expected spanId to be " + counter + ", but was " + value); + } + counter--; + continue; + } + if (!key.equals("Span.name")) { + throw new Exception("Expected span context name, but was " + key); + } + } + } + } + + private static void span(int depth) { + SpanEvent span = new SpanEvent(); + span.name = "span"; + span.spanId = depth; + span.begin(); + if (depth == 0) { + System.gc(); + return; + } + span(depth - 1); + span.commit(); + } + + // Tests that context values are only inhjected into events in the same thread. + private static void testThreadedContext() throws Exception { + try (Recording r = new Recording()) { + r.enable("Trace").withoutStackTrace(); + r.enable("jdk.SystemGC").withoutStackTrace(); + r.start(); + TraceEvent trace = new TraceEvent(); + trace.name = "trace"; + trace.traceId = 42; + trace.begin(); + Thread t = Thread.ofPlatform().name("not-main").start(() -> { + System.gc(); + }); + t.join(); + System.gc(); + trace.commit(); + r.stop(); + + List events = dumpPrintedEvents(r, Path.of("threaded-context.jfr")); + + PrintedEvent e0 = events.get(0); + assertName(e0, "jdk.SystemGC"); + assertMissingContextValues(e0); + + PrintedEvent e1 = events.get(1); + assertName(e1, "jdk.SystemGC"); + assertContextValue(e1, "Trace.name", "trace"); + + PrintedEvent e2 = events.get(2); + assertName(e2, "Trace"); + assertMissingContextValues(e2); + } + } + + // Tests that context values are injected when context events are filtered out + private static void testFiltered() throws Exception { + try (Recording r = new Recording()) { + r.enable("Trace").withoutStackTrace(); + r.enable("jdk.SystemGC").withoutStackTrace(); + r.start(); + + TraceEvent trace = new TraceEvent(); + trace.name = "trace"; + trace.traceId = 22; + trace.begin(); + SpanEvent span = new SpanEvent(); + span.spanId = 11; + span.name = "span"; + span.begin(); + + System.gc(); + + span.commit(); + trace.commit(); + + r.stop(); + Path file = Path.of("filtered.jfr"); + r.dump(file); + List events = parseEvents(readPrintedLines(file, "--events", "jdk.SystemGC")); + if (events.size() != 1) { + throw new Exception("Only expected one event"); + } + PrintedEvent e0 = events.get(0); + assertName(e0, "jdk.SystemGC"); + assertContextValue(e0, "Trace.name", "trace"); + assertContextValue(e0, "Span.name", "span"); + assertContextValue(e0, "Span.spanId", "11"); + } + } + + private static void assertName(PrintedEvent event, String name) throws Exception { + if (!event.name.equals(name)) { + throw new Exception("Expected event name " + name + ", but was " + event.name); + } + } + + private static void assertContextValue(PrintedEvent event, String field, String expectedValue) throws Exception { + String value = event.getContextValue(field); + if (value == null) { + throw new Exception("No value found for field " + field + " in event " + event.name); + } + if (!expectedValue.equals(value)) { + throw new Exception("Expected context value " + expectedValue + " for " + field + ", it was " + value); + } + } + + private static void assertMissingContextValue(PrintedEvent event, String field) throws Exception { + if (event.getContextValue(field) != null) { + throw new Exception("Didn't expect to find context field " + field); + } + } + + private static void assertMissingContextValues(PrintedEvent event) throws Exception { + if (!event.contextValues.isEmpty()) { + throw new Exception("Didn't expect context values in event " + event.name); + } + } + + private static List dumpPrintedEvents(Recording r, Path file) throws Exception { + r.dump(file); + return parseEvents(readPrintedLines(file)); + } + + private static List parseEvents(List lines) { + List events = new ArrayList<>(); + PrintedEvent pe = null; + for (String line : lines) { + if (line.endsWith("{")) { + String[] texts = line.split(" "); + pe = new PrintedEvent(texts[0]); + events.add(pe); + } else if (line.startsWith("}")) { + pe = null; + } else if (pe != null) { + int index = line.indexOf("="); + String field = line.substring(0, index).trim(); + String value = line.substring(index + 1).trim(); + if (value.startsWith("\"") && value.endsWith("\"")) { + value = value.substring(1, value.length() - 1); + } + if (field.startsWith(CONTEXT_MARKER)) { + pe.addContextValue(field.substring(CONTEXT_MARKER.length()), value); + } else { + pe.addValue(field, value); + } + } + } + return events; + } + + private static List readPrintedLines(Path file, String... options) throws Exception { + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jfr"); + launcher.addToolArg("print"); + for (String option : options) { + launcher.addToolArg(option); + } + launcher.addToolArg(file.toAbsolutePath().toString()); + OutputAnalyzer output = ProcessTools.executeCommand(launcher.getCommand()); + return output.asLines(); + } +} From 5243f3851b0345b874ff51ea3a07e82f73741546 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Mon, 2 Jun 2025 19:07:29 +0000 Subject: [PATCH 078/216] 8357924: Remove runtime/ErrorHandling/CreateCoredumpOnCrash.java from problem list for macosx-x64 Reviewed-by: syan, dholmes --- test/hotspot/jtreg/ProblemList.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 62fdbdbaa06..3038daf090d 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -108,7 +108,6 @@ runtime/os/TestTracePageSizes.java#compiler-options 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64 -runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64 runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x From 0418b3295a199af66700521f571c9b2c1051cac6 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 2 Jun 2025 20:23:14 +0000 Subject: [PATCH 079/216] 8357696: Enhance code consistency: java.desktop/unix Reviewed-by: prr --- .../unix/classes/sun/font/DelegateStrike.java | 13 +++++++- .../classes/sun/font/DoubleByteEncoder.java | 2 ++ .../classes/sun/font/FcFontConfiguration.java | 2 +- .../classes/sun/font/FontConfigManager.java | 8 ++--- .../classes/sun/font/MFontConfiguration.java | 11 ++++++- .../unix/classes/sun/font/NativeFont.java | 13 +++++++- .../classes/sun/font/NativeGlyphMapper.java | 9 +++++- .../unix/classes/sun/font/NativeStrike.java | 9 ++++++ .../sun/font/NativeStrikeDisposer.java | 3 +- .../unix/classes/sun/font/X11Dingbats.java | 10 +++++-- .../unix/classes/sun/font/X11GB18030_0.java | 9 ++++-- .../unix/classes/sun/font/X11GB18030_1.java | 9 ++++-- .../unix/classes/sun/font/X11GB2312.java | 13 ++++++-- .../unix/classes/sun/font/X11GBK.java | 9 ++++-- .../unix/classes/sun/font/X11Johab.java | 8 +++-- .../unix/classes/sun/font/X11KSC5601.java | 13 ++++++-- .../classes/sun/font/X11SunUnicode_0.java | 8 +++-- .../classes/sun/font/X11TextRenderer.java | 5 +++- .../unix/classes/sun/font/XMap.java | 2 +- .../unix/classes/sun/font/XRGlyphCache.java | 3 +- .../classes/sun/font/XRGlyphCacheEntry.java | 2 +- .../unix/classes/sun/font/XRTextRenderer.java | 3 +- .../sun/java2d/opengl/GLXGraphicsConfig.java | 9 ++++-- .../sun/java2d/opengl/GLXSurfaceData.java | 11 +++++-- .../opengl/GLXVolatileSurfaceManager.java | 4 ++- .../sun/java2d/x11/X11PMBlitBgLoops.java | 2 +- .../sun/java2d/x11/X11PMBlitLoops.java | 6 ++-- .../classes/sun/java2d/x11/X11Renderer.java | 30 ++++++++++++++++++- .../sun/java2d/x11/X11SurfaceData.java | 17 ++++++++++- .../sun/java2d/x11/X11SurfaceDataProxy.java | 6 ++-- .../java2d/x11/X11VolatileSurfaceManager.java | 5 +++- .../classes/sun/java2d/xr/DirtyRegion.java | 3 +- .../sun/java2d/xr/GrowableByteArray.java | 2 +- .../sun/java2d/xr/GrowableEltArray.java | 3 +- .../sun/java2d/xr/GrowablePointArray.java | 2 +- .../sun/java2d/xr/GrowableRectArray.java | 2 +- .../unix/classes/sun/java2d/xr/MaskTile.java | 2 +- .../sun/java2d/xr/MaskTileManager.java | 2 +- .../classes/sun/java2d/xr/MutableInteger.java | 4 ++- .../classes/sun/java2d/xr/XIDGenerator.java | 2 +- .../sun/java2d/xr/XRBackendNative.java | 28 ++++++++++++++++- .../unix/classes/sun/java2d/xr/XRColor.java | 3 +- .../sun/java2d/xr/XRCompositeManager.java | 2 +- .../classes/sun/java2d/xr/XRDrawImage.java | 2 +- .../classes/sun/java2d/xr/XRDrawLine.java | 2 +- .../sun/java2d/xr/XRGraphicsConfig.java | 3 +- .../classes/sun/java2d/xr/XRMaskBlit.java | 3 +- .../classes/sun/java2d/xr/XRMaskFill.java | 3 +- .../classes/sun/java2d/xr/XRMaskImage.java | 2 +- .../classes/sun/java2d/xr/XRPMBlitLoops.java | 18 +++++++---- .../unix/classes/sun/java2d/xr/XRPaints.java | 8 ++--- .../classes/sun/java2d/xr/XRRenderer.java | 21 +++++++++++-- .../classes/sun/java2d/xr/XRSolidSrcPict.java | 2 +- .../classes/sun/java2d/xr/XRSurfaceData.java | 28 ++++++++++++++--- .../sun/java2d/xr/XRSurfaceDataProxy.java | 3 +- .../unix/classes/sun/java2d/xr/XRUtils.java | 2 +- .../java2d/xr/XRVolatileSurfaceManager.java | 5 +++- .../sun/java2d/xr/XcbRequestCounter.java | 2 +- .../classes/sun/print/AttributeClass.java | 3 +- .../unix/classes/sun/print/CUPSPrinter.java | 2 +- .../classes/sun/print/IPPPrintService.java | 23 ++++++++++++-- .../sun/print/PrintServiceLookupProvider.java | 10 +++++-- .../unix/classes/sun/print/UnixPrintJob.java | 14 +++++++-- .../classes/sun/print/UnixPrintService.java | 22 +++++++++++++- 64 files changed, 391 insertions(+), 96 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/font/DelegateStrike.java b/src/java.desktop/unix/classes/sun/font/DelegateStrike.java index 4f2de5ebc2f..ea9c6b0eb0a 100644 --- a/src/java.desktop/unix/classes/sun/font/DelegateStrike.java +++ b/src/java.desktop/unix/classes/sun/font/DelegateStrike.java @@ -37,7 +37,7 @@ import java.awt.geom.Rectangle2D; * appropriately. */ -class DelegateStrike extends NativeStrike { +final class DelegateStrike extends NativeStrike { private FontStrike delegateStrike; @@ -55,6 +55,7 @@ class DelegateStrike extends NativeStrike { * the metrics and transform them. But currently in such a case it * gets the metrics from a different font - its glyph delegate font. */ + @Override StrikeMetrics getFontMetrics() { if (strikeMetrics == null) { if (pScalerContext != 0) { @@ -67,31 +68,38 @@ class DelegateStrike extends NativeStrike { return strikeMetrics; } + @Override void getGlyphImagePtrs(int[] glyphCodes, long[] images,int len) { delegateStrike.getGlyphImagePtrs(glyphCodes, images, len); } + @Override long getGlyphImagePtr(int glyphCode) { return delegateStrike.getGlyphImagePtr(glyphCode); } + @Override void getGlyphImageBounds(int glyphCode, Point2D.Float pt, Rectangle result) { delegateStrike.getGlyphImageBounds(glyphCode, pt, result); } + @Override Point2D.Float getGlyphMetrics(int glyphCode) { return delegateStrike.getGlyphMetrics(glyphCode); } + @Override float getGlyphAdvance(int glyphCode) { return delegateStrike.getGlyphAdvance(glyphCode); } + @Override Point2D.Float getCharMetrics(char ch) { return delegateStrike.getCharMetrics(ch); } + @Override float getCodePointAdvance(int cp) { if (cp < 0 || cp >= 0x10000) { cp = 0xffff; @@ -99,14 +107,17 @@ class DelegateStrike extends NativeStrike { return delegateStrike.getGlyphAdvance(cp); } + @Override Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) { return delegateStrike.getGlyphOutlineBounds(glyphCode); } + @Override GeneralPath getGlyphOutline(int glyphCode, float x, float y) { return delegateStrike.getGlyphOutline(glyphCode, x, y); } + @Override GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) { return delegateStrike.getGlyphVectorOutline(glyphs, x, y); } diff --git a/src/java.desktop/unix/classes/sun/font/DoubleByteEncoder.java b/src/java.desktop/unix/classes/sun/font/DoubleByteEncoder.java index 36b298a8004..d42b6eda80d 100644 --- a/src/java.desktop/unix/classes/sun/font/DoubleByteEncoder.java +++ b/src/java.desktop/unix/classes/sun/font/DoubleByteEncoder.java @@ -76,6 +76,7 @@ public abstract class DoubleByteEncoder this.index2 = index2; } + @Override public boolean canEncode(char c) { return (encodeSingle(c) != -1 || encodeDouble(c) != 0); @@ -198,6 +199,7 @@ public abstract class DoubleByteEncoder } } + @Override protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { if (src.hasArray() && dst.hasArray()) return encodeArrayLoop(src, dst); diff --git a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java index bfd8acf7739..328e2454842 100644 --- a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java @@ -50,7 +50,7 @@ import sun.util.logging.PlatformLogger; import static java.nio.charset.StandardCharsets.ISO_8859_1; -public class FcFontConfiguration extends FontConfiguration { +public final class FcFontConfiguration extends FontConfiguration { /** Version of the cache file format understood by this code. * Its part of the file name so that we can rev this at diff --git a/src/java.desktop/unix/classes/sun/font/FontConfigManager.java b/src/java.desktop/unix/classes/sun/font/FontConfigManager.java index 6e3b83f4b66..c70fe7dd940 100644 --- a/src/java.desktop/unix/classes/sun/font/FontConfigManager.java +++ b/src/java.desktop/unix/classes/sun/font/FontConfigManager.java @@ -34,7 +34,7 @@ import sun.util.logging.PlatformLogger; /** * Small utility class to manage FontConfig. */ -public class FontConfigManager { +public final class FontConfigManager { static boolean fontConfigFailed = false; @@ -47,14 +47,14 @@ public class FontConfigManager { /* These next three classes are just data structures. */ - public static class FontConfigFont { + public static final class FontConfigFont { public String familyName; // eg Bitstream Vera Sans public String styleStr; // eg Bold public String fullName; // eg Bitstream Vera Sans Bold public String fontFile; // eg /usr/X11/lib/fonts/foo.ttf } - public static class FcCompFont { + public static final class FcCompFont { public String fcName; // eg sans public String fcFamily; // eg sans public String jdkName; // eg sansserif @@ -65,7 +65,7 @@ public class FontConfigManager { public CompositeFont compFont; // null if not yet created/known. } - public static class FontConfigInfo { + public static final class FontConfigInfo { public int fcVersion; public String[] cacheDirs = new String[4]; } diff --git a/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java index 15dc97a1d4f..3d7e68d8dea 100644 --- a/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java @@ -39,7 +39,7 @@ import java.util.Scanner; import static java.nio.charset.StandardCharsets.ISO_8859_1; -public class MFontConfiguration extends FontConfiguration { +public final class MFontConfiguration extends FontConfiguration { private static FontConfiguration fontConfig = null; private static PlatformLogger logger; @@ -66,6 +66,7 @@ public class MFontConfiguration extends FontConfiguration { /* Needs to be kept in sync with updates in the languages used in * the fontconfig files. */ + @Override protected void initReorderMap() { reorderMap = new HashMap<>(); @@ -84,6 +85,7 @@ public class MFontConfiguration extends FontConfiguration { /** * Sets the OS name and version from environment information. */ + @Override protected void setOsNameAndVersion(){ super.setOsNameAndVersion(); @@ -157,6 +159,7 @@ public class MFontConfiguration extends FontConfiguration { private static final String fontsDirPrefix = "$JRE_LIB_FONTS"; + @Override protected String mapFileName(String fileName) { if (fileName != null && fileName.startsWith(fontsDirPrefix)) { return SunFontManager.jreFontDirName @@ -166,6 +169,7 @@ public class MFontConfiguration extends FontConfiguration { } // overrides FontConfiguration.getFallbackFamilyName + @Override public String getFallbackFamilyName(String fontName, String defaultFallback) { // maintain compatibility with old font.properties files, which // either had aliases for TimesRoman & Co. or defined mappings for them. @@ -176,6 +180,7 @@ public class MFontConfiguration extends FontConfiguration { return defaultFallback; } + @Override protected String getEncoding(String awtFontName, String characterSubsetName) { // extract encoding field from XLFD @@ -202,14 +207,17 @@ public class MFontConfiguration extends FontConfiguration { return encoding; } + @Override protected Charset getDefaultFontCharset(String fontName) { return ISO_8859_1; } + @Override protected String getFaceNameFromComponentFontName(String componentFontName) { return null; } + @Override protected String getFileNameFromComponentFontName(String componentFontName) { // for X11, component font name is XLFD // if we have a file name already, just use it; otherwise let's see @@ -222,6 +230,7 @@ public class MFontConfiguration extends FontConfiguration { return ((X11FontManager) fontManager).getFileNameFromXLFD(componentFontName); } + @Override public HashSet getAWTFontPathSet() { HashSet fontDirs = new HashSet(); short[] scripts = getCoreScripts(0); diff --git a/src/java.desktop/unix/classes/sun/font/NativeFont.java b/src/java.desktop/unix/classes/sun/font/NativeFont.java index 337d38c095a..871db2a70d1 100644 --- a/src/java.desktop/unix/classes/sun/font/NativeFont.java +++ b/src/java.desktop/unix/classes/sun/font/NativeFont.java @@ -54,7 +54,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; * to perform limited operations by using bitmaps from X11 helps here. */ -public class NativeFont extends PhysicalFont { +public final class NativeFont extends PhysicalFont { String encoding; @@ -223,6 +223,7 @@ public class NativeFont extends PhysicalFont { private static native boolean haveBitmapFonts(byte[] xlfd); private static native boolean fontExists(byte[] xlfd); + @Override public CharToGlyphMapper getMapper() { if (mapper == null) { if (isBitmapDelegate) { @@ -238,6 +239,7 @@ public class NativeFont extends PhysicalFont { return mapper; } + @Override FontStrike createStrike(FontStrikeDesc desc) { if (isBitmapDelegate) { return new NativeStrike(this, desc); @@ -261,15 +263,19 @@ public class NativeFont extends PhysicalFont { return null; } + @Override native StrikeMetrics getFontMetrics(long pScalerContext); + @Override native float getGlyphAdvance(long pContext, int glyphCode); + @Override Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext, int glyphCode) { return new Rectangle2D.Float(0f, 0f, 0f, 0f); } + @Override public GeneralPath getGlyphOutline(long pScalerContext, int glyphCode, float x, @@ -277,15 +283,18 @@ public class NativeFont extends PhysicalFont { return null; } + @Override native long getGlyphImage(long pScalerContext, int glyphCode); native long getGlyphImageNoDefault(long pScalerContext, int glyphCode); + @Override void getGlyphMetrics(long pScalerContext, int glyphCode, Point2D.Float metrics) { throw new RuntimeException("this should be called on the strike"); } + @Override public GeneralPath getGlyphVectorOutline(long pScalerContext, int[] glyphs, int numGlyphs, float x, float y) { @@ -294,6 +303,7 @@ public class NativeFont extends PhysicalFont { private native int countGlyphs(byte[] platformNameBytes, int ptSize); + @Override public int getNumGlyphs() { if (numGlyphs == -1) { byte[] bytes = getPlatformNameBytes(8); @@ -371,6 +381,7 @@ public class NativeFont extends PhysicalFont { return xlfd.getBytes(UTF_8); } + @Override public String toString() { return " ** Native Font: Family="+familyName+ " Name="+fullName+ " style="+style+" nativeName="+platName; diff --git a/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java b/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java index cec455e2e83..f1756900245 100644 --- a/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java +++ b/src/java.desktop/unix/classes/sun/font/NativeGlyphMapper.java @@ -42,7 +42,7 @@ import java.util.Locale; * XMap classes could be merged, however its cleaner to make them separate * classes so we can build caches for a particular font. */ -public class NativeGlyphMapper extends CharToGlyphMapper { +public final class NativeGlyphMapper extends CharToGlyphMapper { NativeFont font; XMap xmapper; @@ -55,10 +55,12 @@ public class NativeGlyphMapper extends CharToGlyphMapper { missingGlyph = 0; } + @Override public int getNumGlyphs() { return numGlyphs; } + @Override public int charToGlyph(char unicode) { if (unicode >= xmapper.convertedGlyphs.length) { return 0; @@ -67,6 +69,7 @@ public class NativeGlyphMapper extends CharToGlyphMapper { } } + @Override public int charToGlyph(int unicode) { if (unicode >= xmapper.convertedGlyphs.length) { return 0; @@ -75,10 +78,12 @@ public class NativeGlyphMapper extends CharToGlyphMapper { } } + @Override public int charToGlyphRaw(int unicode) { return charToGlyph(unicode); } + @Override public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { for (int i=0; i= 0x2701 && ch <= 0x275e) { // direct map return true; @@ -64,6 +68,7 @@ public class X11Dingbats extends Charset { return false; } + @Override protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); @@ -125,6 +130,7 @@ public class X11Dingbats extends Charset { (byte)0x00, (byte)0x00, (byte)0x00}; /* The default implementation creates a decoder and we don't have one */ + @Override public boolean isLegalReplacement(byte[] repl) { return true; } diff --git a/src/java.desktop/unix/classes/sun/font/X11GB18030_0.java b/src/java.desktop/unix/classes/sun/font/X11GB18030_0.java index e96615bfa36..7b06d785d99 100644 --- a/src/java.desktop/unix/classes/sun/font/X11GB18030_0.java +++ b/src/java.desktop/unix/classes/sun/font/X11GB18030_0.java @@ -29,11 +29,12 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetDecoder; -public class X11GB18030_0 extends Charset { +public final class X11GB18030_0 extends Charset { public X11GB18030_0 () { super("X11GB18030_0", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } @@ -41,18 +42,21 @@ public class X11GB18030_0 extends Charset { /* Seems like supporting a decoder is required, but we aren't going * to be publicly exposing this class, so no need to waste work */ + @Override public CharsetDecoder newDecoder() { throw new Error("Decoder is not implemented for X11GB18030_0 Charset"); } + @Override public boolean contains(Charset cs) { return cs instanceof X11GB18030_0; } - private static class Encoder extends DoubleByteEncoder { + private static final class Encoder extends DoubleByteEncoder { public Encoder(Charset cs) { super(cs, index1, index2); } + @Override protected int encodeSingle(char inputChar) { return -1; } @@ -4266,6 +4270,7 @@ public class X11GB18030_0 extends Charset { }; /* The default implementation creates a decoder and we don't have one */ + @Override public boolean isLegalReplacement(byte[] repl) { return true; } diff --git a/src/java.desktop/unix/classes/sun/font/X11GB18030_1.java b/src/java.desktop/unix/classes/sun/font/X11GB18030_1.java index 1666da96317..9f06ea30ac7 100644 --- a/src/java.desktop/unix/classes/sun/font/X11GB18030_1.java +++ b/src/java.desktop/unix/classes/sun/font/X11GB18030_1.java @@ -29,11 +29,12 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetDecoder; -public class X11GB18030_1 extends Charset { +public final class X11GB18030_1 extends Charset { public X11GB18030_1 () { super("X11GB18030_1", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } @@ -41,17 +42,20 @@ public class X11GB18030_1 extends Charset { /* Seems like supporting a decoder is required, but we aren't going * to be publicly exposing this class, so no need to waste work */ + @Override public CharsetDecoder newDecoder() { throw new Error("Decoder is not implemented for X11GB18030_1 Charset"); } + @Override public boolean contains(Charset cs) { return cs instanceof X11GB18030_1; } - private static class Encoder extends DoubleByteEncoder { + private static final class Encoder extends DoubleByteEncoder { public Encoder(Charset cs) { super(cs, index1, index2); } + @Override protected int encodeSingle(char inputChar) { return -1; } @@ -5263,6 +5267,7 @@ public class X11GB18030_1 extends Charset { }; /* The default implementation creates a decoder and we don't have one */ + @Override public boolean isLegalReplacement(byte[] repl) { return true; } diff --git a/src/java.desktop/unix/classes/sun/font/X11GB2312.java b/src/java.desktop/unix/classes/sun/font/X11GB2312.java index e1d64cbe54d..70643edbea3 100644 --- a/src/java.desktop/unix/classes/sun/font/X11GB2312.java +++ b/src/java.desktop/unix/classes/sun/font/X11GB2312.java @@ -31,28 +31,32 @@ import java.nio.charset.*; import sun.nio.cs.*; import static sun.nio.cs.CharsetMapping.*; -public class X11GB2312 extends Charset { +public final class X11GB2312 extends Charset { public X11GB2312 () { super("X11GB2312", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } + @Override public CharsetDecoder newDecoder() { return new Decoder(this); } + @Override public boolean contains(Charset cs) { return cs instanceof X11GB2312; } - private static class Encoder extends CharsetEncoder { + private static final class Encoder extends CharsetEncoder { private DoubleByte.Encoder enc = (DoubleByte.Encoder)new EUC_CN().newEncoder(); public Encoder(Charset cs) { super(cs, 2.0f, 2.0f); } + @Override public boolean canEncode(char c) { if (c <= 0x7F) { return false; @@ -64,6 +68,7 @@ public class X11GB2312 extends Charset { return enc.encodeChar(c); } + @Override protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); @@ -93,12 +98,13 @@ public class X11GB2312 extends Charset { dst.position(dp - dst.arrayOffset()); } } + @Override public boolean isLegalReplacement(byte[] repl) { return true; } } - private static class Decoder extends CharsetDecoder { + private static final class Decoder extends CharsetDecoder { private DoubleByte.Decoder dec = (DoubleByte.Decoder)new EUC_CN().newDecoder(); public Decoder(Charset cs) { @@ -109,6 +115,7 @@ public class X11GB2312 extends Charset { return dec.decodeDouble(b1, b2); } + @Override protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); diff --git a/src/java.desktop/unix/classes/sun/font/X11GBK.java b/src/java.desktop/unix/classes/sun/font/X11GBK.java index effe8f54f9c..612b41c95c0 100644 --- a/src/java.desktop/unix/classes/sun/font/X11GBK.java +++ b/src/java.desktop/unix/classes/sun/font/X11GBK.java @@ -29,22 +29,25 @@ import java.nio.charset.*; import sun.nio.cs.*; import static sun.nio.cs.CharsetMapping.*; -public class X11GBK extends Charset { +public final class X11GBK extends Charset { public X11GBK () { super("X11GBK", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } + @Override public CharsetDecoder newDecoder() { return new GBK().newDecoder(); } + @Override public boolean contains(Charset cs) { return cs instanceof X11GBK; } - private static class Encoder extends DoubleByte.Encoder { + private static final class Encoder extends DoubleByte.Encoder { private DoubleByte.Encoder enc = (DoubleByte.Encoder)new GBK().newEncoder(); @@ -52,11 +55,13 @@ public class X11GBK extends Charset { super(cs, (char[])null, (char[])null); } + @Override public boolean canEncode(char ch){ if (ch < 0x80) return false; return enc.canEncode(ch); } + @Override public int encodeChar(char ch) { if (ch < 0x80) return UNMAPPABLE_ENCODING; diff --git a/src/java.desktop/unix/classes/sun/font/X11Johab.java b/src/java.desktop/unix/classes/sun/font/X11Johab.java index 9768275b437..ff79e4833f5 100644 --- a/src/java.desktop/unix/classes/sun/font/X11Johab.java +++ b/src/java.desktop/unix/classes/sun/font/X11Johab.java @@ -29,28 +29,32 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetDecoder; -public class X11Johab extends Charset { +public final class X11Johab extends Charset { public X11Johab () { super("X11Johab", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } + @Override public CharsetDecoder newDecoder() { throw new Error("Decoder is not supported by X11Johab Charset"); } + @Override public boolean contains(Charset cs) { return cs instanceof X11GB18030_1; } - private static class Encoder extends DoubleByteEncoder { + private static final class Encoder extends DoubleByteEncoder { public Encoder(Charset cs) { super(cs, index1, index2); } + @Override public boolean isLegalReplacement(byte[] repl) { return true; } diff --git a/src/java.desktop/unix/classes/sun/font/X11KSC5601.java b/src/java.desktop/unix/classes/sun/font/X11KSC5601.java index 1a7cc310bbf..e1ffd133215 100644 --- a/src/java.desktop/unix/classes/sun/font/X11KSC5601.java +++ b/src/java.desktop/unix/classes/sun/font/X11KSC5601.java @@ -31,28 +31,32 @@ import java.nio.charset.*; import sun.nio.cs.*; import static sun.nio.cs.CharsetMapping.*; -public class X11KSC5601 extends Charset { +public final class X11KSC5601 extends Charset { public X11KSC5601 () { super("X11KSC5601", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } + @Override public CharsetDecoder newDecoder() { return new Decoder(this); } + @Override public boolean contains(Charset cs) { return cs instanceof X11KSC5601; } - private static class Encoder extends CharsetEncoder { + private static final class Encoder extends CharsetEncoder { private DoubleByte.Encoder enc = (DoubleByte.Encoder)new EUC_KR().newEncoder(); public Encoder(Charset cs) { super(cs, 2.0f, 2.0f); } + @Override public boolean canEncode(char c) { if (c <= 0x7F) { return false; @@ -64,6 +68,7 @@ public class X11KSC5601 extends Charset { return enc.encodeChar(c); } + @Override protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); @@ -92,12 +97,13 @@ public class X11KSC5601 extends Charset { dst.position(dp - dst.arrayOffset()); } } + @Override public boolean isLegalReplacement(byte[] repl) { return true; } } - private static class Decoder extends CharsetDecoder { + private static final class Decoder extends CharsetDecoder { private DoubleByte.Decoder dec = (DoubleByte.Decoder)new EUC_KR().newDecoder(); public Decoder(Charset cs) { @@ -108,6 +114,7 @@ public class X11KSC5601 extends Charset { return dec.decodeDouble(b1, b2); } + @Override protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); diff --git a/src/java.desktop/unix/classes/sun/font/X11SunUnicode_0.java b/src/java.desktop/unix/classes/sun/font/X11SunUnicode_0.java index a6267416a39..89b568ecd0f 100644 --- a/src/java.desktop/unix/classes/sun/font/X11SunUnicode_0.java +++ b/src/java.desktop/unix/classes/sun/font/X11SunUnicode_0.java @@ -30,11 +30,12 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetDecoder; -public class X11SunUnicode_0 extends Charset { +public final class X11SunUnicode_0 extends Charset { public X11SunUnicode_0 () { super("X11SunUnicode_0", null); } + @Override public CharsetEncoder newEncoder() { return new Encoder(this); } @@ -42,15 +43,17 @@ public class X11SunUnicode_0 extends Charset { /* Seems like supporting a decoder is required, but we aren't going * to be publicly exposing this class, so no need to waste work */ + @Override public CharsetDecoder newDecoder() { throw new Error("Decoder is not implemented for X11SunUnicode_0 Charset"); } + @Override public boolean contains(Charset cs) { return cs instanceof X11SunUnicode_0; } - private static class Encoder extends DoubleByteEncoder { + private static final class Encoder extends DoubleByteEncoder { public Encoder(Charset cs) { super(cs, index1, index2); } @@ -145,6 +148,7 @@ public class X11SunUnicode_0 extends Charset { }; /* The default implementation creates a decoder and we don't have one */ + @Override public boolean isLegalReplacement(byte[] repl) { return true; } diff --git a/src/java.desktop/unix/classes/sun/font/X11TextRenderer.java b/src/java.desktop/unix/classes/sun/font/X11TextRenderer.java index bac23128cd8..86c9fd26a7f 100644 --- a/src/java.desktop/unix/classes/sun/font/X11TextRenderer.java +++ b/src/java.desktop/unix/classes/sun/font/X11TextRenderer.java @@ -47,6 +47,7 @@ public class X11TextRenderer extends GlyphListPipe { * Override super class method to call the AA pipe if * AA is specified in the GlyphVector's FontRenderContext */ + @Override public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector g, float x, float y) { @@ -70,6 +71,7 @@ public class X11TextRenderer extends GlyphListPipe { native void doDrawGlyphList(long dstData, long xgc, Region clip, GlyphList gl); + @Override protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { SunToolkit.awtLock(); try { @@ -88,7 +90,8 @@ public class X11TextRenderer extends GlyphListPipe { return new Tracer(); } - public static class Tracer extends X11TextRenderer { + public static final class Tracer extends X11TextRenderer { + @Override void doDrawGlyphList(long dstData, long xgc, Region clip, GlyphList gl) { diff --git a/src/java.desktop/unix/classes/sun/font/XMap.java b/src/java.desktop/unix/classes/sun/font/XMap.java index ba34cff199b..5935ce1aa97 100644 --- a/src/java.desktop/unix/classes/sun/font/XMap.java +++ b/src/java.desktop/unix/classes/sun/font/XMap.java @@ -30,7 +30,7 @@ import java.nio.charset.*; import java.nio.CharBuffer; import java.nio.ByteBuffer; -class XMap { +final class XMap { private static HashMap xMappers = new HashMap<>(); diff --git a/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java b/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java index 04b5c1a9504..6c8ce7960cd 100644 --- a/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java +++ b/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java @@ -37,7 +37,7 @@ import sun.java2d.xr.*; * @author Clemens Eisserer */ -public class XRGlyphCache implements GlyphDisposedListener { +public final class XRGlyphCache implements GlyphDisposedListener { XRBackend con; XRCompositeManager maskBuffer; HashMap cacheMap = new HashMap(256); @@ -66,6 +66,7 @@ public class XRGlyphCache implements GlyphDisposedListener { StrikeCache.addGlyphDisposedListener(this); } + @Override public void glyphDisposed(ArrayList glyphPtrList) { try { SunToolkit.awtLock(); diff --git a/src/java.desktop/unix/classes/sun/font/XRGlyphCacheEntry.java b/src/java.desktop/unix/classes/sun/font/XRGlyphCacheEntry.java index 94733316fbd..62956f488a8 100644 --- a/src/java.desktop/unix/classes/sun/font/XRGlyphCacheEntry.java +++ b/src/java.desktop/unix/classes/sun/font/XRGlyphCacheEntry.java @@ -33,7 +33,7 @@ import java.io.*; * @author Clemens Eisserer */ -public class XRGlyphCacheEntry { +public final class XRGlyphCacheEntry { long glyphInfoPtr; int lastUsed; diff --git a/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java b/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java index 6f23bf10899..8662b48cf3f 100644 --- a/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java +++ b/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java @@ -36,7 +36,7 @@ import sun.java2d.xr.*; * * @author Clemens Eisserer */ -public class XRTextRenderer extends GlyphListPipe { +public final class XRTextRenderer extends GlyphListPipe { // Workaround for a bug in libXrender. // In case the number of glyphs of an ELT is a multiple of 254, // a few garbage bytes are sent to the XServer causing hangs. @@ -55,6 +55,7 @@ public class XRTextRenderer extends GlyphListPipe { eltList = new GrowableEltArray(64); } + @Override protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { if (gl.getNumGlyphs() == 0) { return; diff --git a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java index 2ea076f8051..1b7a4364ce4 100644 --- a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java +++ b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXGraphicsConfig.java @@ -149,7 +149,7 @@ public final class GLXGraphicsConfig * This is a small helper class that allows us to execute * getGLXConfigInfo() on the queue flushing thread. */ - private static class GLXGetConfigInfo implements Runnable { + private static final class GLXGetConfigInfo implements Runnable { private int screen; private int visual; private long cfginfo; @@ -157,6 +157,7 @@ public final class GLXGraphicsConfig this.screen = screen; this.visual = visual; } + @Override public void run() { cfginfo = getGLXConfigInfo(screen, visual); } @@ -212,6 +213,7 @@ public final class GLXGraphicsConfig } } + @Override public String toString() { return ("GLXGraphicsConfig[dev="+getDevice()+ ",vis=0x"+Integer.toHexString(visual)+ @@ -359,7 +361,7 @@ public final class GLXGraphicsConfig } } - private static class GLXBufferCaps extends BufferCapabilities { + private static final class GLXBufferCaps extends BufferCapabilities { public GLXBufferCaps(boolean dblBuf) { super(imageCaps, imageCaps, dblBuf ? FlipContents.UNDEFINED : null); @@ -374,10 +376,11 @@ public final class GLXGraphicsConfig return bufferCaps; } - private static class GLXImageCaps extends ImageCapabilities { + private static final class GLXImageCaps extends ImageCapabilities { private GLXImageCaps() { super(true); } + @Override public boolean isTrueVolatile() { return true; } diff --git a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXSurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXSurfaceData.java index 790a0c38f0c..b810a4d1e9a 100644 --- a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXSurfaceData.java +++ b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXSurfaceData.java @@ -52,6 +52,7 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { initOps(gc, peer, graphicsConfig.getAData()); } + @Override public GraphicsConfiguration getDeviceConfiguration() { return graphicsConfig; } @@ -112,7 +113,7 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { } } - public static class GLXWindowSurfaceData extends GLXSurfaceData { + public static final class GLXWindowSurfaceData extends GLXSurfaceData { protected final int scale; public GLXWindowSurfaceData(X11ComponentPeer peer, @@ -122,10 +123,12 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { scale = gc.getScale(); } + @Override public SurfaceData getReplacement() { return peer.getSurfaceData(); } + @Override public Rectangle getBounds() { Rectangle r = peer.getBounds(); r.x = r.y = 0; @@ -137,6 +140,7 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { /** * Returns destination Component associated with this SurfaceData. */ + @Override public Object getDestination() { return peer.getTarget(); } @@ -161,7 +165,7 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { * belongs to is showed, it is first copied to the real private * FLIP_BACKBUFFER, which is then flipped. */ - public static class GLXVSyncOffScreenSurfaceData extends + public static final class GLXVSyncOffScreenSurfaceData extends GLXOffScreenSurfaceData { private GLXOffScreenSurfaceData flipSurface; @@ -210,10 +214,12 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { initSurface(this.width, this.height); } + @Override public SurfaceData getReplacement() { return restoreContents(offscreenImage); } + @Override public Rectangle getBounds() { if (type == FLIP_BACKBUFFER) { Rectangle r = peer.getBounds(); @@ -229,6 +235,7 @@ public abstract class GLXSurfaceData extends OGLSurfaceData { /** * Returns destination Image associated with this SurfaceData. */ + @Override public Object getDestination() { return offscreenImage; } diff --git a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXVolatileSurfaceManager.java b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXVolatileSurfaceManager.java index 3657b46373b..73974ab2703 100644 --- a/src/java.desktop/unix/classes/sun/java2d/opengl/GLXVolatileSurfaceManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/opengl/GLXVolatileSurfaceManager.java @@ -44,7 +44,7 @@ import sun.java2d.pipe.hw.ExtendedBufferCapabilities; import static sun.java2d.pipe.hw.AccelSurface.*; import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*; -public class GLXVolatileSurfaceManager extends VolatileSurfaceManager { +public final class GLXVolatileSurfaceManager extends VolatileSurfaceManager { private final boolean accelerationEnabled; @@ -63,6 +63,7 @@ public class GLXVolatileSurfaceManager extends VolatileSurfaceManager { && transparency != Transparency.BITMASK; } + @Override protected boolean isAccelerationEnabled() { return accelerationEnabled; } @@ -71,6 +72,7 @@ public class GLXVolatileSurfaceManager extends VolatileSurfaceManager { * Create a FBO-based SurfaceData object (or init the backbuffer * of an existing window if this is a double buffered GraphicsConfig) */ + @Override protected SurfaceData initAcceleratedSurface() { SurfaceData sData; Component comp = vImg.getComponent(); diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitBgLoops.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitBgLoops.java index c01595a1e52..f8ea7dd759a 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitBgLoops.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitBgLoops.java @@ -45,7 +45,7 @@ import java.awt.Composite; * this type of BlitBg will accelerated double-buffer copies between those * two surfaces. */ -public class X11PMBlitBgLoops extends BlitBg { +public final class X11PMBlitBgLoops extends BlitBg { public static void register() { diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitLoops.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitLoops.java index 486bc0e69ff..a6effd74fe8 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitLoops.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11PMBlitLoops.java @@ -47,7 +47,7 @@ import java.awt.image.IndexColorModel; * this type of Blit will accelerated double-buffer copies between those * two surfaces. */ -public class X11PMBlitLoops extends Blit { +public final class X11PMBlitLoops extends Blit { public static void register() { @@ -144,6 +144,7 @@ public class X11PMBlitLoops extends Blit { dstType); } + @Override public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, @@ -180,7 +181,7 @@ public class X11PMBlitLoops extends Blit { * the pixel data and then updates the X11 clipping bitmask from * the transparent pixels in the source. */ - static class DelegateBlitLoop extends Blit { + static final class DelegateBlitLoop extends Blit { SurfaceType dstType; /** @@ -194,6 +195,7 @@ public class X11PMBlitLoops extends Blit { this.dstType = delegateDstType; } + @Override public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java index bd55d001a2a..5c65c2f51da 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11Renderer.java @@ -81,6 +81,7 @@ public class X11Renderer implements native void XDrawLine(long pXSData, long xgc, int x1, int y1, int x2, int y2); + @Override public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) { SunToolkit.awtLock(); try { @@ -97,6 +98,7 @@ public class X11Renderer implements native void XDrawRect(long pXSData, long xgc, int x, int y, int w, int h); + @Override public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height) { @@ -114,6 +116,7 @@ public class X11Renderer implements int x, int y, int w, int h, int arcW, int arcH); + @Override public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) @@ -132,6 +135,7 @@ public class X11Renderer implements native void XDrawOval(long pXSData, long xgc, int x, int y, int w, int h); + @Override public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height) { @@ -149,6 +153,7 @@ public class X11Renderer implements int x, int y, int w, int h, int angleStart, int angleExtent); + @Override public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) @@ -169,6 +174,7 @@ public class X11Renderer implements int[] xpoints, int[] ypoints, int npoints, boolean isclosed); + @Override public void drawPolyline(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) @@ -184,6 +190,7 @@ public class X11Renderer implements } } + @Override public void drawPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) @@ -202,6 +209,7 @@ public class X11Renderer implements native void XFillRect(long pXSData, long xgc, int x, int y, int w, int h); + @Override public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) { @@ -219,6 +227,7 @@ public class X11Renderer implements int x, int y, int w, int h, int arcW, int arcH); + @Override public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) @@ -237,6 +246,7 @@ public class X11Renderer implements native void XFillOval(long pXSData, long xgc, int x, int y, int w, int h); + @Override public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height) { @@ -254,6 +264,7 @@ public class X11Renderer implements int x, int y, int w, int h, int angleStart, int angleExtent); + @Override public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) @@ -274,6 +285,7 @@ public class X11Renderer implements int[] xpoints, int[] ypoints, int npoints); + @Override public void fillPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) @@ -322,6 +334,7 @@ public class X11Renderer implements } } + @Override public void draw(SunGraphics2D sg2d, Shape s) { if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) { // Delegate to drawPolygon() if possible... @@ -359,6 +372,7 @@ public class X11Renderer implements } } + @Override public void fill(SunGraphics2D sg2d, Shape s) { if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) { // Delegate to fillPolygon() if possible... @@ -418,19 +432,22 @@ public class X11Renderer implements int dstx, int dsty, int w, int h); - public static class X11TracingRenderer extends X11Renderer { + public static final class X11TracingRenderer extends X11Renderer { + @Override void XDrawLine(long pXSData, long xgc, int x1, int y1, int x2, int y2) { GraphicsPrimitive.tracePrimitive("X11DrawLine"); super.XDrawLine(pXSData, xgc, x1, y1, x2, y2); } + @Override void XDrawRect(long pXSData, long xgc, int x, int y, int w, int h) { GraphicsPrimitive.tracePrimitive("X11DrawRect"); super.XDrawRect(pXSData, xgc, x, y, w, h); } + @Override void XDrawRoundRect(long pXSData, long xgc, int x, int y, int w, int h, int arcW, int arcH) @@ -438,12 +455,14 @@ public class X11Renderer implements GraphicsPrimitive.tracePrimitive("X11DrawRoundRect"); super.XDrawRoundRect(pXSData, xgc, x, y, w, h, arcW, arcH); } + @Override void XDrawOval(long pXSData, long xgc, int x, int y, int w, int h) { GraphicsPrimitive.tracePrimitive("X11DrawOval"); super.XDrawOval(pXSData, xgc, x, y, w, h); } + @Override void XDrawArc(long pXSData, long xgc, int x, int y, int w, int h, int angleStart, int angleExtent) @@ -452,6 +471,7 @@ public class X11Renderer implements super.XDrawArc(pXSData, xgc, x, y, w, h, angleStart, angleExtent); } + @Override void XDrawPoly(long pXSData, long xgc, int transx, int transy, int[] xpoints, int[] ypoints, @@ -461,6 +481,7 @@ public class X11Renderer implements super.XDrawPoly(pXSData, xgc, transx, transy, xpoints, ypoints, npoints, isclosed); } + @Override void XDoPath(SunGraphics2D sg2d, long pXSData, long xgc, int transX, int transY, Path2D.Float p2df, boolean isFill) @@ -470,12 +491,14 @@ public class X11Renderer implements "X11DrawPath"); super.XDoPath(sg2d, pXSData, xgc, transX, transY, p2df, isFill); } + @Override void XFillRect(long pXSData, long xgc, int x, int y, int w, int h) { GraphicsPrimitive.tracePrimitive("X11FillRect"); super.XFillRect(pXSData, xgc, x, y, w, h); } + @Override void XFillRoundRect(long pXSData, long xgc, int x, int y, int w, int h, int arcW, int arcH) @@ -483,12 +506,14 @@ public class X11Renderer implements GraphicsPrimitive.tracePrimitive("X11FillRoundRect"); super.XFillRoundRect(pXSData, xgc, x, y, w, h, arcW, arcH); } + @Override void XFillOval(long pXSData, long xgc, int x, int y, int w, int h) { GraphicsPrimitive.tracePrimitive("X11FillOval"); super.XFillOval(pXSData, xgc, x, y, w, h); } + @Override void XFillArc(long pXSData, long xgc, int x, int y, int w, int h, int angleStart, int angleExtent) @@ -497,6 +522,7 @@ public class X11Renderer implements super.XFillArc(pXSData, xgc, x, y, w, h, angleStart, angleExtent); } + @Override void XFillPoly(long pXSData, long xgc, int transx, int transy, int[] xpoints, int[] ypoints, @@ -506,6 +532,7 @@ public class X11Renderer implements super.XFillPoly(pXSData, xgc, transx, transy, xpoints, ypoints, npoints); } + @Override void XFillSpans(long pXSData, long xgc, SpanIterator si, long iterator, int transx, int transy) { @@ -513,6 +540,7 @@ public class X11Renderer implements super.XFillSpans(pXSData, xgc, si, iterator, transx, transy); } + @Override void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx, int dsty, diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java index 862baf6ce4f..39e34e40b16 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java @@ -196,6 +196,7 @@ public abstract class X11SurfaceData extends XSurfaceData { private static Boolean accelerationEnabled = null; + @Override public Raster getRaster(int x, int y, int w, int h) { throw new InternalError("not implemented yet"); } @@ -272,6 +273,7 @@ public abstract class X11SurfaceData extends XSurfaceData { return X11SurfaceDataProxy.createProxy(srcData, graphicsConfig); } + @Override public void validatePipe(SunGraphics2D sg2d) { if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && @@ -376,6 +378,7 @@ public abstract class X11SurfaceData extends XSurfaceData { } } + @Override public RenderLoops getRenderLoops(SunGraphics2D sg2d) { if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY) @@ -385,6 +388,7 @@ public abstract class X11SurfaceData extends XSurfaceData { return super.getRenderLoops(sg2d); } + @Override public GraphicsConfiguration getDeviceConfiguration() { return graphicsConfig; } @@ -458,6 +462,7 @@ public abstract class X11SurfaceData extends XSurfaceData { */ public abstract boolean canSourceSendExposures(int x, int y, int w, int h); + @Override public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) { @@ -591,6 +596,7 @@ public abstract class X11SurfaceData extends XSurfaceData { return sType; } + @Override public void invalidate() { if (isValid()) { setInvalid(); @@ -707,10 +713,12 @@ public abstract class X11SurfaceData extends XSurfaceData { } } + @Override public SurfaceData getReplacement() { return peer.getSurfaceData(); } + @Override public Rectangle getBounds() { Rectangle r = peer.getBounds(); r.x = r.y = 0; @@ -727,6 +735,7 @@ public abstract class X11SurfaceData extends XSurfaceData { /** * Returns destination Component associated with this SurfaceData. */ + @Override public Object getDestination() { return peer.getTarget(); } @@ -767,6 +776,7 @@ public abstract class X11SurfaceData extends XSurfaceData { makePipes(); } + @Override public SurfaceData getReplacement() { return restoreContents(offscreenImage); } @@ -779,10 +789,12 @@ public abstract class X11SurfaceData extends XSurfaceData { * it could choose wrong loop (blit instead of blitbg, * for example). */ + @Override public int getTransparency() { return transparency; } + @Override public Rectangle getBounds() { return new Rectangle(width, height); } @@ -792,6 +804,7 @@ public abstract class X11SurfaceData extends XSurfaceData { return (x < 0 || y < 0 || (x+w) > width || (y+h) > height); } + @Override public void flush() { /* * We need to invalidate the surface before disposing the @@ -808,6 +821,7 @@ public abstract class X11SurfaceData extends XSurfaceData { /** * Returns destination Image associated with this SurfaceData. */ + @Override public Object getDestination() { return offscreenImage; } @@ -825,7 +839,8 @@ public abstract class X11SurfaceData extends XSurfaceData { private static LazyPipe lazypipe = new LazyPipe(); - public static class LazyPipe extends ValidatePipe { + public static final class LazyPipe extends ValidatePipe { + @Override public boolean validate(SunGraphics2D sg2d) { X11SurfaceData xsd = (X11SurfaceData) sg2d.surfaceData; if (!xsd.isDrawableValid()) { diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java index e55c663181f..70ec7f8724a 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java @@ -115,11 +115,12 @@ public abstract class X11SurfaceDataProxy extends SurfaceDataProxy * Proxy for opaque source images. * This proxy can accelerate unscaled Src copies. */ - public static class Opaque extends X11SurfaceDataProxy { + public static final class Opaque extends X11SurfaceDataProxy { public Opaque(X11GraphicsConfig x11gc) { super(x11gc); } + @Override public int getTransparency() { return Transparency.OPAQUE; } @@ -141,11 +142,12 @@ public abstract class X11SurfaceDataProxy extends SurfaceDataProxy * This proxy can accelerate unscaled Src copies or * unscaled SrcOver copies that use an opaque bgColor. */ - public static class Bitmask extends X11SurfaceDataProxy { + public static final class Bitmask extends X11SurfaceDataProxy { public Bitmask(X11GraphicsConfig x11gc) { super(x11gc); } + @Override public int getTransparency() { return Transparency.BITMASK; } diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java index 27b79c00a4a..88609597f05 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11VolatileSurfaceManager.java @@ -44,7 +44,7 @@ import sun.java2d.SurfaceData; * (BufImgSurfaceData) that will be used until the accelerated * SurfaceData can be restored. */ -public class X11VolatileSurfaceManager extends VolatileSurfaceManager { +public final class X11VolatileSurfaceManager extends VolatileSurfaceManager { private boolean accelerationEnabled; @@ -73,6 +73,7 @@ public class X11VolatileSurfaceManager extends VolatileSurfaceManager { } } + @Override protected boolean isAccelerationEnabled() { return accelerationEnabled; } @@ -80,6 +81,7 @@ public class X11VolatileSurfaceManager extends VolatileSurfaceManager { /** * Create a pixmap-based SurfaceData object */ + @Override protected SurfaceData initAcceleratedSurface() { SurfaceData sData; @@ -103,6 +105,7 @@ public class X11VolatileSurfaceManager extends VolatileSurfaceManager { return sData; } + @Override protected boolean isConfigValid(GraphicsConfiguration gc) { // REMIND: we might be too paranoid here, requiring that // the GC be exactly the same as the original one. The diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/DirtyRegion.java b/src/java.desktop/unix/classes/sun/java2d/xr/DirtyRegion.java index bc855aa4940..bc0cc0b7b77 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/DirtyRegion.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/DirtyRegion.java @@ -35,7 +35,7 @@ import static sun.java2d.xr.MaskTileManager.MASK_SIZE; * @author Clemens Eisserer */ -public class DirtyRegion implements Cloneable { +public final class DirtyRegion implements Cloneable { int x, y, x2, y2; public DirtyRegion() { @@ -116,6 +116,7 @@ public class DirtyRegion implements Cloneable { } } + @Override public String toString() { return this.getClass().getName() + "(x: " + x + ", y:" + y + ", x2:" + x2 + ", y2:" + y2 + ")"; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableByteArray.java b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableByteArray.java index 652dbd20637..1a5b615c96d 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableByteArray.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableByteArray.java @@ -34,7 +34,7 @@ import java.util.*; * @author Clemens Eisserer */ -public class GrowableByteArray +public final class GrowableByteArray { byte[] array; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableEltArray.java b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableEltArray.java index bb2070ec9d0..7ec0665db5c 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableEltArray.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableEltArray.java @@ -31,7 +31,7 @@ package sun.java2d.xr; * * @author Clemens Eisserer */ -public class GrowableEltArray extends GrowableIntArray { +public final class GrowableEltArray extends GrowableIntArray { private static final int ELT_SIZE = 4; GrowableIntArray glyphs; @@ -77,6 +77,7 @@ public class GrowableEltArray extends GrowableIntArray { return glyphs; } + @Override public void clear() { glyphs.clear(); super.clear(); diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/GrowablePointArray.java b/src/java.desktop/unix/classes/sun/java2d/xr/GrowablePointArray.java index bdcd3bd235b..1f3eb88e91c 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/GrowablePointArray.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/GrowablePointArray.java @@ -30,7 +30,7 @@ package sun.java2d.xr; * * @author Clemens Eisserer */ -public class GrowablePointArray extends GrowableIntArray +public final class GrowablePointArray extends GrowableIntArray { private static final int POINT_SIZE = 2; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableRectArray.java b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableRectArray.java index 031fe5914f4..e611aae4e3b 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/GrowableRectArray.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/GrowableRectArray.java @@ -30,7 +30,7 @@ package sun.java2d.xr; * * @author Clemens Eisserer */ -public class GrowableRectArray extends GrowableIntArray { +public final class GrowableRectArray extends GrowableIntArray { private static final int RECT_SIZE = 4; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/MaskTile.java b/src/java.desktop/unix/classes/sun/java2d/xr/MaskTile.java index 35deca44e18..d2d0f09ad0a 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/MaskTile.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/MaskTile.java @@ -31,7 +31,7 @@ package sun.java2d.xr; * * @author Clemens Eisserer */ -public class MaskTile { +public final class MaskTile { GrowableRectArray rects; DirtyRegion dirtyArea; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/MaskTileManager.java b/src/java.desktop/unix/classes/sun/java2d/xr/MaskTileManager.java index 947919f9247..7e58e530353 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/MaskTileManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/MaskTileManager.java @@ -38,7 +38,7 @@ import java.util.*; * @author Clemens Eisserer */ -public class MaskTileManager { +public final class MaskTileManager { public static final int MASK_SIZE = 256; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/MutableInteger.java b/src/java.desktop/unix/classes/sun/java2d/xr/MutableInteger.java index be5f8891be9..62bb8c255e9 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/MutableInteger.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/MutableInteger.java @@ -31,17 +31,19 @@ package sun.java2d.xr; * @author Clemens Eisserer */ -public class MutableInteger { +public final class MutableInteger { private int value; public MutableInteger(int value) { this.setValue(value); } + @Override public int hashCode() { return getValue(); } + @Override public boolean equals(Object o) { return (o instanceof MutableInteger) && (((MutableInteger) o).getValue() == getValue()); diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XIDGenerator.java b/src/java.desktop/unix/classes/sun/java2d/xr/XIDGenerator.java index b99666bb3b0..359c4d9f536 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XIDGenerator.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XIDGenerator.java @@ -33,7 +33,7 @@ package sun.java2d.xr; * @author Clemens Eisserer */ -public class XIDGenerator { +public final class XIDGenerator { private static final int XID_BUFFER_SIZE = 512; int[] xidBuffer = new int[XID_BUFFER_SIZE]; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRBackendNative.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRBackendNative.java index e5f337d3415..589f17968c4 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRBackendNative.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRBackendNative.java @@ -40,7 +40,7 @@ import static sun.java2d.xr.XRUtils.XDoubleToFixed; * @author Clemens Eisserer */ -public class XRBackendNative implements XRBackend { +public final class XRBackendNative implements XRBackend { static { initIDs(); @@ -52,34 +52,45 @@ public class XRBackendNative implements XRBackend { private static native void initIDs(); + @Override public native long createGC(int drawable); + @Override public native void freeGC(long gc); + @Override public native int createPixmap(int drawable, int depth, int width, int height); private native int createPictureNative(int drawable, long formatID); + @Override public native void freePicture(int picture); + @Override public native void freePixmap(int pixmap); + @Override public native void setGCExposures(long gc, boolean exposure); + @Override public native void setGCForeground(long gc, int pixel); + @Override public native void setPictureRepeat(int picture, int repeat); + @Override public native void copyArea(int src, int dst, long gc, int srcx, int srcy, int width, int height, int dstx, int dsty); + @Override public native void setGCMode(long gc, boolean copy); private static native void GCRectanglesNative(int drawable, long gc, int[] rectArray, int rectCnt); + @Override public native void renderComposite(byte op, int src, int mask, int dst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, @@ -113,20 +124,24 @@ public class XRBackendNative implements XRBackend { int innerRadius, int outerRadius, int repeat); + @Override public native void setFilter(int picture, int filter); private static native void XRSetClipNative(long dst, int x1, int y1, int x2, int y2, Region clip, boolean isGC); + @Override public void GCRectangles(int drawable, long gc, GrowableRectArray rects) { GCRectanglesNative(drawable, gc, rects.getArray(), rects.getSize()); } + @Override public int createPicture(int drawable, int formatID) { return createPictureNative(drawable, getFormatPtr(formatID)); } + @Override public void setPictureTransform(int picture, AffineTransform transform) { XRSetTransformNative(picture, XDoubleToFixed(transform.getScaleX()), @@ -137,6 +152,7 @@ public class XRBackendNative implements XRBackend { XDoubleToFixed(transform.getTranslateY())); } + @Override public void renderRectangle(int dst, byte op, XRColor color, int x, int y, int width, int height) { renderRectangle(dst, op, (short)color.red, (short)color.green, @@ -170,6 +186,7 @@ public class XRBackendNative implements XRBackend { return 0L; } + @Override public int createLinearGradient(Point2D p1, Point2D p2, float[] fractions, int[] pixels, int repeat) { @@ -182,6 +199,7 @@ public class XRBackendNative implements XRBackend { return gradient; } + @Override public int createRadialGradient(float centerX, float centerY, float innerRadius, float outerRadius, float[] fractions, int[] pixels, int repeat) { @@ -196,12 +214,14 @@ public class XRBackendNative implements XRBackend { repeat); } + @Override public void setGCClipRectangles(long gc, Region clip) { XRSetClipNative(gc, clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip, true); } + @Override public void setClipRectangles(int picture, Region clip) { if (clip != null) { XRSetClipNative(picture, clip.getLoX(), clip.getLoY(), @@ -212,6 +232,7 @@ public class XRBackendNative implements XRBackend { } } + @Override public void renderRectangles(int dst, byte op, XRColor color, GrowableRectArray rects) { XRenderRectanglesNative(dst, op, @@ -229,6 +250,7 @@ public class XRBackendNative implements XRBackend { return glyphInfoPtrs; } + @Override public void XRenderAddGlyphs(int glyphSet, GlyphList gl, List cacheEntries, byte[] pixelData) { @@ -237,6 +259,7 @@ public class XRBackendNative implements XRBackend { glyphInfoPtrs.length, pixelData, pixelData.length); } + @Override public void XRenderFreeGlyphs(int glyphSet, int[] gids) { XRFreeGlyphsNative(glyphSet, gids, gids.length); } @@ -256,12 +279,14 @@ public class XRBackendNative implements XRBackend { int[] eltArray, int[] glyphIDs, int eltCnt, int glyphCnt); + @Override public int XRenderCreateGlyphSet(int formatID) { return XRenderCreateGlyphSetNative(getFormatPtr(formatID)); } private static native int XRenderCreateGlyphSetNative(long format); + @Override public void XRenderCompositeText(byte op, int src, int dst, int maskFormatID, int sx, int sy, int dx, int dy, @@ -273,6 +298,7 @@ public class XRBackendNative implements XRBackend { glyphs.getSize()); } + @Override public void putMaskImage(int drawable, long gc, byte[] imageData, int sx, int sy, int dx, int dy, int width, int height, int maskOff, diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRColor.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRColor.java index d983b8d1336..eb1604374bb 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRColor.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRColor.java @@ -33,7 +33,7 @@ import java.awt.*; * @author Clemens Eisserer */ -public class XRColor { +public final class XRColor { public static final XRColor FULL_ALPHA = new XRColor(0xffff, 0, 0, 0); public static final XRColor NO_ALPHA = new XRColor(0, 0, 0, 0); @@ -109,6 +109,7 @@ public class XRColor { return xrValue; } + @Override public String toString(){ return "A:"+alpha+" R:"+red+" G:"+green+" B:"+blue; } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java index 20f09ed5de6..14182011345 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java @@ -44,7 +44,7 @@ import sun.java2d.loops.XORComposite; * @author Clemens Eisserer */ -public class XRCompositeManager { +public final class XRCompositeManager { private static boolean enableGradCache = true; private static XRCompositeManager instance; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawImage.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawImage.java index 69502f2ee2a..c78303236c6 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawImage.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawImage.java @@ -37,7 +37,7 @@ import sun.java2d.pipe.*; * Class used for re-routing transformed blits to the accelerated loops. */ -public class XRDrawImage extends DrawImage { +public final class XRDrawImage extends DrawImage { @Override protected void renderImageXform(SunGraphics2D sg, Image img, diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawLine.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawLine.java index f2d6b3f15ff..6b76e4ee388 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawLine.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRDrawLine.java @@ -32,7 +32,7 @@ */ package sun.java2d.xr; -public class XRDrawLine { +public final class XRDrawLine { static final int BIG_MAX = ((1 << 29) - 1); static final int BIG_MIN = (-(1 << 29)); diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java index 43f17e11ae1..748286a0828 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRGraphicsConfig.java @@ -34,7 +34,7 @@ import sun.awt.image.SunVolatileImage; import sun.awt.image.VolatileSurfaceManager; import sun.java2d.SurfaceData; -public class XRGraphicsConfig extends X11GraphicsConfig implements +public final class XRGraphicsConfig extends X11GraphicsConfig implements SurfaceManager.ProxiedGraphicsConfig { private final SurfaceManager.ProxyCache surfaceDataProxyCache = new SurfaceManager.ProxyCache(); @@ -44,6 +44,7 @@ public class XRGraphicsConfig extends X11GraphicsConfig implements super(device, visualnum, depth, colormap, doubleBuffer); } + @Override public SurfaceData createSurfaceData(X11ComponentPeer peer) { return XRSurfaceData.createData(peer); } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskBlit.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskBlit.java index 247faa876a3..0600f6c4bcf 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskBlit.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskBlit.java @@ -41,7 +41,7 @@ import sun.java2d.pipe.Region; * * @author Clemens Eisserer */ -public class XRMaskBlit extends MaskBlit { +public final class XRMaskBlit extends MaskBlit { static void register() { GraphicsPrimitive[] primitives = { new XRMaskBlit(XRSurfaceData.IntArgbPreX11, SrcOver, @@ -65,6 +65,7 @@ public class XRMaskBlit extends MaskBlit { int srcy, int dstx, int dsty, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask); + @Override public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int srcx, int srcy, int dstx, int dsty, int width, int height, byte[] mask, int maskoff, int maskscan) { diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskFill.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskFill.java index 24632983767..993b329e3bc 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskFill.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskFill.java @@ -44,7 +44,7 @@ import sun.awt.*; import sun.java2d.*; import sun.java2d.loops.*; -public class XRMaskFill extends MaskFill { +public final class XRMaskFill extends MaskFill { static void register() { GraphicsPrimitive[] primitives = { new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11), @@ -93,6 +93,7 @@ public class XRMaskFill extends MaskFill { protected native void maskFill(long xsdo, int x, int y, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask); + @Override public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp, final int x, final int y, final int w, final int h, final byte[] mask, final int maskoff, final int maskscan) { diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskImage.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskImage.java index bf1c14b1e05..cae3b6af563 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskImage.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRMaskImage.java @@ -34,7 +34,7 @@ import java.awt.geom.*; * @author Clemens Eisserer */ -public class XRMaskImage { +public final class XRMaskImage { private static final int MASK_SCALE_FACTOR = 8; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java index abff8138ca8..260bd629094 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java @@ -162,11 +162,12 @@ public final class XRPMBlitLoops { } } -class XRPMBlit extends Blit { +final class XRPMBlit extends Blit { public XRPMBlit(SurfaceType srcType, SurfaceType dstType) { super(srcType, CompositeType.AnyAlpha, dstType); } + @Override public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) { try { SunToolkit.awtLock(); @@ -185,11 +186,12 @@ class XRPMBlit extends Blit { } } -class XRPMScaledBlit extends ScaledBlit { +final class XRPMScaledBlit extends ScaledBlit { public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) { super(srcType, CompositeType.AnyAlpha, dstType); } + @Override @SuppressWarnings("cast") public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { @@ -229,7 +231,7 @@ class XRPMScaledBlit extends ScaledBlit { * * @author Clemens Eisserer */ -class XRPMTransformedBlit extends TransformBlit { +final class XRPMTransformedBlit extends TransformBlit { final Rectangle compositeBounds = new Rectangle(); final double[] srcCoords = new double[8]; final double[] dstCoords = new double[8]; @@ -290,6 +292,7 @@ class XRPMTransformedBlit extends TransformBlit { compositeBounds.height = (int) (maxY - minY); } + @Override public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) { try { @@ -346,7 +349,7 @@ class XRPMTransformedBlit extends TransformBlit { } } -class XrSwToPMBlit extends Blit { +final class XrSwToPMBlit extends Blit { Blit pmToSurfaceBlit; XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) { @@ -354,6 +357,7 @@ class XrSwToPMBlit extends Blit { pmToSurfaceBlit = new XRPMBlit(dstType, dstType); } + @Override public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) { try { SunToolkit.awtLock(); @@ -366,7 +370,7 @@ class XrSwToPMBlit extends Blit { } } -class XrSwToPMScaledBlit extends ScaledBlit { +final class XrSwToPMScaledBlit extends ScaledBlit { ScaledBlit pmToSurfaceBlit; XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) { @@ -374,6 +378,7 @@ class XrSwToPMScaledBlit extends ScaledBlit { pmToSurfaceBlit = new XRPMScaledBlit(dstType, dstType); } + @Override public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2) { { @@ -391,7 +396,7 @@ class XrSwToPMScaledBlit extends ScaledBlit { } } -class XrSwToPMTransformedBlit extends TransformBlit { +final class XrSwToPMTransformedBlit extends TransformBlit { TransformBlit pmToSurfaceBlit; XrSwToPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) { @@ -399,6 +404,7 @@ class XrSwToPMTransformedBlit extends TransformBlit { pmToSurfaceBlit = new XRPMTransformedBlit(dstType, dstType); } + @Override public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int sx, int sy, int dstx, int dsty, int w, int h) { try { diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java index 1b8576c385d..8720dca6094 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java @@ -91,7 +91,7 @@ abstract class XRPaints { abstract void setXRPaint(SunGraphics2D sg2d, Paint paint); - private static class XRGradient extends XRPaints { + private static final class XRGradient extends XRPaints { private XRGradient() { } @@ -126,7 +126,7 @@ abstract class XRPaints { return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff)); } - private static class XRLinearGradient extends XRPaints { + private static final class XRLinearGradient extends XRPaints { @Override boolean isPaintValid(SunGraphics2D sg2d) { @@ -163,7 +163,7 @@ abstract class XRPaints { } } - private static class XRRadialGradient extends XRPaints { + private static final class XRRadialGradient extends XRPaints { @Override boolean isPaintValid(SunGraphics2D sg2d) { @@ -204,7 +204,7 @@ abstract class XRPaints { } } - private static class XRTexture extends XRPaints { + private static final class XRTexture extends XRPaints { private XRSurfaceData getAccSrcSurface(XRSurfaceData dstData, BufferedImage bi) { // REMIND: this is a hack that attempts to cache the system diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java index 07c8a1d877d..a142d9efda7 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRRenderer.java @@ -51,7 +51,7 @@ import static sun.java2d.xr.XRUtils.clampToUShort; * @author Clemens Eisserer */ -public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { +public final class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { XRDrawHandler drawHandler; MaskTileManager tileManager; XRDrawLine lineGen; @@ -77,6 +77,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { sg2d.paint, sg2d); } + @Override public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) { Region compClip = sg2d.getCompClip(); int transX1 = Region.clipAdd(x1, sg2d.transX); @@ -96,11 +97,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } } + @Override public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height) { draw(sg2d, new Rectangle2D.Float(x, y, width, height)); } + @Override public void drawPolyline(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) { Path2D.Float p2d = new Path2D.Float(); @@ -114,11 +117,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { draw(sg2d, p2d); } + @Override public void drawPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) { draw(sg2d, new Polygon(xpoints, ypoints, npoints)); } + @Override public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) { x = Region.clipAdd(x, sg2d.transX); y = Region.clipAdd(y, sg2d.transY); @@ -158,11 +163,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } } + @Override public void fillPolygon(SunGraphics2D sg2d, int[] xpoints, int[] ypoints, int npoints) { fill(sg2d, new Polygon(xpoints, ypoints, npoints)); } + @Override public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) { @@ -170,6 +177,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { arcWidth, arcHeight)); } + @Override public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) { @@ -177,16 +185,19 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { arcWidth, arcHeight)); } + @Override public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height) { draw(sg2d, new Ellipse2D.Float(x, y, width, height)); } + @Override public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height) { fill(sg2d, new Ellipse2D.Float(x, y, width, height)); } + @Override public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) { @@ -194,6 +205,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { startAngle, arcAngle, Arc2D.OPEN)); } + @Override public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) { @@ -201,7 +213,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { startAngle, arcAngle, Arc2D.PIE)); } - private class XRDrawHandler extends ProcessPath.DrawHandler { + private final class XRDrawHandler extends ProcessPath.DrawHandler { DirtyRegion region; XRDrawHandler() { @@ -222,6 +234,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { validateSurface(sg2d); } + @Override public void drawLine(int x1, int y1, int x2, int y2) { region.setDirtyLineRegion(x1, y1, x2, y2); int xDiff = region.x2 - region.x; @@ -243,10 +256,12 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } } + @Override public void drawPixel(int x, int y) { rectBuffer.pushRectValues(x, y, 1, 1); } + @Override public void drawScanline(int x1, int x2, int y) { rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1); } @@ -296,6 +311,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } } + @Override public void draw(SunGraphics2D sg2d, Shape s) { if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) { Path2D.Float p2df; @@ -326,6 +342,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } } + @Override public void fill(SunGraphics2D sg2d, Shape s) { int transx, transy; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java index 69732a42475..8acad667203 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java @@ -25,7 +25,7 @@ package sun.java2d.xr; -public class XRSolidSrcPict { +public final class XRSolidSrcPict { XRBackend con; XRSurfaceData srcPict; diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java index f4dcee17f7a..54ad6334076 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java @@ -88,6 +88,7 @@ public abstract class XRSurfaceData extends XSurfaceData { public static final SurfaceType IntArgbPreX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11); + @Override public Raster getRaster(int x, int y, int w, int h) { throw new InternalError("not implemented yet"); } @@ -206,6 +207,7 @@ public abstract class XRSurfaceData extends XSurfaceData { return (supportedPaint && supportedCompOp) ? xrtextpipe : null; } + @Override protected MaskFill getMaskFill(SunGraphics2D sg2d) { AlphaComposite aComp = null; if (sg2d.composite instanceof AlphaComposite alphaComposite) { @@ -224,6 +226,7 @@ public abstract class XRSurfaceData extends XSurfaceData { return (supportedPaint && supportedCompOp) ? super.getMaskFill(sg2d) : null; } + @Override public RenderLoops getRenderLoops(SunGraphics2D sg2d) { if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) @@ -234,6 +237,7 @@ public abstract class XRSurfaceData extends XSurfaceData { return super.getRenderLoops(sg2d); } + @Override public GraphicsConfiguration getDeviceConfiguration() { return graphicsConfig; } @@ -366,6 +370,7 @@ public abstract class XRSurfaceData extends XSurfaceData { } } + @Override public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) { if (xrpipe == null) { @@ -412,6 +417,7 @@ public abstract class XRSurfaceData extends XSurfaceData { return sType; } + @Override public void invalidate() { if (isValid()) { setInvalid(); @@ -543,7 +549,7 @@ public abstract class XRSurfaceData extends XSurfaceData { } } - public static class XRWindowSurfaceData extends XRSurfaceData { + public static final class XRWindowSurfaceData extends XRSurfaceData { protected final int scale; @@ -571,10 +577,12 @@ public abstract class XRSurfaceData extends XSurfaceData { } } + @Override public SurfaceData getReplacement() { return peer.getSurfaceData(); } + @Override public Rectangle getBounds() { Rectangle r = peer.getBounds(); r.x = r.y = 0; @@ -591,10 +599,12 @@ public abstract class XRSurfaceData extends XSurfaceData { /** * Returns destination Component associated with this SurfaceData. */ + @Override public Object getDestination() { return peer.getTarget(); } + @Override public void invalidate() { try { SunToolkit.awtLock(); @@ -617,31 +627,35 @@ public abstract class XRSurfaceData extends XSurfaceData { } } - public static class XRInternalSurfaceData extends XRSurfaceData { + public static final class XRInternalSurfaceData extends XRSurfaceData { public XRInternalSurfaceData(XRBackend renderQueue, int pictXid) { super(renderQueue); this.picture = pictXid; this.transformInUse = false; } + @Override public boolean canSourceSendExposures(int x, int y, int w, int h) { return false; } + @Override public Rectangle getBounds() { return null; } + @Override public Object getDestination() { return null; } + @Override public SurfaceData getReplacement() { return null; } } - public static class XRPixmapSurfaceData extends XRSurfaceData { + public static final class XRPixmapSurfaceData extends XRSurfaceData { Image offscreenImage; int width; int height; @@ -675,6 +689,7 @@ public abstract class XRSurfaceData extends XSurfaceData { } } + @Override public SurfaceData getReplacement() { return restoreContents(offscreenImage); } @@ -685,10 +700,12 @@ public abstract class XRSurfaceData extends XSurfaceData { * choose loops based on the transparency on the source SD, so it could * choose wrong loop (blit instead of blitbg, for example). */ + @Override public int getTransparency() { return transparency; } + @Override public Rectangle getBounds() { return new Rectangle(width, height); } @@ -698,6 +715,7 @@ public abstract class XRSurfaceData extends XSurfaceData { return (x < 0 || y < 0 || (x + w) > width || (y + h) > height); } + @Override public void flush() { /* * We need to invalidate the surface before disposing the native @@ -714,6 +732,7 @@ public abstract class XRSurfaceData extends XSurfaceData { /** * Returns destination Image associated with this SurfaceData. */ + @Override public Object getDestination() { return offscreenImage; } @@ -733,7 +752,8 @@ public abstract class XRSurfaceData extends XSurfaceData { return xgc; } - public static class LazyPipe extends ValidatePipe { + public static final class LazyPipe extends ValidatePipe { + @Override public boolean validate(SunGraphics2D sg2d) { XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData; if (!xsd.isXRDrawableValid()) { diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java index 2c82e30197e..b05b90fe267 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java @@ -35,7 +35,7 @@ import sun.java2d.loops.CompositeType; * The proxy class contains the logic if to replace a SurfaceData with a * cached X11 Pixmap and the code to create the accelerated surfaces. */ -public class XRSurfaceDataProxy extends SurfaceDataProxy implements Transparency { +public final class XRSurfaceDataProxy extends SurfaceDataProxy implements Transparency { public static SurfaceDataProxy createProxy(SurfaceData srcData, XRGraphicsConfig dstConfig) { @@ -81,6 +81,7 @@ public class XRSurfaceDataProxy extends SurfaceDataProxy implements Transparency return (bgColor == null || transparency == Transparency.TRANSLUCENT); } + @Override public int getTransparency() { return transparency; } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java index 9f2aad97a09..3a4887e167f 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java @@ -39,7 +39,7 @@ import static java.awt.AlphaComposite.*; * @author Clemens Eisserer */ -public class XRUtils { +public final class XRUtils { public static final int None = 0; /* Composition Operators */ diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java index 0a09c6e35e2..ad29d553055 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRVolatileSurfaceManager.java @@ -35,12 +35,13 @@ import sun.java2d.SurfaceData; /** * XRender platform implementation of the VolatileSurfaceManager class. */ -public class XRVolatileSurfaceManager extends VolatileSurfaceManager { +public final class XRVolatileSurfaceManager extends VolatileSurfaceManager { public XRVolatileSurfaceManager(SunVolatileImage vImg, Object context) { super(vImg, context); } + @Override protected boolean isAccelerationEnabled() { return true; } @@ -48,6 +49,7 @@ public class XRVolatileSurfaceManager extends VolatileSurfaceManager { /** * Create a pixmap-based SurfaceData object */ + @Override protected SurfaceData initAcceleratedSurface() { SurfaceData sData; @@ -74,6 +76,7 @@ public class XRVolatileSurfaceManager extends VolatileSurfaceManager { * XRender should allow copies between different formats and depths. * TODO: verify that this assumption is correct. */ + @Override protected boolean isConfigValid(GraphicsConfiguration gc) { return true; } diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XcbRequestCounter.java b/src/java.desktop/unix/classes/sun/java2d/xr/XcbRequestCounter.java index 3bd4bf4702f..58369b5a866 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XcbRequestCounter.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XcbRequestCounter.java @@ -31,7 +31,7 @@ package sun.java2d.xr; * @author Clemens Eisserer */ -public class XcbRequestCounter { +public final class XcbRequestCounter { private static final long MAX_UINT = 4294967295L; long value; diff --git a/src/java.desktop/unix/classes/sun/print/AttributeClass.java b/src/java.desktop/unix/classes/sun/print/AttributeClass.java index 0fb27909a26..f8eee08411b 100644 --- a/src/java.desktop/unix/classes/sun/print/AttributeClass.java +++ b/src/java.desktop/unix/classes/sun/print/AttributeClass.java @@ -30,7 +30,7 @@ import java.util.Objects; import static java.nio.charset.StandardCharsets.UTF_8; -public class AttributeClass { +public final class AttributeClass { private String myName; private int myType; private int nameLen; @@ -266,6 +266,7 @@ public class AttributeClass { return Objects.hash(myType, myName, myValue); } + @Override public String toString() { return myName; } diff --git a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java index 11e0b45014e..a7f8d3dc24d 100644 --- a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java +++ b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java @@ -48,7 +48,7 @@ import javax.print.attribute.EnumSyntax; import javax.print.attribute.standard.PrinterName; -public class CUPSPrinter { +public final class CUPSPrinter { private static final String debugPrefix = "CUPSPrinter>> "; private static final double PRINTER_DPI = 72.0; private boolean initialized; diff --git a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 96fcdef3a52..cdc8d6e4a0e 100644 --- a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -106,7 +106,7 @@ import javax.print.event.PrintServiceAttributeListener; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; -public class IPPPrintService implements PrintService, SunPrinterJobService { +public final class IPPPrintService implements PrintService, SunPrinterJobService { public static final boolean debugPrint; private static final String debugPrefix = "IPPPrintService>> "; @@ -510,12 +510,14 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public DocPrintJob createPrintJob() { // REMIND: create IPPPrintJob return new UnixPrintJob(this); } + @Override public synchronized Object getSupportedAttributeValues(Class category, DocFlavor flavor, @@ -836,7 +838,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { //This class is for getting all pre-defined Finishings @SuppressWarnings("serial") // JDK implementation class - private static class ExtFinishing extends Finishings { + private static final class ExtFinishing extends Finishings { ExtFinishing(int value) { super(100); // 100 to avoid any conflicts with predefined values. } @@ -848,6 +850,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public AttributeSet getUnsupportedAttributes(DocFlavor flavor, AttributeSet attributes) { if (flavor != null && !isDocFlavorSupported(flavor)) { @@ -882,6 +885,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public synchronized DocFlavor[] getSupportedDocFlavors() { if (supportedDocFlavors != null) { @@ -978,6 +982,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public boolean isDocFlavorSupported(DocFlavor flavor) { if (supportedDocFlavors == null) { getSupportedDocFlavors(); @@ -1075,6 +1080,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { return null; } + @Override public synchronized Class[] getSupportedAttributeCategories() { if (supportedCats != null) { Class [] copyCats = new Class[supportedCats.length]; @@ -1151,6 +1157,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public boolean isAttributeCategorySupported(Class category) { @@ -1188,6 +1195,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { return false; } + @Override @SuppressWarnings("unchecked") public synchronized T getAttribute(Class category) @@ -1257,6 +1265,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public synchronized PrintServiceAttributeSet getAttributes() { if (!init) { // get all attributes for the first time. @@ -1377,6 +1386,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public boolean isAttributeValueSupported(Attribute attr, DocFlavor flavor, AttributeSet attributes) { @@ -1526,6 +1536,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public synchronized Object getDefaultAttributeValue(Class category) { @@ -1716,6 +1727,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { return false; } + @Override public ServiceUIFactory getServiceUIFactory() { return null; } @@ -1728,6 +1740,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } } + @Override public void addPrintServiceAttributeListener( PrintServiceAttributeListener listener) { synchronized (this) { @@ -1741,6 +1754,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } } + @Override public void removePrintServiceAttributeListener( PrintServiceAttributeListener listener) { synchronized (this) { @@ -1759,6 +1773,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { return printer; } + @Override public String getName() { /* * Mac is using printer-info IPP attribute for its human-readable printer @@ -1777,6 +1792,7 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { } + @Override public boolean usesClass(Class c) { return (c == sun.print.PSPrinterJob.class); } @@ -2103,16 +2119,19 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { return (s.length() == 2) ? s : "0"+s; } + @Override public String toString() { return "IPP Printer : " + getName(); } + @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof IPPPrintService && ((IPPPrintService)obj).getName().equals(getName()))); } + @Override public int hashCode() { return this.getClass().hashCode()+getName().hashCode(); } diff --git a/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java b/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java index 3eb02bc7f23..d96894660b9 100644 --- a/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java +++ b/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java @@ -56,7 +56,7 @@ import sun.awt.util.ThreadGroupUtils; * Remind: This class uses solaris commands. We also need a linux * version */ -public class PrintServiceLookupProvider extends PrintServiceLookup +public final class PrintServiceLookupProvider extends PrintServiceLookup implements BackgroundServiceLookup, Runnable { /* Remind: the current implementation is static, as its assumed @@ -209,6 +209,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup * This isn't required by the API and there's a risk doing this will * lead people to assume its guaranteed. */ + @Override public synchronized PrintService[] getPrintServices() { if (printServices == null || !pollServices) { refreshServices(); @@ -541,6 +542,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup * If service attributes are specified then there must be additional * filtering. */ + @Override public PrintService[] getPrintServices(DocFlavor flavor, AttributeSet attributes) { PrintRequestAttributeSet requestSet = null; @@ -599,6 +601,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup /* * return empty array as don't support multi docs */ + @Override public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes) { @@ -606,6 +609,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup } + @Override public synchronized PrintService getDefaultPrintService() { // clear defaultPrintService defaultPrintService = null; @@ -665,6 +669,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup return defaultPrintService; } + @Override public synchronized void getServicesInbackground(BackgroundLookupListener listener) { if (printServices != null) { @@ -695,6 +700,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup } } + @Override public void run() { PrintService[] services = getPrintServices(); synchronized (this) { @@ -897,7 +903,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup } } - private class PrinterChangeListener implements Runnable { + private final class PrinterChangeListener implements Runnable { @Override public void run() { diff --git a/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java b/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java index 3cd353141a4..4604167a0e4 100644 --- a/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java +++ b/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java @@ -86,7 +86,7 @@ import java.awt.print.Printable; import java.awt.print.PrinterException; -public class UnixPrintJob implements CancelablePrintJob { +public final class UnixPrintJob implements CancelablePrintJob { private static String debugPrefix = "UnixPrintJob>> "; private transient ArrayList jobListeners; @@ -132,10 +132,12 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public PrintService getPrintService() { return service; } + @Override public PrintJobAttributeSet getAttributes() { synchronized (this) { if (jobAttrSet == null) { @@ -148,6 +150,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void addPrintJobListener(PrintJobListener listener) { synchronized (this) { if (listener == null) { @@ -160,6 +163,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void removePrintJobListener(PrintJobListener listener) { synchronized (this) { if (listener == null || jobListeners == null ) { @@ -269,6 +273,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void addPrintJobAttributeListener( PrintJobAttributeListener listener, PrintJobAttributeSet attributes) { @@ -288,6 +293,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void removePrintJobAttributeListener( PrintJobAttributeListener listener) { synchronized (this) { @@ -308,6 +314,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void print(Doc doc, PrintRequestAttributeSet attributes) throws PrintException { @@ -894,7 +901,7 @@ public class UnixPrintJob implements CancelablePrintJob { private String mDestination, mOptions=""; private boolean mNoJobSheet = false; - private class PrinterOpener { + private final class PrinterOpener { PrintException pex; OutputStream result; @@ -922,7 +929,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } - private class PrinterSpooler { + private final class PrinterSpooler { PrintException pex; private void handleProcessFailure(final Process failedProcess, @@ -984,6 +991,7 @@ public class UnixPrintJob implements CancelablePrintJob { } } + @Override public void cancel() throws PrintException { synchronized (this) { if (!printing) { diff --git a/src/java.desktop/unix/classes/sun/print/UnixPrintService.java b/src/java.desktop/unix/classes/sun/print/UnixPrintService.java index a5c81362485..46211ba5960 100644 --- a/src/java.desktop/unix/classes/sun/print/UnixPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/UnixPrintService.java @@ -74,7 +74,7 @@ import javax.print.attribute.standard.Sides; import javax.print.event.PrintServiceAttributeListener; -public class UnixPrintService implements PrintService, AttributeUpdater, +public final class UnixPrintService implements PrintService, AttributeUpdater, SunPrinterJobService { /* define doc flavors for text types in the default encoding of @@ -207,6 +207,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, isInvalid = true; } + @Override public String getName() { return printer; } @@ -415,6 +416,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, return false; } + @Override public DocPrintJob createPrintJob() { return new UnixPrintJob(this); } @@ -427,6 +429,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public PrintServiceAttributeSet getUpdatedAttributes() { PrintServiceAttributeSet currSet = getDynamicAttributes(); if (lastSet == null) { @@ -456,6 +459,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public void addPrintServiceAttributeListener( PrintServiceAttributeListener listener) { synchronized (this) { @@ -469,6 +473,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public void removePrintServiceAttributeListener( PrintServiceAttributeListener listener) { synchronized (this) { @@ -483,6 +488,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override @SuppressWarnings("unchecked") public T getAttribute(Class category) @@ -509,6 +515,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public PrintServiceAttributeSet getAttributes() { PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); attrs.add(getPrinterName()); @@ -545,6 +552,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public DocFlavor[] getSupportedDocFlavors() { if (supportedDocFlavors == null) { initSupportedDocFlavors(); @@ -556,6 +564,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, return flavors; } + @Override public boolean isDocFlavorSupported(DocFlavor flavor) { if (supportedDocFlavors == null) { initSupportedDocFlavors(); @@ -568,6 +577,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, return false; } + @Override public Class[] getSupportedAttributeCategories() { ArrayList> categList = new ArrayList<>(otherAttrCats.length); for (Class c : otherAttrCats) { @@ -580,6 +590,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, return categList.toArray(new Class[categList.size()]); } + @Override public boolean isAttributeCategorySupported(Class category) { @@ -602,6 +613,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, /* return defaults for all attributes for which there is a default * value */ + @Override public Object getDefaultAttributeValue(Class category) { @@ -681,6 +693,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public Object getSupportedAttributeValues(Class category, DocFlavor flavor, @@ -885,6 +898,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, flavor.equals(DocFlavor.URL.PNG); } + @Override public boolean isAttributeValueSupported(Attribute attr, DocFlavor flavor, AttributeSet attributes) { @@ -976,6 +990,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, return true; } + @Override public AttributeSet getUnsupportedAttributes(DocFlavor flavor, AttributeSet attributes) { @@ -1010,24 +1025,29 @@ public class UnixPrintService implements PrintService, AttributeUpdater, } } + @Override public ServiceUIFactory getServiceUIFactory() { return null; } + @Override public String toString() { return "Unix Printer : " + getName(); } + @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof UnixPrintService && ((UnixPrintService)obj).getName().equals(getName()))); } + @Override public int hashCode() { return this.getClass().hashCode()+getName().hashCode(); } + @Override public boolean usesClass(Class c) { return (c == sun.print.PSPrinterJob.class); } From e490b4f04dd094db996cdc4f664c2ed1a7ea2ade Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Mon, 2 Jun 2025 21:52:08 +0000 Subject: [PATCH 080/216] 8357082: Stabilize and add debug logs to CopyAreaOOB.java Reviewed-by: serb --- test/jdk/ProblemList.txt | 1 - test/jdk/java/awt/Graphics2D/CopyAreaOOB.java | 152 ++++++++++++------ 2 files changed, 103 insertions(+), 50 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 090b5eb71d7..28bb2a1f033 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -488,7 +488,6 @@ java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all java/awt/Graphics2D/DrawString/RotTransText.java 8316878 linux-all -java/awt/Graphics2D/CopyAreaOOB.java 8343106 macosx-aarch64 java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.java 8257529 windows-x64 java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest/ConsumeForModalDialogTest/ConsumeForModalDialogTest.java 8302787 windows-all java/awt/KeyboardFocusmanager/TypeAhead/MenuItemActivatedTest/MenuItemActivatedTest.java 8302787 windows-all diff --git a/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java b/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java index 8d218d9f189..27a1a3a868a 100644 --- a/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java +++ b/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,75 @@ * @key headful * @bug 6430601 8198613 * @summary Verifies that copyArea() works properly when the - * destination parameters are outside the destination bounds. + * destination parameters are outside the destination bounds. * @run main/othervm CopyAreaOOB - * @author campbelc */ -import java.awt.*; -import java.awt.image.*; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.awt.image.MultiResolutionImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import javax.imageio.ImageIO; public class CopyAreaOOB extends Canvas { + private static Frame frame; + private static Robot robot; + private static BufferedImage captureImg; - private static Robot robot = null; + private static StringBuffer errorLog = new StringBuffer(); + + private static final Point OFF_FRAME_LOC = new Point(50, 50); + private static final int SIZE = 400; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + + // added to move mouse pointer away from test UI + // so that it is not captured in the screenshot + robot.mouseMove(OFF_FRAME_LOC.x, OFF_FRAME_LOC.y); + robot.waitForIdle(); + robot.delay(100); + + createTestUI(); + robot.delay(1000); + + if (!errorLog.isEmpty()) { + saveImages(); + throw new RuntimeException("Test failed: \n" + errorLog.toString()); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + private static void createTestUI() { + CopyAreaOOB canvas = new CopyAreaOOB(); + frame = new Frame(); + frame.setUndecorated(true); + frame.add(canvas); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } public void paint(Graphics g) { int w = getWidth(); @@ -50,73 +108,69 @@ public class CopyAreaOOB extends Canvas { g2d.fillRect(0, 0, w, 10); g2d.setColor(Color.red); - g2d.fillRect(0, 10, 50, h-10); + g2d.fillRect(0, 10, 50, h - 10); // copy the region such that part of it goes below the bottom of the // destination surface - g2d.copyArea(0, 10, 50, h-10, 60, 10); + g2d.copyArea(0, 10, 50, h - 10, 60, 10); Toolkit.getDefaultToolkit().sync(); - BufferedImage capture = null; - try { - Thread.sleep(500); - if (robot == null) robot = new Robot(); - Point pt1 = getLocationOnScreen(); - Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400); - capture = robot.createScreenCapture(rect); - } catch (Exception e) { - throw new RuntimeException("Problems handling Robot"); - } + robot.delay(500); + + Point pt1 = this.getLocationOnScreen(); + Rectangle rect = new Rectangle(pt1.x, pt1.y, SIZE, SIZE); + captureImg = robot.createScreenCapture(rect); + // Test pixels - testRegion(capture, "green", 0, 0, 400, 10, 0xff00ff00); - testRegion(capture, "original red", 0, 10, 50, 400, 0xffff0000); - testRegion(capture, "background", 50, 10, 60, 400, 0xff000000); - testRegion(capture, "in-between", 60, 10, 110, 20, 0xff000000); - testRegion(capture, "copied red", 60, 20, 110, 400, 0xffff0000); - testRegion(capture, "background", 110, 10, 400, 400, 0xff000000); + testRegion("green", 0, 0, 400, 10, 0xff00ff00); + testRegion("original-red", 0, 10, 50, 400, 0xffff0000); + testRegion("background", 50, 10, 60, 400, 0xff000000); + testRegion("in-between", 60, 10, 110, 20, 0xff000000); + testRegion("copied-red", 60, 20, 110, 400, 0xffff0000); + testRegion("background", 110, 10, 400, 400, 0xff000000); } public Dimension getPreferredSize() { - return new Dimension(400, 400); + return new Dimension(SIZE, SIZE); } - private static void testRegion(BufferedImage bi, String name, + private static void testRegion(String region, int x1, int y1, int x2, int y2, - int expected) - { + int expected) { + System.out.print("Test region: " + region); for (int y = y1; y < y2; y++) { for (int x = x1; x < x2; x++) { - int actual = bi.getRGB(x, y); + int actual = captureImg.getRGB(x, y); if (actual != expected) { - throw new RuntimeException("Test failed for " + name + - " region at x="+x+" y="+y+ - " (expected="+ - Integer.toHexString(expected) + - " actual="+ - Integer.toHexString(actual) + - ")"); + System.out.print(" Status: FAILED\n"); + errorLog.append("Test failed for " + region + + " region at x: " + x + " y: " + y + + " (expected: " + + Integer.toHexString(expected) + + " actual: " + + Integer.toHexString(actual) + ")\n"); + return; } } } + System.out.print(" Status: PASSED\n"); } - public static void main(String[] args) { - boolean show = (args.length == 1) && ("-show".equals(args[0])); + private static void saveImages() { + GraphicsConfiguration ge = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration(); - CopyAreaOOB test = new CopyAreaOOB(); - Frame frame = new Frame(); - frame.setUndecorated(true); - frame.add(test); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); + MultiResolutionImage mrImage = robot.createMultiResolutionScreenCapture(ge.getBounds()); + List variants = mrImage.getResolutionVariants(); + RenderedImage screenCapture = (RenderedImage) variants.get(variants.size() - 1); try { - Thread.sleep(3000); - } catch (InterruptedException ex) {} - if (!show) { - frame.dispose(); + ImageIO.write(screenCapture, "png", new File("fullscreen.png")); + ImageIO.write(captureImg, "png", new File("canvas.png")); + } catch (IOException e) { + System.err.println("Can't write image " + e); } } } From c96803dc8b480427bca5b1c6b8c4e8693bc90b92 Mon Sep 17 00:00:00 2001 From: Qizheng Xing Date: Tue, 3 Jun 2025 03:09:18 +0000 Subject: [PATCH 081/216] 8358035: Remove unused `compute_fingerprint` declaration in `ClassFileStream` Reviewed-by: ccheung, iklam --- src/hotspot/share/classfile/classFileStream.cpp | 1 - src/hotspot/share/classfile/classFileStream.hpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/hotspot/share/classfile/classFileStream.cpp b/src/hotspot/share/classfile/classFileStream.cpp index 382bd58af2b..dc5329a65f2 100644 --- a/src/hotspot/share/classfile/classFileStream.cpp +++ b/src/hotspot/share/classfile/classFileStream.cpp @@ -23,7 +23,6 @@ */ #include "classfile/classFileStream.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "memory/resourceArea.hpp" diff --git a/src/hotspot/share/classfile/classFileStream.hpp b/src/hotspot/share/classfile/classFileStream.hpp index 135a34bdeee..7f7e4ccacd5 100644 --- a/src/hotspot/share/classfile/classFileStream.hpp +++ b/src/hotspot/share/classfile/classFileStream.hpp @@ -156,8 +156,6 @@ class ClassFileStream: public ResourceObj { // Tells whether eos is reached bool at_eos() const { return _current == _buffer_end; } - uint64_t compute_fingerprint() const; - bool from_class_file_load_hook() const { return _from_class_file_load_hook; } }; From 24edd3b2c1324fd58575a6273e5cae17e3d6fbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20H=C3=A4ssig?= Date: Tue, 3 Jun 2025 03:19:19 +0000 Subject: [PATCH 082/216] 8354930: IGV: dump C2 graph before and after live range stretching Reviewed-by: rcastanedalo, chagedorn --- src/hotspot/share/opto/chaitin.cpp | 5 +++-- src/hotspot/share/opto/phasetype.hpp | 1 + .../jtreg/compiler/lib/ir_framework/CompilePhase.java | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 7832cbd42f8..e14d63c7651 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -406,6 +406,8 @@ void PhaseChaitin::Register_Allocate() { _live = &live; // Mark LIVE as being available } + C->print_method(PHASE_INITIAL_LIVENESS, 4); + // Base pointers are currently "used" by instructions which define new // derived pointers. This makes base pointers live up to the where the // derived pointer is made, but not beyond. Really, they need to be live @@ -422,10 +424,9 @@ void PhaseChaitin::Register_Allocate() { gather_lrg_masks(false); live.compute(_lrg_map.max_lrg_id()); _live = &live; + C->print_method(PHASE_LIVE_RANGE_STRETCHING, 4); } - C->print_method(PHASE_INITIAL_LIVENESS, 4); - // Create the interference graph using virtual copies build_ifg_virtual(); // Include stack slots this time diff --git a/src/hotspot/share/opto/phasetype.hpp b/src/hotspot/share/opto/phasetype.hpp index b3076dd8091..2546b319762 100644 --- a/src/hotspot/share/opto/phasetype.hpp +++ b/src/hotspot/share/opto/phasetype.hpp @@ -100,6 +100,7 @@ flags(MATCHING, "After matching") \ flags(GLOBAL_CODE_MOTION, "Global code motion") \ flags(INITIAL_LIVENESS, "Initial liveness") \ + flags(LIVE_RANGE_STRETCHING, "Live range stretching") \ flags(AGGRESSIVE_COALESCING, "Aggressive coalescing") \ flags(INITIAL_SPILLING, "Initial spilling") \ flags(CONSERVATIVE_COALESCING, "Conservative coalescing") \ diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java index ad32f6a94b9..46900085b12 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java @@ -108,6 +108,7 @@ public enum CompilePhase { MATCHING("After matching", RegexType.MACH), GLOBAL_CODE_MOTION("Global code motion", RegexType.MACH), INITIAL_LIVENESS("Initial liveness", RegexType.MACH), + LIVE_RANGE_STRETCHING("Live range stretching", RegexType.MACH), AGGRESSIVE_COALESCING("Aggressive coalescing", RegexType.MACH), INITIAL_SPILLING("Initial spilling", RegexType.MACH), CONSERVATIVE_COALESCING("Conservative coalescing", RegexType.MACH, ActionOnRepeat.KEEP_FIRST), From 832c5b06e8f278d70398e07d32d63d094a06967c Mon Sep 17 00:00:00 2001 From: David Beaumont Date: Tue, 3 Jun 2025 04:01:09 +0000 Subject: [PATCH 083/216] 8350880: (zipfs) Add support for read-only zip file systems Reviewed-by: lancea, alanb, jpai --- .../classes/jdk/nio/zipfs/ZipFileSystem.java | 143 ++++++++++++------ src/jdk.zipfs/share/classes/module-info.java | 56 ++++++- .../jdk/jdk/nio/zipfs/NewFileSystemTests.java | 100 +++++++++++- test/jdk/jdk/nio/zipfs/TestPosix.java | 76 ++++++++++ test/jdk/jdk/nio/zipfs/Utils.java | 58 +++++-- 5 files changed, 364 insertions(+), 69 deletions(-) diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 9ea935551b8..ab471694890 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -81,18 +81,24 @@ class ZipFileSystem extends FileSystem { private static final boolean isWindows = System.getProperty("os.name") .startsWith("Windows"); private static final byte[] ROOTPATH = new byte[] { '/' }; + + // Global access mode for "mounted" file system ("readOnly" or "readWrite"). + private static final String PROPERTY_ACCESS_MODE = "accessMode"; + + // Posix file permissions allow per-file access control in a posix-like fashion. + // Using a "readOnly" access mode will change the posix permissions of any + // underlying entries (they may still show as "writable", but will not be). private static final String PROPERTY_POSIX = "enablePosixFileAttributes"; private static final String PROPERTY_DEFAULT_OWNER = "defaultOwner"; private static final String PROPERTY_DEFAULT_GROUP = "defaultGroup"; private static final String PROPERTY_DEFAULT_PERMISSIONS = "defaultPermissions"; // Property used to specify the entry version to use for a multi-release JAR private static final String PROPERTY_RELEASE_VERSION = "releaseVersion"; + // Original property used to specify the entry version to use for a // multi-release JAR which is kept for backwards compatibility. private static final String PROPERTY_MULTI_RELEASE = "multi-release"; - private static final Set DEFAULT_PERMISSIONS = - PosixFilePermissions.fromString("rwxrwxrwx"); // Property used to specify the compression mode to use private static final String PROPERTY_COMPRESSION_METHOD = "compressionMethod"; // Value specified for compressionMethod property to compress Zip entries @@ -104,7 +110,8 @@ class ZipFileSystem extends FileSystem { private final Path zfpath; final ZipCoder zc; private final ZipPath rootdir; - private boolean readOnly; // readonly file system, false by default + // Starts in readOnly (safe mode), but might be reset at the end of initialization. + private boolean readOnly = true; // default time stamp for pseudo entries private final long zfsDefaultTimeStamp = System.currentTimeMillis(); @@ -129,10 +136,37 @@ class ZipFileSystem extends FileSystem { final boolean supportPosix; private final UserPrincipal defaultOwner; private final GroupPrincipal defaultGroup; + // Unmodifiable set. private final Set defaultPermissions; private final Set supportedFileAttributeViews; + private enum ZipAccessMode { + // Creates a file system for read-write access. + READ_WRITE("readWrite"), + // Creates a file system for read-only access. + READ_ONLY("readOnly"); + + private final String label; + + ZipAccessMode(String label) { + this.label = label; + } + + // Parses the access mode from an environmental parameter. + // Returns null for missing value to indicate default behavior. + static ZipAccessMode from(Object value) { + if (value == null) { + return null; + } else if (READ_WRITE.label.equals(value)) { + return ZipAccessMode.READ_WRITE; + } else if (READ_ONLY.label.equals(value)) { + return ZipAccessMode.READ_ONLY; + } + throw new IllegalArgumentException("Unknown file system access mode: " + value); + } + } + ZipFileSystem(ZipFileSystemProvider provider, Path zfpath, Map env) throws IOException @@ -144,15 +178,28 @@ class ZipFileSystem extends FileSystem { this.useTempFile = isTrue(env, "useTempFile"); this.forceEnd64 = isTrue(env, "forceZIP64End"); this.defaultCompressionMethod = getDefaultCompressionMethod(env); + + ZipAccessMode accessMode = ZipAccessMode.from(env.get(PROPERTY_ACCESS_MODE)); + boolean forceReadOnly = (accessMode == ZipAccessMode.READ_ONLY); + this.supportPosix = isTrue(env, PROPERTY_POSIX); this.defaultOwner = supportPosix ? initOwner(zfpath, env) : null; this.defaultGroup = supportPosix ? initGroup(zfpath, env) : null; - this.defaultPermissions = supportPosix ? initPermissions(env) : null; + this.defaultPermissions = supportPosix ? Collections.unmodifiableSet(initPermissions(env)) : null; this.supportedFileAttributeViews = supportPosix ? - Set.of("basic", "posix", "zip") : Set.of("basic", "zip"); + Set.of("basic", "posix", "zip") : Set.of("basic", "zip"); + + // 'create=true' is semantically the same as StandardOpenOption.CREATE, + // and can only be used to create a writable file system (whether the + // underlying ZIP file exists or not), and is always incompatible with + // 'accessMode=readOnly'). + boolean shouldCreate = isTrue(env, "create"); + if (shouldCreate && forceReadOnly) { + throw new IllegalArgumentException( + "Specifying 'accessMode=readOnly' is incompatible with 'create=true'"); + } if (Files.notExists(zfpath)) { - // create a new zip if it doesn't exist - if (isTrue(env, "create")) { + if (shouldCreate) { try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) { new END().write(os, 0, forceEnd64); } @@ -160,12 +207,9 @@ class ZipFileSystem extends FileSystem { throw new NoSuchFileException(zfpath.toString()); } } - // sm and existence check + // Existence check zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ); - boolean writeable = Files.isWritable(zfpath); - this.readOnly = !writeable; this.zc = ZipCoder.get(nameEncoding); - this.rootdir = new ZipPath(this, new byte[]{'/'}); this.ch = Files.newByteChannel(zfpath, READ); try { this.cen = initCEN(); @@ -179,13 +223,29 @@ class ZipFileSystem extends FileSystem { } this.provider = provider; this.zfpath = zfpath; + this.rootdir = new ZipPath(this, new byte[]{'/'}); - initializeReleaseVersion(env); + // Determining a release version uses 'this' instance to read paths etc. + Optional multiReleaseVersion = determineReleaseVersion(env); + + // Set the version-based lookup function for multi-release JARs. + this.entryLookup = + multiReleaseVersion.map(this::createVersionedLinks).orElse(Function.identity()); + + // We only allow read-write zip/jar files if they are not multi-release + // JARs and the underlying file is writable. + this.readOnly = forceReadOnly || multiReleaseVersion.isPresent() || !Files.isWritable(zfpath); + if (readOnly && accessMode == ZipAccessMode.READ_WRITE) { + String reason = multiReleaseVersion.isPresent() + ? "the multi-release JAR file is not writable" + : "the ZIP file is not writable"; + throw new IOException(reason); + } } /** * Return the compression method to use (STORED or DEFLATED). If the - * property {@code commpressionMethod} is set use its value to determine + * property {@code compressionMethod} is set use its value to determine * the compression method to use. If the property is not set, then the * default compression is DEFLATED unless the property {@code noCompression} * is set which is supported for backwards compatibility. @@ -293,12 +353,12 @@ class ZipFileSystem extends FileSystem { " or " + GroupPrincipal.class); } - // Initialize the default permissions for files inside the zip archive. + // Return the default permissions for files inside the zip archive. // If not specified in env, it will return 777. private Set initPermissions(Map env) { Object o = env.get(PROPERTY_DEFAULT_PERMISSIONS); if (o == null) { - return DEFAULT_PERMISSIONS; + return PosixFilePermissions.fromString("rwxrwxrwx"); } if (o instanceof String) { return PosixFilePermissions.fromString((String)o); @@ -346,10 +406,6 @@ class ZipFileSystem extends FileSystem { } } - void setReadOnly() { - this.readOnly = true; - } - @Override public Iterable getRootDirectories() { return List.of(rootdir); @@ -1383,33 +1439,24 @@ class ZipFileSystem extends FileSystem { * Checks if the Zip File System property "releaseVersion" has been specified. If it has, * use its value to determine the requested version. If not use the value of the "multi-release" property. */ - private void initializeReleaseVersion(Map env) throws IOException { + private Optional determineReleaseVersion(Map env) throws IOException { Object o = env.containsKey(PROPERTY_RELEASE_VERSION) ? env.get(PROPERTY_RELEASE_VERSION) : env.get(PROPERTY_MULTI_RELEASE); - if (o != null && isMultiReleaseJar()) { - int version; - if (o instanceof String) { - String s = (String)o; - if (s.equals("runtime")) { - version = Runtime.version().feature(); - } else if (s.matches("^[1-9][0-9]*$")) { - version = Version.parse(s).feature(); - } else { - throw new IllegalArgumentException("Invalid runtime version"); - } - } else if (o instanceof Integer) { - version = Version.parse(((Integer)o).toString()).feature(); - } else if (o instanceof Version) { - version = ((Version)o).feature(); - } else { - throw new IllegalArgumentException("env parameter must be String, " + - "Integer, or Version"); - } - createVersionedLinks(version < 0 ? 0 : version); - setReadOnly(); + if (o == null || !isMultiReleaseJar()) { + return Optional.empty(); } + int version = switch (o) { + case String s when s.equals("runtime") -> Runtime.version().feature(); + case String s when s.matches("^[1-9][0-9]*$") -> Version.parse(s).feature(); + case Integer i -> Version.parse(i.toString()).feature(); + case Version v -> v.feature(); + case String s -> throw new IllegalArgumentException("Invalid runtime version: " + s); + default -> throw new IllegalArgumentException("env parameter must be String, " + + "Integer, or Version"); + }; + return Optional.of(Math.max(version, 0)); } /** @@ -1435,11 +1482,11 @@ class ZipFileSystem extends FileSystem { * Then wrap the map in a function that getEntry can use to override root * entry lookup for entries that have corresponding versioned entries. */ - private void createVersionedLinks(int version) { + private Function createVersionedLinks(int version) { IndexNode verdir = getInode(getBytes("/META-INF/versions")); // nothing to do, if no /META-INF/versions if (verdir == null) { - return; + return Function.identity(); } // otherwise, create a map and for each META-INF/versions/{n} directory // put all the leaf inodes, i.e. entries, into the alias map @@ -1451,10 +1498,7 @@ class ZipFileSystem extends FileSystem { getOrCreateInode(getRootName(entryNode, versionNode), entryNode.isdir), entryNode.name)) ); - entryLookup = path -> { - byte[] entry = aliasMap.get(IndexNode.keyOf(path)); - return entry == null ? path : entry; - }; + return path -> aliasMap.getOrDefault(IndexNode.keyOf(path), path); } /** @@ -3551,7 +3595,8 @@ class ZipFileSystem extends FileSystem { @Override public Set permissions() { - return storedPermissions().orElse(Set.copyOf(defaultPermissions)); + // supportPosix ==> (defaultPermissions != null) + return storedPermissions().orElse(defaultPermissions); } } diff --git a/src/jdk.zipfs/share/classes/module-info.java b/src/jdk.zipfs/share/classes/module-info.java index 52a5aed98f9..db7ae3eec81 100644 --- a/src/jdk.zipfs/share/classes/module-info.java +++ b/src/jdk.zipfs/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -153,8 +153,8 @@ import java.util.Set; * {@link java.lang.String} or {@link java.lang.Boolean} * false * - * If the value is {@code true}, the ZIP file system provider - * creates a new ZIP or JAR file if it does not exist. + * If the value is {@code true}, the ZIP file system provider creates a + * new ZIP or JAR file if it does not exist. * * * @@ -225,8 +225,8 @@ import java.util.Set; * *

    • * If the value is not {@code "STORED"} or {@code "DEFLATED"}, an - * {@code IllegalArgumentException} will be thrown when the Zip - * filesystem is created. + * {@code IllegalArgumentException} will be thrown when creating the + * ZIP file system. *
    • * * @@ -260,12 +260,54 @@ import java.util.Set; *
    • * If the value does not represent a valid * {@linkplain Runtime.Version Java SE Platform version number}, - * an {@code IllegalArgumentException} will be thrown. + * an {@code IllegalArgumentException} will be thrown when creating + * the ZIP file system. *
    • * * * - * + * + * accessMode + * {@link java.lang.String} + * null/unset + * + * A value defining the desired access mode of the file system. + * ZIP file systems can be created to allow for read-write or + * read-only access. + *
        + *
      • + * If no value is set, the file system is created as read-write + * if possible. Use {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} to determine the actual access mode. + *
      • + *
      • + * If the value is {@code "readOnly"}, the file system is created + * read-only, and {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} will always return {@code true}. Creating a + * read-only file system requires the underlying ZIP file to + * already exist. + * Specifying the {@code create} property as {@code true} with the + * {@code accessMode} as {@code readOnly} will cause an {@code + * IllegalArgumentException} to be thrown when creating the ZIP file + * system. + *
      • + *
      • + * If the value is {@code "readWrite"}, the file system is created + * read-write, and {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} will always return {@code false}. If a writable file + * system cannot be created, an {@code IOException} will be thrown + * when creating the ZIP file system. + *
      • + *
      • + * Any other values will cause an {@code IllegalArgumentException} + * to be thrown when creating the ZIP file system. + *
      • + *
      + * The {@code accessMode} property has no effect on reported POSIX file + * permissions (in cases where POSIX support is enabled). + * + * + * * * *

      Examples:

      diff --git a/test/jdk/jdk/nio/zipfs/NewFileSystemTests.java b/test/jdk/jdk/nio/zipfs/NewFileSystemTests.java index 44fe2686aba..d15988176e3 100644 --- a/test/jdk/jdk/nio/zipfs/NewFileSystemTests.java +++ b/test/jdk/jdk/nio/zipfs/NewFileSystemTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -31,11 +31,17 @@ import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Iterator; import java.util.Map; -import static org.testng.Assert.*; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertThrows; +import static org.testng.Assert.assertTrue; /** * @test @@ -170,6 +176,96 @@ public class NewFileSystemTests { FileSystems.newFileSystem(Path.of("basic.jar"), nullMap)); } + /** + * Validate that without {@code "create" = true}, a ZIP file system cannot be + * opened if the underlying file is missing, but even with this set, a ZIP + * file system cannot be opened for conflicting or invalid access modes. + */ + @DataProvider(name = "badEnvMap") + protected Object[][] badEnvMap() { + return new Object[][]{ + {Map.of(), NoSuchFileException.class}, + {Map.of("accessMode", "readOnly"), NoSuchFileException.class}, + {Map.of("accessMode", "readWrite"), NoSuchFileException.class}, + {Map.of("create", true, "accessMode", "readOnly"), IllegalArgumentException.class}, + {Map.of("create", true, "accessMode", "badValue"), IllegalArgumentException.class}, + }; + } + @Test(dataProvider = "badEnvMap") + public void badArgumentsFailure(Map env, Class exception) throws IOException { + assertThrows(exception, () -> FileSystems.newFileSystem(Path.of("no_such.zip"), env)); + } + + /** + * Validate that multi-release JARs can be opened read-write if no release + * version is specified. + */ + @Test + public void multiReleaseJarReadWriteSuccess() throws IOException { + // Multi-release JARs, when opened with a specified version are inherently read-only. + Path multiReleaseJar = createMultiReleaseJar(); + try (FileSystem fs = FileSystems.newFileSystem(multiReleaseJar, Map.of("accessMode", "readWrite"))) { + assertFalse(fs.isReadOnly()); + assertEquals( + Files.readString(fs.getPath("file.txt"), UTF_8), + "Default version", + "unexpected file content"); + } + } + + /** + * Validate that when the underlying file is read-only, it cannot be opened in + * read-write mode. + */ + @Test + public void readOnlyZipFileFailure() throws IOException { + // Underlying file is read-only. + Path readOnlyZip = Utils.createJarFile("read_only.zip", Map.of("file.txt", "Hello World")); + // In theory this can fail, and we should avoid unwanted false-negatives. + if (readOnlyZip.toFile().setReadOnly()) { + assertThrows(IOException.class, + () -> FileSystems.newFileSystem(readOnlyZip, Map.of("accessMode", "readWrite"))); + } + } + + /** + * Validate that multi-release JAR is opened read-only by default if a release + * version is specified. + */ + @Test + public void multiReleaseJarDefaultReadOnly() throws IOException { + Path multiReleaseJar = createMultiReleaseJar(); + try (FileSystem fs = FileSystems.newFileSystem(multiReleaseJar, Map.of("releaseVersion", "1"))) { + assertTrue(fs.isReadOnly()); + assertEquals( + Files.readString(fs.getPath("file.txt"), UTF_8), + "First version", + "unexpected file content"); + } + } + + /** + * Validate that multi-release JARs cannot be opened read-write if a release + * version is specified. + */ + @Test + public void multiReleaseJarReadWriteFailure() throws IOException { + Path multiReleaseJar = createMultiReleaseJar(); + assertThrows(IOException.class, + () -> FileSystems.newFileSystem( + multiReleaseJar, + Map.of("accessMode", "readWrite", "releaseVersion", "1"))); + } + + private static Path createMultiReleaseJar() throws IOException { + return Utils.createJarFile("multi_release.jar", Map.of( + // Newline required for attribute to be read from Manifest file. + "META-INF/MANIFEST.MF", "Multi-Release: true\n", + "META-INF/versions/1/file.txt", "First version", + "META-INF/versions/2/file.txt", "Second version", + "file.txt", "Default version")); + } + /* * DataProvider used to verify that a Zip file system may be returned * when specifying a class loader diff --git a/test/jdk/jdk/nio/zipfs/TestPosix.java b/test/jdk/jdk/nio/zipfs/TestPosix.java index 420c1618e12..ff6f9c4920f 100644 --- a/test/jdk/jdk/nio/zipfs/TestPosix.java +++ b/test/jdk/jdk/nio/zipfs/TestPosix.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, 2024, SAP SE. All rights reserved. + * 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 @@ -35,6 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.spi.ToolProvider; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -50,8 +52,11 @@ import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE; import static java.nio.file.attribute.PosixFilePermission.OWNER_READ; import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -96,6 +101,8 @@ public class TestPosix { // FS open options private static final Map ENV_DEFAULT = Collections.emptyMap(); private static final Map ENV_POSIX = Map.of("enablePosixFileAttributes", true); + private static final Map ENV_READ_ONLY = Map.of("accessMode", "readOnly"); + private static final Map ENV_POSIX_READ_ONLY = Map.of("enablePosixFileAttributes", true, "accessMode", "readOnly"); // misc private static final CopyOption[] COPY_ATTRIBUTES = {StandardCopyOption.COPY_ATTRIBUTES}; @@ -398,6 +405,37 @@ public class TestPosix { doCheckEntries(path, expected); } + private void checkReadOnlyFileSystem(FileSystem fs) throws IOException { + assertTrue(fs.isReadOnly(), "File system should be read-only"); + Path root = fs.getPath("/"); + + // Rather than calling something like "addOwnerRead(root)", we walk all + // files to ensure that all operations fail, not some arbitrary first one. + Set badPerms = Set.of(OTHERS_EXECUTE, OTHERS_WRITE); + FileTime anyTime = FileTime.from(Instant.now()); + try (Stream paths = Files.walk(root)) { + paths.forEach(p -> { + assertFalse(Files.isWritable(p), "File should not be writable: " + p); + assertSame(fs, p.getFileSystem()); + assertThrows( + AccessDeniedException.class, + () -> fs.provider().checkAccess(p, AccessMode.WRITE)); + assertThrows( + ReadOnlyFileSystemException.class, + () -> fs.provider().setAttribute(p, "zip:permissions", badPerms)); + + // These fail because there is not corresponding File for a zip path (they will + // currently fail for read-write ZIP file systems too, but we sanity-check here). + assertThrows(UnsupportedOperationException.class, + () -> Files.setLastModifiedTime(p, anyTime)); + assertThrows(UnsupportedOperationException.class, + () -> Files.setAttribute(p, "zip:permissions", badPerms)); + assertThrows(UnsupportedOperationException.class, + () -> Files.setPosixFilePermissions(p, badPerms)); + }); + } + } + private boolean throwsUOE(Executor e) throws IOException { try { e.doIt(); @@ -440,6 +478,25 @@ public class TestPosix { } } + /** + * As {@code testDefault()} but with {@code "accessMode"="readOnly"}. + */ + @Test + public void testDefaultReadOnly() throws IOException { + // create zip file using zipfs with default option + createTestZipFile(ZIP_FILE, ENV_DEFAULT).close(); + // check entries on zipfs with read-only options + try (FileSystem zip = FileSystems.newFileSystem(ZIP_FILE, ENV_READ_ONLY)) { + checkEntries(zip, checkExpects.permsInZip); + checkReadOnlyFileSystem(zip); + } + // check entries on zipfs with posix and read-only options + try (FileSystem zip = FileSystems.newFileSystem(ZIP_FILE, ENV_POSIX_READ_ONLY)) { + checkEntries(zip, checkExpects.permsPosix); + checkReadOnlyFileSystem(zip); + } + } + /** * This tests whether the entries in a zip file created w/ * Posix support are correct. @@ -460,6 +517,25 @@ public class TestPosix { } } + /** + * As {@code testPosix()} but with {@code "accessMode"="readOnly"}. + */ + @Test + public void testPosixReadOnly() throws IOException { + // create zip file using zipfs with posix option + createTestZipFile(ZIP_FILE, ENV_POSIX).close(); + // check entries on zipfs with read-only options + try (FileSystem zip = FileSystems.newFileSystem(ZIP_FILE, ENV_READ_ONLY)) { + checkEntries(zip, checkExpects.permsInZip); + checkReadOnlyFileSystem(zip); + } + // check entries on zipfs with posix and read-only options + try (FileSystem zip = FileSystems.newFileSystem(ZIP_FILE, ENV_POSIX_READ_ONLY)) { + checkEntries(zip, checkExpects.permsPosix); + checkReadOnlyFileSystem(zip); + } + } + /** * This tests whether the entries in a zip file copied from another * are correct. diff --git a/test/jdk/jdk/nio/zipfs/Utils.java b/test/jdk/jdk/nio/zipfs/Utils.java index a561535dc5a..71cc1117a2f 100644 --- a/test/jdk/jdk/nio/zipfs/Utils.java +++ b/test/jdk/jdk/nio/zipfs/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,25 +23,35 @@ import java.io.IOException; import java.io.OutputStream; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; import java.util.Random; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; -/** - * Utility class for zipfs tests. - */ +import static java.nio.charset.StandardCharsets.UTF_8; -class Utils { - private Utils() { } +/** + * Utility class for {@code ZipFileSystem} tests. + */ +final class Utils { + private Utils() {} /** - * Creates a JAR file of the given name with 0 or more named entries. + * Creates a JAR file of the given name with 0 or more named entries with + * random content. * - * @return Path to the newly created JAR file + *

      If an existing file of the same name already exists, it is silently + * overwritten. + * + * @param name the file name of the jar file to create in the working directory. + * @param entries entries JAR file entry names, whose content will be populated + * with random bytes + * @return the absolute path to the newly created JAR file. */ static Path createJarFile(String name, String... entries) throws IOException { - Path jarFile = Paths.get("basic.jar"); + Path jarFile = Path.of(name); Random rand = new Random(); try (OutputStream out = Files.newOutputStream(jarFile); JarOutputStream jout = new JarOutputStream(out)) { @@ -56,6 +66,32 @@ class Utils { len += 1024; } } - return jarFile; + return jarFile.toAbsolutePath(); + } + + /** + * Creates a JAR file of the given name with 0 or more entries with specified + * content. + * + *

      If an existing file of the same name already exists, it is silently + * overwritten. + * + * @param name the file name of the jar file to create in the working directory. + * @param entries a map of JAR file entry names to entry content (stored as + * UTF-8 encoded bytes). + * @return the absolute path to the newly created JAR file. + */ + static Path createJarFile(String name, Map entries) throws IOException { + Path jarFile = Path.of(name); + try (OutputStream out = Files.newOutputStream(jarFile); + JarOutputStream jout = new JarOutputStream(out)) { + for (var entry : entries.entrySet()) { + JarEntry je = new JarEntry(entry.getKey()); + jout.putNextEntry(je); + jout.write(entry.getValue().getBytes(UTF_8)); + jout.closeEntry(); + } + } + return jarFile.toAbsolutePath(); } } From c5f235c000db6654493ea109008dbccf97f01678 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Tue, 3 Jun 2025 06:00:28 +0000 Subject: [PATCH 084/216] 8347826: Introspector shows wrong method list after 8071693 Reviewed-by: azvegint, serb, aivanov --- .../com/sun/beans/introspect/MethodInfo.java | 14 +- .../sun/beans/introspect/PropertyInfo.java | 20 +- .../classes/java/beans/Introspector.java | 10 +- .../DefaultMethodBeanPropertyTest.java | 478 ++++++++++++++++-- 4 files changed, 456 insertions(+), 66 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java b/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java index 25c95988393..496cbd3cd6b 100644 --- a/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java +++ b/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,11 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.Deque; import java.util.List; import java.util.Set; @@ -105,13 +106,16 @@ final class MethodInfo { } } - // Add default methods inherited from interfaces - for (Class iface : type.getInterfaces()) { + // Add methods inherited from interfaces + Deque> ifaceDeque = new ArrayDeque<>(List.of(type.getInterfaces())); + while (!ifaceDeque.isEmpty()) { + Class iface = ifaceDeque.removeLast(); if (IGNORABLE_INTERFACES.contains(iface)) { continue; } + ifaceDeque.addAll(List.of(iface.getInterfaces())); for (Method method : iface.getMethods()) { - if (!Modifier.isAbstract(method.getModifiers())) { + if (!Modifier.isAbstract(method.getModifiers()) && !method.isBridge()) { (list = createIfNeeded(list)).add(method); } } diff --git a/src/java.desktop/share/classes/com/sun/beans/introspect/PropertyInfo.java b/src/java.desktop/share/classes/com/sun/beans/introspect/PropertyInfo.java index 833aeb7265c..f894a5ca1f2 100644 --- a/src/java.desktop/share/classes/com/sun/beans/introspect/PropertyInfo.java +++ b/src/java.desktop/share/classes/com/sun/beans/introspect/PropertyInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,8 @@ public final class PropertyInfo { } if (!isInitedToIsGetter && this.readList != null) { for (MethodInfo info : this.readList) { - if ((this.read == null) || this.read.type.isAssignableFrom(info.type)) { + if ((this.read == null) || (!info.method.isDefault() + && this.read.type.isAssignableFrom(info.type))) { this.read = info; this.type = info.type; } @@ -91,6 +92,9 @@ public final class PropertyInfo { if (writeType == null) { this.write = info; writeType = info.type; + } else if (isParentOfIncoming(this.write, info)) { + this.write = info; + writeType = info.type; } else if (writeType.isAssignableFrom(info.type)) { if ((this.write == null) || this.write.type.isAssignableFrom(info.type)) { this.write = info; @@ -307,4 +311,16 @@ public final class PropertyInfo { ? Collections.unmodifiableMap(map) : Collections.emptyMap(); } + + private static boolean isParentOfIncoming(MethodInfo current, MethodInfo incoming) { + if (null == current) { + return false; + } + Class currentClass = current.method.getDeclaringClass(); + Class incomingClass = incoming.method.getDeclaringClass(); + if (currentClass == incomingClass) { + return false; + } + return currentClass.isAssignableFrom(incomingClass); + } } diff --git a/src/java.desktop/share/classes/java/beans/Introspector.java b/src/java.desktop/share/classes/java/beans/Introspector.java index c526190808e..564021104a7 100644 --- a/src/java.desktop/share/classes/java/beans/Introspector.java +++ b/src/java.desktop/share/classes/java/beans/Introspector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1052,8 +1052,12 @@ public class Introspector { } } if (match) { - MethodDescriptor composite = new MethodDescriptor(old, md); - methods.put(name, composite); + Class oldClass = old.getMethod().getDeclaringClass(); + Class mdClass = md.getMethod().getDeclaringClass(); + if (oldClass == mdClass || oldClass.isAssignableFrom(mdClass) || !mdClass.isAssignableFrom(oldClass)) { + MethodDescriptor composite = new MethodDescriptor(old, md); + methods.put(name, composite); + } return; } diff --git a/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java b/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java index a1e528880ef..2e79faa2d91 100644 --- a/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java +++ b/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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,20 +23,26 @@ /* * @test - * @bug 8071693 + * @bug 8071693 8347826 * @summary Verify that the Introspector finds default methods inherited * from interfaces */ +import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; +import java.beans.MethodDescriptor; import java.beans.PropertyDescriptor; +import java.beans.SimpleBeanInfo; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.NavigableSet; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; public class DefaultMethodBeanPropertyTest { @@ -78,11 +84,17 @@ public class DefaultMethodBeanPropertyTest { } public static void testScenario1() { + verifyMethods(D1.class, + "public static int DefaultMethodBeanPropertyTest$A1.getStaticValue()", + "public default int DefaultMethodBeanPropertyTest$A1.getValue()", + "public java.lang.Integer DefaultMethodBeanPropertyTest$D1.getFoo()", + "public java.lang.Float DefaultMethodBeanPropertyTest$D1.getObj()" + ); verifyProperties(D1.class, - "getClass", // inherited method - "getValue", // inherited default method - "getFoo", // overridden interface method - "getObj" // overridden default method + "public final native java.lang.Class java.lang.Object.getClass()", + "public default int DefaultMethodBeanPropertyTest$A1.getValue()", + "public java.lang.Integer DefaultMethodBeanPropertyTest$D1.getFoo()", + "public java.lang.Float DefaultMethodBeanPropertyTest$D1.getObj()" ); } @@ -108,9 +120,12 @@ public class DefaultMethodBeanPropertyTest { } public static void testScenario2() { + verifyMethods(D2.class, + "public default java.lang.Object DefaultMethodBeanPropertyTest$A2.getFoo()" + ); verifyProperties(D2.class, - "getClass", - "getFoo" + "public final native java.lang.Class java.lang.Object.getClass()", + "public default java.lang.Object DefaultMethodBeanPropertyTest$A2.getFoo()" ); } @@ -144,60 +159,404 @@ public class DefaultMethodBeanPropertyTest { } public static void testScenario3() { - verifyProperties(D3.class, - "getClass", - "getFoo" + verifyMethods(D3.class, + "public java.util.NavigableSet DefaultMethodBeanPropertyTest$D3.getFoo()" ); + verifyProperties(D3.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public java.util.NavigableSet DefaultMethodBeanPropertyTest$D3.getFoo()" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 4 // +// // +////////////////////////////////////// + + public interface A4 { + default Object getDefault0() { + return null; + } + default Object getDefault1() { + return null; + } + default Object getDefault2() { + return null; + } + default Object getDefault3() { + return null; + } + Object getNonDefault(); + } + + public class B4 implements A4 { + @Override + public Object getDefault1() { + return new B4(); + } + @Override + public String getDefault2() { + return null; + } + @Override + public Float getDefault3() { + return null; + } + public Long getNonDefault() { + return null; + } + } + + public static void testScenario4() { + verifyMethods(B4.class, + "public default java.lang.Object DefaultMethodBeanPropertyTest$A4.getDefault0()", + "public java.lang.Object DefaultMethodBeanPropertyTest$B4.getDefault1()", + "public java.lang.String DefaultMethodBeanPropertyTest$B4.getDefault2()", + "public java.lang.Float DefaultMethodBeanPropertyTest$B4.getDefault3()", + "public java.lang.Long DefaultMethodBeanPropertyTest$B4.getNonDefault()" + ); + verifyProperties(B4.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public default java.lang.Object DefaultMethodBeanPropertyTest$A4.getDefault0()", + "public java.lang.Object DefaultMethodBeanPropertyTest$B4.getDefault1()", + "public java.lang.String DefaultMethodBeanPropertyTest$B4.getDefault2()", + "public java.lang.Float DefaultMethodBeanPropertyTest$B4.getDefault3()", + "public java.lang.Long DefaultMethodBeanPropertyTest$B4.getNonDefault()" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 5 // +// // +////////////////////////////////////// + + public interface A5 { + public default void setParentFoo(Integer num) { + } + public default void setFoo(String num) { + } + public static int getStaticValue() { + return 0; + } + private int getPrivateValue() { + return 0; + } + } + + public class B5 implements A5 { + public void setFoo(Number num) { + } + public void setLocalFoo(Long num) { + } + public static int getStaticValue() { + return 0; + } + } + + public static void testScenario5() { + verifyMethods(B5.class, + "public static int DefaultMethodBeanPropertyTest$B5.getStaticValue()", + "public default void DefaultMethodBeanPropertyTest$A5.setFoo(java.lang.String)", + "public default void DefaultMethodBeanPropertyTest$A5.setParentFoo(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$B5.setFoo(java.lang.Number)", + "public void DefaultMethodBeanPropertyTest$B5.setLocalFoo(java.lang.Long)" + ); + verifyProperties(B5.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public default void DefaultMethodBeanPropertyTest$A5.setParentFoo(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$B5.setFoo(java.lang.Number)", + "public void DefaultMethodBeanPropertyTest$B5.setLocalFoo(java.lang.Long)" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 6 // +// // +////////////////////////////////////// + + public class A6 { + public void setParentFoo(Integer num) { + } + public void setFoo(Integer num) { + } + public static int getStaticValue() { + return 0; + } + private int getPrivateValue() { + return 0; + } + } + + public class B6 extends A6 { + public void setFoo(String num) { + } + public void setLocalFoo(Long num) { + } + public static int getStaticValue() { + return 0; + } + } + + public static void testScenario6() { + verifyMethods(B6.class, + "public static int DefaultMethodBeanPropertyTest$B6.getStaticValue()", + "public void DefaultMethodBeanPropertyTest$A6.setFoo(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$A6.setParentFoo(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$B6.setFoo(java.lang.String)", + "public void DefaultMethodBeanPropertyTest$B6.setLocalFoo(java.lang.Long)" + ); + verifyProperties(B6.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public void DefaultMethodBeanPropertyTest$A6.setParentFoo(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$B6.setFoo(java.lang.String)", + "public void DefaultMethodBeanPropertyTest$B6.setLocalFoo(java.lang.Long)" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 7 // +// // +////////////////////////////////////// + + interface A7 { + T getValue(); + } + + interface B7 { + Runnable getValue(); + } + + interface AB7 extends B7, A7 { + Runnable getValue(); + } + + abstract class D7 implements AB7 { + public void setValue(Runnable value) { + } + } + + public static void testScenario7() { + verifyMethods(D7.class, + "public void DefaultMethodBeanPropertyTest$D7.setValue(java.lang.Runnable)" + ); + verifyProperties(D7.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public void DefaultMethodBeanPropertyTest$D7.setValue(java.lang.Runnable)" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 8 // +// // +////////////////////////////////////// + + public interface A8 { + public default void setFoo(Float num) { + } + public default void setFoo2(Integer num) { + } + } + public interface B8 extends A8 { + public default void setFoo(Integer num) { + } + public default void setFoo2(Float num) { + } + } + + public class C8 implements B8 { + } + + public static void testScenario8() { + verifyMethods(C8.class, + "public default void DefaultMethodBeanPropertyTest$A8.setFoo(java.lang.Float)", + "public default void DefaultMethodBeanPropertyTest$A8.setFoo2(java.lang.Integer)", + "public default void DefaultMethodBeanPropertyTest$B8.setFoo(java.lang.Integer)", + "public default void DefaultMethodBeanPropertyTest$B8.setFoo2(java.lang.Float)" + ); + verifyProperties(C8.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public default void DefaultMethodBeanPropertyTest$B8.setFoo(java.lang.Integer)", + "public default void DefaultMethodBeanPropertyTest$B8.setFoo2(java.lang.Float)" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 9 // +// // +////////////////////////////////////// + + public class A9 { + public void setFoo(Object value) { + } + public void setFoo(String value) { + } + public void setFoo2(Object value) { + } + public void setFoo2(Integer value) { + } + // For the same setters with inconvertible arg types PropertyInfo behavior is undefined. + // public void setLocalFoo3(Long num) { } + // public void setLocalFoo3(Float num) { } + } + + public static void testScenario9() { + verifyMethods(A9.class, + "public void DefaultMethodBeanPropertyTest$A9.setFoo(java.lang.String)", + "public void DefaultMethodBeanPropertyTest$A9.setFoo(java.lang.Object)", + "public void DefaultMethodBeanPropertyTest$A9.setFoo2(java.lang.Integer)", + "public void DefaultMethodBeanPropertyTest$A9.setFoo2(java.lang.Object)" + ); + verifyProperties(A9.class, + "public final native java.lang.Class java.lang.Object.getClass()", + "public void DefaultMethodBeanPropertyTest$A9.setFoo(java.lang.String)", + "public void DefaultMethodBeanPropertyTest$A9.setFoo2(java.lang.Integer)" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 10 // +// // +////////////////////////////////////// + + public static class A10 { + public Object getProp() { + return null; + } + } + + public static interface B10 { + Object getProp(); + } + + public static class C10_1 extends A10 implements B10 { + } + + public static class C10_2 extends A10 implements B10 { + } + + public static class A10BeanInfo extends SimpleBeanInfo { + public MethodDescriptor[] getMethodDescriptors() { + try { + Class params[] = {}; + MethodDescriptor md = new MethodDescriptor(A10.class.getDeclaredMethod("getProp", params)); + md.setDisplayName("display name"); + MethodDescriptor res[] = { md }; + return res; + } catch (Exception exception) { + throw new Error("unexpected exception", exception); + } + } + } + + public static class C10_1BeanInfo extends SimpleBeanInfo { + public BeanInfo[] getAdditionalBeanInfo() { + try { + BeanInfo res[] = { + Introspector.getBeanInfo(A10.class), + Introspector.getBeanInfo(B10.class) + }; + return res; + } catch (IntrospectionException exception) { + throw new Error("unexpected exception", exception); + } + } + } + + public static class C10_2BeanInfo extends SimpleBeanInfo { + public BeanInfo[] getAdditionalBeanInfo() { + try { + BeanInfo res[] = { + Introspector.getBeanInfo(B10.class), + Introspector.getBeanInfo(A10.class) + }; + return res; + } catch (IntrospectionException exception) { + throw new Error("unexpected exception", exception); + } + } + } + + public static void testScenario10() { + { + var md = getMethodDescriptor(C10_1.class, A10.class, "getProp"); + assertEquals("display name", md.getDisplayName(), "getDisplayName()"); + } + { + var md = getMethodDescriptor(C10_2.class, A10.class, "getProp"); + assertEquals("display name", md.getDisplayName(), "getDisplayName()"); + } } // Helper methods - public static void verifyProperties(Class type, String... getterNames) { - - // Gather expected properties - final HashSet expected = new HashSet<>(); - for (String methodName : getterNames) { - final String suffix = methodName.substring(3); - final String propName = Introspector.decapitalize(suffix); - final Method getter; - try { - getter = type.getMethod(methodName); - } catch (NoSuchMethodException e) { - throw new Error("unexpected error", e); - } - final PropertyDescriptor propDesc; - try { - propDesc = new PropertyDescriptor(propName, getter, null); - } catch (IntrospectionException e) { - throw new Error("unexpected error", e); - } - expected.add(propDesc); - } - - // Verify properties can be found directly - expected.stream() - .map(PropertyDescriptor::getName) - .filter(name -> BeanUtils.getPropertyDescriptor(type, name) == null) - .findFirst() - .ifPresent(name -> { - throw new Error("property \"" + name + "\" not found in " + type); - }); - - // Gather actual properties - final Set actual = - Set.of(BeanUtils.getPropertyDescriptors(type)); - - // Verify the two sets are the same + private static void verifyEquality(String title, Set expected, Set actual) { if (!actual.equals(expected)) { - throw new Error("mismatch: " + type - + "\nACTUAL:\n " - + actual.stream() - .map(Object::toString) - .collect(Collectors.joining("\n ")) - + "\nEXPECTED:\n " - + expected.stream() - .map(Object::toString) - .collect(Collectors.joining("\n "))); + throw new Error(title + " mismatch: " + + "\nACTUAL:\n " + + actual.stream() + .map(Object::toString) + .collect(Collectors.joining("\n ")) + + "\nEXPECTED:\n " + + expected.stream() + .map(Object::toString) + .collect(Collectors.joining("\n "))); + } + } + + public static void verifyProperties(Class type, String... methodNames) { + try { + final Set expected = new HashSet<>(Arrays.asList(methodNames)); + final Set actual = Arrays + .stream(Introspector.getBeanInfo(type) + .getPropertyDescriptors()) + .flatMap(pd -> Stream.of(pd.getReadMethod(), pd.getWriteMethod())) + .filter(Objects::nonNull) + .map((Method m) -> m.toString()) + .collect(Collectors.toSet()); + verifyEquality("properties", expected, actual); + } catch (IntrospectionException exception) { + throw new Error("unexpected exception", exception); + } + } + + public static void verifyMethods(Class type, String... methodNames) { + try { + final Set expected = new HashSet<>(Arrays.asList(methodNames)); + final Set actual = Arrays + .stream(Introspector.getBeanInfo(type, Object.class) + .getMethodDescriptors()) + .map(MethodDescriptor::getMethod) + .map(Method::toString) + .collect(Collectors.toSet()); + verifyEquality("methods", expected, actual); + } catch (IntrospectionException exception) { + throw new Error("unexpected exception", exception); + } + } + + private static MethodDescriptor getMethodDescriptor(Class cls, Class stop, String name) { + try { + for (var md : Introspector.getBeanInfo(cls, stop).getMethodDescriptors()) { + if (md.getName().equals(name)) { + return md; + } + } + return null; + } catch (IntrospectionException exception) { + throw new Error("unexpected exception", exception); + } + } + + private static void assertEquals(Object expected, Object actual, String msg) { + if (!expected.equals(actual)) { + throw new Error(msg + ":\nACTUAL: " + actual + "\nEXPECTED: " + expected); } } @@ -207,5 +566,12 @@ public class DefaultMethodBeanPropertyTest { testScenario1(); testScenario2(); testScenario3(); + testScenario4(); + testScenario5(); + testScenario6(); + testScenario7(); + testScenario8(); + testScenario9(); + testScenario10(); } } From 497a1822cabcc0475ce0495d56430f1e99b1fb13 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 3 Jun 2025 06:19:23 +0000 Subject: [PATCH 085/216] 8358254: [AOT] runtime/cds/appcds/applications/JavacBench.java#aot crashes with SEGV in ClassLoaderData::holder Reviewed-by: never --- src/hotspot/share/ci/ciMethodData.cpp | 6 +----- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 9 +++++++-- src/hotspot/share/oops/trainingData.hpp | 8 ++++++++ .../jdk/vm/ci/hotspot/HotSpotMethodData.java | 14 +------------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index 096a674ad56..533e8659968 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -57,11 +57,7 @@ ciMethodData::ciMethodData(MethodData* md) static bool is_klass_loaded(Klass* k) { - if (TrainingData::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(); - } - return true; + return TrainingData::is_klass_loaded(k); } // Check for entries that reference an unloaded method diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index b4b8150917d..6ad039d8839 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -49,6 +49,7 @@ #include "oops/instanceMirrorKlass.hpp" #include "oops/method.inline.hpp" #include "oops/objArrayKlass.inline.hpp" +#include "oops/trainingData.hpp" #include "oops/typeArrayOop.inline.hpp" #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" @@ -505,11 +506,15 @@ C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject b } } else if (JVMCIENV->isa_HotSpotMethodData(base_object)) { jlong base_address = (intptr_t) JVMCIENV->asMethodData(base_object); - klass = *((Klass**) (intptr_t) (base_address + offset)); - if (klass == nullptr || !klass->is_loader_alive()) { + Klass* k = *((Klass**) (intptr_t) (base_address + offset)); + if (k == nullptr || k->class_loader_data() == nullptr || !TrainingData::is_klass_loaded(k)) { + return nullptr; + } + if (!k->is_loader_alive()) { // Klasses in methodData might be concurrently unloading so return null in that case. return nullptr; } + klass = k; } else { goto unexpected; } diff --git a/src/hotspot/share/oops/trainingData.hpp b/src/hotspot/share/oops/trainingData.hpp index d79ffaef13e..2be3026881a 100644 --- a/src/hotspot/share/oops/trainingData.hpp +++ b/src/hotspot/share/oops/trainingData.hpp @@ -283,6 +283,14 @@ private: static bool need_data() { return AOTRecordTraining; } // Going to write static bool assembling_data() { return have_data() && CDSConfig::is_dumping_final_static_archive() && CDSConfig::is_dumping_aot_linked_classes(); } + 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(); + } + return true; + } + template static void iterate(const Function& fn) { iterate(const_cast(fn)); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java index 454949a2e25..2478b97a5b2 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodData.java @@ -443,19 +443,7 @@ final class HotSpotMethodData implements MetaspaceObject { } } - static class RawItemProfile { - final int entries; - final T[] items; - final long[] counts; - final long totalCount; - - RawItemProfile(int entries, T[] items, long[] counts, long totalCount) { - this.entries = entries; - this.items = items; - this.counts = counts; - this.totalCount = totalCount; - } - } + record RawItemProfile(int entries, T[] items, long[] counts, long totalCount) {} abstract static class AbstractTypeData extends CounterData { From 6cfd4057dce9262f54e71a3930e16da84aa0d9f1 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 3 Jun 2025 06:20:29 +0000 Subject: [PATCH 086/216] 8357619: [JVMCI] Revisit phantom_ref parameter in JVMCINMethodData::get_nmethod_mirror Reviewed-by: eosterlund, never --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 ++-- src/hotspot/share/jvmci/jvmciRuntime.cpp | 14 +++++--------- src/hotspot/share/jvmci/jvmciRuntime.hpp | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 6ad039d8839..2256a0edc99 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2836,7 +2836,7 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool if (data != nullptr) { // Only the mirror in the HotSpot heap is accessible // through JVMCINMethodData - oop nmethod_mirror = data->get_nmethod_mirror(nm, /* phantom_ref */ true); + oop nmethod_mirror = data->get_nmethod_mirror(nm); if (nmethod_mirror != nullptr) { result = HotSpotJVMCI::wrap(nmethod_mirror); } @@ -2868,7 +2868,7 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool if (data == nullptr) { JVMCI_THROW_MSG_0(IllegalArgumentException, "Missing HotSpotNmethod data"); } - if (data->get_nmethod_mirror(nm, /* phantom_ref */ false) != nullptr) { + if (data->get_nmethod_mirror(nm) != nullptr) { JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod"); } oop nmethod_mirror = HotSpotJVMCI::resolve(result); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 15fb0d6ed3a..bee5f4ea445 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -776,15 +776,11 @@ void JVMCINMethodData::add_failed_speculation(nmethod* nm, jlong speculation) { FailedSpeculation::add_failed_speculation(nm, _failed_speculations, data, length); } -oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm, bool phantom_ref) { +oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm) { if (_nmethod_mirror_index == -1) { return nullptr; } - if (phantom_ref) { - return nm->oop_at_phantom(_nmethod_mirror_index); - } else { - return nm->oop_at(_nmethod_mirror_index); - } + return nm->oop_at(_nmethod_mirror_index); } void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) { @@ -802,7 +798,7 @@ void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) { } void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) { - oop nmethod_mirror = get_nmethod_mirror(nm, /* phantom_ref */ false); + oop nmethod_mirror = get_nmethod_mirror(nm); if (nmethod_mirror == nullptr) { return; } @@ -2178,7 +2174,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, JVMCINMethodData* data = nm->jvmci_nmethod_data(); assert(data != nullptr, "must be"); if (install_default) { - assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == nullptr, "must be"); + assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == nullptr, "must be"); if (entry_bci == InvocationEntryBci) { // If there is an old version we're done with it nmethod* old = method->code(); @@ -2221,7 +2217,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, } } } else { - assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == HotSpotJVMCI::resolve(nmethod_mirror), "must be"); + assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == HotSpotJVMCI::resolve(nmethod_mirror), "must be"); MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag); if (!nm->make_in_use()) { result = JVMCI::nmethod_reclaimed; diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index aa4685c5818..b49e09a1884 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -124,7 +124,7 @@ public: void invalidate_nmethod_mirror(nmethod* nm); // Gets the mirror from nm's oops table. - oop get_nmethod_mirror(nmethod* nm, bool phantom_ref); + oop get_nmethod_mirror(nmethod* nm); // Sets the mirror in nm's oops table. void set_nmethod_mirror(nmethod* nm, oop mirror); From dbf562c72502ab8da96eb130ff8222bba66c72cc Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 3 Jun 2025 07:25:54 +0000 Subject: [PATCH 087/216] 8358313: G1: Refactor G1CollectedHeap::is_maximal_no_gc Reviewed-by: jsikstro, tschatzl --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 4 ++-- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 8aaab14ad75..705dcd7895b 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1004,7 +1004,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes, WorkerThreads* pretouch_worker log_debug(gc, ergo, heap)("Expand the heap. requested expansion amount: %zuB expansion amount: %zuB", expand_bytes, aligned_expand_bytes); - if (is_maximal_no_gc()) { + if (num_inactive_regions() == 0) { log_debug(gc, ergo, heap)("Did not expand the heap (heap already fully expanded)"); return false; } @@ -1031,7 +1031,7 @@ bool G1CollectedHeap::expand_single_region(uint node_index) { uint expanded_by = _hrm.expand_on_preferred_node(node_index); if (expanded_by == 0) { - assert(is_maximal_no_gc(), "Should be no regions left, available: %u", _hrm.num_inactive_regions()); + assert(num_inactive_regions() == 0, "Should be no regions left, available: %u", num_inactive_regions()); log_debug(gc, ergo, heap)("Did not expand the heap (heap already fully expanded)"); return false; } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 965d01c7089..fbd1fe6165f 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -966,16 +966,15 @@ public: // end fields defining the extent of the contiguous allocation region.) // But G1CollectedHeap doesn't yet support this. - bool is_maximal_no_gc() const { - return _hrm.num_inactive_regions() == 0; - } - // Returns true if an incremental GC should be upgrade to a full gc. This // is done when there are no free regions and the heap can't be expanded. bool should_upgrade_to_full_gc() const { - return is_maximal_no_gc() && num_free_regions() == 0; + return num_inactive_regions() == 0 && num_free_regions() == 0; } + // The number of inactive regions. + uint num_inactive_regions() const { return _hrm.num_inactive_regions(); } + // The current number of regions in the heap. uint num_committed_regions() const { return _hrm.num_committed_regions(); } From be923a8b7229cb7a705e72ebbb3046e9f2085048 Mon Sep 17 00:00:00 2001 From: Marc Chevalier Date: Tue, 3 Jun 2025 08:06:43 +0000 Subject: [PATCH 088/216] 8353266: C2: Wrong execution with Integer.bitCount(int) intrinsic on AArch64 Reviewed-by: aph, thartmann --- src/hotspot/cpu/aarch64/aarch64.ad | 6 +- .../BitCountIAarch64PreservesArgument.java | 80 +++++++++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/intrinsics/BitCountIAarch64PreservesArgument.java diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 690210a8c40..f367362b4d8 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -7761,14 +7761,12 @@ instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ effect(TEMP tmp); ins_cost(INSN_COST * 13); - format %{ "movw $src, $src\n\t" - "mov $tmp, $src\t# vector (1D)\n\t" + format %{ "fmovs $tmp, $src\t# vector (1S)\n\t" "cnt $tmp, $tmp\t# vector (8B)\n\t" "addv $tmp, $tmp\t# vector (8B)\n\t" "mov $dst, $tmp\t# vector (1D)" %} ins_encode %{ - __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 - __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); + __ fmovs($tmp$$FloatRegister, $src$$Register); __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); diff --git a/test/hotspot/jtreg/compiler/intrinsics/BitCountIAarch64PreservesArgument.java b/test/hotspot/jtreg/compiler/intrinsics/BitCountIAarch64PreservesArgument.java new file mode 100644 index 00000000000..eb048e0e8ca --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/BitCountIAarch64PreservesArgument.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8353266 + * @summary Integer.bitCount modifies input register + * @library /test/lib / + * + * @run main/othervm + * -Xbatch + * -XX:CompileOnly=compiler.intrinsics.BitCountIAarch64PreservesArgument::test + * compiler.intrinsics.BitCountIAarch64PreservesArgument + */ + +/** + * @test + * @bug 8353266 + * @library /test/lib / + * + * @run main compiler.intrinsics.BitCountIAarch64PreservesArgument + */ + +package compiler.intrinsics; + +import static compiler.lib.generators.Generators.G; + +public class BitCountIAarch64PreservesArgument { + static long lFld; + static long result; + + public static void main(String[] args) { + lFld = 0xfedc_ba98_7654_3210L; + for (int i = 0; i < 10_000; i++) { + test(); + if (result != 0xfedc_ba98_7654_3210L) { + // Wrongly outputs the cut input 0x7654_3210 == 1985229328 + throw new RuntimeException("Wrong result. Expected result = " + lFld + "; Actual result = " + result); + } + } + + lFld = G.longs().next(); + for (int i = 0; i < 10_000; i++) { + test(); + if (result != lFld) { + throw new RuntimeException("Wrong result. Expected result = " + lFld + "; Actual result = " + result); + } + } + } + + static void test() { + long x = lFld; + try { + result = Integer.bitCount((int) x); // Cut input: 0x7654_3210 == 1985229328 + throw new RuntimeException(); + } catch (RuntimeException _) { + } + result = x; + } +} From cff75eb60628827541ea6c08eb1970401f606ebc Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 3 Jun 2025 08:14:05 +0000 Subject: [PATCH 089/216] 8358316: PKCS8Key.getEncoded() can throw NPE after JDK-8298420 Reviewed-by: ascarpino --- src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java b/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java index 5aa859c58e3..b7cc5e7057f 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS8Key.java @@ -256,7 +256,8 @@ public class PKCS8Key implements PrivateKey, InternalPrivateKey { * or {@code null} if an encoding error occurs. */ public byte[] getEncoded() { - return getEncodedInternal().clone(); + byte[] b = getEncodedInternal(); + return (b != null) ? b.clone() : null; } /** From 6f783e5fab0e98da6c41e3c22d4523733f060d68 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 3 Jun 2025 08:14:23 +0000 Subject: [PATCH 090/216] 8358319: Pem.decode should cache the Pattern Reviewed-by: ascarpino --- .../share/classes/sun/security/util/Pem.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/sun/security/util/Pem.java b/src/java.base/share/classes/sun/security/util/Pem.java index 0acbec8281a..c6e56381771 100644 --- a/src/java.base/share/classes/sun/security/util/Pem.java +++ b/src/java.base/share/classes/sun/security/util/Pem.java @@ -49,7 +49,10 @@ public class Pem { public static final String DEFAULT_ALGO; // Pattern matching for EKPI operations - private static final Pattern pbePattern; + private static final Pattern PBE_PATTERN; + + // Pattern matching for stripping whitespace. + private static final Pattern STRIP_WHITESPACE_PATTERN; // Lazy initialized PBES2 OID value private static ObjectIdentifier PBES2OID; @@ -61,8 +64,9 @@ public class Pem { String algo = Security.getProperty("jdk.epkcs8.defaultAlgorithm"); DEFAULT_ALGO = (algo == null || algo.isBlank()) ? "PBEWithHmacSHA256AndAES_128" : algo; - pbePattern = Pattern.compile("^PBEWith.*And.*", + PBE_PATTERN = Pattern.compile("^PBEWith.*And.*", Pattern.CASE_INSENSITIVE); + STRIP_WHITESPACE_PATTERN = Pattern.compile("\\s+"); } public static final String CERTIFICATE = "CERTIFICATE"; @@ -84,9 +88,9 @@ public class Pem { * @return the decoded bytes */ public static byte[] decode(String input) { - byte[] src = input.replaceAll("\\s+", ""). + byte[] src = STRIP_WHITESPACE_PATTERN.matcher(input).replaceAll(""). getBytes(StandardCharsets.ISO_8859_1); - return Base64.getDecoder().decode(src); + return Base64.getDecoder().decode(src); } /** @@ -100,7 +104,7 @@ public class Pem { public static ObjectIdentifier getPBEID(String algorithm) { // Verify pattern matches PBE Standard Name spec - if (!pbePattern.matcher(algorithm).matches()) { + if (!PBE_PATTERN.matcher(algorithm).matches()) { throw new IllegalArgumentException("Invalid algorithm format."); } From 8674f49127d75d20c074fb8c4f0736bfe190f8b8 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 3 Jun 2025 08:30:17 +0000 Subject: [PATCH 091/216] 8358318: JFR: Tighten up PlatformTracer initialization Reviewed-by: egahlin --- .../jdk/jfr/internal/settings/MethodSetting.java | 5 ----- .../jdk/jfr/internal/tracing/PlatformTracer.java | 14 +++++++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/MethodSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/MethodSetting.java index f819b1b951d..f4f3d93c01c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/MethodSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/MethodSetting.java @@ -41,7 +41,6 @@ import jdk.jfr.internal.tracing.PlatformTracer; @Name(Type.SETTINGS_PREFIX + "Filter") public final class MethodSetting extends FilterSetting { private final Modification modification; - private static volatile boolean initialized; public MethodSetting(PlatformEventType eventType, Modification modification, String defaultValue) { super(eventType, defaultValue); @@ -54,10 +53,6 @@ public final class MethodSetting extends FilterSetting { @Override protected void apply(PlatformEventType eventType, List filters) { - if (!initialized) { - PlatformTracer.initialize(); - initialized = true; - } PlatformTracer.setFilters(modification, filters); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java index 9ebbec5d451..608fe865147 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java @@ -53,6 +53,8 @@ public final class PlatformTracer { private static List timingFilters = List.of(); private static TimedMethod OBJECT; + private static boolean initialized; + public static byte[] onMethodTrace(Module module, ClassLoader classLoader, String className, byte[] oldBytecode, long[] ids, String[] names, String[] signatures, int[] modifications) { @@ -159,6 +161,7 @@ public final class PlatformTracer { } public static void setFilters(Modification modification, List filters) { + ensureInitialized(); publishClasses(applyFilter(modification, filters)); } @@ -251,6 +254,15 @@ public final class PlatformTracer { timedClasses.clear(); } + // Expected to be called when holding external lock, so no extra + // synchronization is required here. + private static void ensureInitialized() { + if (!initialized) { + initialize(); + initialized = true; + } + } + // This method has three purposes: // // 1) Load classes before instrumentation to avoid recursion in class @@ -264,7 +276,7 @@ public final class PlatformTracer { // This method takes 1-10 milliseconds to run and is only executed once, // provided a user has specified a non-empty filter for the MethodTrace or // MethodTiming event. - public static void initialize() { + private static void initialize() { try { Logger.log(LogTag.JFR_METHODTRACE, LogLevel.DEBUG, "Method tracer initialization started."); Thread current = Thread.currentThread(); From 4402527683ed08eebf4953a9d83f72f64a5ff4fa Mon Sep 17 00:00:00 2001 From: Chad Rakoczy Date: Tue, 3 Jun 2025 08:55:34 +0000 Subject: [PATCH 092/216] 8357223: AArch64: Optimize interpreter profile updates Reviewed-by: shade, aph --- .../cpu/aarch64/interp_masm_aarch64.cpp | 50 +++---------------- .../cpu/aarch64/interp_masm_aarch64.hpp | 7 +-- 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 48f92d28e03..276fdd013db 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -926,60 +926,26 @@ void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - int constant, - bool decrement) { - increment_mdp_data_at(mdp_in, noreg, constant, decrement); + int constant) { + increment_mdp_data_at(mdp_in, noreg, constant); } void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - Register reg, - int constant, - bool decrement) { + Register index, + int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - // %%% this does 64bit counters at best it is wasting space - // at worst it is a rare bug when counters overflow - assert_different_registers(rscratch2, rscratch1, mdp_in, reg); + assert_different_registers(rscratch2, rscratch1, mdp_in, index); Address addr1(mdp_in, constant); - Address addr2(rscratch2, reg, Address::lsl(0)); + Address addr2(rscratch2, index, Address::lsl(0)); Address &addr = addr1; - if (reg != noreg) { + if (index != noreg) { lea(rscratch2, addr1); addr = addr2; } - if (decrement) { - // Decrement the register. Set condition codes. - // Intel does this - // addptr(data, (int32_t) -DataLayout::counter_increment); - // If the decrement causes the counter to overflow, stay negative - // Label L; - // jcc(Assembler::negative, L); - // addptr(data, (int32_t) DataLayout::counter_increment); - // so we do this - ldr(rscratch1, addr); - subs(rscratch1, rscratch1, (unsigned)DataLayout::counter_increment); - Label L; - br(Assembler::LO, L); // skip store if counter underflow - str(rscratch1, addr); - bind(L); - } else { - assert(DataLayout::counter_increment == 1, - "flow-free idiom only works with 1"); - // Intel does this - // Increment the register. Set carry flag. - // addptr(data, DataLayout::counter_increment); - // If the increment causes the counter to overflow, pull back by 1. - // sbbptr(data, (int32_t)0); - // so we do this - ldr(rscratch1, addr); - adds(rscratch1, rscratch1, DataLayout::counter_increment); - Label L; - br(Assembler::CS, L); // skip store if counter overflow - str(rscratch1, addr); - bind(L); - } + increment(addr, DataLayout::counter_increment); } void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in, diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp index 58a7ed03150..447d4f8244e 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp @@ -247,11 +247,8 @@ class InterpreterMacroAssembler: public MacroAssembler { void verify_method_data_pointer(); void set_mdp_data_at(Register mdp_in, int constant, Register value); - void increment_mdp_data_at(Address data, bool decrement = false); - void increment_mdp_data_at(Register mdp_in, int constant, - bool decrement = false); - void increment_mdp_data_at(Register mdp_in, Register reg, int constant, - bool decrement = false); + void increment_mdp_data_at(Register mdp_in, int constant); + void increment_mdp_data_at(Register mdp_in, Register index, int constant); void increment_mask_and_jump(Address counter_addr, int increment, Address mask, Register scratch, Register scratch2, From 457d9de81d0f65455e3292fafea03f0e83184029 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 3 Jun 2025 09:24:13 +0000 Subject: [PATCH 093/216] 8358013: [PPC64] VSX has poor performance on Power8 Reviewed-by: dbriemann, clanger --- src/hotspot/cpu/ppc/globals_ppc.hpp | 4 ++-- src/hotspot/cpu/ppc/vm_version_ppc.cpp | 7 +++++++ .../compiler/c2/irTests/TestAutoVectorization2DArray.java | 5 +++-- .../jtreg/compiler/loopopts/superword/MinMaxRed_Int.java | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp index 597d7e2100a..f944408fe29 100644 --- a/src/hotspot/cpu/ppc/globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp @@ -115,8 +115,8 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); "Use static branch prediction hints for uncommon paths.") \ \ /* special instructions */ \ - product(bool, SuperwordUseVSX, true, \ - "Use Power8 VSX instructions for superword optimization.") \ + product(bool, SuperwordUseVSX, false, \ + "Use VSX instructions for superword optimization.") \ \ product(bool, UseByteReverseInstructions, false, DIAGNOSTIC, \ "Use byte reverse instructions.") \ diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index 6a3d88c48ae..ad5e915a838 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -95,6 +95,13 @@ void VM_Version::initialize() { FLAG_SET_ERGO(TrapBasedRangeChecks, false); } + if (PowerArchitecturePPC64 >= 9) { + // Performance is good since Power9. + if (FLAG_IS_DEFAULT(SuperwordUseVSX)) { + FLAG_SET_ERGO(SuperwordUseVSX, true); + } + } + MaxVectorSize = SuperwordUseVSX ? 16 : 8; if (FLAG_IS_DEFAULT(AlignVector)) { FLAG_SET_ERGO(AlignVector, false); diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java b/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java index 9aedc64eff6..ac622e3bcc3 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestAutoVectorization2DArray.java @@ -29,8 +29,9 @@ import compiler.lib.ir_framework.*; * @test * @bug 8279258 * @summary Auto-vectorization enhancement for two-dimensional array operations - * @requires ((os.arch == "x86" | os.arch == "i386") & (vm.opt.UseSSE == "null" | vm.opt.UseSSE >= 2)) - * | (os.arch != "x86" & os.arch != "i386" & os.arch != "riscv64") + * @requires (os.arch != "x86" & os.arch != "i386" & os.arch != "ppc64" & os.arch != "ppc64le" & os.arch != "riscv64") + * | ((os.arch == "x86" | os.arch == "i386") & (vm.opt.UseSSE == "null" | vm.opt.UseSSE >= 2)) + * | ((os.arch == "ppc64" | os.arch == "ppc64le") & vm.cpu.features ~= ".*darn.*") * | (os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*") * @library /test/lib / * @run driver compiler.c2.irTests.TestAutoVectorization2DArray diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java b/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java index 0b84f4e346a..4e15c0de6e9 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/MinMaxRed_Int.java @@ -97,6 +97,7 @@ public class MinMaxRed_Int { applyIfCPUFeature = {"rvv", "true"}, counts = {IRNode.MIN_REDUCTION_V, " > 0"}) @IR(applyIfPlatform = {"ppc", "true"}, + applyIf = {"SuperwordUseVSX", "true"}, counts = {IRNode.MIN_REDUCTION_V, " > 0"}) public static int minReductionImplement(int[] a, int[] b, int res) { for (int i = 0; i < a.length; i++) { @@ -113,6 +114,7 @@ public class MinMaxRed_Int { applyIfCPUFeature = {"rvv", "true"}, counts = {IRNode.MAX_REDUCTION_V, " > 0"}) @IR(applyIfPlatform = {"ppc", "true"}, + applyIf = {"SuperwordUseVSX", "true"}, counts = {IRNode.MAX_REDUCTION_V, " > 0"}) public static int maxReductionImplement(int[] a, int[] b, int res) { for (int i = 0; i < a.length; i++) { From def7355cc97c7099dd04778a7dd7fd4ba5a7a630 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Tue, 3 Jun 2025 09:36:21 +0000 Subject: [PATCH 094/216] 8356716: ZGC: Cleanup Uncommit Logic Reviewed-by: eosterlund, jsikstro --- src/hotspot/share/gc/z/zMappedCache.cpp | 18 +- src/hotspot/share/gc/z/zMappedCache.hpp | 8 +- src/hotspot/share/gc/z/zPageAllocator.cpp | 102 +---- src/hotspot/share/gc/z/zPageAllocator.hpp | 6 +- .../share/gc/z/zPhysicalMemoryManager.cpp | 5 + src/hotspot/share/gc/z/zUncommitter.cpp | 365 +++++++++++++++++- src/hotspot/share/gc/z/zUncommitter.hpp | 28 ++ test/hotspot/jtreg/gc/z/TestUncommit.java | 4 +- 8 files changed, 396 insertions(+), 140 deletions(-) diff --git a/src/hotspot/share/gc/z/zMappedCache.cpp b/src/hotspot/share/gc/z/zMappedCache.cpp index 3fc54087daa..173adfbc010 100644 --- a/src/hotspot/share/gc/z/zMappedCache.cpp +++ b/src/hotspot/share/gc/z/zMappedCache.cpp @@ -405,7 +405,7 @@ ZVirtualMemory ZMappedCache::remove_vmem(ZMappedCacheEntry* const entry, size_t // Update statistics _size -= to_remove; - _min = MIN2(_size, _min); + _min_size_watermark = MIN2(_size, _min_size_watermark); postcond(to_remove == vmem.size()); return vmem; @@ -558,7 +558,7 @@ ZMappedCache::ZMappedCache() : _tree(), _size_class_lists(), _size(0), - _min(_size) {} + _min_size_watermark(_size) {} void ZMappedCache::insert(const ZVirtualMemory& vmem) { _size += vmem.size(); @@ -688,17 +688,15 @@ size_t ZMappedCache::remove_discontiguous(size_t size, ZArray* o return remove_discontiguous_with_strategy(size, out); } -size_t ZMappedCache::reset_min() { - const size_t old_min = _min; - - _min = _size; - - return old_min; +void ZMappedCache::reset_min_size_watermark() { + _min_size_watermark = _size; } -size_t ZMappedCache::remove_from_min(size_t max_size, ZArray* out) { - const size_t size = MIN2(_min, max_size); +size_t ZMappedCache::min_size_watermark() { + return _min_size_watermark; +} +size_t ZMappedCache::remove_for_uncommit(size_t size, ZArray* out) { if (size == 0) { return 0; } diff --git a/src/hotspot/share/gc/z/zMappedCache.hpp b/src/hotspot/share/gc/z/zMappedCache.hpp index 40dfeab2f66..cf1ddbc7289 100644 --- a/src/hotspot/share/gc/z/zMappedCache.hpp +++ b/src/hotspot/share/gc/z/zMappedCache.hpp @@ -92,7 +92,7 @@ private: Tree _tree; SizeClassList _size_class_lists[NumSizeClasses]; size_t _size; - size_t _min; + size_t _min_size_watermark; static int size_class_index(size_t size); static int guaranteed_size_class_index(size_t size); @@ -132,8 +132,10 @@ public: ZVirtualMemory remove_contiguous_power_of_2(size_t min_size, size_t max_size); size_t remove_discontiguous(size_t size, ZArray* out); - size_t reset_min(); - size_t remove_from_min(size_t max_size, ZArray* out); + // ZUncommitter support + void reset_min_size_watermark(); + size_t min_size_watermark(); + size_t remove_for_uncommit(size_t size, ZArray* out); void print_on(outputStream* st) const; void print_extended_on(outputStream* st) const; diff --git a/src/hotspot/share/gc/z/zPageAllocator.cpp b/src/hotspot/share/gc/z/zPageAllocator.cpp index 61f44ec1c84..80a53feed71 100644 --- a/src/hotspot/share/gc/z/zPageAllocator.cpp +++ b/src/hotspot/share/gc/z/zPageAllocator.cpp @@ -630,9 +630,6 @@ ZPartition::ZPartition(uint32_t numa_id, ZPageAllocator* page_allocator) _capacity(0), _claimed(0), _used(0), - _last_commit(0.0), - _last_uncommit(0.0), - _to_uncommit(0), _numa_id(numa_id) {} uint32_t ZPartition::numa_id() const { @@ -650,9 +647,7 @@ size_t ZPartition::increase_capacity(size_t size) { // Update atomically since we have concurrent readers Atomic::add(&_capacity, increased); - _last_commit = os::elapsedTime(); - _last_uncommit = 0; - _cache.reset_min(); + _uncommitter.cancel_uncommit_cycle(); } return increased; @@ -787,101 +782,6 @@ bool ZPartition::claim_capacity_fast_medium(ZMemoryAllocation* allocation) { return true; } -size_t ZPartition::uncommit(uint64_t* timeout) { - ZArray flushed_vmems; - size_t flushed = 0; - - { - // We need to join the suspendible thread set while manipulating capacity - // and used, to make sure GC safepoints will have a consistent view. - SuspendibleThreadSetJoiner sts_joiner; - ZLocker locker(&_page_allocator->_lock); - - const double now = os::elapsedTime(); - const double time_since_last_commit = std::floor(now - _last_commit); - const double time_since_last_uncommit = std::floor(now - _last_uncommit); - - if (time_since_last_commit < double(ZUncommitDelay)) { - // We have committed within the delay, stop uncommitting. - *timeout = uint64_t(double(ZUncommitDelay) - time_since_last_commit); - return 0; - } - - // We flush out and uncommit chunks at a time (~0.8% of the max capacity, - // but at least one granule and at most 256M), in case demand for memory - // increases while we are uncommitting. - const size_t limit_upper_bound = MAX2(ZGranuleSize, align_down(256 * M / ZNUMA::count(), ZGranuleSize)); - const size_t limit = MIN2(align_up(_current_max_capacity >> 7, ZGranuleSize), limit_upper_bound); - - if (limit == 0) { - // This may occur if the current max capacity for this partition is 0 - - // Set timeout to ZUncommitDelay - *timeout = ZUncommitDelay; - return 0; - } - - if (time_since_last_uncommit < double(ZUncommitDelay)) { - // We are in the uncommit phase - const size_t num_uncommits_left = _to_uncommit / limit; - const double time_left = double(ZUncommitDelay) - time_since_last_uncommit; - if (time_left < *timeout * num_uncommits_left) { - // Running out of time, speed up. - uint64_t new_timeout = uint64_t(std::floor(time_left / double(num_uncommits_left + 1))); - *timeout = new_timeout; - } - } else { - // We are about to start uncommitting - _to_uncommit = _cache.reset_min(); - _last_uncommit = now; - - const size_t split = _to_uncommit / limit + 1; - uint64_t new_timeout = ZUncommitDelay / split; - *timeout = new_timeout; - } - - // Never uncommit below min capacity. - const size_t retain = MAX2(_used, _min_capacity); - const size_t release = _capacity - retain; - const size_t flush = MIN3(release, limit, _to_uncommit); - - if (flush == 0) { - // Nothing to flush - return 0; - } - - // Flush memory from the mapped cache to uncommit - flushed = _cache.remove_from_min(flush, &flushed_vmems); - if (flushed == 0) { - // Nothing flushed - return 0; - } - - // Record flushed memory as claimed and how much we've flushed for this partition - Atomic::add(&_claimed, flushed); - _to_uncommit -= flushed; - } - - // Unmap and uncommit flushed memory - for (const ZVirtualMemory vmem : flushed_vmems) { - unmap_virtual(vmem); - uncommit_physical(vmem); - free_physical(vmem); - free_virtual(vmem); - } - - { - SuspendibleThreadSetJoiner sts_joiner; - ZLocker locker(&_page_allocator->_lock); - - // Adjust claimed and capacity to reflect the uncommit - Atomic::sub(&_claimed, flushed); - decrease_capacity(flushed, false /* set_max_capacity */); - } - - return flushed; -} - void ZPartition::sort_segments_physical(const ZVirtualMemory& vmem) { verify_virtual_memory_association(vmem, true /* check_multi_partition */); diff --git a/src/hotspot/share/gc/z/zPageAllocator.hpp b/src/hotspot/share/gc/z/zPageAllocator.hpp index 85ce59a8913..c5d1bedd863 100644 --- a/src/hotspot/share/gc/z/zPageAllocator.hpp +++ b/src/hotspot/share/gc/z/zPageAllocator.hpp @@ -57,6 +57,7 @@ class ZWorkers; class ZPartition { friend class VMStructs; friend class ZPageAllocator; + friend class ZUncommitter; private: ZPageAllocator* const _page_allocator; @@ -68,9 +69,6 @@ private: volatile size_t _capacity; volatile size_t _claimed; size_t _used; - double _last_commit; - double _last_uncommit; - size_t _to_uncommit; const uint32_t _numa_id; const ZVirtualMemoryManager& virtual_memory_manager() const; @@ -103,8 +101,6 @@ public: bool claim_capacity(ZMemoryAllocation* allocation); bool claim_capacity_fast_medium(ZMemoryAllocation* allocation); - size_t uncommit(uint64_t* timeout); - void sort_segments_physical(const ZVirtualMemory& vmem); void claim_physical(const ZVirtualMemory& vmem); diff --git a/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp b/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp index 8f9b8f2a285..2c2f9988d4b 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp +++ b/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp @@ -113,6 +113,11 @@ void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max return; } + const size_t max_delay_without_overflow = std::numeric_limits::max() / MILLIUNITS; + if (ZUncommitDelay > max_delay_without_overflow) { + FLAG_SET_ERGO(ZUncommitDelay, max_delay_without_overflow); + } + log_info_p(gc, init)("Uncommit: Enabled"); log_info_p(gc, init)("Uncommit Delay: %zus", ZUncommitDelay); } diff --git a/src/hotspot/share/gc/z/zUncommitter.cpp b/src/hotspot/share/gc/z/zUncommitter.cpp index 7993bbd56a9..7e9cad5ab0a 100644 --- a/src/hotspot/share/gc/z/zUncommitter.cpp +++ b/src/hotspot/share/gc/z/zUncommitter.cpp @@ -22,12 +22,21 @@ */ #include "gc/shared/gc_globals.hpp" +#include "gc/z/zGlobals.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zLock.inline.hpp" +#include "gc/z/zMappedCache.hpp" +#include "gc/z/zNUMA.inline.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zUncommitter.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" +#include "utilities/align.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.hpp" + +#include static const ZStatCounter ZCounterUncommit("Memory", "Uncommit", ZStatUnitBytesPerSecond); @@ -35,7 +44,13 @@ ZUncommitter::ZUncommitter(uint32_t id, ZPartition* partition) : _id(id), _partition(partition), _lock(), - _stop(false) { + _stop(false), + _cancel_time(0.0), + _next_cycle_timeout(0), + _next_uncommit_timeout(0), + _cycle_start(0.0), + _to_uncommit(0), + _uncommitted(0) { set_name("ZUncommitter#%u", id); create_and_start(); } @@ -47,8 +62,27 @@ bool ZUncommitter::wait(uint64_t timeout) const { } if (!_stop && timeout > 0) { - log_debug(gc, heap)("Uncommitter (%u) Timeout: " UINT64_FORMAT "s", _id, timeout); - _lock.wait(timeout * MILLIUNITS); + if (!uncommit_cycle_is_finished()) { + log_trace(gc, heap)("Uncommitter (%u) Timeout: " UINT64_FORMAT "ms left to uncommit: " + EXACTFMT, _id, timeout, EXACTFMTARGS(_to_uncommit)); + } else { + log_debug(gc, heap)("Uncommitter (%u) Timeout: " UINT64_FORMAT "ms", _id, timeout); + } + + double now = os::elapsedTime(); + const double wait_until = now + double(timeout) / MILLIUNITS; + do { + const uint64_t remaining_timeout_ms = to_millis(wait_until - now); + if (remaining_timeout_ms == 0) { + // Less than a millisecond left to wait, just return early + break; + } + + // Wait + _lock.wait(remaining_timeout_ms); + + now = os::elapsedTime(); + } while (!_stop && now < wait_until); } return !_stop; @@ -59,33 +93,78 @@ bool ZUncommitter::should_continue() const { return !_stop; } -void ZUncommitter::run_thread() { - uint64_t timeout = 0; +void ZUncommitter::update_statistics(size_t uncommitted, Ticks start, Tickspan* accumulated_time) const { + // Update counter + ZStatInc(ZCounterUncommit, uncommitted); - while (wait(timeout)) { - EventZUncommit event; - size_t total_uncommitted = 0; + Ticks end = Ticks::now(); + + // Send event + EventZUncommit::commit(start, end, uncommitted); + + // Track accumulated time + *accumulated_time += end - start; +} + +void ZUncommitter::run_thread() { + // Initialize first cycle timeout + _next_cycle_timeout = to_millis(ZUncommitDelay); + + while (wait(_next_cycle_timeout)) { + // Counters for event and statistics + Ticks start = Ticks::now(); + size_t uncommitted_since_last_timeout = 0; + Tickspan accumulated_time; + + if (!activate_uncommit_cycle()) { + // We failed activating a new cycle, continue until next cycle + continue; + } while (should_continue()) { // Uncommit chunk - const size_t uncommitted = _partition->uncommit(&timeout); - if (uncommitted == 0) { + const size_t uncommitted = uncommit(); + + // Update uncommitted counter + uncommitted_since_last_timeout += uncommitted; + + // 'uncommitted == 0' is a proxy for uncommit_cycle_is_canceled() without + // having to take the page allocator lock + if (uncommitted == 0 || uncommit_cycle_is_finished()) { // Done break; } - total_uncommitted += uncommitted; + if (_next_uncommit_timeout != 0) { + // Update statistics + update_statistics(uncommitted_since_last_timeout, start, &accumulated_time); + + // Wait until next uncommit + wait(_next_uncommit_timeout); + + // Reset event and statistics counters + start = Ticks::now(); + uncommitted_since_last_timeout = 0; + } } - if (total_uncommitted > 0) { - // Update statistics - ZStatInc(ZCounterUncommit, total_uncommitted); - log_info(gc, heap)("Uncommitter (%u) Uncommitted: %zuM(%.0f%%)", - _id, total_uncommitted / M, percent_of(total_uncommitted, ZHeap::heap()->max_capacity())); + if (_uncommitted > 0) { + if (uncommitted_since_last_timeout > 0) { + // Update statistics + update_statistics(uncommitted_since_last_timeout, start, &accumulated_time); + } - // Send event - event.commit(total_uncommitted); + log_info(gc, heap)("Uncommitter (%u) Uncommitted: %zuM(%.0f%%) in %.3fms", + _id, _uncommitted / M, percent_of(_uncommitted, ZHeap::heap()->max_capacity()), + accumulated_time.seconds() * MILLIUNITS); } + + if (!should_continue()) { + // We are terminating + return; + } + + deactivate_uncommit_cycle(); } } @@ -94,3 +173,253 @@ void ZUncommitter::terminate() { _stop = true; _lock.notify_all(); } + +void ZUncommitter::reset_uncommit_cycle() { + _to_uncommit = 0; + _uncommitted = 0; + _cycle_start = 0.0; + _cancel_time = 0.0; + + postcond(uncommit_cycle_is_finished()); + postcond(!uncommit_cycle_is_canceled()); + postcond(!uncommit_cycle_is_active()); +} + +void ZUncommitter::deactivate_uncommit_cycle() { + ZLocker locker(&_partition->_page_allocator->_lock); + + precond(uncommit_cycle_is_active()); + precond(uncommit_cycle_is_finished() || uncommit_cycle_is_canceled()); + + // Update the next timeout + if (uncommit_cycle_is_canceled()) { + update_next_cycle_timeout_on_cancel(); + } else { + update_next_cycle_timeout_on_finish(); + } + + // Reset the cycle + reset_uncommit_cycle(); +} + +bool ZUncommitter::activate_uncommit_cycle() { + ZLocker locker(&_partition->_page_allocator->_lock); + + precond(uncommit_cycle_is_finished()); + precond(!uncommit_cycle_is_active()); + + if (uncommit_cycle_is_canceled()) { + // We were canceled before we managed to activate, update the timeout + update_next_cycle_timeout_on_cancel(); + + // Reset the cycle + reset_uncommit_cycle(); + + return false; + } + + ZMappedCache* const cache = &_partition->_cache; + + // Claim and reset the cache cycle tracking and register the cycle start time. + _cycle_start = os::elapsedTime(); + + // Read watermark from cache + const size_t uncommit_watermark = cache->min_size_watermark(); + + // Keep 10% as a headroom + const size_t to_uncommit = align_up(size_t(double(uncommit_watermark) * 0.9), ZGranuleSize); + + // Never uncommit below min capacity + const size_t uncommit_limit = _partition->_capacity - _partition->_min_capacity; + + _to_uncommit = MIN2(uncommit_limit, to_uncommit); + _uncommitted = 0; + + // Reset watermark for next uncommit cycle + cache->reset_min_size_watermark(); + + postcond(is_aligned(_to_uncommit, ZGranuleSize)); + + return true; +} + +uint64_t ZUncommitter::to_millis(double seconds) const { + return uint64_t(std::floor(seconds * double(MILLIUNITS))); +} + +void ZUncommitter::update_next_cycle_timeout(double from_time) { + const double now = os::elapsedTime(); + + if (now < from_time + double(ZUncommitDelay)) { + _next_cycle_timeout = to_millis(ZUncommitDelay) - to_millis(now - from_time); + } else { + // ZUncommitDelay has already expired + _next_cycle_timeout = 0; + } +} + +void ZUncommitter::update_next_cycle_timeout_on_cancel() { + precond(uncommit_cycle_is_canceled()); + + update_next_cycle_timeout(_cancel_time); + + // Skip logging if there is no delay + if (ZUncommitDelay > 0) { + log_debug(gc, heap)("Uncommitter (%u) Cancel Next Cycle Timeout: " UINT64_FORMAT "ms", + _id, _next_cycle_timeout); + } +} + +void ZUncommitter::update_next_cycle_timeout_on_finish() { + precond(uncommit_cycle_is_active()); + precond(uncommit_cycle_is_finished()); + + update_next_cycle_timeout(_cycle_start); + + // Skip logging if there is no delay + if (ZUncommitDelay > 0) { + log_debug(gc, heap)("Uncommitter (%u) Finish Next Cycle Timeout: " UINT64_FORMAT "ms", + _id, _next_cycle_timeout); + } +} + +void ZUncommitter::cancel_uncommit_cycle() { + // Reset the cache cycle tracking and register the cancel time. + _partition->_cache.reset_min_size_watermark(); + _cancel_time = os::elapsedTime(); +} + +void ZUncommitter::register_uncommit(size_t size) { + precond(uncommit_cycle_is_active()); + precond(size > 0); + precond(size <= _to_uncommit); + precond(is_aligned(size, ZGranuleSize)); + + _to_uncommit -= size; + _uncommitted += size; + + if (uncommit_cycle_is_canceled()) { + // Uncommit cycle got canceled while uncommitting. + return; + } + + if (uncommit_cycle_is_finished()) { + // Everything has been uncommitted. + return; + } + + const double now = os::elapsedTime(); + const double time_since_start = now - _cycle_start; + + if (time_since_start == 0.0) { + // Handle degenerate case where no time has elapsed. + _next_uncommit_timeout = 0; + return; + } + + const double uncommit_rate = double(_uncommitted) / time_since_start; + const double time_to_complete = double(_to_uncommit) / uncommit_rate; + const double time_left = double(ZUncommitDelay) - time_since_start; + + if (time_left < time_to_complete) { + // Too slow, work as fast as we can. + _next_uncommit_timeout = 0; + return; + } + + const size_t uncommits_remaining_estimate = _to_uncommit / size + 1; + const uint64_t millis_left_rounded_down = to_millis(time_left); + + if (uncommits_remaining_estimate < millis_left_rounded_down) { + // We have at least one millisecond per uncommit, spread them out. + _next_uncommit_timeout = millis_left_rounded_down / uncommits_remaining_estimate; + return; + } + + // Randomly distribute the extra time, one millisecond at a time. + const double extra_time = time_left - time_to_complete; + const double random = double(uint32_t(os::random())) / double(std::numeric_limits::max()); + + _next_uncommit_timeout = random < (extra_time / time_left) ? 1 : 0; +} + +bool ZUncommitter::uncommit_cycle_is_finished() const { + return _to_uncommit == 0; +} + +bool ZUncommitter::uncommit_cycle_is_active() const { + return _cycle_start != 0.0; +} + +bool ZUncommitter::uncommit_cycle_is_canceled() const { + return _cancel_time != 0.0; +} + +size_t ZUncommitter::uncommit() { + precond(uncommit_cycle_is_active()); + + ZArray flushed_vmems; + size_t flushed = 0; + + { + // We need to join the suspendible thread set while manipulating capacity + // and used, to make sure GC safepoints will have a consistent view. + SuspendibleThreadSetJoiner sts_joiner; + ZLocker locker(&_partition->_page_allocator->_lock); + + if (uncommit_cycle_is_canceled()) { + // We have committed within the delay, stop uncommitting. + return 0; + } + + // We flush out and uncommit chunks at a time (~0.8% of the max capacity, + // but at least one granule and at most 256M), in case demand for memory + // increases while we are uncommitting. + const size_t current_max_capacity = _partition->_current_max_capacity; + const size_t limit_upper_bound = MAX2(ZGranuleSize, align_down(256 * M / ZNUMA::count(), ZGranuleSize)); + const size_t limit = MIN2(align_up(current_max_capacity >> 7, ZGranuleSize), limit_upper_bound); + + ZMappedCache& cache = _partition->_cache; + + // Never uncommit more than the current uncommit watermark, + // (adjusted by what has already been uncommitted). + const size_t allowed_to_uncommit = MAX2(cache.min_size_watermark(), _uncommitted) - _uncommitted; + const size_t to_uncommit = MIN2(_to_uncommit, allowed_to_uncommit); + + // Never uncommit below min capacity. + const size_t retain = MAX2(_partition->_used, _partition->_min_capacity); + const size_t release = _partition->_capacity - retain; + const size_t flush = MIN3(release, limit, to_uncommit); + + // Flush memory from the mapped cache for uncommit + flushed = cache.remove_for_uncommit(flush, &flushed_vmems); + if (flushed == 0) { + // Nothing flushed + cancel_uncommit_cycle(); + return 0; + } + + // Record flushed memory as claimed and how much we've flushed for this partition + Atomic::add(&_partition->_claimed, flushed); + } + + // Unmap and uncommit flushed memory + for (const ZVirtualMemory vmem : flushed_vmems) { + _partition->unmap_virtual(vmem); + _partition->uncommit_physical(vmem); + _partition->free_physical(vmem); + _partition->free_virtual(vmem); + } + + { + SuspendibleThreadSetJoiner sts_joiner; + ZLocker locker(&_partition->_page_allocator->_lock); + + // Adjust claimed and capacity to reflect the uncommit + Atomic::sub(&_partition->_claimed, flushed); + _partition->decrease_capacity(flushed, false /* set_max_capacity */); + register_uncommit(flushed); + } + + return flushed; +} diff --git a/src/hotspot/share/gc/z/zUncommitter.hpp b/src/hotspot/share/gc/z/zUncommitter.hpp index f8630f7b7fb..a3cd2b17e23 100644 --- a/src/hotspot/share/gc/z/zUncommitter.hpp +++ b/src/hotspot/share/gc/z/zUncommitter.hpp @@ -26,6 +26,7 @@ #include "gc/z/zLock.hpp" #include "gc/z/zThread.hpp" +#include "utilities/ticks.hpp" class ZPartition; @@ -35,16 +36,43 @@ private: ZPartition* const _partition; mutable ZConditionLock _lock; bool _stop; + double _cancel_time; + uint64_t _next_cycle_timeout; + uint64_t _next_uncommit_timeout; + double _cycle_start; + size_t _to_uncommit; + size_t _uncommitted; bool wait(uint64_t timeout) const; bool should_continue() const; + uint64_t to_millis(double seconds) const; + + void update_next_cycle_timeout(double from_time); + void update_next_cycle_timeout_on_cancel(); + void update_next_cycle_timeout_on_finish(); + + void reset_uncommit_cycle(); + void deactivate_uncommit_cycle(); + bool activate_uncommit_cycle(); + void register_uncommit(size_t size); + + bool uncommit_cycle_is_finished() const; + bool uncommit_cycle_is_active() const; + bool uncommit_cycle_is_canceled() const; + + size_t uncommit(); + + void update_statistics(size_t uncommitted, Ticks start, Tickspan* accumulated_time) const; + protected: virtual void run_thread(); virtual void terminate(); public: ZUncommitter(uint32_t id, ZPartition* partition); + + void cancel_uncommit_cycle(); }; #endif // SHARE_GC_Z_ZUNCOMMITTER_HPP diff --git a/test/hotspot/jtreg/gc/z/TestUncommit.java b/test/hotspot/jtreg/gc/z/TestUncommit.java index c07cff85744..0ba4c55f22a 100644 --- a/test/hotspot/jtreg/gc/z/TestUncommit.java +++ b/test/hotspot/jtreg/gc/z/TestUncommit.java @@ -27,12 +27,10 @@ package gc.z; * @test TestUncommit * @requires vm.gc.Z * @summary Test ZGC uncommit unused memory - * @library /test/lib * @run main/othervm -XX:+UseZGC -Xlog:gc*,gc+heap=debug,gc+stats=off -Xms128M -Xmx512M -XX:ZUncommitDelay=5 gc.z.TestUncommit */ import java.util.ArrayList; -import jdk.test.lib.Utils; public class TestUncommit { private static final int delay = 5 * 1000; // milliseconds @@ -110,7 +108,7 @@ public class TestUncommit { throw new Exception("Uncommitted too fast"); } - if (actualDelay > delay * 2 * Utils.TIMEOUT_FACTOR) { + if (actualDelay > delay * 3) { throw new Exception("Uncommitted too slow"); } From c1a81cfb51f9c4e7c32a44126746e8655adc349e Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 3 Jun 2025 10:08:32 +0000 Subject: [PATCH 095/216] 8358284: doc/testing.html is not up to date after JDK-8355003 Reviewed-by: jwaters, dholmes, erikj --- doc/testing.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/testing.html b/doc/testing.html index 6288a552bf0..b9d1f4ed22f 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -72,9 +72,11 @@ id="toc-notes-for-specific-tests">Notes for Specific Tests
    • Non-US locale
    • PKCS11 Tests
    • +
    • Testing Ahead-of-time -Optimizations
    • +id="toc-testing-ahead-of-time-optimizations">### Testing Ahead-of-time +Optimizations +
      • Testing with alternative security providers
      • @@ -599,8 +601,8 @@ element of the appropriate @Artifact class. (See JTREG="JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs"

        For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.

        -

        Testing Ahead-of-time -Optimizations

        +

        ### Testing Ahead-of-time +Optimizations

        One way to improve test coverage of ahead-of-time (AOT) optimizations in the JDK is to run existing jtreg test cases in a special "AOT_JDK" mode. Example:

        From 78a392aa3b0cda52cfacfa15250fa61010519424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Sikstr=C3=B6m?= Date: Tue, 3 Jun 2025 11:42:10 +0000 Subject: [PATCH 096/216] 8356880: ZGC: Backoff in ZLiveMap::reset spin-loop Reviewed-by: stefank, eosterlund, aboldtch --- src/hotspot/share/gc/z/zLiveMap.cpp | 47 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/z/zLiveMap.cpp b/src/hotspot/share/gc/z/zLiveMap.cpp index 5b9e0a932c3..18b44dacab9 100644 --- a/src/hotspot/share/gc/z/zLiveMap.cpp +++ b/src/hotspot/share/gc/z/zLiveMap.cpp @@ -30,6 +30,7 @@ #include "runtime/atomic.hpp" #include "utilities/debug.hpp" #include "utilities/powerOfTwo.hpp" +#include "utilities/spinYield.hpp" static const ZStatCounter ZCounterMarkSeqNumResetContention("Contention", "Mark SeqNum Reset Contention", ZStatUnitOpsPerSecond); static const ZStatCounter ZCounterMarkSegmentResetContention("Contention", "Mark Segment Reset Contention", ZStatUnitOpsPerSecond); @@ -55,33 +56,40 @@ void ZLiveMap::reset(ZGenerationId id) { const uint32_t seqnum_initializing = (uint32_t)-1; bool contention = false; + SpinYield yielder(0, 0, 1000); + // Multiple threads can enter here, make sure only one of them // resets the marking information while the others busy wait. for (uint32_t seqnum = Atomic::load_acquire(&_seqnum); seqnum != generation->seqnum(); seqnum = Atomic::load_acquire(&_seqnum)) { - if ((seqnum != seqnum_initializing) && - (Atomic::cmpxchg(&_seqnum, seqnum, seqnum_initializing) == seqnum)) { - // Reset marking information - _live_bytes = 0; - _live_objects = 0; - // Clear segment claimed/live bits - segment_live_bits().clear(); - segment_claim_bits().clear(); + if (seqnum != seqnum_initializing) { + // No one has claimed initialization of the livemap yet + if (Atomic::cmpxchg(&_seqnum, seqnum, seqnum_initializing) == seqnum) { + // This thread claimed the initialization - // We lazily initialize the bitmap the first time the page is marked, i.e. - // a bit is about to be set for the first time. - initialize_bitmap(); + // Reset marking information + _live_bytes = 0; + _live_objects = 0; - assert(_seqnum == seqnum_initializing, "Invalid"); + // Clear segment claimed/live bits + segment_live_bits().clear(); + segment_claim_bits().clear(); - // Make sure the newly reset marking information is ordered - // before the update of the page seqnum, such that when the - // up-to-date seqnum is load acquired, the bit maps will not - // contain stale information. - Atomic::release_store(&_seqnum, generation->seqnum()); - break; + // We lazily initialize the bitmap the first time the page is marked, i.e. + // a bit is about to be set for the first time. + initialize_bitmap(); + + assert(_seqnum == seqnum_initializing, "Invalid"); + + // Make sure the newly reset marking information is ordered + // before the update of the page seqnum, such that when the + // up-to-date seqnum is load acquired, the bit maps will not + // contain stale information. + Atomic::release_store(&_seqnum, generation->seqnum()); + break; + } } // Mark reset contention @@ -93,6 +101,9 @@ void ZLiveMap::reset(ZGenerationId id) { log_trace(gc)("Mark seqnum reset contention, thread: " PTR_FORMAT " (%s), map: " PTR_FORMAT, p2i(Thread::current()), ZUtils::thread_name(), p2i(this)); } + + // "Yield" to allow the thread that's resetting the livemap to finish + yielder.wait(); } } From 4618374269e8636c772d921ad0c2c2d9e5e3e643 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Tue, 3 Jun 2025 12:15:08 +0000 Subject: [PATCH 097/216] 8358310: ZGC: riscv, ppc ZPlatformAddressOffsetBits may return a too large value Reviewed-by: eosterlund, mdoerr, fyang --- src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp | 8 +++++--- src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp index f3a7a948f70..89417c4691d 100644 --- a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp @@ -34,9 +34,11 @@ #include #endif // LINUX -// Default value if probing is not implemented for a certain platform: 128TB -static const size_t DEFAULT_MAX_ADDRESS_BIT = 47; -// Minimum value returned, if probing fails: 64GB +// Default value if probing is not implemented for a certain platform +// Max address bit is restricted by implicit assumptions in the code, for instance +// the bit layout of ZForwardingEntry or Partial array entry (see ZMarkStackEntry) in mark stack +static const size_t DEFAULT_MAX_ADDRESS_BIT = 46; +// Minimum value returned, if probing fail static const size_t MINIMUM_MAX_ADDRESS_BIT = 36; static size_t probe_valid_max_address_bit() { diff --git a/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp b/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp index 5f783e6fb8b..9df0a431c45 100644 --- a/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/z/zAddress_riscv.cpp @@ -36,9 +36,11 @@ #include #endif // LINUX -// Default value if probe is not implemented for a certain platform: 128TB -static const size_t DEFAULT_MAX_ADDRESS_BIT = 47; -// Minimum value returned, if probing fails: 64GB +// Default value if probing is not implemented for a certain platform +// Max address bit is restricted by implicit assumptions in the code, for instance +// the bit layout of ZForwardingEntry or Partial array entry (see ZMarkStackEntry) in mark stack +static const size_t DEFAULT_MAX_ADDRESS_BIT = 46; +// Minimum value returned, if probing fail static const size_t MINIMUM_MAX_ADDRESS_BIT = 36; static size_t probe_valid_max_address_bit() { From d3f54dae30e377b9fb4aaa06bc123b71de444a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Tue, 3 Jun 2025 14:27:41 +0000 Subject: [PATCH 098/216] 8357954: G1: No SATB barriers applied for runtime IN_NATIVE atomics Reviewed-by: shade, kbarrett, tschatzl --- src/hotspot/share/gc/g1/g1BarrierSet.hpp | 5 +++++ .../share/gc/g1/g1BarrierSet.inline.hpp | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.hpp index 8c2605b9746..2b1074fcd7a 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp @@ -112,6 +112,11 @@ class G1BarrierSet: public CardTableBarrierSet { // Defensive: will catch weak oops at addresses in heap template static oop oop_load_in_heap(T* addr); + + template + static oop oop_atomic_cmpxchg_not_in_heap(T* addr, oop compare_value, oop new_value); + template + static oop oop_atomic_xchg_not_in_heap(T* addr, oop new_value); }; }; diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp index a032f072aed..33c153e9e5d 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp @@ -132,4 +132,26 @@ oop_store_not_in_heap(T* addr, oop new_value) { Raw::oop_store(addr, new_value); } +template +template +inline oop G1BarrierSet::AccessBarrier:: +oop_atomic_cmpxchg_not_in_heap(T* addr, oop compare_value, oop new_value) { + // Apply SATB barriers for all non-heap references, to allow + // concurrent scanning of such references. + G1BarrierSet *bs = barrier_set_cast(BarrierSet::barrier_set()); + bs->write_ref_field_pre(addr); + return Raw::oop_atomic_cmpxchg(addr, compare_value, new_value); +} + +template +template +inline oop G1BarrierSet::AccessBarrier:: +oop_atomic_xchg_not_in_heap(T* addr, oop new_value) { + // Apply SATB barriers for all non-heap references, to allow + // concurrent scanning of such references. + G1BarrierSet *bs = barrier_set_cast(BarrierSet::barrier_set()); + bs->write_ref_field_pre(addr); + return Raw::oop_atomic_xchg(addr, new_value); +} + #endif // SHARE_GC_G1_G1BARRIERSET_INLINE_HPP From e2f736658fbd03d2dc2186dbd9ba9b13b1f1a8ac Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Tue, 3 Jun 2025 14:35:17 +0000 Subject: [PATCH 099/216] 8329951: `var` emits deprecation warnings that do not point to the file or position Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Analyzer.java | 8 ++--- .../com/sun/tools/javac/comp/Attr.java | 4 +-- .../tools/javac/tree/VarWarnPosition.java | 29 +++++++++++++++++++ .../tools/javac/tree/VarWarnPosition.out | 6 ++++ 4 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 test/langtools/tools/javac/tree/VarWarnPosition.java create mode 100644 test/langtools/tools/javac/tree/VarWarnPosition.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java index 514de5e2fe8..1aea9f77a20 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java @@ -365,10 +365,6 @@ public class Analyzer { super(AnalyzerMode.LOCAL, tag); } - boolean isImplicitlyTyped(JCVariableDecl decl) { - return decl.vartype.pos == Position.NOPOS; - } - /** * Map a variable tree into a new declaration using implicit type. */ @@ -401,7 +397,7 @@ public class Analyzer { boolean match(JCVariableDecl tree){ return tree.sym.owner.kind == Kind.MTH && - tree.init != null && !isImplicitlyTyped(tree) && + tree.init != null && !tree.declaredUsingVar() && attr.canInferLocalVarType(tree) == null; } @Override @@ -425,7 +421,7 @@ public class Analyzer { @Override boolean match(JCEnhancedForLoop tree){ - return !isImplicitlyTyped(tree.var); + return !tree.var.declaredUsingVar(); } @Override List rewrite(JCEnhancedForLoop oldTree) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index a9293b2d135..9c9672151c7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -5716,9 +5716,9 @@ public class Attr extends JCTree.Visitor { private void setSyntheticVariableType(JCVariableDecl tree, Type type) { if (type.isErroneous()) { - tree.vartype = make.at(Position.NOPOS).Erroneous(); + tree.vartype = make.at(tree.pos()).Erroneous(); } else { - tree.vartype = make.at(Position.NOPOS).Type(type); + tree.vartype = make.at(tree.pos()).Type(type); } } diff --git a/test/langtools/tools/javac/tree/VarWarnPosition.java b/test/langtools/tools/javac/tree/VarWarnPosition.java new file mode 100644 index 00000000000..7dae84f3542 --- /dev/null +++ b/test/langtools/tools/javac/tree/VarWarnPosition.java @@ -0,0 +1,29 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8329951 + * @summary Check that "var" variable synthetic types have a source position + * @compile/process/ref=VarWarnPosition.out -Xlint:deprecation -XDrawDiagnostics VarWarnPosition.java + */ + +import java.util.*; +import java.util.function.*; + +public class VarWarnPosition { + + VarWarnPosition() { + + // Test 1 + @SuppressWarnings("deprecation") + List deprecatedList = null; + for (var deprValue : deprecatedList) { } + + // Test 2 + Consumer c = d -> { }; + + // Test 3 + Consumer c2 = (var d) -> { }; + } +} + +@Deprecated +class Depr {} diff --git a/test/langtools/tools/javac/tree/VarWarnPosition.out b/test/langtools/tools/javac/tree/VarWarnPosition.out new file mode 100644 index 00000000000..2200c8b4ae0 --- /dev/null +++ b/test/langtools/tools/javac/tree/VarWarnPosition.out @@ -0,0 +1,6 @@ +VarWarnPosition.java:18:14: compiler.warn.has.been.deprecated: Depr, compiler.misc.unnamed.package +VarWarnPosition.java:21:18: compiler.warn.has.been.deprecated: Depr, compiler.misc.unnamed.package +VarWarnPosition.java:21:28: compiler.warn.has.been.deprecated: Depr, compiler.misc.unnamed.package +VarWarnPosition.java:24:18: compiler.warn.has.been.deprecated: Depr, compiler.misc.unnamed.package +VarWarnPosition.java:24:30: compiler.warn.has.been.deprecated: Depr, compiler.misc.unnamed.package +5 warnings From faf19abd312ac461f9f74035fec61af7d834ffc1 Mon Sep 17 00:00:00 2001 From: Yudi Zheng Date: Tue, 3 Jun 2025 15:10:53 +0000 Subject: [PATCH 100/216] 8358333: Use VEX2 prefix in Assembler::psllq Reviewed-by: jbhateja, thartmann --- src/hotspot/cpu/x86/assembler_x86.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 3fb64c8f644..897b06e94df 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -9140,7 +9140,8 @@ void Assembler::pslld(XMMRegister dst, int shift) { } void Assembler::psllq(XMMRegister dst, int shift) { - InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + InstructionAttr attributes(AVX_128bit, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_rex_vex_w_reverted(); // XMM6 is for /6 encoding: 66 0F 73 /6 ib int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int24(0x73, (0xC0 | encode), shift & 0xFF); From 01f01b6f7b8a2f0dbe940bffd567ff2b46732787 Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Tue, 3 Jun 2025 15:31:07 +0000 Subject: [PATCH 101/216] 8358283: Inconsistent failure mode for MetaspaceObj::operator new(size_t, MemTag) Reviewed-by: kvn, kbarrett --- src/hotspot/share/memory/allocation.cpp | 2 +- src/hotspot/share/memory/allocation.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/memory/allocation.cpp b/src/hotspot/share/memory/allocation.cpp index b01ab4014ed..0d99c1bea68 100644 --- a/src/hotspot/share/memory/allocation.cpp +++ b/src/hotspot/share/memory/allocation.cpp @@ -86,7 +86,7 @@ void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data, } // This is used for allocating training data. We are allocating training data in many cases where a GC cannot be triggered. -void* MetaspaceObj::operator new(size_t size, MemTag flags) throw() { +void* MetaspaceObj::operator new(size_t size, MemTag flags) { void* p = AllocateHeap(size, flags, CALLER_PC); memset(p, 0, size); return p; diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index 8cd6e6d4207..9e500135d0b 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -358,7 +358,7 @@ class MetaspaceObj { size_t word_size, Type type) throw(); // This is used for allocating training data. We are allocating training data in many cases where a GC cannot be triggered. - void* operator new(size_t size, MemTag flags) throw(); + void* operator new(size_t size, MemTag flags); void operator delete(void* p) = delete; // Declare a *static* method with the same signature in any subclass of MetaspaceObj From b6f827ef054959662190e21ce63fc3d3c45b92f3 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Tue, 3 Jun 2025 15:36:29 +0000 Subject: [PATCH 102/216] 8348986: Improve coverage of enhanced exception messages Reviewed-by: dfuchs --- .../share/classes/java/net/HostPortrange.java | 42 ++- .../classes/java/net/Inet4AddressImpl.java | 6 +- .../share/classes/java/net/Inet6Address.java | 8 +- .../share/classes/java/net/InetAddress.java | 56 +-- .../classes/java/net/NetworkInterface.java | 6 +- .../share/classes/java/net/Proxy.java | 11 +- .../classes/java/net/SocketPermission.java | 14 +- .../classes/java/net/SocksSocketImpl.java | 8 +- src/java.base/share/classes/java/net/URI.java | 14 +- src/java.base/share/classes/java/net/URL.java | 7 +- .../classes/java/net/URLStreamHandler.java | 13 +- .../classes/jdk/internal/util/Exceptions.java | 322 ++++++++++++++++++ src/java.base/share/classes/module-info.java | 4 + .../classes/sun/net/util/IPAddressUtil.java | 8 +- .../sun/net/util/SocketExceptions.java | 96 ------ .../share/classes/sun/net/www/ParseUtil.java | 4 +- .../net/www/protocol/https/HttpsClient.java | 9 +- .../sun/net/www/protocol/jar/Handler.java | 24 +- .../net/www/protocol/jar/JarFileFactory.java | 6 +- .../www/protocol/jar/JarURLConnection.java | 17 +- .../sun/net/www/protocol/jmod/Handler.java | 2 +- .../sun/nio/ch/DatagramSocketAdaptor.java | 7 +- .../classes/sun/nio/ch/NioSocketImpl.java | 9 +- .../classes/sun/nio/ch/SocketAdaptor.java | 6 +- .../classes/sun/nio/ch/SocketChannelImpl.java | 8 +- .../share/conf/security/java.security | 30 +- src/java.base/share/native/libnet/net_util.c | 29 +- src/java.base/share/native/libnet/net_util.h | 4 +- .../ch/UnixAsynchronousSocketChannelImpl.java | 9 +- .../sun/nio/fs/UnixUserPrincipals.java | 12 +- .../unix/native/libnet/net_util_md.c | 31 +- .../WindowsAsynchronousSocketChannelImpl.java | 12 +- .../sun/nio/fs/WindowsSecurityDescriptor.java | 8 +- .../sun/nio/fs/WindowsUserPrincipals.java | 12 +- .../windows/native/libnet/Inet4AddressImpl.c | 7 +- .../windows/native/libnet/Inet6AddressImpl.c | 4 +- .../classes/com/sun/jndi/ldap/LdapURL.java | 5 +- .../classes/com/sun/jndi/toolkit/url/Uri.java | 34 +- .../net/http/HttpRequestBuilderImpl.java | 7 +- .../net/http/ResponseBodyHandlers.java | 10 +- .../net/http/websocket/OpeningHandshake.java | 12 +- .../share/classes/java/rmi/Naming.java | 29 +- .../httpserver/simpleserver/JWebServer.java | 11 + .../simpleserver/CommandLineNegativeTest.java | 6 +- test/jdk/java/net/URI/Test.java | 1 + .../TestJDKIncludeInExceptions.java | 6 +- test/jdk/sun/net/util/ExceptionsTest.java | 172 ++++++++++ 47 files changed, 883 insertions(+), 275 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/util/Exceptions.java delete mode 100644 src/java.base/share/classes/sun/net/util/SocketExceptions.java create mode 100644 test/jdk/sun/net/util/ExceptionsTest.java diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index fd516b8d2d7..289846841c9 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,6 +29,9 @@ import java.util.Formatter; import java.util.Locale; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; + /** * Parses a string containing a host/domain name and port range */ @@ -56,7 +59,7 @@ class HostPortrange { return hostname.hashCode() + portrange[0] + portrange[1]; } - HostPortrange(String scheme, String str) { + HostPortrange(String scheme, String host) { // Parse the host name. A name has up to three components, the // hostname, a port number, or two numbers representing a port // range. "www.example.com:8080-9090" is a valid host name. @@ -67,21 +70,23 @@ class HostPortrange { // Refer to RFC 2732 for more information. // first separate string into two fields: hoststr, portstr - String hoststr, portstr = null; + String hoststr = null, portstr = null; this.scheme = scheme; // check for IPv6 address - if (str.charAt(0) == '[') { + if (host.charAt(0) == '[') { ipv6 = literal = true; - int rb = str.indexOf(']'); + int rb = host.indexOf(']'); if (rb != -1) { - hoststr = str.substring(1, rb); + hoststr = host.substring(1, rb); } else { - throw new IllegalArgumentException("invalid IPv6 address: " + str); + throw new IllegalArgumentException( + formatMsg("invalid IPv6 address%s", + filterNonSocketInfo(host).prefixWith(": "))); } - int sep = str.indexOf(':', rb + 1); - if (sep != -1 && str.length() > sep) { - portstr = str.substring(sep + 1); + int sep = host.indexOf(':', rb + 1); + if (sep != -1 && host.length() > sep) { + portstr = host.substring(sep + 1); } // need to normalize hoststr now byte[] ip = IPAddressUtil.textToNumericFormatV6(hoststr); @@ -94,16 +99,16 @@ class HostPortrange { + "%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]); - hostname = sb.toString(); + this.hostname = sb.toString(); } else { // not IPv6 therefore ':' is the port separator - int sep = str.indexOf(':'); - if (sep != -1 && str.length() > sep) { - hoststr = str.substring(0, sep); - portstr = str.substring(sep + 1); + int sep = host.indexOf(':'); + if (sep != -1 && host.length() > sep) { + hoststr = host.substring(0, sep); + portstr = host.substring(sep + 1); } else { - hoststr = sep == -1 ? str : str.substring(0, sep); + hoststr = sep == -1 ? host : host.substring(0, sep); } // is this a domain wildcard specification? if (hoststr.lastIndexOf('*') > 0) { @@ -150,13 +155,14 @@ class HostPortrange { } } } - hostname = hoststr; + this.hostname = hoststr; } try { portrange = parsePort(portstr); } catch (Exception e) { - throw new IllegalArgumentException("invalid port range: " + portstr); + throw new IllegalArgumentException( + formatMsg("invalid port range%s", filterNonSocketInfo(portstr).prefixWith(": "))); } } diff --git a/src/java.base/share/classes/java/net/Inet4AddressImpl.java b/src/java.base/share/classes/java/net/Inet4AddressImpl.java index c7feaf4c195..3d8ea56d99f 100644 --- a/src/java.base/share/classes/java/net/Inet4AddressImpl.java +++ b/src/java.base/share/classes/java/net/Inet4AddressImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ import java.io.IOException; import java.net.spi.InetAddressResolver.LookupPolicy; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /* * Package private implementation of InetAddressImpl for IPv4. @@ -38,7 +40,7 @@ final class Inet4AddressImpl implements InetAddressImpl { public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) throws UnknownHostException { if ((lookupPolicy.characteristics() & IPV4) == 0) { - throw new UnknownHostException(hostname); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(hostname))); } return lookupAllHostAddr(hostname); } diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index 06a74ca3adc..f0f386a9d29 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,6 +35,8 @@ import java.io.ObjectStreamField; import java.util.Enumeration; import java.util.Arrays; import java.util.Objects; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents an Internet Protocol version 6 (IPv6) address. @@ -581,7 +583,9 @@ class Inet6Address extends InetAddress { if (addrBytes.length == Inet4Address.INADDRSZ) { if (numericZone != -1 || ifname != null) { // IPv4-mapped address must not contain zone-id - throw new UnknownHostException(addressLiteral + ": invalid IPv4-mapped address"); + throw new UnknownHostException( + formatMsg("%sinvalid IPv4-mapped address", + filterNonSocketInfo(addressLiteral).suffixWith(": "))); } return new Inet4Address(null, addrBytes); } diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index 4bceebdcd0e..4d8a00249a9 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -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 @@ -54,6 +54,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; +import jdk.internal.util.Exceptions; import jdk.internal.access.JavaNetInetAddressAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.Blocker; @@ -68,6 +69,8 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents an Internet Protocol (IP) address. @@ -382,6 +385,7 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In } } ); + Exceptions.setup(); // needed for native exceptions init(); } @@ -902,7 +906,7 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In @Override public InetAddress[] get() throws UnknownHostException { if (inetAddresses == null) { - throw new UnknownHostException(host); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))); } return inetAddresses; } @@ -1095,7 +1099,9 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In } } if (inetAddresses == null || inetAddresses.length == 0) { - throw ex == null ? new UnknownHostException(host) : ex; + throw ex == null + ? new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))) + : ex; } return inetAddresses; } @@ -1203,16 +1209,19 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In } } } catch (IOException e) { - throw new UnknownHostException("Unable to resolve address " - + Arrays.toString(addr) + " as hosts file " + hostsFile - + " not found "); + throw new UnknownHostException( + formatMsg("Unable to resolve address %s as hosts file %s not found", + filterNonSocketInfo(Arrays.toString(addr)), + filterNonSocketInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } if ((host == null) || (host.isEmpty()) || (host.equals(" "))) { - throw new UnknownHostException("Requested address " - + Arrays.toString(addr) - + " resolves to an invalid entry in hosts file " - + hostsFile); + throw new UnknownHostException( + formatMsg("Requested address %s resolves to an invalid entry in hosts file %s", + filterNonSocketInfo(Arrays.toString(addr)), + filterNonSocketInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } return host; } @@ -1273,8 +1282,11 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In } } } catch (IOException e) { - throw new UnknownHostException("Unable to resolve host " + host - + " as hosts file " + hostsFile + " not found "); + throw new UnknownHostException( + formatMsg("Unable to resolve host %s as hosts file %s not found", + filterNonSocketInfo(host), filterNonSocketInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); + } // Check if only IPv4 addresses are requested if (needIPv4 && !needIPv6) { @@ -1305,8 +1317,10 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In private void checkResultsList(List addressesList, String hostName) throws UnknownHostException { if (addressesList.isEmpty()) { - throw new UnknownHostException("Unable to resolve host " + hostName - + " in hosts file " + hostsFile); + throw new UnknownHostException( + formatMsg("Unable to resolve host %s in hosts file %s", + filterNonSocketInfo(hostName), filterNonSocketInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } } @@ -1543,7 +1557,7 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In // Here we check the address string for ambiguity only inetAddress = Inet4Address.parseAddressString(host, false); } catch (IllegalArgumentException iae) { - var uhe = new UnknownHostException(host); + var uhe = new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))); uhe.initCause(iae); throw uhe; } @@ -1570,7 +1584,8 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { String hostString = wrapInBrackets ? "[" + host + "]" : host; - return new UnknownHostException(hostString + ": invalid IPv6 address literal"); + return new UnknownHostException(formatMsg("%sinvalid IPv6 address literal", + filterNonSocketInfo(hostString).suffixWith(": "))); } /** @@ -1708,7 +1723,8 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In InetAddress[] result = addresses == null ? null : addresses.toArray(InetAddress[]::new); if (result == null || result.length == 0) { - throw ex == null ? new UnknownHostException(host) : ex; + throw ex == null ? new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))) + : ex; } return result; } @@ -1780,9 +1796,9 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In localAddr = getAllByName0(local, false)[0]; } catch (UnknownHostException uhe) { // Rethrow with a more informative error message. - UnknownHostException uhe2 = - new UnknownHostException(local + ": " + - uhe.getMessage()); + UnknownHostException uhe2 = + new UnknownHostException(formatMsg(filterNonSocketInfo(local) + .suffixWith(": ") + uhe.getMessage())); uhe2.initCause(uhe); throw uhe2; } diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index 8e0f7137315..f6f7d438864 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -34,6 +34,8 @@ import java.util.Spliterator; import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents a Network Interface. @@ -323,7 +325,9 @@ public final class NetworkInterface { + addr.holder.family); } } else { - throw new IllegalArgumentException("invalid address type: " + addr); + throw new IllegalArgumentException( + formatMsg("invalid address type%s", + filterNonSocketInfo(addr.toString()).prefixWith(": "))); } return getByInetAddress0(addr); } diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index db434238558..4109c586058 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -26,6 +26,8 @@ package java.net; import java.util.Objects; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents a proxy setting, typically a type (http, socks) and @@ -93,8 +95,11 @@ public class Proxy { * incompatible */ public Proxy(Type type, SocketAddress sa) { - if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) - throw new IllegalArgumentException("type " + type + " is not compatible with address " + sa); + if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { + throw new IllegalArgumentException( + formatMsg("type " + type + " is not compatible with address %s", + filterNonSocketInfo(String.valueOf(sa)))); + } this.type = type; this.sa = sa; } diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index e3a85bbf856..eb14099f686 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -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 @@ -46,6 +46,8 @@ import sun.security.util.RegisteredDomain; import sun.security.util.SecurityConstants; import sun.security.util.Debug; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents access to a network via sockets. @@ -392,8 +394,8 @@ public final class SocketPermission extends Permission if (rb != -1) { host = host.substring(start, rb); } else { - throw new - IllegalArgumentException("invalid host/port: "+host); + throw new IllegalArgumentException( + formatMsg("invalid host/port%s", filterNonSocketInfo(host).prefixWith(": "))); } sep = hostport.indexOf(':', rb+1); } else { @@ -410,8 +412,8 @@ public final class SocketPermission extends Permission try { portrange = parsePort(port); } catch (Exception e) { - throw new - IllegalArgumentException("invalid port range: "+port); + throw new IllegalArgumentException( + formatMsg("invalid port range%s", filterNonSocketInfo(port).prefixWith(": "))); } } else { portrange = new int[] { PORT_MIN, PORT_MAX }; @@ -784,7 +786,7 @@ public final class SocketPermission extends Permission throw uhe; } catch (IndexOutOfBoundsException iobe) { invalid = true; - throw new UnknownHostException(getName()); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(getName()))); } } diff --git a/src/java.base/share/classes/java/net/SocksSocketImpl.java b/src/java.base/share/classes/java/net/SocksSocketImpl.java index 54ff612be02..71794d7a0a6 100644 --- a/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -37,6 +37,8 @@ import sun.net.spi.DefaultProxySelector; import sun.net.www.ParseUtil; import static sun.net.util.IPAddressUtil.isIPv6LiteralAddress; +import static jdk.internal.util.Exceptions.filterSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). @@ -330,7 +332,7 @@ class SocksSocketImpl extends DelegatingSocketImpl implements SocksConsts { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throw new UnknownHostException(epoint.toString()); + throw new UnknownHostException(formatMsg("%s", filterSocketInfo(epoint.toString()))); connectV4(in, out, epoint, deadlineMillis); return; } @@ -349,7 +351,7 @@ class SocksSocketImpl extends DelegatingSocketImpl implements SocksConsts { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throw new UnknownHostException(epoint.toString()); + throw new UnknownHostException(formatMsg("%s", filterSocketInfo(epoint.toString()))); connectV4(in, out, epoint, deadlineMillis); return; } diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index cd116f3877b..daf63d19032 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -42,8 +42,12 @@ import java.nio.file.Path; import java.text.Normalizer; import jdk.internal.access.JavaNetUriAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.Exceptions; import sun.nio.cs.UTF_8; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; + /** * Represents a Uniform Resource Identifier (URI) reference. * @@ -2032,7 +2036,8 @@ public final class URI { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(s, "Relative path in absolute URI"); + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(s)), + "Relative path in absolute URI"); } } @@ -2988,11 +2993,14 @@ public final class URI // -- Methods for throwing URISyntaxException in various ways -- private void fail(String reason) throws URISyntaxException { - throw new URISyntaxException(input, reason); + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(input)), reason); } private void fail(String reason, int p) throws URISyntaxException { - throw new URISyntaxException(input, reason, p); + if (!Exceptions.enhancedNonSocketExceptions()) { + p = -1; + } + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(input)), reason, p); } private void failExpecting(String expected, int p) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index be4daa28f33..9266b6c94f1 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -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 @@ -44,6 +44,8 @@ import jdk.internal.access.SharedSecrets; import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * Class {@code URL} represents a Uniform Resource @@ -1168,7 +1170,8 @@ public final class URL implements java.io.Serializable { URI uri = new URI(toString()); if (authority != null && isBuiltinStreamHandler(handler)) { String s = IPAddressUtil.checkAuthority(this); - if (s != null) throw new URISyntaxException(authority, s); + if (s != null) + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(authority)), s); } return uri; } diff --git a/src/java.base/share/classes/java/net/URLStreamHandler.java b/src/java.base/share/classes/java/net/URLStreamHandler.java index 1400741b2bb..f66902a451e 100644 --- a/src/java.base/share/classes/java/net/URLStreamHandler.java +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, 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 @@ -30,6 +30,9 @@ import java.util.Locale; import java.util.Objects; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; + /** * The abstract class {@code URLStreamHandler} is the common * superclass for all stream protocol handlers. A stream protocol @@ -206,7 +209,7 @@ public abstract class URLStreamHandler { if (!IPAddressUtil. isIPv6LiteralAddress(host.substring(1, ind))) { throw new IllegalArgumentException( - "Invalid host: "+ host); + formatMsg("Invalid host%s", filterNonSocketInfo(host).prefixWith(": "))); } port = -1 ; @@ -220,12 +223,14 @@ public abstract class URLStreamHandler { } } else { throw new IllegalArgumentException( - "Invalid authority field: " + authority); + formatMsg("Invalid authority field%s", + filterNonSocketInfo(authority).prefixWith(": "))); } } } else { throw new IllegalArgumentException( - "Invalid authority field: " + authority); + formatMsg("Invalid authority field%s", + filterNonSocketInfo(authority).prefixWith(": "))); } } else { ind = host.indexOf(':'); diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java new file mode 100644 index 00000000000..eb4286cd1af --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2018, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.util; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.UnixDomainSocketAddress; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import sun.security.util.SecurityProperties; +import jdk.internal.misc.VM; + +/** + * Contains static utility methods which can filter exception + * message strings for sensitive information. + * + * Code using this mechanism should use formatMsg() + * to generate a formatted (enhanced or restricted) string for exception + * messages. + * + * The methods above take variable numbers of SensitiveInfo objects + * as parameters which contain the text that may have to be filtered. + * + * The SensitiveInfo objects should be generated with one of the following: + * public static SensitiveInfo filterSocketInfo(String s) + * public static SensitiveInfo filterNonSocketInfo(String s) + * public static SensitiveInfo filterJarName(String name) + * public static SensitiveInfo filterUserName(String name) + */ +public final class Exceptions { + private Exceptions() {} + + private static volatile boolean enhancedSocketExceptionText; + private static volatile boolean enhancedNonSocketExceptionText; + private static volatile boolean enhancedUserExceptionText; + private static volatile boolean enhancedJarExceptionText; + private static volatile boolean initialized = false; + + /** + * Base class for generating exception messages that may + * contain sensitive information which in certain contexts + * needs to be filtered out, in case it gets revealed in + * unexpected places. Exception messages are either enhanced + * or restricted. Enhanced messages include sensitive information. + * Restricted messages don't. + * + * Sub-class for any new category that needs to be independently + * controlled. Consider using a unique value for the + * SecurityProperties.includedInExceptions(String value) mechanism + * Current values defined are "jar", "userInfo" + * "hostInfo", "hostInfoExclSocket". + * + * New code can also piggy back on existing categories + * + * A SensitiveInfo contains the following components + * all of which default to empty strings. + * + * prefix, the sensitive info itself, a suffix + * and a replacement string. + * + * The composeFilteredText(boolean enhance) method generates + * an enhanced string when enhance is true. + * This comprises (enhance == true) + * prefix + info + suffix + * When (enhance == false), then by default the output is: + * "" empty string + * However, if a replacement is set, then when enhance == false + * the output is the replacement string. + */ + public abstract static class SensitiveInfo { + String info, suffix, prefix, replacement; + boolean enhanced; + + SensitiveInfo(String info) { + this.info = info; + prefix = suffix = replacement = ""; + } + public SensitiveInfo prefixWith(String prefix) { + this.prefix = prefix; + return this; + } + public SensitiveInfo suffixWith(String suffix) { + this.suffix = suffix; + return this; + } + public SensitiveInfo replaceWith(String replacement) { + this.replacement = replacement; + return this; + } + + public boolean enhanced() { + return enhanced; + } + + /** + * Implementation should call composeFilteredText(boolean flag) + * where flag contains the boolean value of whether + * the category is enabled or not. + */ + public abstract String output(); + + protected String composeFilteredText(boolean enhance) { + if (enhance) { + this.enhanced = true; + return prefix + info + suffix; + } else { + return replacement; + } + } + } + + static final class SocketInfo extends SensitiveInfo { + public SocketInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.composeFilteredText(enhancedSocketExceptionText); + } + } + + static final class NonSocketInfo extends SensitiveInfo { + public NonSocketInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.composeFilteredText(enhancedNonSocketExceptionText); + } + } + + static final class JarInfo extends SensitiveInfo { + public JarInfo(String name) { + super(name); + } + @Override + public String output() { + setup(); + return super.composeFilteredText(enhancedJarExceptionText); + } + } + + static final class UserInfo extends SensitiveInfo { + public UserInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.composeFilteredText(enhancedUserExceptionText); + } + } + + // remove leading, trailing and duplicated space characters + static String trim(String s) { + int len = s.length(); + if (len == 0) return s; + + StringBuilder sb = new StringBuilder(); + + // initial value deals with leading spaces + boolean inSpace = true; + for (int i=0; i 0 && sb.charAt(sblen - 1) == ' ') + sb.deleteCharAt(sblen - 1); + return sb.toString(); + } + + public static SensitiveInfo filterSocketInfo(String host) { + return new SocketInfo(host); + } + + public static SensitiveInfo filterNonSocketInfo(String host) { + return new NonSocketInfo(host); + } + + public static SensitiveInfo filterJarName(String name) { + return new JarInfo(name); + } + + public static SensitiveInfo filterUserName(String name) { + return new UserInfo(name); + } + + /** + * Transform each SensitiveInfo into a String argument which is passed + * to String.format(). This string is then trimmed. + */ + public static String formatMsg(String format, SensitiveInfo... infos) { + String[] args = new String[infos.length]; + + int i = 0; + + for (SensitiveInfo info : infos) { + args[i++] = info.output(); + } + return trim(String.format(format, (Object[])args)); + } + + /** + * Simplification of above. Equivalent to: + * formatMsg("%s", SensitiveInfo[1]); // ie with one arg + */ + public static String formatMsg(SensitiveInfo info) { + return trim(info.output()); + } + + public static void setup() { + if (initialized || !VM.isBooted()) + return; + enhancedSocketExceptionText = SecurityProperties.includedInExceptions("hostInfo"); + enhancedNonSocketExceptionText = SecurityProperties.includedInExceptions("hostInfoExclSocket") + | enhancedSocketExceptionText; + + enhancedUserExceptionText = SecurityProperties.includedInExceptions("userInfo"); + enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; + initialized = true; + } + + public static boolean enhancedNonSocketExceptions() { + setup(); + return enhancedNonSocketExceptionText; + } + + public static boolean enhancedSocketExceptions() { + setup(); + return enhancedSocketExceptionText; + } + + /** + * The enhanced message text is the socket address appended to + * the original IOException message + */ + public static IOException ioException(IOException e, SocketAddress addr) { + setup(); + if (addr == null) { + return e; + } + if (!enhancedSocketExceptionText) { + return create(e, e.getMessage()); + } + if (addr instanceof UnixDomainSocketAddress) { + return ofUnixDomain(e, (UnixDomainSocketAddress)addr); + } else if (addr instanceof InetSocketAddress) { + return ofInet(e, (InetSocketAddress)addr); + } else { + return e; + } + } + + private static IOException ofInet(IOException e, InetSocketAddress addr) { + return create(e, String.join(": ", e.getMessage(), addr.toString())); + } + + private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress addr) { + String path = addr.getPath().toString(); + StringBuilder sb = new StringBuilder(); + sb.append(e.getMessage()); + sb.append(": "); + sb.append(path); + String enhancedMsg = sb.toString(); + return create(e, enhancedMsg); + } + + // return a new instance of the same type with the given detail + // msg, or if the type doesn't support detail msgs, return given + // instance. + private static T create(T e, String msg) { + try { + Class clazz = e.getClass(); + @SuppressWarnings("unchecked") + Constructor ctor = (Constructor)clazz.getConstructor(String.class); + T e1 = (ctor.newInstance(msg)); + e1.setStackTrace(e.getStackTrace()); + return e1; + } catch (Exception e0) { + // Some eg AsynchronousCloseException have no detail msg + return e; + } + } +} diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index bbcdfef65ec..07de3f2c57f 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -270,9 +270,13 @@ module java.base { java.prefs, java.security.jgss, java.smartcardio, + java.naming, + java.rmi, + java.net.http, jdk.charsets, jdk.incubator.vector, jdk.internal.vm.ci, + jdk.httpserver, jdk.jlink, jdk.jpackage, jdk.net; diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index b3da295c4a7..21bbc5ac455 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -37,6 +37,9 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; + public class IPAddressUtil { private static final int INADDR4SZ = 4; private static final int INADDR16SZ = 16; @@ -161,7 +164,8 @@ public class IPAddressUtil { * @return an {@code IllegalArgumentException} instance */ public static IllegalArgumentException invalidIpAddressLiteral(String src) { - return new IllegalArgumentException("Invalid IP address literal: " + src); + return new IllegalArgumentException( + formatMsg("Invalid IP address literal%s", filterNonSocketInfo(src).prefixWith(": "))); } /* diff --git a/src/java.base/share/classes/sun/net/util/SocketExceptions.java b/src/java.base/share/classes/sun/net/util/SocketExceptions.java deleted file mode 100644 index 1198898edcb..00000000000 --- a/src/java.base/share/classes/sun/net/util/SocketExceptions.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.net.util; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.net.InetSocketAddress; -import java.net.UnixDomainSocketAddress; -import java.net.SocketAddress; - -import sun.security.util.SecurityProperties; - -public final class SocketExceptions { - private SocketExceptions() {} - - private static final boolean enhancedExceptionText = - SecurityProperties.includedInExceptions("hostInfo"); - - /** - * Utility which takes an exception and returns either the same exception - * or a new exception of the same type with the same stack trace - * and detail message enhanced with addressing information from the - * given InetSocketAddress. - * - * If the system/security property "jdk.includeInExceptions" is not - * set or does not contain the category hostInfo, - * then the original exception is returned. - * - * Only specific IOException subtypes are supported. - */ - public static IOException of(IOException e, SocketAddress addr) { - if (!enhancedExceptionText || addr == null) { - return e; - } - if (addr instanceof UnixDomainSocketAddress) { - return ofUnixDomain(e, (UnixDomainSocketAddress)addr); - } else if (addr instanceof InetSocketAddress) { - return ofInet(e, (InetSocketAddress)addr); - } else { - return e; - } - } - - private static IOException ofInet(IOException e, InetSocketAddress addr) { - return create(e, String.join(": ", e.getMessage(), addr.toString())); - } - - private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress addr) { - String path = addr.getPath().toString(); - StringBuilder sb = new StringBuilder(); - sb.append(e.getMessage()); - sb.append(": "); - sb.append(path); - String enhancedMsg = sb.toString(); - return create(e, enhancedMsg); - } - - // return a new instance of the same type with the given detail - // msg, or if the type doesn't support detail msgs, return given - // instance. - private static IOException create(final IOException e, final String msg) { - try { - Class clazz = e.getClass(); - Constructor ctor = clazz.getConstructor(String.class); - IOException e1 = (IOException)(ctor.newInstance(msg)); - e1.setStackTrace(e.getStackTrace()); - return e1; - } catch (Exception e0) { - // Some eg AsynchronousCloseException have no detail msg - return e; - } - } -} diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index 51d1b8398b6..cac32e53288 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -40,6 +40,8 @@ import java.nio.charset.CodingErrorAction; import java.util.HexFormat; import sun.nio.cs.UTF_8; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * A class that contains useful routines common to sun.net.www @@ -502,7 +504,7 @@ public final class ParseUtil { { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(s, + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(s)), "Relative path in absolute URI"); } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index fb2dfe6fff3..2f011f5805b 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -53,7 +53,8 @@ import sun.security.ssl.SSLSocketImpl; import sun.util.logging.PlatformLogger; import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; - +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class provides HTTPS client URL support, building on the standard @@ -559,8 +560,10 @@ final class HttpsClient extends HttpClient serverSocket.close(); session.invalidate(); - throw new IOException("HTTPS hostname wrong: should be <" - + url.getHost() + ">"); + throw new IOException(formatMsg("Wrong HTTPS hostname%s", + filterNonSocketInfo(url.getHost()) + .prefixWith(": should be <") + .suffixWith(">"))); } @Override diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java index 2884f825b84..381d4244238 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, 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 @@ -27,6 +27,8 @@ package sun.net.www.protocol.jar; import java.io.IOException; import java.net.*; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.formatMsg; /* * Jar URL Handler @@ -181,8 +183,11 @@ public class Handler extends java.net.URLStreamHandler { String innerSpec = spec.substring(0, index - 1); newURL(innerSpec); } catch (MalformedURLException e) { - throw new NullPointerException("invalid url: " + - spec + " (" + e + ")"); + throw new NullPointerException( + formatMsg("invalid url: %s %s", filterJarName(spec), + filterJarName(e.getMessage()) + .prefixWith("(") + .suffixWith(")"))); } return spec; } @@ -193,19 +198,18 @@ public class Handler extends java.net.URLStreamHandler { if (spec.startsWith("/")) { int bangSlash = indexOfBangSlash(ctxFile); if (bangSlash == -1) { - throw new NullPointerException("malformed " + - "context url:" + - url + - ": no !/"); + throw new NullPointerException( + formatMsg("malformed context url%s : no !/", + filterJarName(String.valueOf(url)).prefixWith(": "))); } ctxFile = ctxFile.substring(0, bangSlash); } else { // chop up the last component int lastSlash = ctxFile.lastIndexOf('/'); if (lastSlash == -1) { - throw new NullPointerException("malformed " + - "context url:" + - url); + throw new NullPointerException( + formatMsg("malformed context url%s", + filterJarName(String.valueOf(url)).prefixWith(": "))); } else if (lastSlash < ctxFile.length() - 1) { ctxFile = ctxFile.substring(0, lastSlash + 1); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java index 4d695c8d4e8..741854349d7 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -35,6 +35,8 @@ import java.util.jar.JarFile; import jdk.internal.util.OperatingSystem; import sun.net.util.URLUtil; import sun.net.www.ParseUtil; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.formatMsg; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -108,7 +110,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { result = URLJarFile.getJarFile(patched, this); } if (result == null) - throw new FileNotFoundException(url.toString()); + throw new FileNotFoundException(formatMsg("%s", filterJarName(url.toString()))); return result; } @@ -200,7 +202,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { result = URLJarFile.getJarFile(url, this); } if (result == null) - throw new FileNotFoundException(url.toString()); + throw new FileNotFoundException(formatMsg("%s", filterJarName(url.toString()))); return result; } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 3a346308f71..96c04132551 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -37,6 +37,9 @@ import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.formatMsg; + /** * @author Benjamin Renaud @@ -129,9 +132,10 @@ public class JarURLConnection extends java.net.JarURLConnection { factory.closeIfNotCached(url, jarFile); } catch (Exception e) { } - throw new FileNotFoundException("JAR entry " + entryName + - " not found in " + - jarFile.getName()); + throw new FileNotFoundException( + formatMsg("JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName()))); } } @@ -169,9 +173,10 @@ public class JarURLConnection extends java.net.JarURLConnection { throw new IOException("no entry name specified"); } else { if (jarEntry == null) { - throw new FileNotFoundException("JAR entry " + entryName + - " not found in " + - jarFile.getName()); + throw new FileNotFoundException( + formatMsg("JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName()))); } result = new JarURLInputStream (jarFile.getInputStream(jarEntry)); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java index 95bc2179a31..51a88cb229d 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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 diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index 4930e1447a3..44b05f97472 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -53,6 +53,8 @@ import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; /** * A multicast datagram socket based on a datagram channel. @@ -490,7 +492,8 @@ public class DatagramSocketAdaptor NetworkInterface ni = NetworkInterface.getByInetAddress(inf); if (ni == null) { String address = inf.getHostAddress(); - throw new SocketException("No network interface with address " + address); + throw new SocketException(formatMsg("No network interface found with address %s", + filterNonSocketInfo(address))); } synchronized (outgoingInterfaceLock) { // set interface and update cached values diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index b3939f2ca05..6705134648d 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -58,10 +58,12 @@ import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.PlatformSocketImpl; import sun.net.ext.ExtendedSocketOptions; -import sun.net.util.SocketExceptions; +import jdk.internal.util.Exceptions; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * NIO based SocketImpl. @@ -554,7 +556,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp throw new IOException("Unsupported address type"); InetSocketAddress isa = (InetSocketAddress) remote; if (isa.isUnresolved()) { - throw new UnknownHostException(isa.getHostName()); + throw new UnknownHostException( + formatMsg(filterNonSocketInfo(isa.getHostName()))); } InetAddress address = isa.getAddress(); @@ -604,7 +607,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp assert Thread.currentThread().isVirtual(); throw new SocketException("Closed by interrupt"); } else { - throw SocketExceptions.of(ioe, isa); + throw Exceptions.ioException(ioe, isa); } } } diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index d8ed1cfb675..bf777ed23e4 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -40,6 +40,9 @@ import java.nio.channels.SocketChannel; import java.util.Set; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; + // Make a socket channel look like a socket. // @@ -92,7 +95,8 @@ class SocketAdaptor if (sc.isConnected()) throw new SocketException("Already connected"); close(); - throw new UnknownHostException(remote.toString()); + throw new UnknownHostException( + formatMsg(filterNonSocketInfo(remote.toString()))); } if (timeout < 0) throw new IllegalArgumentException("connect: timeout can't be negative"); diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index 0980592abab..c1241a51f85 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -64,7 +64,7 @@ import jdk.internal.event.SocketWriteEvent; import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.ext.ExtendedSocketOptions; -import sun.net.util.SocketExceptions; +import jdk.internal.util.Exceptions; /** * An implementation of SocketChannels @@ -975,7 +975,7 @@ class SocketChannelImpl } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, sa); + throw Exceptions.ioException(ioe, sa); } } @@ -1065,7 +1065,7 @@ class SocketChannelImpl } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, remoteAddress); + throw Exceptions.ioException(ioe, remoteAddress); } } @@ -1313,7 +1313,7 @@ class SocketChannelImpl } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, sa); + throw Exceptions.ioException(ioe, sa); } } diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index b750c1b82b0..61e8aaaf6d1 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1277,8 +1277,13 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # Enhanced exception message information # -# By default, exception messages should not include potentially sensitive -# information such as file names, host names, or port numbers. This property +# Exception messages may include potentially sensitive information such as file +# names, host names, or port numbers. By default, socket related exceptions +# have this information restricted (meaning the sensitive details are removed). +# Exception messages relating to JAR files and exceptions containing user +# identity information are also restricted by default. +# This property can be used to relax this restriction or to place further +# restrictions on other categories, defined below. The property # accepts one or more comma separated values, each of which represents a # category of enhanced exception message information to enable. Values are # case-insensitive. Leading and trailing whitespaces, surrounding each value, @@ -1291,17 +1296,28 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # The categories are: # -# hostInfo - IOExceptions thrown by java.net.Socket and the socket types in the -# java.nio.channels package will contain enhanced exception -# message information +# hostInfo - All networking related exceptions will contain enhanced +# exception message information. +# +# hostInfoExclSocket - The hostInfo category defined above, excluding +# IOExceptions thrown by java.net.Socket and the NetworkChannel +# types in the java.nio.channels package, will contain enhanced +# exception message information # # jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package # +# userInfo - enables more detailed information in exceptions which may contain +# user identity information +# # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # -#jdk.includeInExceptions=hostInfo,jar +# If the property is not set or set to an empty string, then this is the most +# restricted setting with all categories disabled. The following is the default +# (out of the box) setting, meaning these categories are not restricted. +# +jdk.includeInExceptions=hostInfoExclSocket # # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) @@ -1557,4 +1573,4 @@ jdk.tls.alpnCharset=ISO_8859_1 # java.security.PEMEncoder when configured for encryption with the # withEncryption method. # -jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128 \ No newline at end of file +jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128 diff --git a/src/java.base/share/native/libnet/net_util.c b/src/java.base/share/native/libnet/net_util.c index a198152563a..9c0f14b0d90 100644 --- a/src/java.base/share/native/libnet/net_util.c +++ b/src/java.base/share/native/libnet/net_util.c @@ -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 @@ -86,9 +86,36 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved) /* check if SO_REUSEPORT is supported on this platform */ REUSEPORT_available = reuseport_supported(IPv6_available); + return JNI_VERSION_1_2; } +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; \ + } + +int getEnhancedExceptionsAllowed(JNIEnv *env) { + jclass cls; + jfieldID fid; + + if (enhancedExceptionsInitialized) { + return enhancedExceptionsAllowed; + } + cls = (*env)->FindClass(env, "jdk/internal/util/Exceptions"); + CHECK_NULL_THROW_ERROR(cls); + fid = (*env)->GetStaticFieldID(env, cls, "enhancedNonSocketExceptionText", "Z"); + CHECK_NULL_THROW_ERROR(fid); + enhancedExceptionsAllowed = (*env)->GetStaticBooleanField(env, cls, fid); + enhancedExceptionsInitialized = 1; + return enhancedExceptionsAllowed; +} + static int initialized = 0; JNIEXPORT void JNICALL initInetAddressIDs(JNIEnv *env) { diff --git a/src/java.base/share/native/libnet/net_util.h b/src/java.base/share/native/libnet/net_util.h index a1fa9571821..89537a7f47d 100644 --- a/src/java.base/share/native/libnet/net_util.h +++ b/src/java.base/share/native/libnet/net_util.h @@ -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 @@ -183,4 +183,6 @@ int lookupCharacteristicsToAddressFamily(int characteristics); int addressesInSystemOrder(int characteristics); +int getEnhancedExceptionsAllowed(JNIEnv *env); + #endif /* NET_UTILS_H */ diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java index b9c099ef92f..5e75e3b2486 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -32,9 +32,10 @@ import java.util.concurrent.*; import java.io.IOException; import java.io.FileDescriptor; +import jdk.internal.util.Exceptions; + import sun.net.ConnectionResetException; import sun.net.NetHooks; -import sun.net.util.SocketExceptions; /** * Unix implementation of AsynchronousSocketChannel @@ -264,7 +265,7 @@ class UnixAsynchronousSocketChannelImpl if (e != null) { if (e instanceof IOException) { var isa = (InetSocketAddress)pendingRemote; - e = SocketExceptions.of((IOException)e, isa); + e = Exceptions.ioException((IOException)e, isa); } // close channel if connection cannot be established try { @@ -355,7 +356,7 @@ class UnixAsynchronousSocketChannelImpl // close channel if connect fails if (e != null) { if (e instanceof IOException) { - e = SocketExceptions.of((IOException)e, isa); + e = Exceptions.ioException((IOException)e, isa); } try { close(); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java index f50dea108b0..b1e7b7cbcc4 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -29,6 +29,9 @@ import java.nio.file.attribute.*; import java.io.IOException; import static sun.nio.fs.UnixNativeDispatcher.*; +import static jdk.internal.util.Exceptions.filterUserName; +import static jdk.internal.util.Exceptions.formatMsg; + /** * Unix implementation of java.nio.file.attribute.UserPrincipal */ @@ -132,18 +135,19 @@ public class UnixUserPrincipals { private static int lookupName(String name, boolean isGroup) throws IOException { - int id; + int id = -1; try { id = (isGroup) ? getgrnam(name) : getpwnam(name); } catch (UnixException x) { - throw new IOException(name + ": " + x.errorString()); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } if (id == -1) { // lookup failed, allow input to be uid or gid try { id = Integer.parseInt(name); } catch (NumberFormatException ignore) { - throw new UserPrincipalNotFoundException(name); + throw new UserPrincipalNotFoundException(formatMsg("%s", filterUserName(name))); } } return id; diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 1713d0a8ccd..d50130d188b 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -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 @@ -184,23 +184,36 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, { int size; char *buf; - const char *format = "%s: %s"; const char *error_string = gai_strerror(gai_error); if (error_string == NULL) error_string = "unknown error"; + int enhancedExceptions = getEnhancedExceptionsAllowed(env); + + if (enhancedExceptions) { + size = strlen(hostname); + } else { + size = 0; + } + size += strlen(error_string) + 3; - size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; buf = (char *) malloc(size); if (buf) { jstring s; - snprintf(buf, size, format, hostname, error_string); - s = JNU_NewStringPlatform(env, buf); - if (s != NULL) { - jobject x = JNU_NewObjectByName(env, + int n; + if (enhancedExceptions) { + n = snprintf(buf, size, "%s: %s", hostname, error_string); + } else { + n = snprintf(buf, size, " %s", error_string); + } + if (n >= 0) { + s = JNU_NewStringPlatform(env, buf); + if (s != NULL) { + jobject x = JNU_NewObjectByName(env, "java/net/UnknownHostException", "(Ljava/lang/String;)V", s); - if (x != NULL) - (*env)->Throw(env, x); + if (x != NULL) + (*env)->Throw(env, x); + } } free(buf); } diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java index f8b5fab4316..36065f040a0 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,9 +33,9 @@ import java.nio.BufferOverflowException; import java.net.*; import java.util.concurrent.*; import java.io.IOException; +import jdk.internal.util.Exceptions; import jdk.internal.invoke.MhUtil; import jdk.internal.misc.Unsafe; -import sun.net.util.SocketExceptions; /** * Windows implementation of AsynchronousSocketChannel using overlapped I/O. @@ -253,7 +253,7 @@ class WindowsAsynchronousSocketChannelImpl if (exc != null) { closeChannel(); - exc = SocketExceptions.of(toIOException(exc), remote); + exc = Exceptions.ioException(toIOException(exc), remote); result.setFailure(exc); } Invoker.invoke(result); @@ -280,7 +280,7 @@ class WindowsAsynchronousSocketChannelImpl if (exc != null) { closeChannel(); IOException ee = toIOException(exc); - ee = SocketExceptions.of(ee, remote); + ee = Exceptions.ioException(ee, remote); result.setFailure(ee); } @@ -296,12 +296,12 @@ class WindowsAsynchronousSocketChannelImpl */ @Override public void failed(int error, IOException x) { - x = SocketExceptions.of(x, remote); + x = Exceptions.ioException(x, remote); if (isOpen()) { closeChannel(); result.setFailure(x); } else { - x = SocketExceptions.of(new AsynchronousCloseException(), remote); + x = Exceptions.ioException(new AsynchronousCloseException(), remote); result.setFailure(x); } Invoker.invoke(result); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java index da3460592f4..8c3dfa5546e 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,6 +33,8 @@ import jdk.internal.misc.Unsafe; import static sun.nio.fs.WindowsNativeDispatcher.*; import static sun.nio.fs.WindowsConstants.*; +import static jdk.internal.util.Exceptions.filterUserName; +import static jdk.internal.util.Exceptions.formatMsg; /** * A SecurityDescriptor for use when setting a file's ACL or creating a file @@ -136,8 +138,8 @@ class WindowsSecurityDescriptor { Math.max(SIZEOF_ACCESS_ALLOWED_ACE, SIZEOF_ACCESS_DENIED_ACE); } catch (WindowsException x) { - throw new IOException("Failed to get SID for " + user.getName() - + ": " + x.errorString()); + throw new IOException(formatMsg("Failed to get SID %s : " + x.errorString(), + filterUserName(user.getName()).prefixWith("for "))); } } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java index 336bbe22cfb..0a4e2b9c9fa 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -29,6 +29,8 @@ import java.io.IOException; import static sun.nio.fs.WindowsConstants.*; import static sun.nio.fs.WindowsNativeDispatcher.*; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterUserName; class WindowsUserPrincipals { private WindowsUserPrincipals() { } @@ -132,13 +134,14 @@ class WindowsUserPrincipals { static UserPrincipal lookup(String name) throws IOException { // invoke LookupAccountName to get buffer size needed for SID - int size; + int size = 0; try { size = LookupAccountName(name, 0L, 0); } catch (WindowsException x) { if (x.lastError() == ERROR_NONE_MAPPED) throw new UserPrincipalNotFoundException(name); - throw new IOException(name + ": " + x.errorString()); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } assert size > 0; @@ -153,7 +156,8 @@ class WindowsUserPrincipals { // return user principal return fromSid(sidBuffer.address()); } catch (WindowsException x) { - throw new IOException(name + ": " + x.errorString()); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } } } diff --git a/src/java.base/windows/native/libnet/Inet4AddressImpl.c b/src/java.base/windows/native/libnet/Inet4AddressImpl.c index 0e2d6a3455f..0ef0cae5be7 100644 --- a/src/java.base/windows/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet4AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -88,8 +88,9 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { // report error - NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException", - hostname); + NET_ThrowByNameWithLastError( + env, "java/net/UnknownHostException", + getEnhancedExceptionsAllowed(env) ? hostname : ""); goto cleanupAndReturn; } else { int i = 0; diff --git a/src/java.base/windows/native/libnet/Inet6AddressImpl.c b/src/java.base/windows/native/libnet/Inet6AddressImpl.c index 244e2fefa9b..0281e2ddecb 100644 --- a/src/java.base/windows/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet6AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -84,7 +84,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { // report error NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException", - hostname); + getEnhancedExceptionsAllowed(env) ? hostname : ""); goto cleanupAndReturn; } else { int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0, diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index 140f025b779..d9319818801 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java @@ -33,6 +33,8 @@ import java.util.Locale; import java.util.StringTokenizer; import com.sun.jndi.toolkit.url.Uri; import com.sun.jndi.toolkit.url.UrlUtil; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /* * Extract components of an LDAP URL. @@ -119,7 +121,8 @@ public final class LdapURL extends Uri { @Override protected MalformedURLException newInvalidURISchemeException(String uri) { - return new MalformedURLException("Not an LDAP URL: " + uri); + return new MalformedURLException(formatMsg("Not an LDAP URL%s", + filterNonSocketInfo(uri).prefixWith(": "))); } @Override diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index 10316b1ca69..a4db62868b0 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java @@ -29,6 +29,8 @@ package com.sun.jndi.toolkit.url; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** @@ -232,6 +234,12 @@ public class Uri { } } + private MalformedURLException newMalformedURLException(String prefix, String msg) { + return new MalformedURLException(prefix + + formatMsg(filterNonSocketInfo(msg) + .prefixWith(prefix.isEmpty()? "" : ": "))); + } + /* * Parses a URI string and sets this object's fields accordingly. * Use java.net.URI to validate the uri string syntax @@ -241,7 +249,7 @@ public class Uri { if (!isSchemeOnly(uri)) { URI u = new URI(uri); scheme = u.getScheme(); - if (scheme == null) throw new MalformedURLException("Invalid URI: " + uri); + if (scheme == null) throw newMalformedURLException("Invalid URI", uri); var auth = u.getRawAuthority(); hasAuthority = auth != null; if (hasAuthority) { @@ -253,7 +261,7 @@ public class Uri { + (port == -1 ? "" : (":" + port)); if (!hostport.equals(auth)) { // throw if we have user info or regname - throw new MalformedURLException("unsupported authority: " + auth); + throw newMalformedURLException("unsupported authority", auth); } } path = u.getRawPath(); @@ -262,7 +270,7 @@ public class Uri { } if (u.getRawFragment() != null) { if (!acceptsFragment()) { - throw new MalformedURLException("URI fragments not supported: " + uri); + throw newMalformedURLException("URI fragments not supported", uri); } fragment = "#" + u.getRawFragment(); } @@ -279,7 +287,7 @@ public class Uri { path = ""; } } catch (URISyntaxException e) { - var mue = new MalformedURLException(e.getMessage()); + var mue = newMalformedURLException("", e.getMessage()); mue.initCause(e); throw mue; } @@ -299,11 +307,11 @@ public class Uri { int qmark = uri.indexOf('?'); int fmark = uri.indexOf('#'); if (i < 0 || slash > 0 && i > slash || qmark > 0 && i > qmark || fmark > 0 && i > fmark) { - throw new MalformedURLException("Invalid URI: " + uri); + throw newMalformedURLException("Invalid URI", uri); } if (fmark > -1) { if (!acceptsFragment()) { - throw new MalformedURLException("URI fragments not supported: " + uri); + throw newMalformedURLException("URI fragments not supported", uri); } } if (i == uri.length() - 1) { @@ -349,26 +357,26 @@ public class Uri { String f = u.getRawFragment(); String ui = u.getRawUserInfo(); if (ui != null) { - throw new MalformedURLException("user info not supported in authority: " + ui); + throw newMalformedURLException("user info not supported in authority", ui); } if (!"/".equals(p)) { - throw new MalformedURLException("invalid authority: " + auth); + throw newMalformedURLException("invalid authority", auth); } if (q != null) { - throw new MalformedURLException("invalid trailing characters in authority: ?" + q); + throw newMalformedURLException("invalid trailing characters in authority '?'", "?" + q); } if (f != null) { - throw new MalformedURLException("invalid trailing characters in authority: #" + f); + throw newMalformedURLException("invalid trailing characters in authority: '#'", "#" + f); } String hostport = (host == null ? "" : host) + (port == -1?"":(":" + port)); if (!auth.equals(hostport)) { // throw if we have user info or regname - throw new MalformedURLException("Authority component is not server-based, " + - "or contains user info. Unsupported authority: " + auth); + throw newMalformedURLException("Authority component is not server-based, " + + "or contains user info. Unsupported authority", auth); } } catch (URISyntaxException e) { - var mue = new MalformedURLException(e.getMessage()); + var mue = newMalformedURLException("", e.getMessage()); mue.initCause(e); throw mue; } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java index e4dee55d8ea..a495fcce1ee 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ import static java.util.Objects.requireNonNull; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.isValidValue; import static jdk.internal.net.http.common.Utils.newIAE; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; public class HttpRequestBuilderImpl implements HttpRequest.Builder { @@ -82,7 +84,8 @@ public class HttpRequestBuilderImpl implements HttpRequest.Builder { throw newIAE("invalid URI scheme %s", scheme); } if (uri.getHost() == null) { - throw newIAE("unsupported URI %s", uri); + throw new IllegalArgumentException( + formatMsg("unsupported URI %s", filterNonSocketInfo(uri.toString()))); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index 79b2332ae37..a74c632c218 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -46,6 +46,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import jdk.internal.net.http.ResponseSubscribers.PathSubscriber; +import jdk.internal.util.Exceptions; import static java.util.regex.Pattern.CASE_INSENSITIVE; public final class ResponseBodyHandlers { @@ -190,7 +191,12 @@ public final class ResponseBodyHandlers { static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { - String s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); + String s; + if (Exceptions.enhancedNonSocketExceptions()) { + s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); + } else { + s = String.format("%s in response [%d]", msg, rinfo.statusCode()); + } return new UncheckedIOException(new IOException(s)); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index c1c0853504c..6e76a272cd0 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,6 +61,8 @@ import java.util.concurrent.CompletableFuture; import static java.lang.String.format; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.stringOf; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; public class OpeningHandshake { @@ -336,9 +338,13 @@ public class OpeningHandshake { if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) throw illegal("invalid URI scheme: " + scheme); if (uri.getHost() == null) - throw illegal("URI must contain a host: " + uri); + throw new IllegalArgumentException( + formatMsg("URI must contain a host%s", + filterNonSocketInfo(uri.toString()).prefixWith(": "))); if (uri.getFragment() != null) - throw illegal("URI must not contain a fragment: " + uri); + throw new IllegalArgumentException( + formatMsg("URI must not contain a fragment%s", + filterNonSocketInfo(uri.toString()).prefixWith(": "))); return uri; } diff --git a/src/java.rmi/share/classes/java/rmi/Naming.java b/src/java.rmi/share/classes/java/rmi/Naming.java index c4677991770..cb8766564a9 100644 --- a/src/java.rmi/share/classes/java/rmi/Naming.java +++ b/src/java.rmi/share/classes/java/rmi/Naming.java @@ -28,6 +28,8 @@ import java.rmi.registry.*; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * The Naming class provides methods for storing and obtaining @@ -221,6 +223,11 @@ public final class Naming { return LocateRegistry.getRegistry(parsed.host, parsed.port); } + private static MalformedURLException newMalformedURLException(String prefix, String msg) { + return new MalformedURLException( + prefix + formatMsg(filterNonSocketInfo(msg).prefixWith(": "))); + } + /** * Dissect Naming URL strings to obtain referenced host, port and * object name. @@ -240,8 +247,8 @@ public final class Naming { * '//:' forms will result in a URI syntax exception * Convert the authority to a localhost: form */ - MalformedURLException mue = new MalformedURLException( - "invalid URL String: " + str); + MalformedURLException mue = newMalformedURLException( + "invalid URL String", str); mue.initCause(ex); int indexSchemeEnd = str.indexOf(':'); int indexAuthorityBegin = str.indexOf("//:"); @@ -272,22 +279,22 @@ public final class Naming { { URI uri = new URI(str); if (uri.isOpaque()) { - throw new MalformedURLException( - "not a hierarchical URL: " + str); + throw newMalformedURLException( + "not a hierarchical URL", str); } if (uri.getFragment() != null) { - throw new MalformedURLException( - "invalid character, '#', in URL name: " + str); + throw newMalformedURLException( + "invalid character, '#', in URL name", str); } else if (uri.getQuery() != null) { - throw new MalformedURLException( - "invalid character, '?', in URL name: " + str); + throw newMalformedURLException( + "invalid character, '?', in URL name", str); } else if (uri.getUserInfo() != null) { - throw new MalformedURLException( - "invalid character, '@', in URL host: " + str); + throw newMalformedURLException( + "invalid character, '@', in URL host", str); } String scheme = uri.getScheme(); if (scheme != null && !scheme.equals("rmi")) { - throw new MalformedURLException("invalid URL scheme: " + str); + throw newMalformedURLException("invalid URL scheme", str); } String name = uri.getPath(); diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java index c97162ef9bd..d6a42d366c8 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java @@ -35,6 +35,8 @@ public class JWebServer { private static final String SYS_PROP_MAX_CONNECTIONS = "jdk.httpserver.maxConnections"; private static final String DEFAULT_JWEBSERVER_MAX_CONNECTIONS = "200"; + private static final String SYS_PROP_ENHANCED_EXCEP = "jdk.includeInExceptions"; + private static final String DEFAULT_ENHANCED_EXCEP = "net"; /** * This constructor should never be called. */ @@ -61,6 +63,7 @@ public class JWebServer { */ public static void main(String... args) { setMaxReqTime(); + setEnhancedExceptions(); setMaxConnectionsIfNotSet(); int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true), "jwebserver", args); @@ -80,6 +83,14 @@ public class JWebServer { } } + static void setEnhancedExceptions() { + if (System.getProperty(SYS_PROP_ENHANCED_EXCEP) != null) { + // an explicit value has already been set, so we don't override it + return; + } + System.setProperty(SYS_PROP_ENHANCED_EXCEP, DEFAULT_ENHANCED_EXCEP); + } + static void setMaxConnectionsIfNotSet() { if (System.getProperty(SYS_PROP_MAX_CONNECTIONS) == null) { System.setProperty(SYS_PROP_MAX_CONNECTIONS, DEFAULT_JWEBSERVER_MAX_CONNECTIONS); diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java index 5a16bedc29d..a82b0bf5a6f 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java @@ -226,7 +226,11 @@ public class CommandLineNegativeTest { } static OutputAnalyzer simpleserver(String... args) throws Throwable { - var pb = new ProcessBuilder(args) + String[] nargs = new String[args.length + 1]; + nargs[0] = args[0]; + System.arraycopy(args, 1, nargs, 2, args.length-1); + nargs[1] = "-Djdk.includeInExceptions=hostInfo"; + var pb = new ProcessBuilder(nargs) .directory(TEST_DIR.toFile()); var outputAnalyser = ProcessTools.executeCommand(pb) .outputTo(System.out) diff --git a/test/jdk/java/net/URI/Test.java b/test/jdk/java/net/URI/Test.java index 95dd49ea34f..57da0ac3607 100644 --- a/test/jdk/java/net/URI/Test.java +++ b/test/jdk/java/net/URI/Test.java @@ -26,6 +26,7 @@ * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 8353013 * @author Mark Reinhold + * @run main/othervm Test */ import java.io.ByteArrayInputStream; diff --git a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java index 353309c1654..011fc6bbaf4 100644 --- a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java +++ b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java @@ -28,7 +28,7 @@ import java.security.Security; * @bug 8207846 8208691 * @summary Test the default setting of the jdk.net.includeInExceptions * security property - * @comment In OpenJDK, this property is empty by default and on purpose. + * @comment In OpenJDK, this property has value "hostInfoExclSocket" by default * This test assures the default is not changed. * @run main TestJDKIncludeInExceptions */ @@ -36,9 +36,9 @@ public class TestJDKIncludeInExceptions { public static void main(String args[]) throws Exception { String incInExc = Security.getProperty("jdk.includeInExceptions"); - if (incInExc != null) { + if (incInExc == null || !incInExc.equals("hostInfoExclSocket")) { throw new RuntimeException("Test failed: default value of " + - "jdk.includeInExceptions security property is not null: " + + "jdk.includeInExceptions security property does not have expected value: " + incInExc); } } diff --git a/test/jdk/sun/net/util/ExceptionsTest.java b/test/jdk/sun/net/util/ExceptionsTest.java new file mode 100644 index 00000000000..d6717763afb --- /dev/null +++ b/test/jdk/sun/net/util/ExceptionsTest.java @@ -0,0 +1,172 @@ +/* + * 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. + */ +import java.io.IOException; +import java.net.InetAddress; +import java.util.Arrays; +import jdk.internal.util.Exceptions; +import jdk.internal.util.Exceptions.SensitiveInfo; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.enhancedNonSocketExceptions; + +/* + * @test + * @bug 8348986 + * @summary Improve coverage of enhanced exception messages + * @modules java.base/jdk.internal.util + * @run main/othervm -Djdk.includeInExceptions=hostInfo ExceptionsTest + * @run main/othervm ExceptionsTest + * @run main/othervm -Djdk.includeInExceptions=userInfo ExceptionsTest + * @run main/othervm -Djdk.net.hosts.file=does.not.exist -Djdk.includeInExceptions=userInfo ExceptionsTest + * @run main/othervm -Djdk.net.hosts.file=does.not.exist -Djdk.includeInExceptions=hostInfo ExceptionsTest + */ +public class ExceptionsTest { + + static boolean netEnabled() { + System.out.printf("netEnabled = %b\n", enhancedNonSocketExceptions()); + return enhancedNonSocketExceptions(); + } + + static boolean dnsEnabled() { + System.out.printf("dnsEnabled = %b\n", enhancedNonSocketExceptions()); + return enhancedNonSocketExceptions(); + } + + static boolean hostFileEnabled() { + return System.getProperty("jdk.net.hosts.file", "").length() > 0; + } + + static String[][][] tests = { + // + // If a format argument is of the form ".pre(xxx)" or ".suf(yyy)", then that is + // interpreted as a .prefixWith("xxx") or .suffixWith("yyy") call to the preceding + // argument. .rep() signifies .replaceWith() + // + // Number of elements in array + // --------------------------- + // 1 N 2 + // + // Format string args to format Enhanced o/p non-enhanced o/p + // + /* 1 */ {{"foo: %s bar"}, {"abc"}, {"foo: abc bar", "foo: bar"}}, + /* 2 */ {{"foo: %s bar"}, {"a", "b"}, {"foo: a bar", "foo: bar"}}, + /* 3 */ {{"foo: %s bar"}, {null}, {"foo: null bar", "foo: bar"}}, + /* 4 */ {{"foo: %s bar"}, {""}, {"foo: bar", "foo: bar"}}, + /* 5 */ {{"%s foo: %s bar"}, {"a", "b"}, {"a foo: b bar", "foo: bar"}}, + /* 6 */ {{"foo: %s bar %s"}, {"a", "b"}, {"foo: a bar b", "foo: bar"}}, + /* 7 */ {{"foo: %s bar %s"}, {"abc", "def"}, {"foo: abc bar def", "foo: bar"}}, + /* 8 */ {{"%s bar %s"}, {"abc", ".pre(foo: )", "def"}, {"foo: abc bar def", "bar"}}, + /* 9 */ {{"%s baz"}, {"abc", ".suf(: bar)"}, {"abc: bar baz", "baz"}}, + /* 10 */ {{"%s baz"}, {"abc", ".suf(: bar)" + , ".rep(bob)"}, {"abc: bar baz", "bob baz"}} + }; + + + static void dnsTest() { + String host = "fub.z.a.bar.foo"; + try { + var addr = InetAddress.getByName(host); + } catch (IOException e) { + if (!dnsEnabled() && e.toString().contains(host)) + throw new RuntimeException("Name lookup failed"); + } + } + + static void hostFileTest() { + String result1 = "Unable to resolve host www.rte.ie as hosts file does.not.exist not found"; + String result2 = "Unable to resolve host as hosts file " + + "from ${jdk.net.hosts.file} system property not found"; + + try { + var a = InetAddress.getByName("www.rte.ie"); + } catch (IOException e) { + if (dnsEnabled() && !e.toString().contains(result1)) { + System.out.println("Lookup failed: " + e.toString()); + throw new RuntimeException("Name lookup failed"); + } + if (!dnsEnabled() && !e.toString().contains(result2)) { + System.out.println("Lookup failed: " + e.toString()); + throw new RuntimeException("Name lookup failed"); + } + } + } + + + final static String PRE = ".pre("; + final static String SUF = ".suf("; + final static String REP = ".rep("; + + static SensitiveInfo[] getArgs(String[] args) { + SensitiveInfo[] sa = new SensitiveInfo[args.length]; + + int index = 0; + for (String s : args) { + if (s != null && s.startsWith(PRE)) { + var preArg = s.substring(PRE.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].prefixWith(preArg); + } else if (s != null && s.startsWith(SUF)) { + var sufArg = s.substring(SUF.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].suffixWith(sufArg); + } else if (s != null && s.startsWith(REP)) { + var repArg = s.substring(REP.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].replaceWith(repArg); + } else { + sa[index++] = filterNonSocketInfo(s); + } + } + return Arrays.copyOf(sa, index); + } + + public static void main(String[] a) { + if (!hostFileEnabled()) { + dnsTest(); + } else { + hostFileTest(); + return; + } + + int count = 1; + for (String[][] test : tests) { + String format = test[0][0]; + String expectedEnhanced = test[2][0]; + String expectedNormal = test[2][1]; + SensitiveInfo[] args = getArgs(test[1]); + + String output = formatMsg(format, args); + if (netEnabled()) { + if (!output.equals(expectedEnhanced)) { + var msg = String.format("FAIL %d: got: \"%s\" Expected: \"%s\"", count, + output, expectedEnhanced); + throw new RuntimeException(msg); + } + } else { + if (!output.equals(expectedNormal)) { + var msg = String.format("FAIL %d: got: \"%s\" Expected: \"%s\"", count, + output, expectedNormal); + throw new RuntimeException(msg); + } + } + count++; + } + } +} From 4604c86d2fced32c186680788ba98f74df071b23 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Tue, 3 Jun 2025 15:43:26 +0000 Subject: [PATCH 103/216] 8357425: (fs) SecureDirectoryStream setPermissions should use fchmodat Reviewed-by: alanb --- .../sun/nio/fs/UnixNativeDispatcher.java | 22 +++++- .../sun/nio/fs/UnixSecureDirectoryStream.java | 25 ++++--- .../native/libnio/fs/UnixNativeDispatcher.c | 23 +++++++ .../nio/file/DirectoryStream/SecureDS.java | 67 ++++++++++++++++++- 4 files changed, 125 insertions(+), 12 deletions(-) diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java index 046f843371d..09611f23298 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -347,6 +347,18 @@ class UnixNativeDispatcher { } private static native void fchmod0(int fd, int mode) throws UnixException; + /** + * fchmodat(int fd, const char *path, mode_t mode, int flag) + */ + static void fchmodat(int fd, UnixPath path, int mode, int flag) + throws UnixException { + try (NativeBuffer buffer = copyToNativeBuffer(path)) { + fchmodat0(fd, buffer.address(), mode, flag); + } + } + private static native void fchmodat0(int fd, long pathAddress, int mode, int flag) + throws UnixException; + /** * futimens(int fildes, const struct timespec times[2]) */ @@ -558,6 +570,14 @@ class UnixNativeDispatcher { return (capabilities & SUPPORTS_XATTR) != 0; } + /** + * Supports fchmodat with AT_SYMLINK_NOFOLLOW flag + */ + static boolean fchmodatNoFollowSupported() { + return fchmodatNoFollowSupported0(); + } + private static native boolean fchmodatNoFollowSupported0(); + private static native int init(); static { jdk.internal.loader.BootLoader.loadLibrary("nio"); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java b/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java index c583afb588a..5c0693870e6 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java @@ -414,15 +414,24 @@ class UnixSecureDirectoryStream if (!ds.isOpen()) throw new ClosedDirectoryStreamException(); - int fd = (file == null) ? dfd : open(); - try { - fchmod(fd, UnixFileModeAttribute.toUnixMode(perms)); - } catch (UnixException x) { - x.rethrowAsIOException(file); - } finally { - if (file != null && fd >= 0) - UnixNativeDispatcher.close(fd, e-> null); + int mode = UnixFileModeAttribute.toUnixMode(perms); + if (file == null) + fchmod(dfd, mode); + else if (followLinks) + fchmodat(dfd, file, mode, 0); + else if (fchmodatNoFollowSupported()) + fchmodat(dfd, file, mode, AT_SYMLINK_NOFOLLOW); + else { + int fd = open(); + try { + fchmod(fd, mode); + } finally { + if (fd >= 0) + UnixNativeDispatcher.close(fd, e-> null); + } } + } catch (UnixException x) { + x.rethrowAsIOException(file); } finally { ds.readLock().unlock(); } diff --git a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c index fefaac94b48..fbf996886ae 100644 --- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c +++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c @@ -398,6 +398,16 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this) return capabilities; } +JNIEXPORT jboolean JNICALL +Java_sun_nio_fs_UnixNativeDispatcher_fchmodatNoFollowSupported0(JNIEnv* env, jclass this) { +#if defined(__linux__) + // Linux recognizes but does not support the AT_SYMLINK_NOFOLLOW flag + return JNI_FALSE; +#else + return JNI_TRUE; +#endif +} + JNIEXPORT jbyteArray JNICALL Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) { jbyteArray result = NULL; @@ -797,6 +807,19 @@ Java_sun_nio_fs_UnixNativeDispatcher_fchmod0(JNIEnv* env, jclass this, jint file } } +JNIEXPORT void JNICALL +Java_sun_nio_fs_UnixNativeDispatcher_fchmodat0(JNIEnv* env, jclass this, + jint fd, jlong pathAddress, jint mode, jint flag) +{ + int err; + const char* path = (const char*)jlong_to_ptr(pathAddress); + + RESTARTABLE(fchmodat((int)fd, path, (mode_t)mode, (int)flag), err); + if (err == -1) { + throwUnixException(env, errno); + } +} + JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_chown0(JNIEnv* env, jclass this, jlong pathAddress, jint uid, jint gid) diff --git a/test/jdk/java/nio/file/DirectoryStream/SecureDS.java b/test/jdk/java/nio/file/DirectoryStream/SecureDS.java index e058d782c52..6199596b30c 100644 --- a/test/jdk/java/nio/file/DirectoryStream/SecureDS.java +++ b/test/jdk/java/nio/file/DirectoryStream/SecureDS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,12 @@ */ /* @test - * @bug 4313887 6838333 8343020 + * @bug 4313887 6838333 8343020 8357425 * @summary Unit test for java.nio.file.SecureDirectoryStream * @requires (os.family == "linux" | os.family == "mac") - * @library .. + * @library .. /test/lib + * @build jdk.test.lib.Platform + * @run main SecureDS */ import java.nio.file.*; @@ -37,6 +39,8 @@ import java.nio.channels.*; import java.io.IOException; import java.util.*; +import jdk.test.lib.Platform; + public class SecureDS { static boolean supportsSymbolicLinks; @@ -54,6 +58,7 @@ public class SecureDS { // run tests doBasicTests(dir); doMoveTests(dir); + doSetPermissions(dir); miscTests(dir); } finally { @@ -172,6 +177,62 @@ public class SecureDS { delete(dir2); } + // Exercise setting permisions on the SecureDirectoryStream's view + static void doSetPermissions(Path dir) throws IOException { + Path aDir = createDirectory(dir.resolve("dir")); + + Set noperms = EnumSet.noneOf(PosixFilePermission.class); + Set permsDir = getPosixFilePermissions(aDir); + + try (SecureDirectoryStream stream = + (SecureDirectoryStream)newDirectoryStream(aDir);) { + + // Test setting permission on directory with no permissions + setPosixFilePermissions(aDir, noperms); + assertTrue(getPosixFilePermissions(aDir).equals(noperms)); + PosixFileAttributeView view = stream.getFileAttributeView(PosixFileAttributeView.class); + view.setPermissions(permsDir); + assertTrue(getPosixFilePermissions(aDir).equals(permsDir)); + + if (supportsSymbolicLinks) { + // Create a file and a link to the file + Path fileEntry = Path.of("file"); + Path file = createFile(aDir.resolve(fileEntry)); + Set permsFile = getPosixFilePermissions(file); + Path linkEntry = Path.of("link"); + Path link = createSymbolicLink(aDir.resolve(linkEntry), fileEntry); + Set permsLink = getPosixFilePermissions(link, NOFOLLOW_LINKS); + + // Test following link to file + view = stream.getFileAttributeView(link, PosixFileAttributeView.class); + view.setPermissions(noperms); + assertTrue(getPosixFilePermissions(file).equals(noperms)); + assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); + view.setPermissions(permsFile); + assertTrue(getPosixFilePermissions(file).equals(permsFile)); + assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); + + // Symbolic link permissions do not apply on Linux + if (!Platform.isLinux()) { + // Test not following link to file + view = stream.getFileAttributeView(link, PosixFileAttributeView.class, NOFOLLOW_LINKS); + view.setPermissions(noperms); + assertTrue(getPosixFilePermissions(file).equals(permsFile)); + assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(noperms)); + view.setPermissions(permsLink); + assertTrue(getPosixFilePermissions(file).equals(permsFile)); + assertTrue(getPosixFilePermissions(link, NOFOLLOW_LINKS).equals(permsLink)); + } + + delete(link); + delete(file); + } + + // clean-up + delete(aDir); + } + } + // Exercise SecureDirectoryStream's move method static void doMoveTests(Path dir) throws IOException { Path dir1 = createDirectory(dir.resolve("dir1")); From d7def20afa045a0bb154655b02e56346f7f51347 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Tue, 3 Jun 2025 16:02:14 +0000 Subject: [PATCH 104/216] 8358448: JFR: Incorrect time unit for MethodTiming event Reviewed-by: mgronlun, ayang --- src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java index 3eb3116db55..cc1d8f681c7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java @@ -43,7 +43,7 @@ public final class MethodTimingEvent extends AbstractJDKEvent { public long invocations; @Label("Average Time") - @Timespan + @Timespan(Timespan.TICKS) public long average; public static void commit(long start, long method, long invocations, long average) { From 16e120b00842e340401b6930354edfb1515f6ca4 Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo Date: Tue, 3 Jun 2025 16:12:53 +0000 Subject: [PATCH 105/216] 8357910: LoaderConstraintsTest.java fails when run with TEST_THREAD_FACTORY=Virtual Reviewed-by: dholmes, coleenp --- test/hotspot/jtreg/ProblemList-Virtual.txt | 1 - .../runtime/logging/LoaderConstraintsTest.java | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index cb5b92b96cf..dbd555c1cdd 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -92,7 +92,6 @@ gc/arguments/TestNewSizeThreadIncrease.java 0000000 generic-all gc/g1/TestSkipRebuildRemsetPhase.java 0000000 generic-all runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java 8346442 generic-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 0000000 generic-all -runtime/logging/LoaderConstraintsTest.java 8346442 generic-all runtime/Thread/AsyncExceptionOnMonitorEnter.java 0000000 generic-all runtime/Thread/StopAtExit.java 0000000 generic-all runtime/handshake/HandshakeWalkStackTest.java 0000000 generic-all diff --git a/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java index 39ad3b872a2..f1c493e5e93 100644 --- a/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java +++ b/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -38,6 +38,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import java.lang.ref.WeakReference; import java.lang.reflect.Method; +import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -49,22 +50,25 @@ public class LoaderConstraintsTest { private static ProcessBuilder pb; private static class ClassUnloadTestMain { public static void main(String... args) throws Exception { - String className = "test.Empty"; ClassLoader cl = ClassUnloadCommon.newClassLoader(); - Class c = cl.loadClass(className); - cl = null; c = null; - ClassUnloadCommon.triggerUnloading(); + Class c = cl.loadClass("test.Empty"); + // Causes class test.Empty to be linked, which triggers the + // constraint on class String due to override of toString(). + Constructor constructor = c.getDeclaredConstructor(); } } // Use the same command-line heap size setting as ../ClassUnload/UnloadTest.java static ProcessBuilder exec(String... args) throws Exception { + String classPath = System.getProperty("test.class.path", "."); + List argsList = new ArrayList<>(); Collections.addAll(argsList, args); Collections.addAll(argsList, "-Xmn8m"); Collections.addAll(argsList, "-Xbootclasspath/a:."); Collections.addAll(argsList, "-XX:+UnlockDiagnosticVMOptions"); Collections.addAll(argsList, "-XX:+WhiteBoxAPI"); + Collections.addAll(argsList, "-Dtest.class.path=" + classPath); Collections.addAll(argsList, ClassUnloadTestMain.class.getName()); return ProcessTools.createLimitedTestJavaProcessBuilder(argsList); } @@ -75,13 +79,12 @@ public class LoaderConstraintsTest { pb = exec("-Xlog:class+loader+constraints=info"); out = new OutputAnalyzer(pb.start()); out.shouldHaveExitValue(0); - out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: 'app', loader[1]: 'bootstrap'"); + out.stdoutShouldMatch("\\[class,loader,constraints\\] adding new constraint for name: java/lang/String, loader\\[0\\]: 'ClassUnloadCommonClassLoader' @[\\da-f]+, loader\\[1\\]: 'bootstrap'"); // -Xlog:class+loader+constraints=off pb = exec("-Xlog:class+loader+constraints=off"); out = new OutputAnalyzer(pb.start()); out.shouldHaveExitValue(0); out.shouldNotContain("[class,loader,constraints]"); - } } From 04c15466f68f1208084ee6e5f2322ace707d0446 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Tue, 3 Jun 2025 16:13:14 +0000 Subject: [PATCH 106/216] 8358095: Cleanup tests with explicit locale provider set to only CLDR Reviewed-by: bpb, naoto --- .../Format/NumberFormat/CurrencyFormat.java | 4 +- test/jdk/java/util/Calendar/Bug8007038.java | 4 +- test/jdk/java/util/Calendar/Bug8167273.java | 4 +- .../util/Calendar/CldrFormatNamesTest.java | 4 +- .../Calendar/GenericTimeZoneNamesTest.java | 7 +--- .../util/Calendar/JapaneseEraNameTest.java | 5 +-- .../java/util/Calendar/NarrowNamesTest.java | 4 +- .../util/Formatter/BasicTestLauncher.java | 7 ++-- .../AliasesShouldBeRecognizedInCLDR.java | 4 +- .../Locale/RequiredAvailableLocalesTest.java | 4 +- .../Locale/bcp47u/CurrencyFormatTests.java | 4 +- .../util/Locale/bcp47u/DisplayNameTests.java | 4 +- .../java/util/Locale/bcp47u/FormatTests.java | 4 +- .../java/util/Locale/bcp47u/SymbolsTests.java | 4 +- test/jdk/java/util/TimeZone/Bug8167143.java | 42 +++++++++---------- .../util/TimeZone/CLDRDisplayNamesTest.java | 2 +- .../TimeZone/ChineseTimeZoneNameTest.java | 4 +- .../sun/util/resources/cldr/Bug8134250.java | 4 +- .../sun/util/resources/cldr/Bug8134384.java | 2 +- .../cldr/LikelySubtagLocalesTest.java | 2 +- .../resources/cldr/TimeZoneNamesTest.java | 2 +- 21 files changed, 58 insertions(+), 63 deletions(-) diff --git a/test/jdk/java/text/Format/NumberFormat/CurrencyFormat.java b/test/jdk/java/text/Format/NumberFormat/CurrencyFormat.java index fa50ecde2aa..6d7a906e394 100644 --- a/test/jdk/java/text/Format/NumberFormat/CurrencyFormat.java +++ b/test/jdk/java/text/Format/NumberFormat/CurrencyFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @summary Basic tests for currency formatting. * Tests both COMPAT and CLDR data. * @modules jdk.localedata - * @run junit/othervm -Djava.locale.providers=CLDR CurrencyFormat + * @run junit CurrencyFormat */ import java.io.File; diff --git a/test/jdk/java/util/Calendar/Bug8007038.java b/test/jdk/java/util/Calendar/Bug8007038.java index 874aaf10922..310c3e8c2a0 100644 --- a/test/jdk/java/util/Calendar/Bug8007038.java +++ b/test/jdk/java/util/Calendar/Bug8007038.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,7 +29,7 @@ * @modules java.base/sun.util.locale.provider * @modules jdk.localedata * @compile -XDignore.symbol.file Bug8007038.java - * @run main/othervm -Djava.locale.providers=CLDR Bug8007038 CLDR + * @run main Bug8007038 CLDR */ import java.util.*; diff --git a/test/jdk/java/util/Calendar/Bug8167273.java b/test/jdk/java/util/Calendar/Bug8167273.java index e4de858d4da..de9a72f5dc8 100644 --- a/test/jdk/java/util/Calendar/Bug8167273.java +++ b/test/jdk/java/util/Calendar/Bug8167273.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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.base/sun.util.spi * jdk.localedata * @run main Bug8167273 testEraName - * @run main/othervm -Djava.locale.providers=CLDR Bug8167273 testCldr + * @run main Bug8167273 testCldr * @run main Bug8167273 testEmptyEraNames */ import java.text.DateFormatSymbols; diff --git a/test/jdk/java/util/Calendar/CldrFormatNamesTest.java b/test/jdk/java/util/Calendar/CldrFormatNamesTest.java index ea6db600640..36369bef8a7 100644 --- a/test/jdk/java/util/Calendar/CldrFormatNamesTest.java +++ b/test/jdk/java/util/Calendar/CldrFormatNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @modules java.base/sun.util.locale.provider * jdk.localedata * @compile -XDignore.symbol.file CldrFormatNamesTest.java - * @run main/othervm -Djava.locale.providers=CLDR CldrFormatNamesTest + * @run main CldrFormatNamesTest */ import java.util.*; diff --git a/test/jdk/java/util/Calendar/GenericTimeZoneNamesTest.java b/test/jdk/java/util/Calendar/GenericTimeZoneNamesTest.java index 17fd09d4458..4c0e6c73585 100644 --- a/test/jdk/java/util/Calendar/GenericTimeZoneNamesTest.java +++ b/test/jdk/java/util/Calendar/GenericTimeZoneNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, 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 @@ -26,12 +26,9 @@ * @bug 8003267 * @summary Unit test for generic time zone names support. This test is locale * data-dependent and assumes that both JRE and CLDR have the same - * geneic time zone names in English. + * generic time zone names in English. * @modules java.base/sun.util.locale.provider - * @comment Locale providers: default * @run main GenericTimeZoneNamesTest en-US - * @comment Locale providers: CLDR - * @run main/othervm -Djava.locale.providers=CLDR GenericTimeZoneNamesTest en-US */ import java.util.Locale; diff --git a/test/jdk/java/util/Calendar/JapaneseEraNameTest.java b/test/jdk/java/util/Calendar/JapaneseEraNameTest.java index 8fccfe7bb16..11e35927adf 100644 --- a/test/jdk/java/util/Calendar/JapaneseEraNameTest.java +++ b/test/jdk/java/util/Calendar/JapaneseEraNameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,7 @@ * @summary Test the localized Japanese new era name (May 1st. 2019-) * is retrieved no matter CLDR provider contains the name or not. * @modules jdk.localedata - * @run testng/othervm JapaneseEraNameTest - * @run testng/othervm -Djava.locale.providers=CLDR JapaneseEraNameTest + * @run testng JapaneseEraNameTest */ import static java.util.Calendar.*; diff --git a/test/jdk/java/util/Calendar/NarrowNamesTest.java b/test/jdk/java/util/Calendar/NarrowNamesTest.java index ab79e339444..2be43fdc1c0 100644 --- a/test/jdk/java/util/Calendar/NarrowNamesTest.java +++ b/test/jdk/java/util/Calendar/NarrowNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -31,7 +31,7 @@ * @comment Locale providers: CLDR,SPI * @run main/othervm -Djava.locale.providers=CLDR,SPI NarrowNamesTest CLDR,SPI * @comment Locale providers: CLDR - * @run main/othervm -Djava.locale.providers=CLDR NarrowNamesTest CLDR + * @run main NarrowNamesTest CLDR */ import java.time.LocalDateTime; diff --git a/test/jdk/java/util/Formatter/BasicTestLauncher.java b/test/jdk/java/util/Formatter/BasicTestLauncher.java index 4dfc0e36743..3fa35c901cb 100644 --- a/test/jdk/java/util/Formatter/BasicTestLauncher.java +++ b/test/jdk/java/util/Formatter/BasicTestLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,7 @@ import org.junit.jupiter.params.provider.ValueSource; * @run junit BasicTestLauncher */ public class BasicTestLauncher { - // Locale flag for testJVM - private static final String JAVA_OPTS = "-Djava.locale.providers=CLDR"; + // Test class private static final String TEST_CLASS = "Basic"; @@ -82,7 +81,7 @@ public class BasicTestLauncher { */ private static OutputAnalyzer RunTest(String timeZone) throws IOException{ // Build and run Basic class with correct configuration - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(JAVA_OPTS, TEST_CLASS); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(TEST_CLASS); pb.environment().put("TZ", timeZone); Process process = pb.start(); return new OutputAnalyzer(process); diff --git a/test/jdk/java/util/Locale/AliasesShouldBeRecognizedInCLDR.java b/test/jdk/java/util/Locale/AliasesShouldBeRecognizedInCLDR.java index fa41aeea07c..5af83062fba 100644 --- a/test/jdk/java/util/Locale/AliasesShouldBeRecognizedInCLDR.java +++ b/test/jdk/java/util/Locale/AliasesShouldBeRecognizedInCLDR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @bug 8179071 8202537 8231273 8251317 * @summary Test that language aliases of CLDR supplemental metadata are handled correctly. * @modules jdk.localedata - * @run junit/othervm -Djava.locale.providers=CLDR AliasesShouldBeRecognizedInCLDR + * @run junit AliasesShouldBeRecognizedInCLDR */ /* diff --git a/test/jdk/java/util/Locale/RequiredAvailableLocalesTest.java b/test/jdk/java/util/Locale/RequiredAvailableLocalesTest.java index a1d6edd5d70..017e8af0fde 100644 --- a/test/jdk/java/util/Locale/RequiredAvailableLocalesTest.java +++ b/test/jdk/java/util/Locale/RequiredAvailableLocalesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -25,7 +25,7 @@ * @bug 8276186 8174269 * @summary Checks whether getAvailableLocales() returns at least Locale.ROOT and * Locale.US instances. - * @run testng/othervm -Djava.locale.providers=CLDR RequiredAvailableLocalesTest + * @run testng RequiredAvailableLocalesTest */ import java.lang.invoke.MethodHandles; diff --git a/test/jdk/java/util/Locale/bcp47u/CurrencyFormatTests.java b/test/jdk/java/util/Locale/bcp47u/CurrencyFormatTests.java index d3e14fb0d5a..feb52a49df5 100644 --- a/test/jdk/java/util/Locale/bcp47u/CurrencyFormatTests.java +++ b/test/jdk/java/util/Locale/bcp47u/CurrencyFormatTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, 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 @@ -27,7 +27,7 @@ * @bug 8215181 8230284 8231273 8284840 * @summary Tests the "u-cf" extension * @modules jdk.localedata - * @run testng/othervm -Djava.locale.providers=CLDR CurrencyFormatTests + * @run testng CurrencyFormatTests */ import static org.testng.Assert.assertEquals; diff --git a/test/jdk/java/util/Locale/bcp47u/DisplayNameTests.java b/test/jdk/java/util/Locale/bcp47u/DisplayNameTests.java index 11c4272f160..1f1a4d3e8ca 100644 --- a/test/jdk/java/util/Locale/bcp47u/DisplayNameTests.java +++ b/test/jdk/java/util/Locale/bcp47u/DisplayNameTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 8176841 8202537 * @summary Tests the display names for BCP 47 U extensions * @modules jdk.localedata - * @run testng/othervm -Djava.locale.providers=CLDR DisplayNameTests + * @run testng DisplayNameTests */ import static org.testng.Assert.assertEquals; diff --git a/test/jdk/java/util/Locale/bcp47u/FormatTests.java b/test/jdk/java/util/Locale/bcp47u/FormatTests.java index 774d1e3dee1..3e4b0bf5ea0 100644 --- a/test/jdk/java/util/Locale/bcp47u/FormatTests.java +++ b/test/jdk/java/util/Locale/bcp47u/FormatTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @summary Tests *Format class deals with Unicode extensions * correctly. * @modules jdk.localedata - * @run testng/othervm -Djava.locale.providers=CLDR FormatTests + * @run testng FormatTests */ import static org.testng.Assert.assertEquals; diff --git a/test/jdk/java/util/Locale/bcp47u/SymbolsTests.java b/test/jdk/java/util/Locale/bcp47u/SymbolsTests.java index 2a8e8bf8e1e..451eac4c050 100644 --- a/test/jdk/java/util/Locale/bcp47u/SymbolsTests.java +++ b/test/jdk/java/util/Locale/bcp47u/SymbolsTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * @summary Tests *FormatSymbols class deals with Unicode extensions * correctly. * @modules jdk.localedata - * @run testng/othervm -Djava.locale.providers=CLDR SymbolsTests + * @run testng SymbolsTests */ import static org.testng.Assert.assertEquals; diff --git a/test/jdk/java/util/TimeZone/Bug8167143.java b/test/jdk/java/util/TimeZone/Bug8167143.java index b8ce459a5de..fb94c94214f 100644 --- a/test/jdk/java/util/TimeZone/Bug8167143.java +++ b/test/jdk/java/util/TimeZone/Bug8167143.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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.base/sun.util.spi * jdk.localedata * @run main Bug8167143 testTimeZone - * @run main/othervm -Djava.locale.providers=CLDR Bug8167143 testCldr + * @run main Bug8167143 testCldr * @run main Bug8167143 testCache * @run main Bug8167143 testCandidateLocales */ @@ -236,40 +236,40 @@ public class Bug8167143 { private static void testImplicitCompatLocales() { LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE(); checkPresenceCompat("BreakIteratorProvider", - jre.getBreakIteratorProvider().getAvailableLocales()); + jre.getBreakIteratorProvider().getAvailableLocales()); checkPresenceCompat("CollatorProvider", - jre.getCollatorProvider().getAvailableLocales()); + jre.getCollatorProvider().getAvailableLocales()); checkPresenceCompat("DateFormatProvider", - jre.getDateFormatProvider().getAvailableLocales()); + jre.getDateFormatProvider().getAvailableLocales()); checkPresenceCompat("DateFormatSymbolsProvider", - jre.getDateFormatSymbolsProvider().getAvailableLocales()); + jre.getDateFormatSymbolsProvider().getAvailableLocales()); checkPresenceCompat("DecimalFormatSymbolsProvider", - jre.getDecimalFormatSymbolsProvider().getAvailableLocales()); + jre.getDecimalFormatSymbolsProvider().getAvailableLocales()); checkPresenceCompat("NumberFormatProvider", - jre.getNumberFormatProvider().getAvailableLocales()); + jre.getNumberFormatProvider().getAvailableLocales()); checkPresenceCompat("CurrencyNameProvider", - jre.getCurrencyNameProvider().getAvailableLocales()); + jre.getCurrencyNameProvider().getAvailableLocales()); checkPresenceCompat("LocaleNameProvider", - jre.getLocaleNameProvider().getAvailableLocales()); + jre.getLocaleNameProvider().getAvailableLocales()); checkPresenceCompat("TimeZoneNameProvider", - jre.getTimeZoneNameProvider().getAvailableLocales()); + jre.getTimeZoneNameProvider().getAvailableLocales()); checkPresenceCompat("CalendarDataProvider", - jre.getCalendarDataProvider().getAvailableLocales()); + jre.getCalendarDataProvider().getAvailableLocales()); checkPresenceCompat("CalendarNameProvider", - jre.getCalendarNameProvider().getAvailableLocales()); + jre.getCalendarNameProvider().getAvailableLocales()); checkPresenceCompat("CalendarProvider", - jre.getCalendarProvider().getAvailableLocales()); + jre.getCalendarProvider().getAvailableLocales()); } private static void checkPresenceCompat(String testName, Locale[] got) { List gotLocalesList = Arrays.asList(got); List gotList = new ArrayList<>(gotLocalesList); - if (!gotList.removeAll(COMPAT_IMPLICIT_LOCS)) { - // check which Implicit locale are not present in retrievedLocales List. - List implicitLocales = new ArrayList<>(COMPAT_IMPLICIT_LOCS); - implicitLocales.removeAll(gotList); - throw new RuntimeException("Locales those not correctly reflected are " - + implicitLocales + " for test " + testName); - } + if (!gotList.removeAll(COMPAT_IMPLICIT_LOCS)) { + // check which Implicit locale are not present in retrievedLocales List. + List implicitLocales = new ArrayList<>(COMPAT_IMPLICIT_LOCS); + implicitLocales.removeAll(gotList); + throw new RuntimeException("Locales those not correctly reflected are " + + implicitLocales + " for test " + testName); + } } } diff --git a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java index c1200445407..b6c80b6d7d0 100644 --- a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java +++ b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java @@ -26,7 +26,7 @@ * @bug 8005471 8008577 8129881 8130845 8136518 8181157 8210490 8220037 * 8234347 8236548 8317979 * @modules jdk.localedata - * @run main/othervm -Djava.locale.providers=CLDR CLDRDisplayNamesTest + * @run main CLDRDisplayNamesTest * @summary Make sure that localized time zone names of CLDR are used * if specified. */ diff --git a/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java b/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java index f874da18df3..335d147f9ab 100644 --- a/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java +++ b/test/jdk/sun/util/resources/TimeZone/ChineseTimeZoneNameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @bug 8275721 8174269 * @modules jdk.localedata * @summary Checks Chinese time zone names for `UTC` using CLDR are consistent - * @run testng/othervm -Djava.locale.providers=CLDR ChineseTimeZoneNameTest + * @run testng ChineseTimeZoneNameTest */ import java.time.Instant; diff --git a/test/jdk/sun/util/resources/cldr/Bug8134250.java b/test/jdk/sun/util/resources/cldr/Bug8134250.java index d38fce53352..bbc385cb870 100644 --- a/test/jdk/sun/util/resources/cldr/Bug8134250.java +++ b/test/jdk/sun/util/resources/cldr/Bug8134250.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @bug 8134250 8134520 * @modules jdk.localedata * @summary Tests CLDR/LDML features are correctly reflected in JDK. - * @run main/othervm -Djava.locale.providers=CLDR Bug8134250 + * @run main Bug8134250 */ // Note this test highly depends on a particular version of CLDR. Results diff --git a/test/jdk/sun/util/resources/cldr/Bug8134384.java b/test/jdk/sun/util/resources/cldr/Bug8134384.java index f27b587ca98..17f41ba4c8d 100644 --- a/test/jdk/sun/util/resources/cldr/Bug8134384.java +++ b/test/jdk/sun/util/resources/cldr/Bug8134384.java @@ -25,7 +25,7 @@ * @test * @bug 8134384 8234347 8236548 8347841 * @summary Tests CLDR TimeZoneNames has English names for all tzids - * @run main/othervm -Djava.locale.providers=CLDR Bug8134384 + * @run main Bug8134384 */ import java.text.*; diff --git a/test/jdk/sun/util/resources/cldr/LikelySubtagLocalesTest.java b/test/jdk/sun/util/resources/cldr/LikelySubtagLocalesTest.java index 0e66db5c5da..c717e099f06 100644 --- a/test/jdk/sun/util/resources/cldr/LikelySubtagLocalesTest.java +++ b/test/jdk/sun/util/resources/cldr/LikelySubtagLocalesTest.java @@ -26,7 +26,7 @@ * @bug 8145136 8202537 8221432 8251317 8258794 8265315 8306116 8346948 * @modules jdk.localedata * @summary Tests LikelySubtags is correctly reflected in Locale.getAvailableLocales(). - * @run junit/othervm -Djava.locale.providers=CLDR LikelySubtagLocalesTest + * @run junit LikelySubtagLocalesTest */ import java.util.Arrays; import java.util.List; diff --git a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java index 4fe1a7d25a9..ed6fb2a58d8 100644 --- a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java +++ b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java @@ -27,7 +27,7 @@ * @modules jdk.localedata * @summary Checks CLDR time zone names are generated correctly at * either build or runtime - * @run testng/othervm -Djava.locale.providers=CLDR TimeZoneNamesTest + * @run testng TimeZoneNamesTest */ import java.text.DateFormatSymbols; From 57862005f9914ce60aa389a6e35d2e0cd38f8c35 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Tue, 3 Jun 2025 16:32:12 +0000 Subject: [PATCH 107/216] 8354450: A File should be invalid if an element of its name sequence ends with a space Reviewed-by: alanb --- .../classes/java/io/WinNTFileSystem.java | 25 +++--- test/jdk/java/io/File/WinTrailingSpace.java | 83 +++++++++++++++++++ 2 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/io/File/WinTrailingSpace.java diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java index 56aa27c004d..e053f7f004c 100644 --- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java +++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java @@ -365,27 +365,28 @@ final class WinNTFileSystem extends FileSystem { @Override public boolean isInvalid(File f) { - if (f.getPath().indexOf('\u0000') >= 0) + final String pathname = f.getPath(); + + // Invalid if the pathname string contains a null character or if + // any name in the pathname's name sequence ends with a space + if (pathname.indexOf('\u0000') >= 0 || pathname.endsWith(" ") + || pathname.contains(" \\")) return true; + // The remaining checks are irrelevant for alternate data streams (ADS) if (ENABLE_ADS) return false; - // Invalid if there is a ":" at a position greater than 1, or if there + // Invalid if there is a ":" at a position other than 1, or if there // is a ":" at position 1 and the first character is not a letter - String pathname = f.getPath(); int lastColon = pathname.lastIndexOf(":"); + if (lastColon >= 0 && + (lastColon != 1 || !isLetter(pathname.charAt(0)))) + return true; - // Valid if there is no ":" present or if the last ":" present is - // at index 1 and the first character is a latter - if (lastColon < 0 || - (lastColon == 1 && isLetter(pathname.charAt(0)))) - return false; - - // Invalid if path creation fails - Path path = null; + // Invalid if the path string cannot be converted to a Path try { - path = sun.nio.fs.DefaultFileSystemProvider.theFileSystem().getPath(pathname); + Path path = sun.nio.fs.DefaultFileSystemProvider.theFileSystem().getPath(pathname); return false; } catch (InvalidPathException ignored) { } diff --git a/test/jdk/java/io/File/WinTrailingSpace.java b/test/jdk/java/io/File/WinTrailingSpace.java new file mode 100644 index 00000000000..1997a867195 --- /dev/null +++ b/test/jdk/java/io/File/WinTrailingSpace.java @@ -0,0 +1,83 @@ +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* @test + * @bug 8354450 + * @requires os.family == "windows" + * @summary Verify behavior for file names with a trailing space + * @run junit WinTrailingSpace + */ +public class WinTrailingSpace { + private static final String FILENAME_NO_TRAILING_SPACE = "foobargus"; + private static final String FILENAME_TRAILING_SPACE = "foobargus "; + private static final String DIRNAME_TRAILING_SPACE = "foo \\bar\\gus"; + + @Test + public void noTrailingSpace() throws IOException { + File f = null; + try { + f = new File(".", FILENAME_NO_TRAILING_SPACE); + f.delete(); + f.createNewFile(); + assertTrue(f.exists()); + } finally { + if (f != null) + f.delete(); + } + } + + @Test + public void trailingSpace() throws IOException { + File f = null; + try { + f = new File(".", FILENAME_TRAILING_SPACE); + f.delete(); + f.createNewFile(); + assertFalse(f.exists(), "Creation of " + f + " should have failed"); + } catch (IOException expected) { + } finally { + if (f != null) + f.delete(); + } + } + + @Test + public void dirTrailingSpace() throws IOException { + File f = null; + try { + f = new File(".", DIRNAME_TRAILING_SPACE); + f.delete(); + assertFalse(f.mkdirs(), "Creation of " + f + " should have failed"); + } finally { + if (f != null) + f.delete(); + } + } +} From d7e58ac480b06c6340a65e67731d8f6dc179acfb Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Tue, 3 Jun 2025 17:00:54 +0000 Subject: [PATCH 108/216] 8351635: C2 ROR/ROL: assert failed: Long constant expected Reviewed-by: thartmann, chagedorn --- src/hotspot/share/opto/vectornode.cpp | 3 +- .../TestVectorRotateScalarCount.java | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/vectorapi/TestVectorRotateScalarCount.java diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 05ef64af704..2b40ca77198 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1722,8 +1722,7 @@ Node* VectorNode::degenerate_vector_rotate(Node* src, Node* cnt, bool is_rotate_ if (cnt->Opcode() == Op_ConvI2L) { cnt = cnt->in(1); } else { - assert(cnt->bottom_type()->isa_long() && - cnt->bottom_type()->is_long()->is_con(), "Long constant expected"); + assert(cnt->bottom_type()->isa_long(), "long type shift count expected"); cnt = phase->transform(new ConvL2INode(cnt)); } } diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestVectorRotateScalarCount.java b/test/hotspot/jtreg/compiler/vectorapi/TestVectorRotateScalarCount.java new file mode 100644 index 00000000000..f9b14b9f130 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/TestVectorRotateScalarCount.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import compiler.lib.ir_framework.*; +import compiler.lib.verify.Verify; +import jdk.incubator.vector.*; + +/* + * @test + * @bug 8351635 + * @summary Test missing pattern in vector rotate generation + * @modules jdk.incubator.vector + * @library /test/lib / + * @run driver compiler.vectorapi.TestVectorRotateScalarCount + */ +public class TestVectorRotateScalarCount { + public static void main(String[] args) { + TestFramework.runWithFlags("--add-modules=jdk.incubator.vector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:UseAVX=2"); + } + + public static long long_shift = 31L; + public static int int_shift = 12; + + static final Object GOLD_PATTERN1a = pattern1a(); + static final Object GOLD_PATTERN1b = pattern1b(); + static final Object GOLD_PATTERN2 = pattern2(); + static final Object GOLD_PATTERN3 = pattern3(); + static final Object GOLD_PATTERN4 = pattern4(); + + @Test + @IR(counts = {IRNode.URSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.LSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.OR_VL, IRNode.VECTOR_SIZE_2, "1"}, + applyIfCPUFeatureAnd = {"avx2", "true", "avx512f", "false", "avx512vl", "false"}) + public static Object pattern1a() { + LongVector lv1 = LongVector.broadcast(LongVector.SPECIES_128, 1); + long x = Long.divideUnsigned(long_shift, Long.MIN_VALUE); + return lv1.lanewise(VectorOperators.ROL, x); + } + + @Check(test = "pattern1a") + public static void check_pattern1a(Object param) { + Verify.checkEQ(GOLD_PATTERN1a, param); + } + + @Test + @IR(counts = {IRNode.URSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.LSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.OR_VL, IRNode.VECTOR_SIZE_2, "1"}, + applyIfCPUFeatureAnd = {"avx2", "true", "avx512f", "false", "avx512vl", "false"}) + public static Object pattern1b() { + LongVector lv1 = LongVector.broadcast(LongVector.SPECIES_128, 1); + long x = Long.min(32, Long.max(Long.reverse(long_shift), 0)); + return lv1.lanewise(VectorOperators.ROR, x); + } + + @Check(test = "pattern1b") + public static void check_pattern1b(Object param) { + Verify.checkEQ(GOLD_PATTERN1b, param); + } + + @Test + @IR(counts = {IRNode.URSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.LSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.OR_VL, IRNode.VECTOR_SIZE_2, "1"}, + applyIfCPUFeatureAnd = {"avx2", "true", "avx512f", "false", "avx512vl", "false"}) + public static Object pattern2() { + LongVector lv1 = LongVector.broadcast(LongVector.SPECIES_128, 1); + return lv1.lanewise(VectorOperators.ROL, int_shift); + } + + @Check(test = "pattern2") + public static void check_pattern2(Object param) { + Verify.checkEQ(GOLD_PATTERN2, param); + } + + @Test + @IR(counts = {IRNode.URSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.LSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.OR_VL, IRNode.VECTOR_SIZE_2, "1"}, + applyIfCPUFeatureAnd = {"avx2", "true", "avx512f", "false", "avx512vl", "false"}) + public static Object pattern3() { + LongVector lv1 = LongVector.broadcast(LongVector.SPECIES_128, 1); + return lv1.lanewise(VectorOperators.ROL, lv1); + } + + @Check(test = "pattern3") + public static void check_pattern3(Object param) { + Verify.checkEQ(GOLD_PATTERN3, param); + } + @Test + @IR(counts = {IRNode.URSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.LSHIFT_VL, IRNode.VECTOR_SIZE_2, "1", + IRNode.OR_VL, IRNode.VECTOR_SIZE_2, "1"}, + applyIfCPUFeatureAnd = {"avx2", "true", "avx512f", "false", "avx512vl", "false"}) + public static Object pattern4() { + LongVector lv1 = LongVector.broadcast(LongVector.SPECIES_128, 1); + return lv1.lanewise(VectorOperators.ROL, 15L); + } + + @Check(test = "pattern4") + public static void check_pattern4(Object param) { + Verify.checkEQ(GOLD_PATTERN4, param); + } +} From 44d62c8e21fb09381f9f86a081f70549cc321b1e Mon Sep 17 00:00:00 2001 From: Larry Cable Date: Tue, 3 Jun 2025 17:13:22 +0000 Subject: [PATCH 109/216] 8358077: sun.tools.attach.VirtualMachineImpl::checkCatchesAndSendQuitTo on Linux leaks file handles after JDK-8327114 Reviewed-by: kevinw, sspitsyn, syan --- .../classes/sun/tools/attach/VirtualMachineImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java index 820af57ec37..af8870ecf64 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -35,6 +35,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Optional; + import java.util.regex.Pattern; import static java.nio.charset.StandardCharsets.UTF_8; @@ -358,7 +360,11 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { if (okToSendQuit) { sendQuitTo(pid); } else if (throwIfNotReady) { - final var cmdline = Files.lines(procPid.resolve("cmdline")).findFirst(); + Optional cmdline = Optional.empty(); + + try (final var clf = Files.lines(procPid.resolve("cmdline"))) { + cmdline = clf.findFirst(); + } var cmd = "null"; // default From c382da579884c28f2765b2c6ba68c0ad4fdcb2ce Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 3 Jun 2025 17:19:31 +0000 Subject: [PATCH 110/216] 8358178: Some nsk/jdi tests should be run with includevirtualthreads=y even though they pass without Reviewed-by: sspitsyn, lmesnik --- .../nsk/jdi/EventSet/resume/resume001/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume002/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume003/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume004/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume005/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume006/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume007/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume008/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume009/TestDescription.java | 3 ++- .../nsk/jdi/EventSet/resume/resume010/TestDescription.java | 3 ++- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume001/TestDescription.java index 5c86dc74fbc..87d47222fc1 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume001 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002/TestDescription.java index 5d79a05338e..b2bafcff62d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume002 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003/TestDescription.java index d19aff7885e..7e36d18e21e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume003 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004/TestDescription.java index d0c405c19e8..e435cd78796 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume004/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume004 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005/TestDescription.java index eef8e00a5d4..6a41ca7ebff 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume005/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume005 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006/TestDescription.java index 67536af919a..74a92b22a7c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume006/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume006 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007/TestDescription.java index 61239470b7d..fc708b63343 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume007/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume007 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008/TestDescription.java index 3a331640279..498fe9ba1da 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume008 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume009/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume009/TestDescription.java index bd8e7cf0977..e030264986e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume009/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume009/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -66,6 +66,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume009 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010/TestDescription.java index 15abd8db247..ed2a97533e3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume010/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -65,6 +65,7 @@ * @run driver * nsk.jdi.EventSet.resume.resume010 * -verbose + * -includevirtualthreads * -arch=${os.family}-${os.simpleArch} * -waittime=5 * -debugee.vmkind=java From 461cb84277b40d01c5d04be3c74f25d8667a207c Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Tue, 3 Jun 2025 18:02:47 +0000 Subject: [PATCH 111/216] 8345538: Robot.mouseMove doesn't clamp bounds on macOS when trying to move mouse off screen Reviewed-by: honkar, prr --- .../classes/sun/lwawt/macosx/CRobot.java | 40 ++++++++- .../java/awt/Robot/MouseMoveOffScreen.java | 83 +++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/awt/Robot/MouseMoveOffScreen.java diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java index 5dba06cb612..036da04a7cb 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, 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 @@ -25,6 +25,8 @@ package sun.lwawt.macosx; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.peer.RobotPeer; @@ -63,7 +65,41 @@ final class CRobot implements RobotPeer { mouseLastX = x; mouseLastY = y; - mouseEvent(mouseLastX, mouseLastY, mouseButtonsState, true, true); + int leastDiff = Integer.MAX_VALUE; + int finX = x; + int finY = y; + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gs = ge.getScreenDevices(); + Rectangle[] allScreenBounds = new Rectangle[gs.length]; + + for (int i = 0; i < gs.length; i++) { + allScreenBounds[i] = gs[i].getDefaultConfiguration().getBounds(); + } + + for (Rectangle screenBounds : allScreenBounds) { + Point cP = calcClosestPoint(x, y, screenBounds); + + int currXDiff = Math.abs(x - cP.x); + int currYDiff = Math.abs(y - cP.y); + int currDiff = (int) Math.round(Math.hypot(currXDiff, currYDiff)); + + if (currDiff == 0) { + mouseEvent(mouseLastX, mouseLastY, mouseButtonsState, true, true); + return; + } if (currDiff < leastDiff) { + finX = cP.x; + finY = cP.y; + leastDiff = currDiff; + } + } + + mouseEvent(finX, finY, mouseButtonsState, true, true); + } + + private Point calcClosestPoint(int x, int y, Rectangle screenBounds) { + return new Point(Math.min(Math.max(x, screenBounds.x), screenBounds.x + screenBounds.width - 1), + Math.min(Math.max(y, screenBounds.y), screenBounds.y + screenBounds.height - 1)); } /** diff --git a/test/jdk/java/awt/Robot/MouseMoveOffScreen.java b/test/jdk/java/awt/Robot/MouseMoveOffScreen.java new file mode 100644 index 00000000000..809e3dd1ff1 --- /dev/null +++ b/test/jdk/java/awt/Robot/MouseMoveOffScreen.java @@ -0,0 +1,83 @@ +/* + * 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. + */ + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; + +/* + * @test + * @bug 8345538 + * @summary Tests mouseMove clamping to screen bounds when set to move offscreen + * @requires (os.family == "mac") + * @key headful + * @run main MouseMoveOffScreen + */ + +public class MouseMoveOffScreen { + private static final Point STARTING_LOC = new Point(200, 200); + private static final Point OFF_SCREEN_LOC = new Point(20000, 200); + private static Rectangle[] r; + + public static void main(String[] args) throws Exception { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gs = ge.getScreenDevices(); + r = new Rectangle[gs.length]; + + for (int i = 0; i < gs.length; i++) { + r[i] = gs[i].getDefaultConfiguration().getBounds(); + System.out.println("Screen: "+ gs[i].getIDstring() + " Bounds: " + r[i]); + } + + Point offsc = validateOffScreen(OFF_SCREEN_LOC); + Robot robot = new Robot(); + robot.mouseMove(STARTING_LOC.x, STARTING_LOC.y); + robot.delay(500); + robot.mouseMove(offsc.x, offsc.y); + robot.delay(500); + + Point currLoc = MouseInfo.getPointerInfo().getLocation(); + + if (currLoc == null) { + throw new RuntimeException("Test Failed, getLocation returned null."); + } + + System.out.println("Current mouse location: " + currLoc); + if (currLoc.equals(OFF_SCREEN_LOC)) { + throw new RuntimeException("Test Failed, robot moved mouse off screen."); + } + } + + private static Point validateOffScreen(Point p) { + for (Rectangle rect : r) { + if (rect.contains(p)) { + return validateOffScreen(new Point(p.x * 2, p.y)); + } + } + return p; + } +} From e984fa7997dda922708edf556d1839b866e44e55 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 3 Jun 2025 18:41:05 +0000 Subject: [PATCH 112/216] 8358539: ProblemList jdk/jfr/api/consumer/TestRecordingFileWrite.java Reviewed-by: ayang, bpb --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 28bb2a1f033..f44dd5c7a7d 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -774,6 +774,7 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic- jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64 jdk/jfr/jvm/TestWaste.java 8282427 generic-all +jdk/jfr/api/consumer/TestRecordingFileWrite.java 8358536 generic-all ############################################################################ From 406f1bc5b94408778063b885cdac807fd1501e44 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Tue, 3 Jun 2025 18:46:55 +0000 Subject: [PATCH 113/216] 8357650: ThreadSnapshot to take snapshot of thread for thread dumps Co-authored-by: Alan Bateman Co-authored-by: Alex Menkov Reviewed-by: sspitsyn, kevinw --- src/hotspot/share/classfile/javaClasses.cpp | 2 +- src/hotspot/share/classfile/vmSymbols.hpp | 6 + src/hotspot/share/include/jvm.h | 3 + src/hotspot/share/prims/jvm.cpp | 9 + src/hotspot/share/prims/jvmtiThreadState.hpp | 2 +- .../share/services/diagnosticCommand.cpp | 2 + src/hotspot/share/services/threadService.cpp | 436 +++++++++++++++++- src/hotspot/share/services/threadService.hpp | 7 + .../jdk/internal/vm/ThreadSnapshot.java | 217 +++++++++ .../share/native/libjava/ThreadSnapshot.c | 36 ++ 10 files changed, 716 insertions(+), 4 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java create mode 100644 src/java.base/share/native/libjava/ThreadSnapshot.c diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 3b34edf416e..8d32d73fb47 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1872,7 +1872,7 @@ ByteSize java_lang_Thread::thread_id_offset() { } oop java_lang_Thread::park_blocker(oop java_thread) { - return java_thread->obj_field(_park_blocker_offset); + return java_thread->obj_field_access(_park_blocker_offset); } oop java_lang_Thread::async_get_stack_trace(oop java_thread, TRAPS) { diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index f9f6bd07254..dc9ce61627b 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -742,6 +742,12 @@ class SerializeClosure; template(jdk_internal_vm_ThreadDumper, "jdk/internal/vm/ThreadDumper") \ template(dumpThreads_name, "dumpThreads") \ template(dumpThreadsToJson_name, "dumpThreadsToJson") \ + template(jdk_internal_vm_ThreadSnapshot, "jdk/internal/vm/ThreadSnapshot") \ + template(jdk_internal_vm_ThreadLock, "jdk/internal/vm/ThreadSnapshot$ThreadLock") \ + template(jdk_internal_vm_ThreadLock_signature, "Ljdk/internal/vm/ThreadSnapshot$ThreadLock;") \ + template(jdk_internal_vm_ThreadLock_array, "[Ljdk/internal/vm/ThreadSnapshot$ThreadLock;") \ + template(java_lang_StackTraceElement_of_name, "of") \ + template(java_lang_StackTraceElement_of_signature, "([Ljava/lang/StackTraceElement;)[Ljava/lang/StackTraceElement;") \ \ /* jcmd Thread.vthread_scheduler and Thread.vthread_pollers */ \ template(jdk_internal_vm_JcmdVThreadCommands, "jdk/internal/vm/JcmdVThreadCommands") \ diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 61857ac3ccd..73f60765a70 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -301,6 +301,9 @@ JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj); JNIEXPORT jobject JNICALL JVM_GetStackTrace(JNIEnv *env, jobject thread); +JNIEXPORT jobject JNICALL +JVM_CreateThreadSnapshot(JNIEnv* env, jobject thread); + JNIEXPORT jobjectArray JNICALL JVM_GetAllThreads(JNIEnv *env, jclass dummy); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index e50318c90b6..d669d7bf5ec 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -2961,6 +2961,15 @@ JVM_ENTRY(jobject, JVM_GetStackTrace(JNIEnv *env, jobject jthread)) return JNIHandles::make_local(THREAD, trace); JVM_END +JVM_ENTRY(jobject, JVM_CreateThreadSnapshot(JNIEnv* env, jobject jthread)) +#if INCLUDE_JVMTI + oop snapshot = ThreadSnapshotFactory::get_thread_snapshot(jthread, THREAD); + return JNIHandles::make_local(THREAD, snapshot); +#else + return nullptr; +#endif +JVM_END + JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name)) // We don't use a ThreadsListHandle here because the current thread // must be alive. diff --git a/src/hotspot/share/prims/jvmtiThreadState.hpp b/src/hotspot/share/prims/jvmtiThreadState.hpp index cb0a779bd5a..62d0c45e337 100644 --- a/src/hotspot/share/prims/jvmtiThreadState.hpp +++ b/src/hotspot/share/prims/jvmtiThreadState.hpp @@ -77,7 +77,7 @@ class JvmtiEnvThreadStateIterator : public StackObj { // // Virtual Thread Mount State Transition (VTMS transition) mechanism // -class JvmtiVTMSTransitionDisabler { +class JvmtiVTMSTransitionDisabler : public AnyObj { private: static volatile int _VTMS_transition_disable_for_one_count; // transitions for one virtual thread are disabled while it is positive static volatile int _VTMS_transition_disable_for_all_count; // transitions for all virtual threads are disabled while it is positive diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index 26a762fa109..8b6fa392c95 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -127,7 +127,9 @@ void DCmd::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // INCLUDE_JVMTI DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); +#if INCLUDE_JVMTI DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); +#endif // INCLUDE_JVMTI DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp index d320e17fafb..8e0c955bff8 100644 --- a/src/hotspot/share/services/threadService.cpp +++ b/src/hotspot/share/services/threadService.cpp @@ -34,21 +34,25 @@ #include "nmt/memTag.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" +#include "oops/method.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "prims/jvmtiRawMonitor.hpp" +#include "prims/jvmtiThreadState.hpp" #include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" +#include "runtime/javaCalls.hpp" #include "runtime/javaThread.inline.hpp" +#include "runtime/jniHandles.inline.hpp" #include "runtime/objectMonitor.inline.hpp" -#include "runtime/synchronizer.hpp" +#include "runtime/synchronizer.inline.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threads.hpp" #include "runtime/threadSMR.inline.hpp" -#include "runtime/vframe.hpp" +#include "runtime/vframe.inline.hpp" #include "runtime/vmThread.hpp" #include "runtime/vmOperations.hpp" #include "services/threadService.hpp" @@ -1115,3 +1119,431 @@ ThreadsListEnumerator::ThreadsListEnumerator(Thread* cur_thread, _threads_array->append(h); } } + + +// jdk.internal.vm.ThreadSnapshot support +#if INCLUDE_JVMTI + +class GetThreadSnapshotClosure: public HandshakeClosure { +private: + static OopStorage* oop_storage() { + assert(_thread_service_storage != nullptr, "sanity"); + return _thread_service_storage; + } + +public: + struct OwnedLock { + // should be synced with ordinals of jdk.internal.vm.ThreadSnapshot.OwnedLockType enum + enum Type { + NOTHING = -1, + LOCKED = 0, + ELIMINATED = 1, + }; + + int _frame_depth; + Type _type; + // synchronization object (when type == LOCKED) or its klass (type == ELIMINATED) + OopHandle _obj; + + OwnedLock(int depth, Type type, OopHandle obj): _frame_depth(depth), _type(type), _obj(obj) {} + OwnedLock(): _frame_depth(0), _type(NOTHING), _obj(nullptr) {} + }; + + struct Blocker { + // should be synced with ordinals of jdk.internal.vm.ThreadSnapshot.BlockerLockType enum + enum Type { + NOTHING = -1, + PARK_BLOCKER = 0, + WAITING_TO_LOCK = 1, + WAITING_ON = 2, + }; + + Type _type; + // park blocker or an object the thread waiting on/trying to lock + OopHandle _obj; + + Blocker(Type type, OopHandle obj): _type(type), _obj(obj) {} + Blocker(): _type(NOTHING), _obj(nullptr) {} + + bool is_empty() const { + return _type == NOTHING; + } + }; + + Handle _thread_h; + JavaThread* _java_thread; + int _frame_count; // length of _methods and _bcis arrays + GrowableArray* _methods; + GrowableArray* _bcis; + JavaThreadStatus _thread_status; + OopHandle _thread_name; + GrowableArray* _locks; + Blocker _blocker; + + GetThreadSnapshotClosure(Handle thread_h, JavaThread* java_thread): + HandshakeClosure("GetThreadSnapshotClosure"), + _thread_h(thread_h), _java_thread(java_thread), + _frame_count(0), _methods(nullptr), _bcis(nullptr), + _thread_status(), _thread_name(nullptr), + _locks(nullptr), _blocker() { + } + virtual ~GetThreadSnapshotClosure() { + delete _methods; + delete _bcis; + _thread_name.release(oop_storage()); + if (_locks != nullptr) { + for (int i = 0; i < _locks->length(); i++) { + _locks->at(i)._obj.release(oop_storage()); + } + delete _locks; + } + _blocker._obj.release(oop_storage()); + } + +private: + void detect_locks(javaVFrame* jvf, int depth) { + Thread* current = Thread::current(); + + if (depth == 0 && _blocker.is_empty()) { + // If this is the first frame and it is java.lang.Object.wait(...) + // then print out the receiver. + if (jvf->method()->name() == vmSymbols::wait_name() && + jvf->method()->method_holder()->name() == vmSymbols::java_lang_Object()) { + OopHandle lock_object; + StackValueCollection* locs = jvf->locals(); + if (!locs->is_empty()) { + StackValue* sv = locs->at(0); + if (sv->type() == T_OBJECT) { + Handle o = locs->at(0)->get_obj(); + lock_object = OopHandle(oop_storage(), o()); + } + } + _blocker = Blocker(Blocker::WAITING_ON, lock_object); + } + } + + GrowableArray* mons = jvf->monitors(); + if (!mons->is_empty()) { + for (int index = (mons->length() - 1); index >= 0; index--) { + MonitorInfo* monitor = mons->at(index); + if (monitor->eliminated() && jvf->is_compiled_frame()) { // Eliminated in compiled code + if (monitor->owner_is_scalar_replaced()) { + Klass* k = java_lang_Class::as_Klass(monitor->owner_klass()); + _locks->push(OwnedLock(depth, OwnedLock::ELIMINATED, OopHandle(oop_storage(), k->klass_holder()))); + } else { + Handle owner(current, monitor->owner()); + if (owner.not_null()) { + Klass* k = owner->klass(); + _locks->push(OwnedLock(depth, OwnedLock::ELIMINATED, OopHandle(oop_storage(), k->klass_holder()))); + } + } + continue; + } + if (monitor->owner() != nullptr) { + // the monitor is associated with an object, i.e., it is locked + + if (depth == 0 && _blocker.is_empty()) { + ObjectMonitor* pending_moninor = java_lang_VirtualThread::is_instance(_thread_h()) + ? java_lang_VirtualThread::current_pending_monitor(_thread_h()) + : jvf->thread()->current_pending_monitor(); + + markWord mark = monitor->owner()->mark(); + // The first stage of async deflation does not affect any field + // used by this comparison so the ObjectMonitor* is usable here. + if (mark.has_monitor()) { + ObjectMonitor* mon = ObjectSynchronizer::read_monitor(current, monitor->owner(), mark); + if (// if the monitor is null we must be in the process of locking + mon == nullptr || + // we have marked ourself as pending on this monitor + mon == pending_moninor || + // we are not the owner of this monitor + (_java_thread != nullptr && !mon->is_entered(_java_thread))) { + _blocker = Blocker(Blocker::WAITING_TO_LOCK, OopHandle(oop_storage(), monitor->owner())); + continue; // go to next monitor + } + } + } + _locks->push(OwnedLock(depth, OwnedLock::LOCKED, OopHandle(oop_storage(), monitor->owner()))); + } + } + } + } + +public: + void do_thread(Thread* th) override { + Thread* current = Thread::current(); + + bool is_virtual = java_lang_VirtualThread::is_instance(_thread_h()); + if (_java_thread != nullptr) { + if (is_virtual) { + // mounted vthread, use carrier thread state + oop carrier_thread = java_lang_VirtualThread::carrier_thread(_thread_h()); + _thread_status = java_lang_Thread::get_thread_status(carrier_thread); + } else { + _thread_status = java_lang_Thread::get_thread_status(_thread_h()); + } + } else { + // unmounted vthread + int vt_state = java_lang_VirtualThread::state(_thread_h()); + _thread_status = java_lang_VirtualThread::map_state_to_thread_status(vt_state); + } + _thread_name = OopHandle(oop_storage(), java_lang_Thread::name(_thread_h())); + + if (_java_thread != nullptr && !_java_thread->has_last_Java_frame()) { + // stack trace is empty + return; + } + + bool vthread_carrier = !is_virtual && (_java_thread != nullptr) && (_java_thread->vthread_continuation() != nullptr); + + oop park_blocker = java_lang_Thread::park_blocker(_thread_h()); + if (park_blocker != nullptr) { + _blocker = Blocker(Blocker::PARK_BLOCKER, OopHandle(oop_storage(), park_blocker)); + } + + ResourceMark rm(current); + HandleMark hm(current); + + const int max_depth = MaxJavaStackTraceDepth; + const bool skip_hidden = !ShowHiddenFrames; + + // Pick minimum length that will cover most cases + int init_length = 64; + _methods = new (mtInternal) GrowableArray(init_length, mtInternal); + _bcis = new (mtInternal) GrowableArray(init_length, mtInternal); + _locks = new (mtInternal) GrowableArray(init_length, mtInternal); + int total_count = 0; + + vframeStream vfst(_java_thread != nullptr + ? vframeStream(_java_thread, false, true, vthread_carrier) + : vframeStream(java_lang_VirtualThread::continuation(_thread_h()))); + + for (; + !vfst.at_end() && (max_depth == 0 || max_depth != total_count); + vfst.next()) { + + detect_locks(vfst.asJavaVFrame(), total_count); + + if (skip_hidden && (vfst.method()->is_hidden() || + vfst.method()->is_continuation_enter_intrinsic())) { + continue; + } + _methods->push(vfst.method()); + _bcis->push(vfst.bci()); + total_count++; + } + + _frame_count = total_count; + } +}; + +class jdk_internal_vm_ThreadLock: AllStatic { + static bool _inited; + static int _depth_offset; + static int _typeOrdinal_offset; + static int _obj_offset; + + static void compute_offsets(InstanceKlass* klass, TRAPS) { + JavaClasses::compute_offset(_depth_offset, klass, "depth", vmSymbols::int_signature(), false); + JavaClasses::compute_offset(_typeOrdinal_offset, klass, "typeOrdinal", vmSymbols::int_signature(), false); + JavaClasses::compute_offset(_obj_offset, klass, "obj", vmSymbols::object_signature(), false); + } +public: + static void init(InstanceKlass* klass, TRAPS) { + if (!_inited) { + compute_offsets(klass, CHECK); + _inited = true; + } + } + + static Handle create(InstanceKlass* klass, int depth, int type_ordinal, OopHandle obj, TRAPS) { + init(klass, CHECK_NH); + Handle result = klass->allocate_instance_handle(CHECK_NH); + result->int_field_put(_depth_offset, depth); + result->int_field_put(_typeOrdinal_offset, type_ordinal); + result->obj_field_put(_obj_offset, obj.resolve()); + return result; + } +}; + +bool jdk_internal_vm_ThreadLock::_inited = false; +int jdk_internal_vm_ThreadLock::_depth_offset; +int jdk_internal_vm_ThreadLock::_typeOrdinal_offset; +int jdk_internal_vm_ThreadLock::_obj_offset; + +class jdk_internal_vm_ThreadSnapshot: AllStatic { + static bool _inited; + static int _name_offset; + static int _threadStatus_offset; + static int _carrierThread_offset; + static int _stackTrace_offset; + static int _locks_offset; + static int _blockerTypeOrdinal_offset; + static int _blockerObject_offset; + + static void compute_offsets(InstanceKlass* klass, TRAPS) { + JavaClasses::compute_offset(_name_offset, klass, "name", vmSymbols::string_signature(), false); + JavaClasses::compute_offset(_threadStatus_offset, klass, "threadStatus", vmSymbols::int_signature(), false); + JavaClasses::compute_offset(_carrierThread_offset, klass, "carrierThread", vmSymbols::thread_signature(), false); + JavaClasses::compute_offset(_stackTrace_offset, klass, "stackTrace", vmSymbols::java_lang_StackTraceElement_array(), false); + JavaClasses::compute_offset(_locks_offset, klass, "locks", vmSymbols::jdk_internal_vm_ThreadLock_array(), false); + JavaClasses::compute_offset(_blockerTypeOrdinal_offset, klass, "blockerTypeOrdinal", vmSymbols::int_signature(), false); + JavaClasses::compute_offset(_blockerObject_offset, klass, "blockerObject", vmSymbols::object_signature(), false); + } +public: + static void init(InstanceKlass* klass, TRAPS) { + if (!_inited) { + compute_offsets(klass, CHECK); + _inited = true; + } + } + + static Handle allocate(InstanceKlass* klass, TRAPS) { + init(klass, CHECK_NH); + Handle h_k = klass->allocate_instance_handle(CHECK_NH); + return h_k; + } + + static void set_name(oop snapshot, oop name) { + snapshot->obj_field_put(_name_offset, name); + } + static void set_thread_status(oop snapshot, int status) { + snapshot->int_field_put(_threadStatus_offset, status); + } + static void set_carrier_thread(oop snapshot, oop carrier_thread) { + snapshot->obj_field_put(_carrierThread_offset, carrier_thread); + } + static void set_stack_trace(oop snapshot, oop trace) { + snapshot->obj_field_put(_stackTrace_offset, trace); + } + static void set_locks(oop snapshot, oop locks) { + snapshot->obj_field_put(_locks_offset, locks); + } + static void set_blocker(oop snapshot, int type_ordinal, oop lock) { + snapshot->int_field_put(_blockerTypeOrdinal_offset, type_ordinal); + snapshot->obj_field_put(_blockerObject_offset, lock); + } +}; + +bool jdk_internal_vm_ThreadSnapshot::_inited = false; +int jdk_internal_vm_ThreadSnapshot::_name_offset; +int jdk_internal_vm_ThreadSnapshot::_threadStatus_offset; +int jdk_internal_vm_ThreadSnapshot::_carrierThread_offset; +int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset; +int jdk_internal_vm_ThreadSnapshot::_locks_offset; +int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset; +int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset; + +oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) { + ThreadsListHandle tlh(THREAD); + + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + Handle thread_h(THREAD, JNIHandles::resolve(jthread)); + + // wrapper to auto delete JvmtiVTMSTransitionDisabler + class TransitionDisabler { + JvmtiVTMSTransitionDisabler* _transition_disabler; + public: + TransitionDisabler(): _transition_disabler(nullptr) {} + ~TransitionDisabler() { + reset(); + } + void init(jobject jthread) { + _transition_disabler = new (mtInternal) JvmtiVTMSTransitionDisabler(jthread); + } + void reset() { + if (_transition_disabler != nullptr) { + delete _transition_disabler; + _transition_disabler = nullptr; + } + } + } 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 + transition_disabler.init(jthread); + + carrier_thread = Handle(THREAD, java_lang_VirtualThread::carrier_thread(thread_h())); + if (carrier_thread != nullptr) { + java_thread = java_lang_Thread::thread(carrier_thread()); + } + } else { + java_thread = java_lang_Thread::thread(thread_h()); + } + + // Handshake with target + GetThreadSnapshotClosure cl(thread_h, java_thread); + if (java_thread == nullptr) { + // unmounted vthread, execute on the current thread + cl.do_thread(nullptr); + } else { + Handshake::execute(&cl, &tlh, java_thread); + } + + // all info is collected, can enable transitions. + transition_disabler.reset(); + + // StackTrace + InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass(); + assert(ste_klass != nullptr, "must be loaded"); + + objArrayHandle trace = oopFactory::new_objArray_handle(ste_klass, cl._frame_count, CHECK_NULL); + + for (int i = 0; i < cl._frame_count; i++) { + methodHandle method(THREAD, cl._methods->at(i)); + oop element = java_lang_StackTraceElement::create(method, cl._bcis->at(i), CHECK_NULL); + trace->obj_at_put(i, element); + } + + // Locks + Symbol* lock_sym = vmSymbols::jdk_internal_vm_ThreadLock(); + Klass* lock_k = SystemDictionary::resolve_or_fail(lock_sym, true, CHECK_NULL); + InstanceKlass* lock_klass = InstanceKlass::cast(lock_k); + + objArrayHandle locks; + if (cl._locks != nullptr && cl._locks->length() > 0) { + locks = oopFactory::new_objArray_handle(lock_klass, cl._locks->length(), CHECK_NULL); + for (int n = 0; n < cl._locks->length(); n++) { + GetThreadSnapshotClosure::OwnedLock* lock_info = cl._locks->adr_at(n); + + Handle lock = jdk_internal_vm_ThreadLock::create(lock_klass, + lock_info->_frame_depth, lock_info->_type, lock_info->_obj, CHECK_NULL); + locks->obj_at_put(n, lock()); + } + } + + // call static StackTraceElement[] StackTraceElement.of(StackTraceElement[] stackTrace) + // to properly initialize STEs. + JavaValue result(T_OBJECT); + JavaCalls::call_static(&result, + ste_klass, + vmSymbols::java_lang_StackTraceElement_of_name(), + vmSymbols::java_lang_StackTraceElement_of_signature(), + trace, + CHECK_NULL); + // the method return the same trace array + + Symbol* snapshot_klass_name = vmSymbols::jdk_internal_vm_ThreadSnapshot(); + Klass* snapshot_klass = SystemDictionary::resolve_or_fail(snapshot_klass_name, true, CHECK_NULL); + if (snapshot_klass->should_be_initialized()) { + snapshot_klass->initialize(CHECK_NULL); + } + + Handle snapshot = jdk_internal_vm_ThreadSnapshot::allocate(InstanceKlass::cast(snapshot_klass), CHECK_NULL); + jdk_internal_vm_ThreadSnapshot::set_name(snapshot(), cl._thread_name.resolve()); + jdk_internal_vm_ThreadSnapshot::set_thread_status(snapshot(), (int)cl._thread_status); + jdk_internal_vm_ThreadSnapshot::set_carrier_thread(snapshot(), carrier_thread()); + jdk_internal_vm_ThreadSnapshot::set_stack_trace(snapshot(), trace()); + jdk_internal_vm_ThreadSnapshot::set_locks(snapshot(), locks()); + if (!cl._blocker.is_empty()) { + jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(), cl._blocker._type, cl._blocker._obj.resolve()); + } + return snapshot(); +} + +#endif // INCLUDE_JVMTI + diff --git a/src/hotspot/share/services/threadService.hpp b/src/hotspot/share/services/threadService.hpp index 17d8ba9b3cc..b1de4bc8703 100644 --- a/src/hotspot/share/services/threadService.hpp +++ b/src/hotspot/share/services/threadService.hpp @@ -631,4 +631,11 @@ class JavaThreadSleepState : public JavaThreadStatusChanger { } }; + +// jdk.internal.vm.ThreadSnapshot support +class ThreadSnapshotFactory: AllStatic { +public: + JVMTI_ONLY(static oop get_thread_snapshot(jobject jthread, TRAPS);) +}; + #endif // SHARE_SERVICES_THREADSERVICE_HPP diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java new file mode 100644 index 00000000000..205bfde5449 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java @@ -0,0 +1,217 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm; + +import java.util.Arrays; +import java.util.stream.Stream; + +/** + * Represents a snapshot of information about a Thread. + */ +class ThreadSnapshot { + private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0]; + private static final ThreadLock[] EMPTY_LOCKS = new ThreadLock[0]; + + // filled by VM + private String name; + private int threadStatus; + private Thread carrierThread; + private StackTraceElement[] stackTrace; + // owned monitors + private ThreadLock[] locks; + // an object the thread is blocked/waiting on, converted to ThreadBlocker by ThreadSnapshot.of() + private int blockerTypeOrdinal; + private Object blockerObject; + + // set by ThreadSnapshot.of() + private ThreadBlocker blocker; + + private ThreadSnapshot() {} + + /** + * Take a snapshot of a Thread to get all information about the thread. + */ + static ThreadSnapshot of(Thread thread) { + ThreadSnapshot snapshot = create(thread); + if (snapshot.stackTrace == null) { + snapshot.stackTrace = EMPTY_STACK; + } + if (snapshot.locks != null) { + Arrays.stream(snapshot.locks).forEach(ThreadLock::finishInit); + } else { + snapshot.locks = EMPTY_LOCKS; + } + if (snapshot.blockerObject != null) { + snapshot.blocker = new ThreadBlocker(snapshot.blockerTypeOrdinal, snapshot.blockerObject); + snapshot.blockerObject = null; // release + } + return snapshot; + } + + /** + * Returns the thread name. + */ + String threadName() { + return name; + } + + /** + * Returns the thread state. + */ + Thread.State threadState() { + return jdk.internal.misc.VM.toThreadState(threadStatus); + } + + /** + * Returns the thread stack trace. + */ + StackTraceElement[] stackTrace() { + return stackTrace; + } + + /** + * Returns the thread's parkBlocker. + */ + Object parkBlocker() { + return getBlocker(BlockerLockType.PARK_BLOCKER); + } + + /** + * Returns the object that the thread is blocked on. + * @throws IllegalStateException if not in the blocked state + */ + Object blockedOn() { + if (threadState() != Thread.State.BLOCKED) { + throw new IllegalStateException(); + } + return getBlocker(BlockerLockType.WAITING_TO_LOCK); + } + + /** + * Returns the object that the thread is waiting on. + * @throws IllegalStateException if not in the waiting state + */ + Object waitingOn() { + if (threadState() != Thread.State.WAITING + && threadState() != Thread.State.TIMED_WAITING) { + throw new IllegalStateException(); + } + return getBlocker(BlockerLockType.WAITING_ON); + } + + private Object getBlocker(BlockerLockType type) { + return (blocker != null && blocker.type == type) ? blocker.obj : null; + } + + /** + * Returns true if the thread owns any object monitors. + */ + boolean ownsMonitors() { + return locks.length > 0; + } + + /** + * Returns the objects that the thread locked at the given depth. The stream + * will contain a null element for a monitor that has been eliminated. + */ + Stream ownedMonitorsAt(int depth) { + return Arrays.stream(locks) + .filter(lock -> lock.depth() == depth) + .map(lock -> (lock.type == OwnedLockType.LOCKED) + ? lock.lockObject() + : /*eliminated*/ null); + } + + /** + * If the thread is a mounted virtual thread then return its carrier. + */ + Thread carrierThread() { + return carrierThread; + } + + /** + * Represents information about a locking operation. + */ + private enum OwnedLockType { + LOCKED, + // Lock object is a class of the eliminated monitor + ELIMINATED, + } + + private enum BlockerLockType { + // Park blocker + PARK_BLOCKER, + WAITING_TO_LOCK, + // Object.wait() + WAITING_ON, + } + + /** + * Represents a locking operation of a thread at a specific stack depth. + */ + private class ThreadLock { + private static final OwnedLockType[] lockTypeValues = OwnedLockType.values(); // cache + + // set by the VM + private int depth; + private int typeOrdinal; + private Object obj; + + // set by ThreadLock.of() + private OwnedLockType type; + + private ThreadLock() {} + + void finishInit() { + type = lockTypeValues[typeOrdinal]; + } + + int depth() { + return depth; + } + + OwnedLockType type() { + return type; + } + + Object lockObject() { + if (type == OwnedLockType.ELIMINATED) { + // we have no lock object, lock contains lock class + return null; + } + return obj; + } + } + + private record ThreadBlocker(BlockerLockType type, Object obj) { + private static final BlockerLockType[] lockTypeValues = BlockerLockType.values(); // cache + + ThreadBlocker(int typeOrdinal, Object obj) { + this(lockTypeValues[typeOrdinal], obj); + } + } + + private static native ThreadSnapshot create(Thread thread); +} diff --git a/src/java.base/share/native/libjava/ThreadSnapshot.c b/src/java.base/share/native/libjava/ThreadSnapshot.c new file mode 100644 index 00000000000..feea629f4c7 --- /dev/null +++ b/src/java.base/share/native/libjava/ThreadSnapshot.c @@ -0,0 +1,36 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "jni.h" +#include "jvm.h" + +#include "jdk_internal_vm_ThreadSnapshot.h" + + +JNIEXPORT jobject JNICALL +Java_jdk_internal_vm_ThreadSnapshot_create(JNIEnv *env, jclass cls, jobject thread) +{ + return JVM_CreateThreadSnapshot(env, thread); +} From cc11b7d1f560d42d1de123e650470362f1f2aabb Mon Sep 17 00:00:00 2001 From: Stefan Lobbenmeier Date: Tue, 3 Jun 2025 19:22:52 +0000 Subject: [PATCH 114/216] 8356128: Correct documentation for --linux-package-deps Reviewed-by: asemenyuk, almatvee --- .../jdk/jpackage/internal/resources/HelpResources.properties | 2 +- .../jdk/jpackage/internal/resources/HelpResources_de.properties | 2 +- .../jdk/jpackage/internal/resources/HelpResources_ja.properties | 2 +- .../jpackage/internal/resources/HelpResources_zh_CN.properties | 2 +- src/jdk.jpackage/share/man/jpackage.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties index c21daab30d0..0f0d9fd5a17 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties @@ -295,7 +295,7 @@ MSG_Help_linux_install=\ \ Maintainer for .deb package\n\ \ --linux-menu-group \n\ \ Menu group this application is placed in\n\ -\ --linux-package-deps\n\ +\ --linux-package-deps \n\ \ Required packages or capabilities for the application\n\ \ --linux-rpm-license-type \n\ \ Type of the license ("License: " of the RPM .spec)\n\ diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties index 31d6e11d70c..3c66e8bb151 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties @@ -33,7 +33,7 @@ MSG_Help_win_install=\ --win-dir-chooser\n Fügt ein Dialogfeld hinzu, MSG_Help_win_install_dir=Relativer Unterpfad unter dem Standardinstallationsverzeichnis\n MSG_Help_mac_install=\ --mac-dmg-content [,...]\n Nimmt den gesamten referenzierten Inhalt in die DMG-Datei auf.\n Diese Option kann mehrmals verwendet werden. \n MSG_Help_mac_launcher=\ --mac-package-identifier \n Eine ID, die die Anwendung für macOS eindeutig identifiziert\n Standardwert ist der Hauptklassenname.\n Es dürfen nur alphanumerische Zeichen (A-Z, a-z, 0-9), Bindestriche (-)\n und Punkte (.) verwendet werden.\n --mac-package-name \n Name der Anwendung, wie in der Menüleiste angezeigt\n Dieser kann vom Anwendungsnamen abweichen.\n Er darf maximal 15 Zeichen enthalten und muss für die Anzeige\n in der Menüleiste und im Infofenster der Anwendung geeignet sein.\n Standardwert: Anwendungsname.\n --mac-package-signing-prefix \n Beim Signieren des Anwendungspackages wird dieser Wert\n allen zu signierenden Komponenten ohne vorhandene\n Package-ID als Präfix vorangestellt.\n --mac-sign\n Anforderung zum Signieren des Packages oder des vordefinierten\nAnwendungsimages\n --mac-signing-keychain \n Name des Schlüsselbundes für die Suche nach der Signaturidentität\n Bei fehlender Angabe werden die Standardschlüsselbunde verwendet.\n --mac-signing-key-user-name \n Team- oder Benutzernamensteil der Apple-Signaturidentitäten. Um direkt zu steuern,\n welche Signaturidentität zum Signieren eines Anwendungsimages oder\n Installationsprogramms verwendet wird, verwenden Sie --mac-app-image-sign-identity und/oder\n --mac-installer-sign-identity. Diese Option kann nicht mit\n --mac-app-image-sign-identity oder --mac-installer-sign-identity kombiniert werden.\n --mac-app-image-sign-identity \n Zum Signieren des Anwendungsimages verwendete Identität. Dieser Wert wird\n direkt an die Option --sign des Tools "codesign" übergeben. Diese Option kann nicht\n mit --mac-signing-key-user-name kombiniert werden.\n --mac-installer-sign-identity \n Zum Signieren des Installationsprogramms "pkg" verwendete Identität. Dieser Wert wird\n direkt an die Option --sign des Tools "productbuild" übergeben. Diese Option\n kann nicht mit --mac-signing-key-user-name kombiniert werden.\n --mac-app-store\n Gibt an, dass die jpackage-Ausgabe für den\n Mac App Store bestimmt ist.\n --mac-entitlements \n Pfad zu einer Datei mit Berechtigungen, die beim Signieren\n von ausführbaren Dateien und Librarys im Bundle verwendet werden sollen.\n --mac-app-category \n Zeichenfolge für das Erstellen von LSApplicationCategoryType in\n Anwendungs-plist. Standardwert: "utilities".\n -MSG_Help_linux_install=\ --linux-package-name \n Name für das Linux-Package, Standardwert: Anwendungsname\n --linux-deb-maintainer \n Maintainer für .deb-Package\n --linux-menu-group \n Menügruppe, in der diese Anwendung abgelegt wird\n --linux-package-deps\n Erforderliche Packages oder Funktionen für die Anwendung\n --linux-rpm-license-type \n Typ der Lizenz ("License: " der RPM-SPEC-Datei)\n --linux-app-release \n Releasewert der RPM-SPEC-Datei oder \n Debian-Revisionswert der DEB-Kontrolldatei\n --linux-app-category \n Gruppenwert der RPM-SPEC-Datei oder \n Abschnittswert der DEB-Kontrolldatei\n --linux-shortcut\n Erstellt eine Verknüpfung für die Anwendung.\n +MSG_Help_linux_install=\ --linux-package-name \n Name für das Linux-Package, Standardwert: Anwendungsname\n --linux-deb-maintainer \n Maintainer für .deb-Package\n --linux-menu-group \n Menügruppe, in der diese Anwendung abgelegt wird\n --linux-package-deps \n Erforderliche Packages oder Funktionen für die Anwendung\n --linux-rpm-license-type \n Typ der Lizenz ("License: " der RPM-SPEC-Datei)\n --linux-app-release \n Releasewert der RPM-SPEC-Datei oder \n Debian-Revisionswert der DEB-Kontrolldatei\n --linux-app-category \n Gruppenwert der RPM-SPEC-Datei oder \n Abschnittswert der DEB-Kontrolldatei\n --linux-shortcut\n Erstellt eine Verknüpfung für die Anwendung.\n MSG_Help_mac_linux_install_dir=Absoluter Pfad des Installationsverzeichnisses der Anwendung\n MSG_Help_default_install_dir=Absoluter Pfad des Installationsverzeichnisses der Anwendung auf OS X\n oder Linux. Relativer Unterpfad des Installationsverzeichnisses der\n Anwendung wie "Programme" oder "AppData" unter Windows.\n MSG_Help_no_args=Verwendung: jpackage \nVerwenden Sie jpackage --help (oder -h), um eine Liste möglicher Optionen aufzurufen diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties index 39483b8f116..cae6ae216d3 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties @@ -36,7 +36,7 @@ MSG_Help_win_install_dir=デフォルトのインストール場所の下の相 MSG_Help_mac_install=\ --mac-dmg-content [,...]\n dmgに参照されたコンテンツをすべて含めます。\n このオプションは複数回使用できます。 \n MSG_Help_mac_launcher=\ --mac-package-identifier \n macOSのアプリケーションを一意に識別するID\n メイン・クラス名にデフォルト設定されています。\n 英数字(A-Z、a-z、0-9)、ハイフン(-)およびピリオド(.)文字のみ\n 使用できます。\n --mac-package-name \n メニュー・バーに表示されるアプリケーションの名前\n アプリケーション名とは異なります。\n この名前は16文字未満にする必要があり、メニュー・バーおよびアプリケーション情報ウィンドウに\n 表示するのに適している必要があります。\n アプリケーション名にデフォルト設定されています。\n --mac-package-signing-prefix \n アプリケーション・パッケージに署名する際、\n 既存のパッケージIDのない署名が必要なすべてのコンポーネントに、\n この値が接頭辞として付けられます。\n --mac-sign\n パッケージまたは事前定義済アプリケーション・イメージに署名するよう\n リクエストします。\n --mac-signing-keychain \n 署名アイデンティティを検索するキーチェーンの名前\n 指定しなかった場合、標準のキーチェーンが使用されます。\n --mac-signing-key-user-name \n Apple署名アイデンティティのチームまたはユーザー名部分。\n アプリケーション・イメージまたはインストーラの署名に使用する署名アイデンティティの\n 直接制御には、--mac-app-image-sign-identityまたは\n --mac-installer-sign-identity(あるいは両方)を使用します。このオプションは\n --mac-app-image-sign-identityまたは--mac-installer-sign-identityと組み合せることはできません。\n --mac-app-image-sign-identity \n アプリケーション・イメージの署名に使用するアイデンティティ。この値は直接\n "codesign"ツールの--signオプションに渡されます。このオプションは\n \ --mac-signing-key-user-nameと組み合せることはできません。\n --mac-installer-sign-identity \n "pkg"インストーラの署名に使用するアイデンティティ。この値は直接\n "productbuild"ツールの--signオプションに渡されます。このオプションは\n --mac-signing-key-user-nameと組み合せることはできません。\n --mac-app-store\n jpackage出力がMac App Store用であること\n を示します。\n --mac-entitlements \n バンドルの実行可能ファイルおよびライブラリの署名時に\n 使用する権限を含むファイルのパス。\n --mac-app-category \n アプリケーションのplistのLSApplicationCategoryTypeを生成する際に使用する文字列。\n デフォルト値は"utilities"です。\n -MSG_Help_linux_install=\ --linux-package-name \n Linuxパッケージの名前。アプリケーション名にデフォルト設定されています\n --linux-deb-maintainer \n .debパッケージのMaintainer\n --linux-menu-group \n このアプリケーションが配置されているメニュー・グループ\n --linux-package-deps\n アプリケーションに必要なパッケージまたは機能\n --linux-rpm-license-type \n ライセンスのタイプ(RPM .specの"License: ")\n --linux-app-release \n RPM .specファイルのリリース値または\n DEBコントロール・ファイルのDebianリビジョン値。\n --linux-app-category \n RPM .specファイルのグループ値または \n DEBコントロール・ファイルのセクション値\n --linux-shortcut\n アプリケーションのショートカットを作成します。\n +MSG_Help_linux_install=\ --linux-package-name \n Linuxパッケージの名前。アプリケーション名にデフォルト設定されています\n --linux-deb-maintainer \n .debパッケージのMaintainer\n --linux-menu-group \n このアプリケーションが配置されているメニュー・グループ\n --linux-package-deps \n アプリケーションに必要なパッケージまたは機能\n --linux-rpm-license-type \n ライセンスのタイプ(RPM .specの"License: ")\n --linux-app-release \n RPM .specファイルのリリース値または\n DEBコントロール・ファイルのDebianリビジョン値。\n --linux-app-category \n RPM .specファイルのグループ値または \n DEBコントロール・ファイルのセクション値\n --linux-shortcut\n アプリケーションのショートカットを作成します。\n MSG_Help_mac_linux_install_dir=アプリケーションのインストール・ディレクトリの絶対パス\n MSG_Help_default_install_dir=OS XまたはLinux上のアプリケーションのインストール・ディレクトリの絶対パス。\n "プログラム・ファイル"や"AppData"など、Windows上のアプリケーションの\n インストール場所の相対サブパス。\n MSG_Help_no_args=使用方法: jpackage \n利用可能なオプションのリストについては、jpackage --help (or -h)を使用します diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties index 482381dd624..6adf62ef1f8 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties @@ -34,7 +34,7 @@ MSG_Help_win_install=\ --win-dir-chooser\n 添加一个对话框以允 MSG_Help_win_install_dir=默认安装位置下面的相对子路径\n MSG_Help_mac_install=\ --mac-dmg-content [,...]\n 包括 DMG 中引用的所有内容。\n 此选项可以使用多次。\n MSG_Help_mac_launcher=\ --mac-package-identifier \n 用来唯一地标识 macOS 应用程序的标识符\n 默认为主类名称。\n 只能使用字母数字 (A-Z,a-z,0-9)、连字符 (-) 和\n 句点 (.) 字符。\n --mac-package-name \n 出现在菜单栏中的应用程序名称\n 这可以与应用程序名称不同。\n 此名称的长度必须小于 16 个字符,适合\n 显示在菜单栏中和应用程序“信息”窗口中。\n 默认为应用程序名称。\n --mac-package-signing-prefix \n 在对应用程序包签名时,会在所有需要签名\n 但当前没有程序包标识符的组件的\n 前面加上此值。\n --mac-sign\n 请求对程序包或预定义的应用程序映像\n 进行签名。\n --mac-signing-keychain \n 要用来搜索签名身份的密钥链的名称\n 如果未指定,则使用标准的密钥链。\n --mac-signing-key-user-name \n Apple 签名身份的团队或用户名称部分。为了直接\n 控制用于对应用程序映像或安装程序进行签名的\n 签名身份,请使用 --mac-app-image-sign-identity 和/或\n --mac-installer-sign-identity。此选项不能与\n --mac-app-image-sign-identity 或 --mac-installer-sign-identity 结合使用。\n --mac-app-image-sign-identity \n 用于对应用程序映像进行签名的身份。此值将直接\n 传递至 "codesign" 工具的 --sign 选项。此选项不能\n 与 --mac-signing-key-user-name 结合使用。\n --mac-installer-sign-identity \n 用于对 "pkg" 安装程序进行签名的身份。此值将直接\n 传递至 "productbuild" 工具的 --sign 选项。此选项不能\n 与 --mac-signing-key-user-name 结合使用。\n --mac-app-store\n 指示 jpackage 输出面向\n Mac App Store。\n --mac-entitlements \n 包含一些权利的文件的路径,在对捆绑包中的可执行文件\n 和库进行签名时会使用这些权利。\n --mac-app-category \n 用于构造应用程序 plist 中 LSApplicationCategoryType 的\n 字符串。默认值为 "utilities"。\n -MSG_Help_linux_install=\ --linux-package-name \n Linux 程序包的名称,默认为应用程序名称\n --linux-deb-maintainer \n .deb 程序包的维护程序\n --linux-menu-group \n 此应用程序所在的菜单组\n --linux-package-deps\n 应用程序所需的程序包或功能\n --linux-rpm-license-type \n 许可证的类型(RPM .spec 的 "License: ")\n --linux-app-release \n RPM .spec 文件的发行版值或 \n DEB 控制文件的 Debian 修订版值\n --linux-app-category \n RPM .spec 文件的组值或 \n DEB 控制文件的节值\n --linux-shortcut\n 为应用程序创建快捷方式。\n +MSG_Help_linux_install=\ --linux-package-name \n Linux 程序包的名称,默认为应用程序名称\n --linux-deb-maintainer \n .deb 程序包的维护程序\n --linux-menu-group \n 此应用程序所在的菜单组\n --linux-package-deps \n 应用程序所需的程序包或功能\n --linux-rpm-license-type \n 许可证的类型(RPM .spec 的 "License: ")\n --linux-app-release \n RPM .spec 文件的发行版值或 \n DEB 控制文件的 Debian 修订版值\n --linux-app-category \n RPM .spec 文件的组值或 \n DEB 控制文件的节值\n --linux-shortcut\n 为应用程序创建快捷方式。\n MSG_Help_mac_linux_install_dir=应用程序安装目录的绝对路径\n MSG_Help_default_install_dir=OS X 或 Linux 上应用程序安装目录的绝对路径。\n Windows 上应用程序安装位置的相对子路径\n (如 "Program Files" 或 "AppData")。\n MSG_Help_no_args=用法:jpackage \n使用 jpackage --help(或 -h)可获取可能选项的列表 diff --git a/src/jdk.jpackage/share/man/jpackage.md b/src/jdk.jpackage/share/man/jpackage.md index 34e524f9eee..e49b04e204e 100644 --- a/src/jdk.jpackage/share/man/jpackage.md +++ b/src/jdk.jpackage/share/man/jpackage.md @@ -446,7 +446,7 @@ The `jpackage` tool will take as input a Java application and a Java run-time im : Menu group this application is placed in -`--linux-package-deps` +`--linux-package-deps` *package-dep-string* : Required packages or capabilities for the application From a44a470052aff3b17fa53165f043ccce36c1ef9b Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 3 Jun 2025 19:23:29 +0000 Subject: [PATCH 115/216] 8358515: make cmp-baseline is broken after JDK-8349665 Reviewed-by: erikj --- make/Init.gmk | 22 ++++++++++++++-------- make/Main.gmk | 8 -------- make/PreInit.gmk | 3 ++- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/make/Init.gmk b/make/Init.gmk index 32624d7dee6..38959323628 100644 --- a/make/Init.gmk +++ b/make/Init.gmk @@ -110,7 +110,18 @@ reconfigure: CUSTOM_CONFIG_DIR="$(CUSTOM_CONFIG_DIR)" \ $(RECONFIGURE_COMMAND) ) -.PHONY: print-modules print-targets print-tests print-configuration reconfigure +# Create files that are needed to run most targets in Main.gmk +create-make-helpers: + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -j 1 -f make/GenerateFindTests.gmk \ + $(USER_MAKE_VARS) ) + ( cd $(TOPDIR) && \ + $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ + UPDATE_MODULE_DEPS=true NO_RECIPES=true \ + create-main-targets-include ) + +.PHONY: print-modules print-targets print-tests print-configuration \ + reconfigure create-make-helpers ############################################################################## # The main target. This will delegate all other targets into Main.gmk. @@ -130,7 +141,7 @@ TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \ # variables are explicitly propagated using $(USER_MAKE_VARS). main: MAKEOVERRIDES := -main: $(INIT_TARGETS) +main: $(INIT_TARGETS) create-make-helpers ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), ) $(call RotateLogFiles) $(ECHO) "Building $(TARGET_DESCRIPTION)" $(BUILD_LOG_PIPE_SIMPLE) @@ -142,12 +153,7 @@ main: $(INIT_TARGETS) $(SEQUENTIAL_TARGETS) ) # We might have cleaned away essential files, recreate them. ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -j 1 -f make/GenerateFindTests.gmk \ - $(USER_MAKE_VARS) ) - ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -j 1 -f make/Main.gmk $(USER_MAKE_VARS) \ - UPDATE_MODULE_DEPS=true NO_RECIPES=true \ - create-main-targets-include ) + $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk create-make-helpers ) endif ifneq ($(PARALLEL_TARGETS), ) $(call PrepareFailureLogs) diff --git a/make/Main.gmk b/make/Main.gmk index 386bd226842..d0568509a4e 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -423,14 +423,6 @@ bootcycle-images: ifneq ($(COMPILE_TYPE), cross) $(call LogWarn, Boot cycle build step 2: Building a new JDK image using previously built image) $(call MakeDir, $(OUTPUTDIR)/bootcycle-build) - # We need to create essential files for the bootcycle spec dir - ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -f make/GenerateFindTests.gmk \ - SPEC=$(BOOTCYCLE_SPEC)) - ( cd $(TOPDIR) && \ - $(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Main.gmk \ - SPEC=$(BOOTCYCLE_SPEC) UPDATE_MODULE_DEPS=true NO_RECIPES=true \ - create-main-targets-include ) +$(MAKE) $(MAKE_ARGS) -f $(TOPDIR)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \ LOG_PREFIX="[bootcycle] " JOBS= SPEC=$(BOOTCYCLE_SPEC) main else diff --git a/make/PreInit.gmk b/make/PreInit.gmk index bce61ccde5f..3df44308dd9 100644 --- a/make/PreInit.gmk +++ b/make/PreInit.gmk @@ -50,7 +50,8 @@ include $(TOPDIR)/make/Global.gmk # Targets provided by Init.gmk. ALL_INIT_TARGETS := print-modules print-targets print-configuration \ - print-tests reconfigure pre-compare-build post-compare-build + print-tests reconfigure pre-compare-build post-compare-build \ + create-make-helpers # CALLED_TARGETS is the list of targets that the user provided, # or "default" if unspecified. From e235b61a8bb70462921c09d197adc4b60267d327 Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Tue, 3 Jun 2025 19:38:58 +0000 Subject: [PATCH 116/216] 8357987: [JVMCI] Add support for retrieving all methods of a ResolvedJavaType Reviewed-by: dnsimon, yzheng, never --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 21 +++++++++++++++++++ src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 1 + .../jdk/vm/ci/hotspot/CompilerToVM.java | 12 ++++++++++- .../HotSpotResolvedJavaMethodImpl.java | 13 ++++++++++++ .../HotSpotResolvedObjectTypeImpl.java | 8 +++++++ .../hotspot/HotSpotResolvedPrimitiveType.java | 5 +++++ .../jdk/vm/ci/hotspot/HotSpotVMConfig.java | 1 + .../jdk/vm/ci/meta/ResolvedJavaMethod.java | 6 ++++++ .../jdk/vm/ci/meta/ResolvedJavaType.java | 12 +++++++++++ .../runtime/test/TestResolvedJavaMethod.java | 13 ++++++++++++ .../ci/runtime/test/TestResolvedJavaType.java | 12 +++++++++++ 11 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 2256a0edc99..4f6d4aaa099 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2224,6 +2224,26 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, ARGUME return JVMCIENV->get_jobjectArray(methods); C2V_END +C2V_VMENTRY_NULL(jobjectArray, getAllMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass))) + Klass* klass = UNPACK_PAIR(Klass, klass); + if (klass == nullptr) { + JVMCI_THROW_NULL(NullPointerException); + } + if (!klass->is_instance_klass()) { + JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL); + return JVMCIENV->get_jobjectArray(methods); + } + + InstanceKlass* iklass = InstanceKlass::cast(klass); + JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(iklass->methods()->length(), JVMCI_CHECK_NULL); + for (int i = 0; i < iklass->methods()->length(); i++) { + methodHandle mh(THREAD, iklass->methods()->at(i)); + JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL); + JVMCIENV->put_object_at(methods, i, method); + } + return JVMCIENV->get_jobjectArray(methods); +C2V_END + C2V_VMENTRY_NULL(jobjectArray, getDeclaredFieldsInfo, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass))) Klass* klass = UNPACK_PAIR(Klass, klass); if (klass == nullptr) { @@ -3359,6 +3379,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "boxPrimitive", CC "(" OBJECT ")" OBJECTCONSTANT, FN_PTR(boxPrimitive)}, {CC "getDeclaredConstructors", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getDeclaredConstructors)}, {CC "getDeclaredMethods", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getDeclaredMethods)}, + {CC "getAllMethods", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getAllMethods)}, {CC "getDeclaredFieldsInfo", CC "(" HS_KLASS2 ")[" FIELDINFO, FN_PTR(getDeclaredFieldsInfo)}, {CC "readStaticFieldValue", CC "(" HS_KLASS2 "JC)" JAVACONSTANT, FN_PTR(readStaticFieldValue)}, {CC "readFieldValue", CC "(" OBJECTCONSTANT HS_KLASS2 "JC)" JAVACONSTANT, FN_PTR(readFieldValue)}, diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 4302c0ce6ad..e26c815946d 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -693,6 +693,7 @@ declare_constant(ConstMethodFlags::_misc_reserved_stack_access) \ declare_constant(ConstMethodFlags::_misc_changes_current_thread) \ declare_constant(ConstMethodFlags::_misc_is_scoped) \ + declare_constant(ConstMethodFlags::_misc_is_overpass) \ \ declare_constant(CounterData::count_off) \ \ diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java index d7356659296..045b1f0fc12 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java @@ -1148,7 +1148,8 @@ final class CompilerToVM { native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass, long klassPointer); /** - * Gets the {@link ResolvedJavaMethod}s for all the non-constructor methods of {@code klass}. + * Gets the {@link ResolvedJavaMethod}s for all non-overpass and non-initializer + * methods of {@code klass}. */ ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass) { return getDeclaredMethods(klass, klass.getKlassPointer()); @@ -1156,6 +1157,15 @@ final class CompilerToVM { native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer); + /** + * Gets the {@link ResolvedJavaMethod}s for all methods of {@code klass}. + */ + ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass) { + return getAllMethods(klass, klass.getKlassPointer()); + } + + native ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer); + HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass) { return getDeclaredFieldsInfo(klass, klass.getKlassPointer()); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java index 59f5320cc54..9440a719dd4 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java @@ -573,6 +573,19 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); } + /* + * Currently in hotspot a method can either be a "normal" or an "overpass" + * method. Overpass methods are instance methods which are created when + * otherwise a valid candidate for method resolution would not be found. + */ + @Override + public boolean isDeclared() { + if (isConstructor() || isClassInitializer()) { + return false; + } + return (getConstMethodFlags() & config().constMethodFlagsIsOverpass) == 0; + } + @Override public Type[] getGenericParameterTypes() { if (isClassInitializer()) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java index 8d3b9f48b4c..17eede6f490 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -1067,6 +1067,14 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem return runtime().compilerToVm.getDeclaredMethods(this); } + @Override + public List getAllMethods(boolean forceLink) { + if (forceLink) { + link(); + } + return List.of(runtime().compilerToVm.getAllMethods(this)); + } + @Override public ResolvedJavaMethod getClassInitializer() { if (!isArray()) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java index 4425ade0880..b707906af08 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java @@ -296,6 +296,11 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType return new ResolvedJavaMethod[0]; } + @Override + public List getAllMethods(boolean forceLink) { + return List.of(); + } + @Override public ResolvedJavaMethod getClassInitializer() { return null; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index e93b98042b6..bc2e121fe90 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -196,6 +196,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class); final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class); final int constMethodFlagsIsScoped = getConstant("ConstMethodFlags::_misc_is_scoped", Integer.class); + final int constMethodFlagsIsOverpass = getConstant("ConstMethodFlags::_misc_is_overpass", Integer.class); final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class); final int constMethodHasLocalVariableTable = getConstant("ConstMethodFlags::_misc_has_localvariable_table", Integer.class); final int constMethodHasMethodAnnotations = getConstant("ConstMethodFlags::_misc_has_method_annotations", Integer.class); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java index 8758dbb3bb6..f401bc30f83 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaMethod.java @@ -114,6 +114,12 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP */ boolean isDefault(); + /** + * Returns {@code true} if this method is contained in the array returned by + * {@code getDeclaringClass().getDeclaredMethods()} + */ + boolean isDeclared(); + /** * Checks whether this method is a class initializer. * diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java index b5d29733a69..929a4713330 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java @@ -23,6 +23,7 @@ package jdk.vm.ci.meta; import java.lang.reflect.AnnotatedElement; +import java.util.List; import jdk.vm.ci.meta.Assumptions.AssumptionResult; @@ -365,6 +366,17 @@ public interface ResolvedJavaType extends JavaType, ModifiersProvider, Annotated throw new UnsupportedOperationException(); } + /** + * Returns a list containing all methods present within this type. This list can + * include methods implicitly created and used by the VM that are not present in + * {@link #getDeclaredMethods}. The returned List is unmodifiable; calls to any + * mutator method will always cause {@code UnsupportedOperationException} to be + * thrown. + * + * @param forceLink if {@code true}, forces this type to be {@link #link linked} + */ + List getAllMethods(boolean forceLink); + /** * Returns the {@code } method for this class if there is one. */ diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java index 75f074ad09d..6151ae68ce7 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java @@ -425,6 +425,19 @@ public class TestResolvedJavaMethod extends MethodUniverse { } } + @Test + public void isDeclaredTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + boolean expectedDeclared = Arrays.stream(m.getDeclaringClass().getDeclaredMethods()).anyMatch(i -> i.equals(m)); + assertEquals(expectedDeclared, m.isDeclared()); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isDeclared()); + } + } + @Test public void hasReceiverTest() { for (Map.Entry e : methods.entrySet()) { diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 456c4a5fd88..ee48724b71d 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -1019,6 +1019,18 @@ public class TestResolvedJavaType extends TypeUniverse { } } + @Test + public void getAllMethodsTest() { + for (Class c : classes) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + Set allMethods = new HashSet<>(type.getAllMethods(true)); + Stream allKnownMethods = Stream.concat(Arrays.stream(type.getDeclaredMethods()), Arrays.stream(type.getDeclaredConstructors())); + allKnownMethods = Stream.concat(allKnownMethods, Stream.ofNullable(type.getClassInitializer())); + List missingMethods = allKnownMethods.filter(m -> !allMethods.contains(m)).toList(); + assertTrue(missingMethods.toString(), missingMethods.isEmpty()); + } + } + static class A { static String name = "foo"; } From 704b5990a750719ca927e156553db7982637e590 Mon Sep 17 00:00:00 2001 From: Cesar Soares Lucas Date: Tue, 3 Jun 2025 20:15:20 +0000 Subject: [PATCH 117/216] 8358534: Bailout in Conv2B::Ideal when type of cmp input is not supported Reviewed-by: shade --- src/hotspot/share/opto/convertnode.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index 5df79a36edb..c468c66fdfd 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp @@ -79,6 +79,11 @@ Node* Conv2BNode::Ideal(PhaseGVN* phase, bool can_reshape) { assert(false, "Unrecognized comparison for Conv2B: %s", NodeClassNames[in(1)->Opcode()]); } + // Skip the transformation if input is unexpected. + if (cmp == nullptr) { + return nullptr; + } + // Replace Conv2B with the cmove Node* bol = phase->transform(new BoolNode(cmp, BoolTest::eq)); return new CMoveINode(bol, phase->intcon(1), phase->intcon(0), TypeInt::BOOL); From da49fa5e15b137c086ad8fd438bf448da42121cb Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Tue, 3 Jun 2025 20:47:17 +0000 Subject: [PATCH 118/216] 8354460: Streaming output for attach API should be turned on by default Reviewed-by: sspitsyn, kevinw --- src/hotspot/share/services/attachListener.cpp | 4 ++-- .../share/classes/sun/tools/attach/HotSpotVirtualMachine.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/services/attachListener.cpp b/src/hotspot/share/services/attachListener.cpp index d13a2e70b2b..92d3c302ded 100644 --- a/src/hotspot/share/services/attachListener.cpp +++ b/src/hotspot/share/services/attachListener.cpp @@ -172,8 +172,8 @@ volatile AttachListenerState AttachListener::_state = AL_NOT_INITIALIZED; AttachAPIVersion AttachListener::_supported_version = ATTACH_API_V1; -// Default is false (if jdk.attach.vm.streaming property is not set). -bool AttachListener::_default_streaming_output = false; +// Default is true (if jdk.attach.vm.streaming property is not set). +bool AttachListener::_default_streaming_output = true; static bool get_bool_sys_prop(const char* name, bool default_value, TRAPS) { ResourceMark rm(THREAD); diff --git a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java index e0ac0edda51..97139a5a206 100644 --- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java +++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java @@ -63,9 +63,8 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { static { String s = VM.getSavedProperty("jdk.attach.allowAttachSelf"); ALLOW_ATTACH_SELF = "".equals(s) || Boolean.parseBoolean(s); - // For now the default is false. String s2 = VM.getSavedProperty("jdk.attach.allowStreamingOutput"); - ALLOW_STREAMING_OUTPUT = "".equals(s2) || Boolean.parseBoolean(s2); + ALLOW_STREAMING_OUTPUT = !("false".equals(s2)); } private final boolean selfAttach; From 939753579b80d2910c78d8bbb1c97bd56afa21ba Mon Sep 17 00:00:00 2001 From: Daniel Gredler Date: Tue, 3 Jun 2025 23:27:44 +0000 Subject: [PATCH 119/216] 8356803: Test TextLayout/TestControls fails on windows & linux: line and paragraph separator show non-zero advance 8356812: Create an automated version of TextLayout/TestControls Reviewed-by: prr, honkar --- .../share/classes/sun/font/FontUtilities.java | 12 +- .../TextLayout/FormatCharAdvanceTest.java | 56 ++++-- .../awt/font/TextLayout/TestControls.java | 161 ------------------ 3 files changed, 54 insertions(+), 175 deletions(-) delete mode 100644 test/jdk/java/awt/font/TextLayout/TestControls.java diff --git a/src/java.desktop/share/classes/sun/font/FontUtilities.java b/src/java.desktop/share/classes/sun/font/FontUtilities.java index c2e3137e1b5..a14214ab751 100644 --- a/src/java.desktop/share/classes/sun/font/FontUtilities.java +++ b/src/java.desktop/share/classes/sun/font/FontUtilities.java @@ -370,17 +370,25 @@ public final class FontUtilities { } /** - * Checks whether or not the specified codepoint is whitespace which is + *

        Checks whether or not the specified codepoint is whitespace which is * ignorable at the shaping stage of text rendering. These ignorable * whitespace characters should be used prior to text shaping and * rendering to determine the position of the text, but are not themselves * rendered. * + *

        Includes 0x0009 (horizontal tab / TAB), 0x000A (line feed / LF), + * 0x000B (vertical tab / VT), 0x000C (form feed / FF), + * 0x000D (carriage return / CR), 0x0085 (next line / NEL), + * 0x2028 (line separator / LS), 0x2029 (paragraph separator / PS). + * * @param ch the codepoint to check * @return whether the specified codepoint is ignorable whitespace */ public static boolean isIgnorableWhitespace(int ch) { - return ch == 0x0009 || ch == 0x000a || ch == 0x000d; + return (ch >= 0x0009 && ch <= 0x000d) + || ch == 0x0085 + || ch == 0x2028 + || ch == 0x2029; } public static PlatformLogger getLogger() { diff --git a/test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java b/test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java index b37f7e02707..63cd890f1db 100644 --- a/test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java +++ b/test/jdk/java/awt/font/TextLayout/FormatCharAdvanceTest.java @@ -21,10 +21,11 @@ * questions. */ -/** +/* * @test - * @bug 8208377 6562489 8270265 - * @summary Confirm that format-category glyphs are not rendered or measured. + * @bug 8208377 6562489 8270265 8356803 8356812 4517298 + * @summary Confirm that default-ignorable and ignorable-whitespace + * glyphs are not rendered or measured. */ import java.awt.Color; @@ -48,9 +49,11 @@ import java.util.Map; public class FormatCharAdvanceTest { /** - *

        Font created for this test which contains glyphs for 0-9, a-z, A-Z, space, and most - * characters with Unicode general category = Format (Cf); the tests will pass if these - * format glyphs and their advances are ignored during text measurement and text drawing. + *

        Font created for this test which contains glyphs for 0-9, a-z, A-Z, + * some whitespace characters, and most characters with Unicode "Format" + * (Cf) general category; the tests will pass if the font glyphs and + * advances for default-ignorable and ignorable-whitespace characters + * are ignored during text measurement and text drawing. * *

        The following FontForge Python script was used to generate this font: * @@ -87,9 +90,11 @@ public class FormatCharAdvanceTest { * chars = 'bcdefghijklmnopqrstuvwxyz' \ * 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \ * '1234567890' \ - * '\u00AD\u0600\u0601\u0602\u0603\u0604\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E' \ - * '\u200B\u200C\u200D\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2060\u2061\u2062\u2063\u2064' \ - * '\u2066\u2067\u2068\u2069\u206A\u206B\u206C\u206D\u206E\u206F\uFEFF\uFFF9\uFFFA\uFFFB' \ + * '\u0009\u000A\u000B\u000C\u000D\u0085\u00AD' \ + * '\u0600\u0601\u0602\u0603\u0604\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E' \ + * '\u200B\u200C\u200D\u200E\u200F\u2028\u2029\u202A\u202B\u202C\u202D\u202E\u202F' \ + * '\u2060\u2061\u2062\u2063\u2064\u2065\u2066\u2067\u2068\u2069\u206A\u206B\u206C' \ + * '\u206D\u206E\u206F\uFEFF\uFFF9\uFFFA\uFFFB' \ * '\U000110BD\U000110CD\U00013430\U00013431\U00013432\U00013433\U00013434\U00013435\U00013436' \ * '\U00013437\U00013438\U00013439\U0001343A\U0001343B\U0001343C\U0001343D\U0001343E\U0001343F' \ * '\U0001BCA0\U0001BCA1\U0001BCA2\U0001BCA3\U0001D173\U0001D174\U0001D175\U0001D176\U0001D177' \ @@ -119,12 +124,12 @@ public class FormatCharAdvanceTest { * f4.write(encoded) * */ - private static final String TTF_BYTES = "AAEAAAANAIAAAwBQRkZUTaj5NMoAABWEAAAAHE9TLzKEBfqWAAABWAAAAGBjbWFw6BKIbQAAAuQAAAMoY3Z0IABEBREAAAYMAAAABGdhc3D//wADAAAVfAAAAAhnbHlmcb+r/AAABzQAAAksaGVhZCi9kzQAAADcAAAANmhoZWEIcgJeAAABFAAAACRobXR4JX8bnAAAAbgAAAEqbG9jYam4p4gAAAYQAAABIm1heHAA1wBCAAABOAAAACBuYW1lImUC5wAAEGAAAAGJcG9zdBd/2qEAABHsAAADjwABAAAAAQAAEAez8l8PPPUACwgAAAAAAON7pHEAAAAA43ukcQBEAAACZAVVAAAACAACAAAAAAAAAAEAAAVVAAAAuAJYAAAAAAJkAAEAAAAAAAAAAAAAAAAAAAAFAAEAAACQAAgAAgAIAAIAAgAAAAEAAQAAAEAALgABAAEABAJXAZAABQAABTMFmQAAAR4FMwWZAAAD1wBmAhIAAAIABQMAAAAAAACAACADAgAAABECAKgAAAAAUGZFZACAACD//wZm/mYAuAVVAAAAAAABAAAAAADIAMgAAAAgAAEC7ABEAAAAAAKqAAACOQAAAlgAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAAAAAAAFAAAAAwAAACwAAAAEAAAA2gABAAAAAAIiAAMAAQAAACwAAwAKAAAA2gAEAK4AAAAmACAABAAGACAAOQBaAHoArQYFBhwG3QcPCJEI4hgOIA8gLiBkIG/+///7//8AAAAgADAAQQBhAK0GAAYcBt0HDwiQCOIYDiALICogYCBm/v//+f///+P/1P/N/8f/lfpD+i35bfk897z3bOhB4EXgK9/63/kBagAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABqAGsAbAAMAAAAAAFIAAAAAAAAABoAAAAgAAAAIAAAAAMAAAAwAAAAOQAAAAQAAABBAAAAWgAAAA4AAABhAAAAegAAACgAAACtAAAArQAAAEIAAAYAAAAGBQAAAEMAAAYcAAAGHAAAAEkAAAbdAAAG3QAAAEoAAAcPAAAHDwAAAEsAAAiQAAAIkQAAAEwAAAjiAAAI4gAAAE4AABgOAAAYDgAAAE8AACALAAAgDwAAAFAAACAqAAAgLgAAAFUAACBgAAAgZAAAAFoAACBmAAAgbwAAAF8AAP7/AAD+/wAAAGkAAP/5AAD/+wAAAGoAARC9AAEQvQAAAG0AARDNAAEQzQAAAG4AATQwAAE0PwAAAG8AAbygAAG8owAAAH8AAdFzAAHRegAAAIMADgABAA4AAQAAAIsADgAgAA4AIQAAAIwADgB+AA4AfwAAAI4AAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMAAAAAAAAAAAAAAAAAAAAEBQYHCAkKCwwNAAAAAAAAAA4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnAAAAAAAAKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQFEQAAACwALAAsACwANAA8AEQATABUAFwAZABsAHQAfACEAIwAlACcAKQArAC0ALwAxADMANQA3ADkAOwA9AD8AQQBDAEUARwBJAEsATQBPAFEAUwBXgFmAW4BdgF+AYYBjgGWAZ4BpgGuAbYBvgHGAc4B1gHeAeYB7gH2Af4CBgIOAhYCHgImAi4CNgI+AkYCTgJWAl4CZgJuAnYCfgKGAo4ClgKeAqYCrgK2Ar4CxgLOAtYC3gLmAu4C9gL+AwYDDgMWAx4DJgMuAzYDPgNGA04DVgNeA2YDbgN2A34DhgOOA5YDngOmA64DtgO+A8YDzgPWA94D5gPuA/YD/gQGBA4EFgQeBCYELgQ2BD4ERgROBFYEXgRmBG4EdgR+BIYEjgSWAAAAAgBEAAACZAVVAAMABwAusQEALzyyBwQA7TKxBgXcPLIDAgDtMgCxAwAvPLIFBADtMrIHBgH8PLIBAgDtMjMRIRElIREhRAIg/iQBmP5oBVX6q0QEzQAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAAAAIAZABkAfQAyAADAAcAADc1IRUhNSEVZAGQ/nABkGRkZGRk//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAP//AGQAZAH0AMgSBgAoAAD//wBkAGQB9ADIEgYAKAAA//8AZABkAfQAyBIGACgAAAAAAA4ArgABAAAAAAAAAAAAAgABAAAAAAABAAQADQABAAAAAAACAAcAIgABAAAAAAADACAAbAABAAAAAAAEAAQAlwABAAAAAAAFAA8AvAABAAAAAAAGAAQA1gADAAEECQAAAAAAAAADAAEECQABAAgAAwADAAEECQACAA4AEgADAAEECQADAEAAKgADAAEECQAEAAgAjQADAAEECQAFAB4AnAADAAEECQAGAAgAzAAAAABUAGUAcwB0AABUZXN0AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABGAG8AbgB0AEYAbwByAGcAZQAgADIALgAwACAAOgAgAFQAZQBzAHQAIAA6ACAAOAAtADEAMgAtADIAMAAyADQAAEZvbnRGb3JnZSAyLjAgOiBUZXN0IDogOC0xMi0yMDI0AABUAGUAcwB0AABUZXN0AABWAGUAcgBzAGkAbwBuACAAMAAwADEALgAwADAAMAAAVmVyc2lvbiAwMDEuMDAwAABUAGUAcwB0AABUZXN0AAAAAAACAAAAAAAA/2cAZgAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAAAABAAIAAwATABQAFQAWABcAGAAZABoAGwAcACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0BAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8HdW5pMDBBRAd1bmkwNjAwB3VuaTA2MDEHdW5pMDYwMgd1bmkwNjAzB3VuaTA2MDQHdW5pMDYwNQd1bmkwNjFDB3VuaTA2REQHdW5pMDcwRgd1bmkwODkwB3VuaTA4OTEHdW5pMDhFMgd1bmkxODBFB3VuaTIwMEIHdW5pMjAwQwd1bmkyMDBEB3VuaTIwMEUHdW5pMjAwRgd1bmkyMDJBB3VuaTIwMkIHdW5pMjAyQwd1bmkyMDJEB3VuaTIwMkUHdW5pMjA2MAd1bmkyMDYxB3VuaTIwNjIHdW5pMjA2Mwd1bmkyMDY0B3VuaTIwNjYHdW5pMjA2Nwd1bmkyMDY4B3VuaTIwNjkHdW5pMjA2QQd1bmkyMDZCB3VuaTIwNkMHdW5pMjA2RAd1bmkyMDZFB3VuaTIwNkYHdW5pRkVGRgd1bmlGRkY5B3VuaUZGRkEHdW5pRkZGQgZ1MTEwQkQGdTExMENEBnUxMzQzMAZ1MTM0MzEGdTEzNDMyBnUxMzQzMwZ1MTM0MzQGdTEzNDM1BnUxMzQzNgZ1MTM0MzcGdTEzNDM4BnUxMzQzOQZ1MTM0M0EGdTEzNDNCBnUxMzQzQwZ1MTM0M0QGdTEzNDNFBnUxMzQzRgZ1MUJDQTAGdTFCQ0ExBnUxQkNBMgZ1MUJDQTMGdTFEMTczBnUxRDE3NAZ1MUQxNzUGdTFEMTc2BnUxRDE3NwZ1MUQxNzgGdTFEMTc5BnUxRDE3QQZ1RTAwMDEGdUUwMDIwBnVFMDAyMQZ1RTAwN0UGdUUwMDdGAAAAAAH//wACAAAAAQAAAADiAevnAAAAAON7pHEAAAAA43ukcQ=="; + private static final String TTF_BYTES = "AAEAAAANAIAAAwBQRkZUTarBS1AAABbcAAAAHE9TLzKD7vqWAAABWAAAAGBjbWFw11zF/AAAAvwAAANSY3Z0IABEBREAAAZQAAAABGdhc3D//wADAAAW1AAAAAhnbHlmgVJ3qAAAB4gAAAnMaGVhZCqFqboAAADcAAAANmhoZWEIcgJiAAABFAAAACRobXR4L1UevAAAAbgAAAFEbG9jYb8EwZoAAAZUAAABNG1heHAA4ABCAAABOAAAACBuYW1lJWcF2wAAEVQAAAGJcG9zdBSfZd0AABLgAAAD8QABAAAAAQAAzMHptF8PPPUACwgAAAAAAORfr7QAAAAA5F+vtABEAAACZAVVAAAACAACAAAAAAAAAAEAAAVVAAAAuAJYAAAAAAJkAAEAAAAAAAAAAAAAAAAAAAAJAAEAAACZAAgAAgAIAAIAAgAAAAEAAQAAAEAALgABAAEABAJXAZAABQAABTMFmQAAAR4FMwWZAAAD1wBmAhIAAAIABQMAAAAAAACAACADAgAAABECAKgAAAAAUGZFZACAAAn//wZm/mYAuAVVAAAAAAABAAAAAADIAMgAAAAgAAEC7ABEAAAAAAJYAGQCWABkAlgAZAJYAGQCWABkAjkAAAJYAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAZABkAGQAAAAFAAAAAwAAACwAAAAEAAAA7AABAAAAAAJMAAMAAQAAACwAAwAKAAAA7AAEAMAAAAAoACAABAAIAA0AIAA5AFoAegCFAK0GBQYcBt0HDwiRCOIYDiAPIC8gb/7///v//wAAAAkAIAAwAEEAYQCFAK0GAAYcBt0HDwiQCOIYDiALICggYP7///n//wAA/+f/2P/R/8v/wf+a+kj6Mvly+UH3wfdx6EbgSuAy4AIBcwAAAAEAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAMABAAFAAYAAgBzAHQAdQAMAAAAAAFgAAAAAAAAABwAAAAJAAAADAAAAAMAAAANAAAADQAAAAIAAAAgAAAAIAAAAAcAAAAwAAAAOQAAAAgAAABBAAAAWgAAABIAAABhAAAAegAAACwAAACFAAAAhQAAAEYAAACtAAAArQAAAEcAAAYAAAAGBQAAAEgAAAYcAAAGHAAAAE4AAAbdAAAG3QAAAE8AAAcPAAAHDwAAAFAAAAiQAAAIkQAAAFEAAAjiAAAI4gAAAFMAABgOAAAYDgAAAFQAACALAAAgDwAAAFUAACAoAAAgLwAAAFoAACBgAAAgbwAAAGIAAP7/AAD+/wAAAHIAAP/5AAD/+wAAAHMAARC9AAEQvQAAAHYAARDNAAEQzQAAAHcAATQwAAE0PwAAAHgAAbygAAG8owAAAIgAAdFzAAHRegAAAIwADgABAA4AAQAAAJQADgAgAA4AIQAAAJUADgB+AA4AfwAAAJcAAAEGAAABAAAAAAAAAAEDBAUGAgAAAAAAAAAAAAAAAAAAAAEAAAcAAAAAAAAAAAAAAAAAAAAICQoLDA0ODxARAAAAAAAAABITFBUWFxgZGhscHR4fICEiIyQlJicoKSorAAAAAAAALC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARAURAAAALAAsADQAPABEAEwAVABUAFwAZABsAHQAfACEAIwAlACcAKQArAC0ALwAxADMANQA3ADkAOwA9AD8AQQBDAEUARwBJAEsATQBPAFEAUwBVAFcAWQBbAF0AYYBjgGWAZ4BpgGuAbYBvgHGAc4B1gHeAeYB7gH2Af4CBgIOAhYCHgImAi4CNgI+AkYCTgJWAl4CZgJuAnYCfgKGAo4ClgKeAqYCrgK2Ar4CxgLOAtYC3gLmAu4C9gL+AwYDDgMWAx4DJgMuAzYDPgNGA04DVgNeA2YDbgN2A34DhgOOA5YDngOmA64DtgO+A8YDzgPWA94D5gPuA/YD/gQGBA4EFgQeBCYELgQ2BD4ERgROBFYEXgRmBG4EdgR+BIYEjgSWBJ4EpgSuBLYEvgTGBM4E1gTeBOYAAgBEAAACZAVVAAMABwAusQEALzyyBwQA7TKxBgXcPLIDAgDtMgCxAwAvPLIFBADtMrIHBgH8PLIBAgDtMjMRIRElIREhRAIg/iQBmP5oBVX6q0QEzQAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAAAAgBkAGQB9ADIAAMABwAANzUhFSE1IRVkAZD+cAGQZGRkZGT//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAD//wBkAGQB9ADIEgYALAAA//8AZABkAfQAyBIGACwAAP//AGQAZAH0AMgSBgAsAAAAAAAOAK4AAQAAAAAAAAAAAAIAAQAAAAAAAQAEAA0AAQAAAAAAAgAHACIAAQAAAAAAAwAgAGwAAQAAAAAABAAEAJcAAQAAAAAABQAPALwAAQAAAAAABgAEANYAAwABBAkAAAAAAAAAAwABBAkAAQAIAAMAAwABBAkAAgAOABIAAwABBAkAAwBAACoAAwABBAkABAAIAI0AAwABBAkABQAeAJwAAwABBAkABgAIAMwAAAAAVABlAHMAdAAAVGVzdAAAUgBlAGcAdQBsAGEAcgAAUmVndWxhcgAARgBvAG4AdABGAG8AcgBnAGUAIAAyAC4AMAAgADoAIABUAGUAcwB0ACAAOgAgADMAMAAtADUALQAyADAAMgA1AABGb250Rm9yZ2UgMi4wIDogVGVzdCA6IDMwLTUtMjAyNQAAVABlAHMAdAAAVGVzdAAAVgBlAHIAcwBpAG8AbgAgADAAMAAxAC4AMAAwADAAAFZlcnNpb24gMDAxLjAwMAAAVABlAHMAdAAAVGVzdAAAAAAAAgAAAAAAAP9nAGYAAAAAAAAAAAAAAAAAAAAAAAAAAACZAAAAAQECAQMBBAEFAQYAAwATABQAFQAWABcAGAAZABoAGwAcACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0BBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZB3VuaTAwMEQHdW5pMDAwOQd1bmkwMDBBB3VuaTAwMEIHdW5pMDAwQwd1bmkwMDg1B3VuaTAwQUQHdW5pMDYwMAd1bmkwNjAxB3VuaTA2MDIHdW5pMDYwMwd1bmkwNjA0B3VuaTA2MDUHdW5pMDYxQwd1bmkwNkREB3VuaTA3MEYHdW5pMDg5MAd1bmkwODkxB3VuaTA4RTIHdW5pMTgwRQd1bmkyMDBCB3VuaTIwMEMHdW5pMjAwRAd1bmkyMDBFB3VuaTIwMEYHdW5pMjAyOAd1bmkyMDI5B3VuaTIwMkEHdW5pMjAyQgd1bmkyMDJDB3VuaTIwMkQHdW5pMjAyRQd1bmkyMDJGB3VuaTIwNjAHdW5pMjA2MQd1bmkyMDYyB3VuaTIwNjMHdW5pMjA2NAd1bmkyMDY1B3VuaTIwNjYHdW5pMjA2Nwd1bmkyMDY4B3VuaTIwNjkHdW5pMjA2QQd1bmkyMDZCB3VuaTIwNkMHdW5pMjA2RAd1bmkyMDZFB3VuaTIwNkYHdW5pRkVGRgd1bmlGRkY5B3VuaUZGRkEHdW5pRkZGQgZ1MTEwQkQGdTExMENEBnUxMzQzMAZ1MTM0MzEGdTEzNDMyBnUxMzQzMwZ1MTM0MzQGdTEzNDM1BnUxMzQzNgZ1MTM0MzcGdTEzNDM4BnUxMzQzOQZ1MTM0M0EGdTEzNDNCBnUxMzQzQwZ1MTM0M0QGdTEzNDNFBnUxMzQzRgZ1MUJDQTAGdTFCQ0ExBnUxQkNBMgZ1MUJDQTMGdTFEMTczBnUxRDE3NAZ1MUQxNzUGdTFEMTc2BnUxRDE3NwZ1MUQxNzgGdTFEMTc5BnUxRDE3QQZ1RTAwMDEGdUUwMDIwBnVFMDAyMQZ1RTAwN0UGdUUwMDdGAAAAAAAAAf//AAIAAAABAAAAAOIB6+cAAAAA5F+vtAAAAADkX6+0"; /** * Same font as above, but in PostScript Type1 (PFB) format. */ - private static final String TYPE1_BYTES = "gAHhBgAAJSFQUy1BZG9iZUZvbnQtMS4wOiBUZXN0IDAwMS4wMDAKJSVUaXRsZTogVGVzdAolVmVyc2lvbjogMDAxLjAwMAolJUNyZWF0aW9uRGF0ZTogVHVlIERlYyAxMCAwMDo0Mzo1MCAyMDI0CiUlQ3JlYXRvcjogRGFuaWVsIEdyZWRsZXIKJSAyMDI0LTEyLTEwOiBDcmVhdGVkIHdpdGggRm9udEZvcmdlIChodHRwOi8vZm9udGZvcmdlLm9yZykKJSBHZW5lcmF0ZWQgYnkgRm9udEZvcmdlIDIwMjMwMTAxIChodHRwOi8vZm9udGZvcmdlLnNmLm5ldC8pCiUlRW5kQ29tbWVudHMKCjEwIGRpY3QgYmVnaW4KL0ZvbnRUeXBlIDEgZGVmCi9Gb250TWF0cml4IFswLjAwMDQ4ODI4MSAwIDAgMC4wMDA0ODgyODEgMCAwIF1yZWFkb25seSBkZWYKL0ZvbnROYW1lIC9UZXN0IGRlZgovRm9udEJCb3ggezEwMCAxMDAgNTAwIDIwMCB9cmVhZG9ubHkgZGVmCi9QYWludFR5cGUgMCBkZWYKL0ZvbnRJbmZvIDEwIGRpY3QgZHVwIGJlZ2luCiAvdmVyc2lvbiAoMDAxLjAwMCkgcmVhZG9ubHkgZGVmCiAvTm90aWNlICgpIHJlYWRvbmx5IGRlZgogL0Z1bGxOYW1lIChUZXN0KSByZWFkb25seSBkZWYKIC9GYW1pbHlOYW1lIChUZXN0KSByZWFkb25seSBkZWYKIC9XZWlnaHQgKFJlZ3VsYXIpIHJlYWRvbmx5IGRlZgogL0ZTVHlwZSAwIGRlZgogL0l0YWxpY0FuZ2xlIDAgZGVmCiAvaXNGaXhlZFBpdGNoIGZhbHNlIGRlZgogL1VuZGVybGluZVBvc2l0aW9uIC0yMDQuOCBkZWYKIC9VbmRlcmxpbmVUaGlja25lc3MgMTAyLjQgZGVmCmVuZCByZWFkb25seSBkZWYKL0VuY29kaW5nIDI1NiBhcnJheQogMCAxIDI1NSB7IDEgaW5kZXggZXhjaCAvLm5vdGRlZiBwdXR9IGZvcgpkdXAgMzIvc3BhY2UgcHV0CmR1cCA0OC96ZXJvIHB1dApkdXAgNDkvb25lIHB1dApkdXAgNTAvdHdvIHB1dApkdXAgNTEvdGhyZWUgcHV0CmR1cCA1Mi9mb3VyIHB1dApkdXAgNTMvZml2ZSBwdXQKZHVwIDU0L3NpeCBwdXQKZHVwIDU1L3NldmVuIHB1dApkdXAgNTYvZWlnaHQgcHV0CmR1cCA1Ny9uaW5lIHB1dApkdXAgNjUvQSBwdXQKZHVwIDY2L0IgcHV0CmR1cCA2Ny9DIHB1dApkdXAgNjgvRCBwdXQKZHVwIDY5L0UgcHV0CmR1cCA3MC9GIHB1dApkdXAgNzEvRyBwdXQKZHVwIDcyL0ggcHV0CmR1cCA3My9JIHB1dApkdXAgNzQvSiBwdXQKZHVwIDc1L0sgcHV0CmR1cCA3Ni9MIHB1dApkdXAgNzcvTSBwdXQKZHVwIDc4L04gcHV0CmR1cCA3OS9PIHB1dApkdXAgODAvUCBwdXQKZHVwIDgxL1EgcHV0CmR1cCA4Mi9SIHB1dApkdXAgODMvUyBwdXQKZHVwIDg0L1QgcHV0CmR1cCA4NS9VIHB1dApkdXAgODYvViBwdXQKZHVwIDg3L1cgcHV0CmR1cCA4OC9YIHB1dApkdXAgODkvWSBwdXQKZHVwIDkwL1ogcHV0CmR1cCA5Ny9hIHB1dApkdXAgOTgvYiBwdXQKZHVwIDk5L2MgcHV0CmR1cCAxMDAvZCBwdXQKZHVwIDEwMS9lIHB1dApkdXAgMTAyL2YgcHV0CmR1cCAxMDMvZyBwdXQKZHVwIDEwNC9oIHB1dApkdXAgMTA1L2kgcHV0CmR1cCAxMDYvaiBwdXQKZHVwIDEwNy9rIHB1dApkdXAgMTA4L2wgcHV0CmR1cCAxMDkvbSBwdXQKZHVwIDExMC9uIHB1dApkdXAgMTExL28gcHV0CmR1cCAxMTIvcCBwdXQKZHVwIDExMy9xIHB1dApkdXAgMTE0L3IgcHV0CmR1cCAxMTUvcyBwdXQKZHVwIDExNi90IHB1dApkdXAgMTE3L3UgcHV0CmR1cCAxMTgvdiBwdXQKZHVwIDExOS93IHB1dApkdXAgMTIwL3ggcHV0CmR1cCAxMjEveSBwdXQKZHVwIDEyMi96IHB1dApkdXAgMTczL3VuaTAwQUQgcHV0CnJlYWRvbmx5IGRlZgpjdXJyZW50ZGljdCBlbmQKY3VycmVudGZpbGUgZWV4ZWMKgAI5FQAAdD+EE/NjbKhan/77ULS7JzAqXMCrbi+Vm/INMgw3PCEo0KDOcHKx9nKgqjjDwOzrBLRMsXShwxYS1x/6IMkJVCVjeDcveVsL8pQfQ38Fn0GuBZjABRX+8YczNVfzLOMqnufUurZdpTQ/knB+LPzz6M5Eblraw5/Dfs5ktos1bODXEPRbHn8s12iryhQ2CDZodhoQCUZBYtBUwfa/LEajGbPGZFKHYxbBOpJkVtNmKVj9VnQNWFZzbmEE+BPtMZFWd3k07rHFRFrmv27lnlsZcItCh9tLm6+YgpGrwG/ed/zDHuFzCpT7xs7MdEpZqfajjiw9JKNtvO6XgdQ7y2rxwhv69q6/DIarClaEsha9+rFXfYTEkK8BcaUY1RI7beRwxnGx8Mt8pafG9aKKUpeQEJnqFv6Bk9Kz6/t+fAPkHdv8KUIErVw3AxMUFg63Ti+yeRa+1QQ7vDTTkV3O3Obim9olUKuQDhfmH2uWx+K3iBXFqwCLQTC/S/W/LDn9UCsxsphc4HA1txBMdO2NO8rPec0i5GLWOZZI5tOxhUsjPXLloUXLWOkU3I0wBTXW8TlAV2yBn+EPJ4XV14tyCoWHanYChLFqYcChHUHj+0GKluGz0gfPNQ4xf3u6+jyJLmvDFxiNxtSNAud0yBZx12ouXbVSeHGYXWk84KA/Sus2DDbG/E6H+kx2MfnEVMz2yZm/lW6a4w5Pevvdoxfj9BMLm1dBkDCxHQsjw1dbv7yBz3j6kibdv2I4JFxLoEW8qsxcH2SXXgJpM3KrNQlPRIqq8IKmxH3ZllsL/QQ8YJFg+KJjygCl9QOmrL/1FXx/JXmx0m6ynXaUfF1PwtiP7e1ISNfaExaiL1C9OtTK2T4h2WhRPW57ycPj/dYRfjKD7OvXXYQ+Co+s+jCWDRpbwGTLlDP0XQFMBNxx4cBogjdx6ouFfm8lXgfeQf/GC0CtQolv6YH1O06mdXeZ1hqAFwHALulGBr2WdAoV9wBD5SBSeMeIV3waNCP5P0xB7rP7uXTZv/oscgXK/61/3tsjyAXyZASQxvMf8uyWsThQA9TTEOM1o28z9bj6Yhs0Snwl2CxemFy3xgyidcNyBDRsCDFwYKjsejtr9sZGIXAFJK2djcN8aUa549kahghsM9NAB65fQFOwjWjPAZEnunfOsU/LXlWK30nIkQBl+0U0yDsCS6VOi3PKI5fFU4AoRKo71Ax77FoD2fNw16GFRgRagDsfvPWGHutBKIxwbPNTOks4YU8I+pzT3AGdID63P/cLQNDKDfhj2MX+jsr9J7cbAr9GipMFwap2Jls4jSt7wmKqfH/3aQYFwr0OL4EWYKcPGngbKXZU8/q4CkEc2Udvd+jwSDZGPSrMD/dd1b1WuZJfach8jzjYSrqBYqw9fJ1TN/TAr6bltKUFoIHGMArP5qH2RSGq289zzT5GO1vVBHCpBHHGdEYyKBGnYtcOJ+HXNzynHxP7pT+CbBux+zWpg681ryr4TTuVQj2nnBDxfoFmuWIx1wnANhjGXI3Hm/H/X031UQHeONr6mjapeuElW7P85UsunaWeI7Kaz20CH3jEZSq0Olc/qrT6pY5rb7Dtg0Hiue+VXSZquOKbTBMlbWL9zEkrTWWApXDmKjSlRkbf9IlVFebl/KO14wADGp5Q6BjOkl57wNPS/JI/amh72Acy5LEfYHXGMFvMfZ0ZElZLNlstV9YMGD5hPz4M/ZA2O9TMIhj7cVMacHAmV/GTyFIGkONjEM7Z6Cz6NOVBFmkolHa5SHOZMZ2NIy6RVaVi+agAZWSMz6Gt+h1zb7+B9feaArb92rJNha/+T5CR/0p+1fW01vDHSwbX8tkR9CS87ijM0VB/HV9ZHV5OsOqU5NbaIKESihbglj772nnG0iLqt55ZY34M818JpnnCU1oTG26tcbLOGcnfg1z9gSCcD05uG5oI1QmTLlY8iOlbbDf5sZeSTcQp/mWobcEXsTzx3tLH9nk6FZSnUp7Os67Eb3zhe69rLsEBsQrOAV/uKm+Iq4YUQQPjtj3vClIyIMT3i9Be9Yug4qZbl1BiTRLeLICi29JrbQvDBb2t17fIU1f6QmeNVnoT9UuvTBxsUOc2TgmO6SjHP56iAhwfdzIL8RWyMTfR/gaoQ+nwABwi0Z5+9+/hJAzTQby9VRd46WnCVTe+JuUjNt+P1gBa8UfpKlsW9D0PxMtBmY2k4POt3bYDzWnotzEyqBfTksuH7xhZJE5l96VnsBmmJU0qdUFymA6rHunbcaxZXYWa5KlnQvAqM2/Osz5YkNwWUheteEOc8czbDaL7PFZW8kKSAWKBVbCU17oU1sidYJhQ7hy1Bn39pJJcJi7zHnYs9E1Qn0IDcP2YylXdU6i685jTKaLA6dWcFuoHhhHF8tiEcWFyxj+P7wx15mbl1B6kwh3Omot4fA9sPtxbbATz0ElHXM7eTB8jsQBuH8CShTwM7X6wG+M0W0aT4MBE5IjD0n5et7A3cJD1vxo9Td149OWBycfpsmcCwyQfwrvpo6p4dCgju+x5GJ/E3DjzU1lKqmdcEl+wuTP/7Cl2vE60lg8hyeVf99lhycgB85UD0ZDQY+H5zHMF0sH4PJ9CXJFDZdaaeSJTCYpFc73Ttk/syOd91qMjfNFOXua+3pzJnwoz/iis54sbgLCfnGX3yGivMOrgGb2HcOWoVWOhGhzjE3fna21bAS2O5mMsvJGl1vpB0g9qZqSE0afF9KLi+SvoH9yu/Ui9NE3fgz4oxawafRJpoPubIG3ZBDTSxuSIcLfSfMu4eUXTsfB7n2/8DXdb6GqkH1du8ZaJ/KrfgHxa8z+AUaXDfKfJC6RT3f9AgKNMX+Dhzlc71ly1Lcmr6toErG32VKnvdIwMjStMTDxvLiMExCkpIkz1LI1zNPHThh4dgCpYOYmcGBr0tQ/sbw+Bj9Ra1z7maiQs09OoI5bAwkkGQhK8cMVL/DR6tIfcxxAUzjo7Bb706q2qr5TrVGF7/DbQbbDFCj/+OeUBA6NyuMO26mA7+T9KA22UVP5r05R5z2HA6yVZ3o/zCBD3p0HvlpiV3MnIhppxgShfOKXzQRoGcCmhxbHJtsFgs+/BMUPrXdwvArl882UbAyNWTXM/N99crf24ATi7mekTfYrupH+imr6ay1JLqVsbb5V3TJNibiRsVoJI8RG4Ymqu+pJHvjXU7aIuX/OHLMGznB7JP6LV2O0IAk4MItP7q2N6u3I3MIRhbtyrE3N2NkvLwEi2oK7inxqDzwbWlX4L5RalxBO4PLgQUjX01RxykUBsSg2GRbHxX3vT1Qxiyi1C/N5WP/fu8jMzT/X3Akx1yEinQFK9JvuC0f2U/paJamt3kab0Lap4HVnoga+emmxIkjz3UzC+zsGg0cLwEMY7dR8bFivfroAMgynqfgCYwSeFYCWbOrA8Wo12UNGSl3oE+xCMfz6vLvkotp0Woegf5XKshlqLJslQjSBxnjks/k/nGt2cABNZ38L4C8J1IZn7kHnCcIWn6ALn7D0AC5//Mjc+NH+TxAAJ9xnCrgwSf3xIpMt3nQkjXkkT/Rvh1Hk/v7RwYHlU4s5b3acCDJWN3HsMKKjESakM4+5i4+I3WNjnVGUqS4x17pX0KkHLfywKVg5IKjqW7eM6Kz6lG36xOgbG78vySxSiu+9xh97Bv6Ev2e0nYjtTRBwZuwPKGUymrlmKBgwU/kvi4SapC/xXsVWqaS+RM0CstLvu00UbuVNhYRfuEO7bYN3lgQicxK1pXqf6bz1lYZ3fMm0kr9wNetnMl+/wsQV3qVfoC7Z3ykW4mMxtYz6IkfJ6i5lTGytU3UGyQEXvaKb0WvywSiJt6ieXXpJN/z9/m+AHFAPq7OzGqDkri+Ce8NxLU3vHl8QpaJtX/4zZp1Q6/SKGcWe+rAriU5aIy6WYYogaJfgRfYXO4kddrDBEfy09PpeI+nMDTWO/HD/IeXHY1z2HpyZJsGo9SM7CaE/Z+ovSXjIjh3YlPSMG+apFiNXe1Aq66s/1dk3f+3YO1rRGNsTYhiLSFVWQSvzE/xM2UOeoOC5k3nAKB38SoveuX8EvbdVP8YgEkMClJUjinSjZvZY3esyLQjMPd45/1ZcoX6u7EnUNMP+9hyUZ2Owb7YV4RTmPAf9hkXE7bK7qVnFsTgLoarRfeYjgXLf9kez7Z/GQi/HqJRyX3Voh6RhEN8fJ61d8tAMC2vy5IoQLyPqyVnq3L5qeA6vKMSEeLF/i9zBqUJA4T1rfEfWMOPjXydg/VRoj3zS+91gtXM6bshSIHUKUrrHjK/bq9Oa4mEtP9bfoWKcybuZgENB/uatiUGtYFB8nFbO2qgSuJ8YdmHXhABG+mt1QZvHD0EstfjbC8zaT1o9GOPqwbv/F60lRDbIOXRjn9IENptVRZI/ZeYHB6pyOxDmFGlQcxs3axa1bX5yBlmYvr96Gm9gIL0rCw7kO8NHB7aTOUQm3j8MBTe54h1TgDSpsK+W60t/DDX0WDlXcqxev422fFEm3URF9Cipw/NJSXSV4ELwnT6ZjV0xnI7ooz6PBPcfVTEJtymuYd5oWBAGK3QgpNg41c09DuiAST797/UOO8HK8zhK06nF/jWzyPAtbXXCgvqSH2yk8zJDKk/d+Xncb5UsH6VUmEzZbiie38gysjOevISf3d7yi7hu/YEgiwGND2+AlLYV+5d/pMWthxGpHWmEAfBVY4b83VTNDlD6z51akm+RY06HkKM+Mn0byZlopP2MIxZluvfxVK/SiOm5TM+7T0SBlkCEBQEhx5X4h2W1lfIGOHA8RLHfXWLjX7b/PS0rIOZsjplYwg7SA7n/HzukyYassHdDP67wDmMG3bGFYYCsB+9M5JumEGhDpCoYC5SOd6lST+1YGyNs9xiF9hYRtp1Q+7blpsx5OVpdQwctuLEJnciPc5F5hJ7D1qWLFLStTbCPnNxqUtTUAD8mGbBvve0ic+YlKrM8ZdPIzmX0Y0R8GqcEw5wHXoOxedf6kpppOEO+9J1xCKNdAxFbTZqkRplSc96M4rNn8JRTP7g7hecqGaMkL/7rS+fCJj7oBIggyGK9iKvzO9/qx/WCcXf39LgzzT3ZyQa61S0T4z+bNe0nnXzrQmaDMSXyuzNpCR8woWEq5u5dh3ZY/ygwB953URXyjyO9g6RfDaZ7TXPdzrbeQ8Oo9avQTLapa77v3fGyF2mrrz2KgBF+AW99iDh/0pVCtwsRvA6QZMkCBl54O1TEb3Lmrd9dlGFLkRpRfap3Mi1zFqyjRl+c5ENgyfiqVwo/omZS/kjVqQqtAXRw6p/cIaEQRffxvQ3DVJwPplyujMqHb8oiE/fLYVY/qSFTAh5vs60AiZAVpq7h5vqtQtXdiEDs0auIupihC/uxKajYHQ/DohM1QHE+M4DF2itDJf9Go8gy/mRY47vK6IwwNy9TSFZCioIKOlR3LOde+6GcGwYn3i5mSCknfQVydkPHxkHWXIj4gg78y1RUBFgdV3/b7wJ2c+FCQHu/+4RZ8FwlbLBa+zotTpMtU2XGJbQ3KDYYkmjDvXkurqevIZMqjuBOF30b0xqxjC/kNgaczjsj3maTG5yjvCqov98LQIZN7IimQanoM6RMfof3+eZLIV6Uay/xQwl4Hr/LualgYI68MCRKr/h8J/V/o+0OtfLgbTp+UGn2949BtVwxNbR1Few28a6cRrNKTvCFC/AnRTPmUoXgYM2z7/P67ZAJusnLkrTfNoavXFOVgM1hmxCeTtSsBeN/S4cVCUPjg5/UX5uEaIdssVtQk6rTwABW88l6SRsBr1y57hSAXxqCbzvmNi1vbe0icG0MPR/3FuipycvW8w8dxpp86gAGGBG9n/wa0/jWNc8P3kbWbILfMGt8iCjMaAm495oK9cQHrRs6Yp9IJikCzPQk8GaqiZ6V2i9tsOjxyUXuG8MJegMH+3xwncHTfIU/Xw4Y9XmfrNTw1DtcmRgfY0MqkcNa/IwBjB/U7Xx9GLcflIF2T6VcsYFyJiyW3FDLNLOqWkVTG/t82TAs1jzIBz9ZL6lxRm/vcEQql5ApmAU69DCulf1FciksWVGuvpSplApgSeRlfDvRgj0OZ1ViV/nFZJUok9n2V3Qi+BFM3qUWE6s5jD4rl+RaaM+dSo3yKi3ykpuqs0lhvPZMyFYwP8OeQH7rKf+oP3N4LMmAj7Aw+9PcdxarZYQFWY1X93oY7vWm5OIUYHE1lTT8fD4e317PuJnkAh5Mf40fVMJdiMkFU6L4lWK0T1cLWanSG57RaLugCV51wz/LwkliHf5BQkg5yWdm7kDUYj5YIjFyOPtnA23yLoQG6lkAG/G132Y5lh3yJ+8wfQjJVxRO4eTnMNr5shz+2RmDvVVgvGcWXnjLkin8tx12F+8hjgCDnHFJGarimNsyLXAmzH4k5jAaYUBN+soYtTZNTkKScuIcGpcjK9+9gkTTkU0Y18trJfoof94R9kE2s6pTa+QmVYhY2AuI1Po1xmAtdkwjO6VhJl3dHDC/8MVsF2qgbNasaaXFnjvRRZCoszskgYDgQAOiySLt4j7wkaR4m8OzQb2h9DOEMHg4opCHf+ac3+T7l53E8ZBb6teOCHsOVHr9uPwTuhcs5/whJmrDypKUKWVC1rfpFE7HBuiPIftm2OYmgszWMlSWQDJRRWdec/R39T8N1cLo8rAkGF89/wIPasWhgGrv6hjS95LlB/z4NhVDK3/IvsNvDei8H2eCFWZzWBdM49CfcEmzSJKLOrN4053kkFM87XskTJIxBQOVKnX700J3K+ZERkyjS03t4xPCgaE6A3mzxNC3nsbXk5GHUE3C7k2esm7VZeixJQg6VUAkED8enaP3y0Jzz+qVLfuNrg+kzJoyaKlyTId6lAoftXv58qn+TuLJbPONek+Vda36Da6UxrcHjhEnN9QklI9e/RXUt58RUiVXrOKncsPvSQZTvCKKZWEK/6J66oE0h5JBbNIU0U18SqzmN/dWAV/2yBemo0YQ2lptRJ2ayS83C8xSnuQH3q31jaxwnC1hxXmRIjWWe5Lo4QIGnuZbKnoZNkffZ0k+c3Z8epK/V1W+EqUyxIw1CqymYlBYB5PDYqTe527xNVpn51EE6VeyhQpepKYACPNQb9VCHjwT5kjX4xdxKCqfkE27HKYn9g2EsU+f9B1upDybnpzyXbhA23JBHrbonaBrF6vXzCi8KVur+/3eGTZXRhy+xTtzpHDMjpK51SoEiLIntftx+LFsw/C/HgAEVAgAACjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMApjbGVhcnRvbWFyawqAAw=="; + private static final String TYPE1_BYTES = "gAFSBwAAJSFQUy1BZG9iZUZvbnQtMS4wOiBUZXN0IDAwMS4wMDAKJSVUaXRsZTogVGVzdAolVmVyc2lvbjogMDAxLjAwMAolJUNyZWF0aW9uRGF0ZTogRnJpIE1heSAzMCAyMDo1NTo0OCAyMDI1CiUlQ3JlYXRvcjogRGFuaWVsIEdyZWRsZXIKJSAyMDI1LTUtMzA6IENyZWF0ZWQgd2l0aCBGb250Rm9yZ2UgKGh0dHA6Ly9mb250Zm9yZ2Uub3JnKQolIEdlbmVyYXRlZCBieSBGb250Rm9yZ2UgMjAyMzAxMDEgKGh0dHA6Ly9mb250Zm9yZ2Uuc2YubmV0LykKJSVFbmRDb21tZW50cwoKMTAgZGljdCBiZWdpbgovRm9udFR5cGUgMSBkZWYKL0ZvbnRNYXRyaXggWzAuMDAwNDg4MjgxIDAgMCAwLjAwMDQ4ODI4MSAwIDAgXXJlYWRvbmx5IGRlZgovRm9udE5hbWUgL1Rlc3QgZGVmCi9Gb250QkJveCB7MTAwIDEwMCA1MDAgMjAwIH1yZWFkb25seSBkZWYKL1BhaW50VHlwZSAwIGRlZgovRm9udEluZm8gMTAgZGljdCBkdXAgYmVnaW4KIC92ZXJzaW9uICgwMDEuMDAwKSByZWFkb25seSBkZWYKIC9Ob3RpY2UgKCkgcmVhZG9ubHkgZGVmCiAvRnVsbE5hbWUgKFRlc3QpIHJlYWRvbmx5IGRlZgogL0ZhbWlseU5hbWUgKFRlc3QpIHJlYWRvbmx5IGRlZgogL1dlaWdodCAoUmVndWxhcikgcmVhZG9ubHkgZGVmCiAvRlNUeXBlIDAgZGVmCiAvSXRhbGljQW5nbGUgMCBkZWYKIC9pc0ZpeGVkUGl0Y2ggZmFsc2UgZGVmCiAvVW5kZXJsaW5lUG9zaXRpb24gLTIwNC44IGRlZgogL1VuZGVybGluZVRoaWNrbmVzcyAxMDIuNCBkZWYKZW5kIHJlYWRvbmx5IGRlZgovRW5jb2RpbmcgMjU2IGFycmF5CiAwIDEgMjU1IHsgMSBpbmRleCBleGNoIC8ubm90ZGVmIHB1dH0gZm9yCmR1cCA5L3VuaTAwMDkgcHV0CmR1cCAxMC91bmkwMDBBIHB1dApkdXAgMTEvdW5pMDAwQiBwdXQKZHVwIDEyL3VuaTAwMEMgcHV0CmR1cCAxMy91bmkwMDBEIHB1dApkdXAgMzIvc3BhY2UgcHV0CmR1cCA0OC96ZXJvIHB1dApkdXAgNDkvb25lIHB1dApkdXAgNTAvdHdvIHB1dApkdXAgNTEvdGhyZWUgcHV0CmR1cCA1Mi9mb3VyIHB1dApkdXAgNTMvZml2ZSBwdXQKZHVwIDU0L3NpeCBwdXQKZHVwIDU1L3NldmVuIHB1dApkdXAgNTYvZWlnaHQgcHV0CmR1cCA1Ny9uaW5lIHB1dApkdXAgNjUvQSBwdXQKZHVwIDY2L0IgcHV0CmR1cCA2Ny9DIHB1dApkdXAgNjgvRCBwdXQKZHVwIDY5L0UgcHV0CmR1cCA3MC9GIHB1dApkdXAgNzEvRyBwdXQKZHVwIDcyL0ggcHV0CmR1cCA3My9JIHB1dApkdXAgNzQvSiBwdXQKZHVwIDc1L0sgcHV0CmR1cCA3Ni9MIHB1dApkdXAgNzcvTSBwdXQKZHVwIDc4L04gcHV0CmR1cCA3OS9PIHB1dApkdXAgODAvUCBwdXQKZHVwIDgxL1EgcHV0CmR1cCA4Mi9SIHB1dApkdXAgODMvUyBwdXQKZHVwIDg0L1QgcHV0CmR1cCA4NS9VIHB1dApkdXAgODYvViBwdXQKZHVwIDg3L1cgcHV0CmR1cCA4OC9YIHB1dApkdXAgODkvWSBwdXQKZHVwIDkwL1ogcHV0CmR1cCA5Ny9hIHB1dApkdXAgOTgvYiBwdXQKZHVwIDk5L2MgcHV0CmR1cCAxMDAvZCBwdXQKZHVwIDEwMS9lIHB1dApkdXAgMTAyL2YgcHV0CmR1cCAxMDMvZyBwdXQKZHVwIDEwNC9oIHB1dApkdXAgMTA1L2kgcHV0CmR1cCAxMDYvaiBwdXQKZHVwIDEwNy9rIHB1dApkdXAgMTA4L2wgcHV0CmR1cCAxMDkvbSBwdXQKZHVwIDExMC9uIHB1dApkdXAgMTExL28gcHV0CmR1cCAxMTIvcCBwdXQKZHVwIDExMy9xIHB1dApkdXAgMTE0L3IgcHV0CmR1cCAxMTUvcyBwdXQKZHVwIDExNi90IHB1dApkdXAgMTE3L3UgcHV0CmR1cCAxMTgvdiBwdXQKZHVwIDExOS93IHB1dApkdXAgMTIwL3ggcHV0CmR1cCAxMjEveSBwdXQKZHVwIDEyMi96IHB1dApkdXAgMTMzL3VuaTAwODUgcHV0CmR1cCAxNzMvdW5pMDBBRCBwdXQKcmVhZG9ubHkgZGVmCmN1cnJlbnRkaWN0IGVuZApjdXJyZW50ZmlsZSBlZXhlYwqAAo0WAAB0P4QT82NsqFqf/vtQtLsnMCpcwKtuL5Wb8g0yDDc8ISjQoM5wcrH2cqCqOMPA7OsEtEyxdKHDFhLXH/ogyQlUJWN4Ny95WwvylB9DfwWfQa4FmMAFFf7xhzM1V/Ms4yqe59S6tl2lND+ScH4s/PPozkRuWtrDn8N+zmS2izVs4NcQ9FsefyzXaKvKFDYINmh2GhAJRkFi0FTB9r8sRqMZs8ZkUodjFsE6kmRW02YpWP1WdA1YVnNuYQT4E+0xkVZ3eTTuscVEWua/buWeWxlwi0KH20ubr5iCkavAb953/MMe4XMKlPvGzsx0Slmp9qOOLD0ko2287peB1DvLavHCG/r2rr8MhqsKVoSyFr36sVd9hMSQrwFxpRjVEjtt5HDGcbHwy3ylp8b1oopSl5AQmeoW/oGT0rPr+358A+Qd2/wpQgStXDcDExQWDrdOL7J5Fr7VBDu8NNORXc7c5uKb2iVQq5AOF+Yfa5bH4reIFcWrAItBML9L9b8sOf1QKzGymFzgcDW3EEx07Y07ys95zSLkYtY5lkjm07GFSyM9cuWhRctY6RTcjTAFNdbxOUBXbIGf4Q8nhdXXi3IKhYdqdgKEsWphwKEdQeP7QYqW4bPSB881DjF/e7r6PIkua8MXGI3G1I0C53TIFnHXai5dtVJ4cZhdaTzgoD9K6zYMNsb8Tof6THYx+cRUzPbJmb+VbprjDk96+92jF+P0EwubV0GQMLEdCyPDV1u/vIHPePqSJt2/YjgkXEugRbyqzFwfZJdeAmkzcqs1CU9EiqrwgqbEfdmWWwv9BDxgkWD4omPKAKX1A6asv/UVfH8lebHSbrKddpR8XU/C2I/t7UhI19oTFqIvUL061MrZPiHZaFE9bnvJw+P91hF+MoPs69ddhD4Kj6z6MJYNGlvAZMuUM/RdAUwE3HHhwGiCN3Hqi4V+byVeB95B/8YLQK1CiW/pgfU7TqZ1d5nWGoAXAcAu6UYGvZZ0ChX3AEPlIFJ4x4hXfBo0I/k/TEHus/u5dNm/+ixyBcr/rX/e2yPIBfJkBJDG8x/y7JaxOFAD1NMQ4zWjbzP1uPpiGzRKfCXYLF6YXLfGDKJ1w3IENGwIMXBgqOx6O2v2xkYhcAUkrZ2Nw3xpRrnj2RqGCGwz00AHrl9AU7CNaM8BkSe6d86xT8teVYuOk926Xj4/+Kx6rfu526Ylz91kxebopcMvql6ysRVzzSGsW2ec9ZPJo1Q/WKb+tCvBm8OdUnRi+DldIajpytyl08TmlS+IRUcHZbxoIjxb7ZCvF8hd03yDhs9bsUSO6h7jbhegenLIiQPX7RtsGAg3logZLD0NUjcAm2tKBieMHhMxAD89lVmuMkNj5r6EaixXvkvhgqzhjPExdu30Knife5IEnlCvIlMCh1EXQsY9KRkzeTRTKfnZTJ/idze+cX0nCEGcFrvCCjZRfNuaLRHx73o2KlDHmoYBm1mFEEvfUReQxS987AiVfSF7cs8IrLEqV9qe2mCAv7ATbVUFbnvYxTBYvHL9sc4892rLrjSu/yP5RZmmIMOpTH8CStLw1zGAcXH3W3ZfPjQkEA4jzvo1U5Oi9EkBKqlgqjj2pFLWepwuNG/L3Iyr36frW6NFtqCxyVQYcNwOTnmQjY0LXPAKxyz2l+xyo/gcDY8nqtWms5aqINgemqM0pG2wBt3GawARbEVkkKllyB/WJbRw0GGHktmj73ixkTulD6nHZ+vMd+aS8iKXPa2ASEOPpxp515DZxg+VYZIrM0h4mDdRff4To/8NKs7Kx4IZx2qzlhIKS2zHpLwuY/U2Wt80e9nqMCFEtnS8sKpcy1rrE9FzXsFUNtYE6LdIat4ygQxoq24Y6D3bfDpl3E8wMvECaVCJX8lfBhQcGGU6+Jba1qfQ7jonjQM0zfoOwHrApk/dkPkSdjQy7UM+dZNMtgZf2N46UuWC2YCtcqCN1X+o5SpojTgXNmTjUy3KOy6L4GNYOxutsDhWiah6rJ+FGVL9D51MJvT3l02T1+LpNt8ZeZQSkZpx7NdFFTFA4/SE8zycfBLNm71Q9pjQKa30TnCY9ZkMEH9rnArLV0w2Gi6LoJoWpT7GoAB2Cdvi3x9wGDdt60K6oABWiD5mpAv4KfrJMBn5dRDJVyRPARXxwBUROAc3BxY8St3WuWKqDqqef0t0rlqAXGynPrcAjqFMXc/GBWORQ7W/dTvbu/eZb+apjKEX7szjaY4cSRsNge4gTyCEsfhLrdBkncM7up9jj206tIaqZQILxHAnrVwYplJ5D2EvSSLYvxFEVHSrI19aNJEvDK64tzXCV+P4yOCOuXpBmc15PDlrMQEauqrD+xneCO+CrCbudHXOJsbmvQq56+ovLp5SNBfdEPQpqo5tBgQaNHcEjg/iVt++uLxT3vAEFW5d7WXPMYdy+XqoMmdRDOzey0Mdx5BZ92rNM/LthQa6F54nvzkypM64HdxCYlri8cO3k0G6bp2eWdseP0P4zMc5QikuXc/Dr4NztBYe2yJLbLLesWSB8nOWcl+gd0GMX5PY4P5mn5WJDNStLWPdD9NapzMsyx6lZwR9Tfv/XSmay9LEo9YaaxysWfllDIasUCdvhZVi7LJvPu/0GbuHLOz9mP6prkF8h8KmjBYMlMktouA23G74M+Pkdfbj9KAM8zOYCgQFZUaXx3iZ4m3uBtDPeKjUcdFZSnHdW11eSv5aCz2fMbExV/qnPOSMbkR5rvpR71WwVZP6j3tNWr8jlPQ8d60k8jXPy7d8wjw9obnDEpvKzKreEzjfA0wCovNt7FLH9oxWmO5TF8JMg/U7+ToEv0fPAW475dXTXdue98/k/c+3+LCJNbHzBBx14CzpteKXKqGNA3jwgJUhfDsTISiN4gF222zIi1deY9BspjPl7jergbwh+ZPdfk2BLaPTDeNUycKdeiFoJEd8gKLvjMrnPa9IX4HwR9gJSjsQ0UWhnYuaXdk12zk8sVkGJAJLrphh5tHcd4LwG2rWcVXwM/2zw1YXQR+jffC1uxUEPVaq1fSf9RB6iEb8LgIollE+gDEybc+Dw3Q/gxVe5/Nu0vHHur6B+4YEcxvz3O5cYKUQTxDgG4mXJhqZ6z7etSWINChQyP6PUFFbsUIDXjfuHZ9oF4ce1NNOnn/RIwm/u/+AduDTtqloUooZjqak4VbvmBEZcW75liKm0MggeilL0nl5arItzTwE8OudJDBkJ/xnf1yZIgeFKSODIz5aQrIiSMJX3BGRxHEEQrm1xtwCfjtMPpFhFtG+o5fjMlCnowJ6+/HrG3FdZKn4/gv7qCxF2/3NW2J4OWuXbjEsUlSHu57DFvhrVl/q8jv81OfXhZKutYQWjaDWwOQHR+ym6wvMyQ9YfiiJpBXa+Ig9uGAbERyApc8wsCLcy0d8Msxx9PAfhrDa+Gf2yhYGA57t8iGxEcoI0A4B8zKVqYXKf4AdsrVzE9cUpfRN/HH8OGWyv9mKMTJyGJQql/OH5hYHnvJVKZXIz6l3nL/7gnpYaGtASiV1q+JwO7WSk1pfwT9SE4sFl7uS7f3pu4BwPhcz/wyN82f144yav11mrGqypOMaMDR27/L0sW1c3hWBBa8BMU/EuwF7ldclS9nxmFHOc35RLruyQ26cp1niukcpK42wg3ozqGQLoQRIoin0AWnUwnOmkdBEkILqFCiWgERDZuCB7G3pZJW/32HPgD3byO0lH8JF6OiINsUmM+75Y3qdvuepTHxXwpDa9Isero3x/f+UWGGUO12s+Ou2yQKtLsQaBNSTaGEBVCAtpJ58TgZ+KfVyhgRQdINr7GuGq9iRPQBY00anspxvsrhfffggqOariHO8h0jdEZPJarJJAufQbYgKiACtJ8iG6jlIs3GfWRI0jRYDw+kHPc2/A6fS5XGF360aX1I6iy5J1pZpN+6stJq5MQ8QRHopTJWQ0DW1Pq46BglmHH9av/X4tvLFFyyC4X6OB2jDb9+XwwcuJ2t/352IcJC06IsWKDsr6E6vF3hC3GUBUy9I7JbqlAh7zlYK52MITQzGINZD2p8+TJjmDycEr/UM/JHqBzbJniUzxg8vo2/FjpZggU8NuBsTZ5P/YZSgRsZcVKkhkGYAn+euvrQIiZ2LMwOygD0gW/zy7v+Z1aHfxKig7kkOR1ZuVCFE8FWx1unCnFHtkjFIx9JY4cYHboveIlF2IzNhfnKJncBt7DuZORqfAT3gQDZlIFNx06tSnTe1v5l7u7VSKMXRhc3bbeCqfvO/NSOqfLz1QYlj2b0C5sm0AcUe1RpC7rOu6muPLeJ38DOIhJHzs+wpqBZTHJr9zdnjZl+OyXaAAbgCsxamEQW91iGdRmVHqyT+0+XQxssYOF795eGYpsXy9Bik6Z4apt/AcuZQFu3XthVXvjyVCi0Rj3gXjOkFdT1YaiRe6yPRdBB2GorcxCzQQvjZXTuh5P4a7MD/6W0mJYoh0BzQHYC0O/T9v3d8GepAbQTytL7MWIWk9C2qZ0pPciuIfXNmGRWBUkCCts1BAsW39l4giNBCwDQ6CauWkz8iWaxx2krBQpKl0WyBBSd/SIJUFM4psvYNaGNk+xR18s0OrPqvxQvc3NNgVwpAljSM/wt3IzIcIsJHF/u0T60hXgEv4H0f44/SzROL0iGUZIfRZK6sJRGBQH2ZVrFCJ6ageJX7WTBLVwKAtxgIUK2dXAemsYgGm/CIe3JCmwL/YmEh8I8W4LrWzXq4vNF6/Sq1hQ2r4dndAO+HEZ8nYpPr+9pUCUgSvnN7aVWZpc/xJaj5L4U6W28hVZ2mb+UUKDpq0bSxKdkVr2SC/7Q/8WimMNDYCaExzXQ+RzZyv/4227pn/k3y1avulXGz3ujy+lqdciVVWHmPYyJPhqeoyDEkM6g46KL9kg912jsB1SGP7Yc2l7XENW59mh5RE+fNiW8wWjxW0Oa+xSe2+RTOgRA+Ojq2L8+g9sL7jKw7BPAPjnYTo8gMat4DurAKbJrtaRLZMzXkFyE7heHr9NsLJl/d1JLRwNoGDpnvLjyPNBUjW/2CTEEIyI6yq3oOJivAwe1yiJib7IUTkh5MCBSnEssvxOYJRUaR/ILAHMJpAoEV/VOCfBlh/I55gVYZWa+Y/5/AMs5Po1w9/18Q6V4ichv80Qr+Up7+2s8sV6zM7m78WMmQp3IR6uTJasqI2Vnr99KAY31BJVpBelRq2xjIruSHx/BAr2kSHA+Kuk1I9+Y1dEaSbfUpjcly0WDUh9x1VTkrUu1u6XN/i/SkFeO1k8o2o7s0rVXNI+VipXQt69H+yVDea7AYuvy9Rp2kKuq7o7mgcFCVq1Vbeyv++vDSKdYmKbyQ2N7ubU6u41Td59YNfRldl56ec0bl7hgyMUb/7/ifjdRXOVl1sTTMUiETnT+44vuAiiUeOHRgKmRlLgHp9iMnPPZVF3DqExLV1IPraZO/olA9QIc4bM2g6SPebITaH94rZn80oQzWzBAFUzK/B2vY39XGdPSTAZTFn1yAYcRHIhqWZs9+FtJvBN9f9lUxPFHUs3vyKBC8sFph/yee7KNIKyTinMNAs1+jcnVS4LPqR4L4cn3ancasZ6wBgexKIjjwf8KPkgUcMwZqk+KwDeJbmyGblqsRzSuhrwPq0U+n4n1ktcqI11Y4D/u93UrU04LgZwWPEZPrgjGUgciPrRa3BIJb6oT1s5VSfgiupwHaFYgF5sJ3VD0ZcT1zwdet8tPprxRq00SIZMZKZeVSIWD0ai82pPxH4PYLUGwUbW3ocaYouILRf9sF9DP1gaVfd4SDRUuKUtZRiG6lpSopmFO24N1vWq90caknzY91uUWX2v4+C/JHDd47e4h/g1Lf13euI6csefzsnQDTDsyrh5zSJDo26B81kY5RyKv+AnsvTnTl8uroRsh1KqeIUywpWImmlnnWT8rpNg822BjraGaWc9NHFzkUSmOmD/iJRdfRjno1JaeDVk8KBniY0vnMqdBG1BWRMsnUAhWxHJ4Jn5fXCltO2C5OV+x+jYocNhWw4Mgu3CVZp9erAEPsDEUsY4qaMitjRq6yJPn3nwkQRpFHGbXv187fPU/z8+BQ5/W4Qfg/qEmJKcp1T5VcrwLAlZQTomKAt/7xNlJIxlx9bCMVXnvk3Y8hB7kCTaSQmvjC8IXCHbJyMCFQV7qAKdmaihyV7zmpqWcDqfELQChm2KxmQJ1dPYJ1+jR+aYm3an5bPEoCdbsZauFF8qXHIhx8JKvRGgxPrTGHi8N5FcfuNsCA3xOkoSGX9Sxg6h5KEtoeFdkwf5BKqhJj5pcsBewAHkWng86BzAqt7R+a9TnyvLMWvmpI/0fkpRkbg731aWOnWOvbpz6f+nXSxGgrvs/B6xSgFPDo6Ty3ivL+CGitfK6XwdHA07TV/eK5vd5oyNe/Ay5wMdXiypEUWukN+jiuGmrVMkke/0DmXmtqqY3T45iLrqfgwRhXsT9kEdzcWVqM4OkAEqEzpjI0NHG74cslhQvDPbX/ZRp57/bcOuarHpCDakvzajblF2NXf0Wp0dO0NltExHFoY8myAlBu/SMn3VN6GF5faMq370MevoNi4eNRD8XiGUYh+QzVphqtLIeqyyt6W4MzTjwSLgAB0kITRYcG0KVi89iUgZMQdwIOfMUBmS/q1GpBtTFKqI2TwC3dz9oBnNzwi3Ru9yyNuX1mw1p0Sd8UNY0yVbdb7UrLrd0ldVrx2FWNVCEedkn0npe9xstIJvgMuRLA0DNN7vex3hfvGvV7qCuQi5ssNVYUkoyEjlFR3xCThuVCgwzK77JmvWMpeB0eR0O3SH9KK/1qaAkXK/bhyazFdT+WHrexsFYZuO5I1MiQWJzNDQ9r3act5mt0senky0dQ+Sb233mB+RX2AWxOf9SUcRtkKjiTvfSdcKHmLx7ns2F8MQdwFoKz7j4a7sPsuruL+BMHWuDj/VTfnVmG6nlzIjs92LVWKnZ010UOv156HJYQvhlSV+WzPv8EC/2A2LhBx0g1ZJ3vYQIu2G1AuhcZurtEOfbhcIsS6cq9P2YoRYTYTHeiXHNzKot/25uSAFs85GQhWyMz+2L3HBiszTmSdwtf0ZzHgGEBc90JD6yNfjwqF4FJ7AcuLYw5euNz/VEON3z2C021shibn6LGd4RjflA8XmBGSakJ0nkpplflYaQ9Awcv2eKYR4ebAVjhyErm4zHikUC5Vgtz/0UbghbNcX0RIEESW2GaGtFNYIYNPHJNtj4QMYLK7BrUOnzITF+Kx/FZG6oIeySnU+TJoZIkJBIqGLOYSkw+QuEbCbf1BM5nERddA8z+IFxYz7Goxg4XMpc3+L/Hx29UZzkNSY55Y2Swii1qxBWgBaRGpzI66cKfr6mHES+cbb9vNAdFPuBgJttyT/t3Jf+W5yRYt8M4VyIlEiUjAGqL3bqakDP5IwywMSpYeS1PmqWBsbUcV9bAavsLMnnEHvUue8GboIr+EeBMCk6XPBKFahrRZBTQq802IGDYOi++VjG7805Tleu2pX6H/IY/LDQVLnqVhxDaVonTvQqMffVvSwXp7EFNvR/XKxh+IJxO/W3tQeAi8Jn77E3itRU+tQEl8QQ65psW7FBQXujG6YYWK9XbPUPI/AkdVmaAuQQt7RPni0MhxB0Q8k6BqzhwbpyLMPa/XCkHdJLrO2xGupnrwYvt0OcF7Ia/hN9+HAekLtq8l+HcNGIY/JA2RPYOYGSEgAEVAgAACjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAKMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMApjbGVhcnRvbWFyawqAAw=="; public static void main(String[] args) throws Exception { @@ -162,12 +167,20 @@ public class FormatCharAdvanceTest { } private static void testChars(BufferedImage image, Graphics2D g2d, Font font) { + testChar('\t', image, g2d, font); // horizontal tab (TAB) + testChar('\n', image, g2d, font); // line feed (LF) + testChar('\u000B', image, g2d, font); // vertical tab (VT) + testChar('\u000C', image, g2d, font); // form feed (FF) + testChar('\r', image, g2d, font); // carriage return (CR) + testChar('\u0085', image, g2d, font); // next line (NEL) testChar('\u00AD', image, g2d, font); // soft hyphen (SHY) testChar('\u200B', image, g2d, font); // zero width space (ZWSP) testChar('\u200C', image, g2d, font); // zero width non-joiner (ZWNJ) testChar('\u200D', image, g2d, font); // zero width joiner (ZWJ) testChar('\u200E', image, g2d, font); // left-to-right mark (LRM) testChar('\u200F', image, g2d, font); // right-to-left mark (RLM) + testChar('\u2028', image, g2d, font); // line separator (LS) + testChar('\u2029', image, g2d, font); // paragraph separator (PS) testChar('\u202A', image, g2d, font); // left-to-right embedding (LRE) testChar('\u202B', image, g2d, font); // right-to-left embedding (RLE) testChar('\u202C', image, g2d, font); // pop directional formatting (PDF) @@ -181,6 +194,12 @@ public class FormatCharAdvanceTest { testChar('\u2067', image, g2d, font); // right-to-left isolate (RLI) testChar('\u2068', image, g2d, font); // first strong isolate (FSI) testChar('\u2069', image, g2d, font); // pop directional isolate (PDI) + testChar('\u206A', image, g2d, font); // inhibit symmetric swapping + testChar('\u206B', image, g2d, font); // activate symmetric swapping + testChar('\u206C', image, g2d, font); // inhibit arabic form shaping + testChar('\u206D', image, g2d, font); // activate arabic form shaping + testChar('\u206E', image, g2d, font); // national digit shapes + testChar('\u206F', image, g2d, font); // nominal digit shapes testChar('\uFEFF', image, g2d, font); // zero width no-break space (ZWNBSP/BOM) } @@ -191,8 +210,9 @@ public class FormatCharAdvanceTest { int h = image.getHeight(); FontRenderContext frc = g2d.getFontRenderContext(); FontMetrics metrics = g2d.getFontMetrics(font); - String c5 = String.valueOf(c).repeat(5); + assertEqual(0, metrics.charWidth(c), "charWidth", c, font); + String c5 = String.valueOf(c).repeat(5); int ab1 = metrics.stringWidth("AB"); int ab2 = metrics.stringWidth("A" + c5 + "B"); assertEqual(ab1, ab2, "stringWidth", c, font); @@ -226,6 +246,18 @@ public class FormatCharAdvanceTest { ab2 = (int) layout2.getAdvance(); assertEqual(ab1, ab2, "getAdvance", c, font); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, w, h); + g2d.setColor(Color.BLACK); + layout1.draw(g2d, w / 2, h / 2); + ab1 = findTextBoundingBox(image).width; + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, w, h); + g2d.setColor(Color.BLACK); + layout2.draw(g2d, w / 2, h / 2); + ab2 = findTextBoundingBox(image).width; + assertEqual(ab1, ab2, "TextLayout.draw", c, font); + g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, w, h); g2d.setColor(Color.BLACK); diff --git a/test/jdk/java/awt/font/TextLayout/TestControls.java b/test/jdk/java/awt/font/TextLayout/TestControls.java deleted file mode 100644 index ee15038a845..00000000000 --- a/test/jdk/java/awt/font/TextLayout/TestControls.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2001, 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. - */ - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Frame; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Panel; -import java.awt.ScrollPane; -import java.awt.font.FontRenderContext; -import java.awt.font.TextLayout; - -/* - * @test - * @bug 4517298 - * @summary Display special control characters using both TextLayout.draw and - * Graphics.drawString. In no case should a missing glyph appear. - * Also display the advance of the control characters, in all cases - * these should be 0. The space character is also displayed as a reference. - * Note, the character is rendered between '><' but owing to the directional - * properties of two of the characters, the second '<' is rendered as '>'. - * This is correct behavior. - * @library /java/awt/regtesthelpers - * @build PassFailJFrame - * @run main/manual TestControls - */ - -public class TestControls { - private static String fontName = Font.DIALOG; - - public static void main(String[] args) throws Exception { - final String INSTRUCTIONS = """ - A number of control characters are displayed, one per line. - Each line displays the hex value of the character, the character - between '><' as rendered by TextLayout, the character between '><' - as rendered by drawString, and the advance of the character. - The first line renders the space character, as a reference. - The following lines all render the controls. - All controls should not render (even as space) and report a zero advance. - - Pass the test if this is true. - - Note: two of the control characters have the effect of changing the '<' - following the control character so that it renders as '>'. - This is not an error."""; - - PassFailJFrame.builder() - .title("TestControls Instruction") - .instructions(INSTRUCTIONS) - .columns(45) - .testUI(TestControls::createUI) - .build() - .awaitAndCheck(); - } - - private static Frame createUI() { - Frame f = new Frame("TestControls Test UI"); - Panel panel = new ControlPanel(fontName); - ScrollPane sp = new ScrollPane(); - sp.add("Center", panel); - f.add(sp); - f.setSize(450, 400); - return f; - } - - static class ControlPanel extends Panel { - - static final char[] chars = { - (char)0x0020, (char)0x0009, - (char)0x000A, (char)0x000D, (char)0x200C, (char)0x200D, (char)0x200E, - (char)0x200F, (char)0x2028, (char)0x2029, (char)0x202A, (char)0x202B, - (char)0x202C, (char)0x202D, (char)0x202E, (char)0x206A, (char)0x206B, - (char)0x206C, (char)0x206D, (char)0x206E, (char)0x206F - }; - - ControlPanel(String fontName) { - Font font = new Font(fontName, Font.PLAIN, 24); - System.out.println("using font: " + font); - setFont(font); - setForeground(Color.BLACK); - setBackground(Color.WHITE); - } - - @Override - public Dimension getPreferredSize() { - return new Dimension(400, 750); - } - - @Override - public Dimension getMaximumSize() { - return getPreferredSize(); - } - - @Override - public void paint(Graphics g) { - Graphics2D g2d = (Graphics2D)g; - FontRenderContext frc = g2d.getFontRenderContext(); - Font font = g2d.getFont(); - FontMetrics fm = g2d.getFontMetrics(); - Insets insets = getInsets(); - - String jvmString = System.getProperty("java.version"); - String osString = System.getProperty("os.name") + " / " + - System.getProperty("os.arch") + " / " + - System.getProperty("os.version"); - - int x = insets.left + 10; - int y = insets.top; - - y += 30; - g2d.drawString("jvm: " + jvmString, x, y); - - y += 30; - g2d.drawString("os: " + osString, x, y); - - y += 30; - g2d.drawString("font: " + font.getFontName(), x, y); - - for (int i = 0; i < chars.length; ++i) { - String s = ">" + chars[i] + "<"; - x = insets.left + 10; - y += 30; - - g2d.drawString(Integer.toHexString(chars[i]), x, y); - x += 100; - - new TextLayout(s, font, frc).draw(g2d, x, y); - x += 100; - - g2d.drawString(s, x, y); - x += 100; - - g2d.drawString(Integer.toString(fm.charWidth(chars[i])), x, y); - } - } - } -} From 9c74d545147c2eeec187df552037a12b6b476a61 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 3 Jun 2025 23:28:00 +0000 Subject: [PATCH 120/216] 8358158: test/jdk/java/io/Console/CharsetTest.java failing with NoClassDefFoundError: jtreg/SkippedException Reviewed-by: joehw, jlu, iris --- test/jdk/java/io/Console/CharsetTest.java | 73 ------------------ .../java/io/Console/ConsolePromptTest.java | 5 +- test/jdk/java/io/Console/RestoreEchoTest.java | 5 +- .../java/io/Console/StdinEncodingTest.java | 4 +- .../java/io/Console/StdoutEncodingTest.java | 75 +++++++++++++++++++ .../{script.exp => stdoutEncoding.exp} | 6 +- 6 files changed, 83 insertions(+), 85 deletions(-) delete mode 100644 test/jdk/java/io/Console/CharsetTest.java create mode 100644 test/jdk/java/io/Console/StdoutEncodingTest.java rename test/jdk/java/io/Console/{script.exp => stdoutEncoding.exp} (88%) diff --git a/test/jdk/java/io/Console/CharsetTest.java b/test/jdk/java/io/Console/CharsetTest.java deleted file mode 100644 index c8c756def81..00000000000 --- a/test/jdk/java/io/Console/CharsetTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2021, 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. - */ - -import java.io.Console; -import java.nio.file.Files; -import java.nio.file.Paths; - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import static jdk.test.lib.Utils.*; - -/** - * @test - * @bug 8264208 8265918 8356985 - * @summary Tests Console.charset() method. "expect" command in Windows/Cygwin - * does not work as expected. Ignoring tests on Windows. - * @requires (os.family == "linux") | (os.family == "mac") - * @library /test/lib - * @run main CharsetTest en_US.ISO8859-1 ISO-8859-1 - * @run main CharsetTest en_US.US-ASCII US-ASCII - * @run main CharsetTest en_US.UTF-8 UTF-8 - */ -public class CharsetTest { - public static void main(String... args) throws Throwable { - if (args.length == 0) { - // no arg means child java process being tested. - Console con = System.console(); - System.out.println(con.charset()); - return; - } else { - // check "expect" command availability - var expect = Paths.get("/usr/bin/expect"); - if (!Files.exists(expect) || !Files.isExecutable(expect)) { - throw new jtreg.SkippedException("'expect' command not found. Test ignored."); - } - - // invoking "expect" command - OutputAnalyzer output = ProcessTools.executeProcess( - "expect", - "-n", - TEST_SRC + "/script.exp", - TEST_JDK + "/bin/java", - args[0], - args[1], - TEST_CLASSES); - output.reportDiagnosticSummary(); - var eval = output.getExitValue(); - if (eval != 0) { - throw new RuntimeException("Test failed. Exit value from 'expect' command: " + eval); - } - } - } -} diff --git a/test/jdk/java/io/Console/ConsolePromptTest.java b/test/jdk/java/io/Console/ConsolePromptTest.java index 1e4f73b65d2..0c59aaccac4 100644 --- a/test/jdk/java/io/Console/ConsolePromptTest.java +++ b/test/jdk/java/io/Console/ConsolePromptTest.java @@ -104,10 +104,7 @@ public class ConsolePromptTest { OutputAnalyzer output = ProcessTools.executeProcess(command.toArray(String[]::new)); output.reportDiagnosticSummary(); - var eval = output.getExitValue(); - if (eval != 0) { - throw new RuntimeException("Test failed. Exit value from 'expect' command: " + eval); - } + output.shouldHaveExitValue(0); } public static class ConsoleTest { diff --git a/test/jdk/java/io/Console/RestoreEchoTest.java b/test/jdk/java/io/Console/RestoreEchoTest.java index 78d36faa537..6ccc434e7ad 100644 --- a/test/jdk/java/io/Console/RestoreEchoTest.java +++ b/test/jdk/java/io/Console/RestoreEchoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledOnOs; import org.junit.jupiter.api.condition.OS; -import static org.junit.jupiter.api.Assertions.*; /** @@ -72,7 +71,7 @@ public class RestoreEchoTest { "-classpath", testClasses, "RestoreEchoTest"); output.reportDiagnosticSummary(); - assertEquals(0, output.getExitValue()); + output.shouldHaveExitValue(0); } public static void main(String... args) throws Throwable { diff --git a/test/jdk/java/io/Console/StdinEncodingTest.java b/test/jdk/java/io/Console/StdinEncodingTest.java index 1f2ea225f96..55811ac912a 100644 --- a/test/jdk/java/io/Console/StdinEncodingTest.java +++ b/test/jdk/java/io/Console/StdinEncodingTest.java @@ -31,7 +31,6 @@ import static jdk.test.lib.Utils.*; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; /** * @test @@ -64,8 +63,7 @@ public class StdinEncodingTest { "-Dstdin.encoding=Uppercasing", // <- gist of this test "StdinEncodingTest"); output.reportDiagnosticSummary(); - var eval = output.getExitValue(); - assertEquals(0, eval, "Test failed. Exit value from 'expect' command: " + eval); + output.shouldHaveExitValue(0); } public static void main(String... args) throws Throwable { diff --git a/test/jdk/java/io/Console/StdoutEncodingTest.java b/test/jdk/java/io/Console/StdoutEncodingTest.java new file mode 100644 index 00000000000..38deddae8b6 --- /dev/null +++ b/test/jdk/java/io/Console/StdoutEncodingTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021, 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. + */ + +import java.nio.file.Files; +import java.nio.file.Paths; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import static jdk.test.lib.Utils.*; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +/** + * @test + * @bug 8264208 8265918 8356985 8358158 + * @summary Tests if "stdout.encoding" property is reflected in + * Console.charset() method. "expect" command in Windows/Cygwin + * does not work as expected. Ignoring tests on Windows. + * @requires (os.family == "linux") | (os.family == "mac") + * @library /test/lib + * @run junit StdoutEncodingTest + */ +public class StdoutEncodingTest { + + @ParameterizedTest + @CsvSource({ + "en_US.ISO8859-1, ISO-8859-1", + "en_US.US-ASCII, US-ASCII", + "en_US.UTF-8, UTF-8" + }) + void testCharset(String locale, String expectedCharset) throws Exception { + // check "expect" command availability + var expect = Paths.get("/usr/bin/expect"); + Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect), + "'" + expect + "' not found. Test ignored."); + + // invoking "expect" command + OutputAnalyzer output = ProcessTools.executeProcess( + "expect", + "-n", + TEST_SRC + "/stdoutEncoding.exp", + TEST_JDK + "/bin/java", + locale, + expectedCharset, + TEST_CLASSES); + output.reportDiagnosticSummary(); + output.shouldHaveExitValue(0); + } + + public static void main(String... args) { + System.out.println(System.console().charset()); + } +} diff --git a/test/jdk/java/io/Console/script.exp b/test/jdk/java/io/Console/stdoutEncoding.exp similarity index 88% rename from test/jdk/java/io/Console/script.exp rename to test/jdk/java/io/Console/stdoutEncoding.exp index c416990cbe9..4e23fd5fcd8 100644 --- a/test/jdk/java/io/Console/script.exp +++ b/test/jdk/java/io/Console/stdoutEncoding.exp @@ -21,12 +21,14 @@ # questions. # +# `expect` script for StdoutEncodingTest + set java [lrange $argv 0 0] set locale [lrange $argv 1 1] set expected [lrange $argv 2 2] -set args [lrange $argv 3 end] +set classpath [lrange $argv 3 end] regexp {([a-zA-Z_]*).([a-zA-Z0-9\-]*)} $locale dummy lang_region encoding -eval spawn $java -Dstdout.encoding=$encoding -classpath $args CharsetTest +eval spawn $java -Dstdout.encoding=$encoding -classpath $classpath StdoutEncodingTest expect $expected expect eof From 2345065166c56a958365a6362af356e7c95fcaff Mon Sep 17 00:00:00 2001 From: Cesar Soares Lucas Date: Tue, 3 Jun 2025 23:39:32 +0000 Subject: [PATCH 121/216] 8357600: Patch nmethod flushing message to include more details Reviewed-by: shade, kvn --- src/hotspot/share/code/nmethod.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 83afc02cdfc..d82e31fd855 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -2143,10 +2143,19 @@ void nmethod::purge(bool unregister_nmethod) { // completely deallocate this method Events::log_nmethod_flush(Thread::current(), "flushing %s nmethod " INTPTR_FORMAT, is_osr_method() ? "osr" : "", p2i(this)); - log_debug(codecache)("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT - "/Free CodeCache:%zuKb", - is_osr_method() ? "osr" : "",_compile_id, p2i(this), CodeCache::blob_count(), - CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024); + + LogTarget(Debug, codecache) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + const char* method_name = method()->name()->as_C_string(); + const size_t codecache_capacity = CodeCache::capacity()/1024; + const size_t codecache_free_space = CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024; + ls.print("Flushing nmethod %6d/" INTPTR_FORMAT ", level=%d, osr=%d, cold=%d, epoch=" UINT64_FORMAT ", cold_count=" UINT64_FORMAT ". " + "Cache capacity: %zuKb, free space: %zuKb. method %s (%s)", + _compile_id, p2i(this), _comp_level, is_osr_method(), is_cold(), _gc_epoch, CodeCache::cold_gc_count(), + codecache_capacity, codecache_free_space, method_name, compiler_name()); + } // We need to deallocate any ExceptionCache data. // Note that we do not need to grab the nmethod lock for this, it From 939521b8e4120357108220d177228b683af3334f Mon Sep 17 00:00:00 2001 From: Anjian Wen Date: Wed, 4 Jun 2025 02:03:22 +0000 Subject: [PATCH 122/216] 8358105: RISC-V: Optimize interpreter profile updates Reviewed-by: fjiang, fyang --- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 38 ++++++--------------- src/hotspot/cpu/riscv/interp_masm_riscv.hpp | 7 ++-- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 2a01a6d209d..fae34a9c770 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -955,47 +955,29 @@ void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - int constant, - bool decrement) { - increment_mdp_data_at(mdp_in, noreg, constant, decrement); + int constant) { + increment_mdp_data_at(mdp_in, noreg, constant); } void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, - Register reg, - int constant, - bool decrement) { + Register index, + int constant) { assert(ProfileInterpreter, "must be profiling interpreter"); - // %%% this does 64bit counters at best it is wasting space - // at worst it is a rare bug when counters overflow - assert_different_registers(t1, t0, mdp_in, reg); + assert_different_registers(t1, t0, mdp_in, index); Address addr1(mdp_in, constant); Address addr2(t1, 0); Address &addr = addr1; - if (reg != noreg) { + if (index != noreg) { la(t1, addr1); - add(t1, t1, reg); + add(t1, t1, index); addr = addr2; } - if (decrement) { - ld(t0, addr); - subi(t0, t0, DataLayout::counter_increment); - Label L; - bltz(t0, L); // skip store if counter underflow - sd(t0, addr); - bind(L); - } else { - assert(DataLayout::counter_increment == 1, - "flow-free idiom only works with 1"); - ld(t0, addr); - addi(t0, t0, DataLayout::counter_increment); - Label L; - blez(t0, L); // skip store if counter overflow - sd(t0, addr); - bind(L); - } + ld(t0, addr); + addi(t0, t0, DataLayout::counter_increment); + sd(t0, addr); } void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in, diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.hpp b/src/hotspot/cpu/riscv/interp_masm_riscv.hpp index 7a3e6764aaa..891db16b243 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.hpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.hpp @@ -233,11 +233,8 @@ class InterpreterMacroAssembler: public MacroAssembler { void verify_method_data_pointer(); void set_mdp_data_at(Register mdp_in, int constant, Register value); - void increment_mdp_data_at(Address data, bool decrement = false); - void increment_mdp_data_at(Register mdp_in, int constant, - bool decrement = false); - void increment_mdp_data_at(Register mdp_in, Register reg, int constant, - bool decrement = false); + void increment_mdp_data_at(Register mdp_in, int constant); + void increment_mdp_data_at(Register mdp_in, Register index, int constant); void increment_mask_and_jump(Address counter_addr, int increment, Address mask, Register tmp1, Register tmp2, From ebd85288ce309b7dc7ff8b36558dd9f2a2300209 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 4 Jun 2025 02:14:17 +0000 Subject: [PATCH 123/216] 8358289: [asan] runtime/cds/appcds/aotCode/AOTCodeFlags.java reports heap-buffer-overflow in ArchiveBuilder Reviewed-by: shade, iklam, asmehra --- src/hotspot/share/runtime/sharedRuntime.cpp | 23 ++++++++++++--------- src/hotspot/share/runtime/sharedRuntime.hpp | 1 + 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index edb33b3500a..9c710fc98e4 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2199,10 +2199,11 @@ class AdapterFingerPrint : public MetaspaceObj { } // Private construtor. Use allocate() to get an instance. - AdapterFingerPrint(int total_args_passed, BasicType* sig_bt) { + AdapterFingerPrint(int total_args_passed, BasicType* sig_bt, int len) { int* data = data_pointer(); // Pack the BasicTypes with 8 per int - _length = length(total_args_passed); + assert(len == length(total_args_passed), "sanity"); + _length = len; int sig_index = 0; for (int index = 0; index < _length; index++) { int value = 0; @@ -2217,16 +2218,15 @@ class AdapterFingerPrint : public MetaspaceObj { // Call deallocate instead ~AdapterFingerPrint() { - FreeHeap(this); + ShouldNotCallThis(); } static int length(int total_args) { return (total_args + (_basic_types_per_int-1)) / _basic_types_per_int; } - static int compute_size(int total_args_passed, BasicType* sig_bt) { - int len = length(total_args_passed); - return sizeof(AdapterFingerPrint) + (len * sizeof(int)); + static int compute_size_in_words(int len) { + return (int)heap_word_size(sizeof(AdapterFingerPrint) + (len * sizeof(int))); } // Remap BasicTypes that are handled equivalently by the adapters. @@ -2289,12 +2289,15 @@ class AdapterFingerPrint : public MetaspaceObj { public: static AdapterFingerPrint* allocate(int total_args_passed, BasicType* sig_bt) { - int size_in_bytes = compute_size(total_args_passed, sig_bt); - return new (size_in_bytes) AdapterFingerPrint(total_args_passed, sig_bt); + int len = length(total_args_passed); + int size_in_bytes = BytesPerWord * compute_size_in_words(len); + AdapterFingerPrint* afp = new (size_in_bytes) AdapterFingerPrint(total_args_passed, sig_bt, len); + assert((afp->size() * BytesPerWord) == size_in_bytes, "should match"); + return afp; } static void deallocate(AdapterFingerPrint* fp) { - fp->~AdapterFingerPrint(); + FreeHeap(fp); } int value(int index) { @@ -2418,7 +2421,7 @@ class AdapterFingerPrint : public MetaspaceObj { // methods required by virtue of being a MetaspaceObj void metaspace_pointers_do(MetaspaceClosure* it) { return; /* nothing to do here */ } - int size() const { return (int)heap_word_size(sizeof(AdapterFingerPrint) + (_length * sizeof(int))); } + int size() const { return compute_size_in_words(_length); } MetaspaceObj::Type type() const { return AdapterFingerPrintType; } static bool equals(AdapterFingerPrint* const& fp1, AdapterFingerPrint* const& fp2) { diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 86074ac7aca..eb2ffb82e5a 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -711,6 +711,7 @@ class AdapterHandlerEntry : public MetaspaceObj { // Dummy argument is used to avoid C++ warning about using // deleted opearator MetaspaceObj::delete(). void* operator new(size_t size, size_t dummy) throw() { + assert(size == BytesPerWord * heap_word_size(sizeof(AdapterHandlerEntry)), "should match"); void* p = AllocateHeap(size, mtCode); memset(p, 0, size); return p; From f17b2bc06ad358933481c0e2cffd57c842bc0e76 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 4 Jun 2025 04:10:10 +0000 Subject: [PATCH 124/216] 8356870: HotSpotDiagnosticMXBean.dumpThreads and jcmd Thread.dump_to_file updates Reviewed-by: sspitsyn, kevinw --- .../classes/jdk/internal/vm/ThreadDumper.java | 587 ++++++++++---- .../jdk/internal/vm/ThreadSnapshot.java | 4 + .../management/HotSpotDiagnosticMXBean.java | 10 +- .../doc-files/threadDump.schema.json | 171 ++++ .../internal/HotSpotDiagnostic.java | 4 +- .../dcmd/thread/ThreadDumpToFileTest.java | 27 +- .../HotSpotDiagnosticMXBean/DumpThreads.java | 750 ++++++++++++++---- .../DumpThreadsWithEliminatedLock.java | 171 ++++ .../jdk/test/lib/threaddump/ThreadDump.java | 280 ++++--- 9 files changed, 1565 insertions(+), 439 deletions(-) create mode 100644 src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json create mode 100644 test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreadsWithEliminatedLock.java diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java index d0705bc2457..58729774f24 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,11 +24,13 @@ */ package jdk.internal.vm; -import java.io.BufferedOutputStream; +import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.io.PrintStream; +import java.io.OutputStreamWriter; +import java.io.UncheckedIOException; +import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; @@ -36,15 +38,19 @@ import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.time.Instant; -import java.util.ArrayList; +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; import java.util.Iterator; import java.util.List; +import java.util.Objects; /** * Thread dump support. * - * This class defines methods to dump threads to an output stream or file in plain - * text or JSON format. + * This class defines static methods to support the Thread.dump_to_file diagnostic command + * and the HotSpotDiagnosticMXBean.dumpThreads API. It defines methods to generate a + * thread dump to a file or byte array in plain text or JSON format. */ public class ThreadDumper { private ThreadDumper() { } @@ -53,13 +59,12 @@ public class ThreadDumper { private static final int MAX_BYTE_ARRAY_SIZE = 16_000; /** - * Generate a thread dump in plain text format to a byte array or file, UTF-8 encoded. - * + * Generate a thread dump in plain text format to a file or byte array, UTF-8 encoded. * This method is invoked by the VM for the Thread.dump_to_file diagnostic command. * * @param file the file path to the file, null or "-" to return a byte array * @param okayToOverwrite true to overwrite an existing file - * @return the UTF-8 encoded thread dump or message to return to the user + * @return the UTF-8 encoded thread dump or message to return to the tool user */ public static byte[] dumpThreads(String file, boolean okayToOverwrite) { if (file == null || file.equals("-")) { @@ -70,13 +75,12 @@ public class ThreadDumper { } /** - * Generate a thread dump in JSON format to a byte array or file, UTF-8 encoded. - * + * Generate a thread dump in JSON format to a file or byte array, UTF-8 encoded. * This method is invoked by the VM for the Thread.dump_to_file diagnostic command. * * @param file the file path to the file, null or "-" to return a byte array * @param okayToOverwrite true to overwrite an existing file - * @return the UTF-8 encoded thread dump or message to return to the user + * @return the UTF-8 encoded thread dump or message to return to the tool user */ public static byte[] dumpThreadsToJson(String file, boolean okayToOverwrite) { if (file == null || file.equals("-")) { @@ -88,21 +92,32 @@ public class ThreadDumper { /** * Generate a thread dump in plain text or JSON format to a byte array, UTF-8 encoded. + * This method is the implementation of the Thread.dump_to_file diagnostic command + * when a file path is not specified. It returns the thread dump and/or message to + * send to the tool user. */ private static byte[] dumpThreadsToByteArray(boolean json, int maxSize) { - try (var out = new BoundedByteArrayOutputStream(maxSize); - PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8)) { + var out = new BoundedByteArrayOutputStream(maxSize); + try (out; var writer = new TextWriter(out)) { if (json) { - dumpThreadsToJson(ps); + dumpThreadsToJson(writer); } else { - dumpThreads(ps); + dumpThreads(writer); } - return out.toByteArray(); + } catch (Exception ex) { + if (ex instanceof UncheckedIOException ioe) { + ex = ioe.getCause(); + } + String reply = String.format("Failed: %s%n", ex); + return reply.getBytes(StandardCharsets.UTF_8); } + return out.toByteArray(); } /** * Generate a thread dump in plain text or JSON format to the given file, UTF-8 encoded. + * This method is the implementation of the Thread.dump_to_file diagnostic command. + * It returns the thread dump and/or message to send to the tool user. */ private static byte[] dumpThreadsToFile(String file, boolean okayToOverwrite, boolean json) { Path path = Path.of(file).toAbsolutePath(); @@ -110,224 +125,412 @@ public class ThreadDumper { ? new OpenOption[0] : new OpenOption[] { StandardOpenOption.CREATE_NEW }; String reply; - try (OutputStream out = Files.newOutputStream(path, options); - BufferedOutputStream bos = new BufferedOutputStream(out); - PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8)) { - if (json) { - dumpThreadsToJson(ps); - } else { - dumpThreads(ps); + try (OutputStream out = Files.newOutputStream(path, options)) { + try (var writer = new TextWriter(out)) { + if (json) { + dumpThreadsToJson(writer); + } else { + dumpThreads(writer); + } + reply = String.format("Created %s%n", path); + } catch (UncheckedIOException e) { + reply = String.format("Failed: %s%n", e.getCause()); } - reply = String.format("Created %s%n", path); - } catch (FileAlreadyExistsException e) { + } catch (FileAlreadyExistsException _) { reply = String.format("%s exists, use -overwrite to overwrite%n", path); - } catch (IOException ioe) { - reply = String.format("Failed: %s%n", ioe); + } catch (Exception ex) { + reply = String.format("Failed: %s%n", ex); } return reply.getBytes(StandardCharsets.UTF_8); } /** - * Generate a thread dump in plain text format to the given output stream, - * UTF-8 encoded. - * - * This method is invoked by HotSpotDiagnosticMXBean.dumpThreads. + * Generate a thread dump in plain text format to the given output stream, UTF-8 + * encoded. This method is invoked by HotSpotDiagnosticMXBean.dumpThreads. + * @throws IOException if an I/O error occurs */ - public static void dumpThreads(OutputStream out) { - BufferedOutputStream bos = new BufferedOutputStream(out); - PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8); + public static void dumpThreads(OutputStream out) throws IOException { + var writer = new TextWriter(out); try { - dumpThreads(ps); - } finally { - ps.flush(); // flushes underlying stream + dumpThreads(writer); + writer.flush(); + } catch (UncheckedIOException e) { + IOException ioe = e.getCause(); + throw ioe; } } /** - * Generate a thread dump in plain text format to the given print stream. + * Generate a thread dump in plain text format to the given text stream. + * @throws UncheckedIOException if an I/O error occurs */ - private static void dumpThreads(PrintStream ps) { - ps.println(processId()); - ps.println(Instant.now()); - ps.println(Runtime.version()); - ps.println(); - dumpThreads(ThreadContainers.root(), ps); + private static void dumpThreads(TextWriter writer) { + writer.println(processId()); + writer.println(Instant.now()); + writer.println(Runtime.version()); + writer.println(); + dumpThreads(ThreadContainers.root(), writer); } - private static void dumpThreads(ThreadContainer container, PrintStream ps) { - container.threads().forEach(t -> dumpThread(t, ps)); - container.children().forEach(c -> dumpThreads(c, ps)); + private static void dumpThreads(ThreadContainer container, TextWriter writer) { + container.threads().forEach(t -> dumpThread(t, writer)); + container.children().forEach(c -> dumpThreads(c, writer)); } - private static void dumpThread(Thread thread, PrintStream ps) { - String suffix = thread.isVirtual() ? " virtual" : ""; - ps.println("#" + thread.threadId() + " \"" + thread.getName() + "\"" + suffix); - for (StackTraceElement ste : thread.getStackTrace()) { - ps.print(" "); - ps.println(ste); + private static void dumpThread(Thread thread, TextWriter writer) { + ThreadSnapshot snapshot = ThreadSnapshot.of(thread); + Instant now = Instant.now(); + Thread.State state = snapshot.threadState(); + writer.println("#" + thread.threadId() + " \"" + snapshot.threadName() + + "\" " + (thread.isVirtual() ? "virtual " : "") + state + " " + now); + + StackTraceElement[] stackTrace = snapshot.stackTrace(); + int depth = 0; + while (depth < stackTrace.length) { + writer.print(" at "); + writer.println(stackTrace[depth]); + snapshot.ownedMonitorsAt(depth).forEach(o -> { + if (o != null) { + writer.println(" - locked " + decorateObject(o)); + } else { + writer.println(" - lock is eliminated"); + } + }); + + // if parkBlocker set, or blocked/waiting on monitor, then print after top frame + if (depth == 0) { + // park blocker + Object parkBlocker = snapshot.parkBlocker(); + if (parkBlocker != null) { + writer.println(" - parking to wait for " + decorateObject(parkBlocker)); + } + + // blocked on monitor enter or Object.wait + if (state == Thread.State.BLOCKED && snapshot.blockedOn() instanceof Object obj) { + writer.println(" - waiting to lock " + decorateObject(obj)); + } else if ((state == Thread.State.WAITING || state == Thread.State.TIMED_WAITING) + && snapshot.waitingOn() instanceof Object obj) { + writer.println(" - waiting on " + decorateObject(obj)); + } + } + + depth++; } - ps.println(); + writer.println(); + } + + /** + * Returns the identity string for the given object in a form suitable for the plain + * text format thread dump. + */ + private static String decorateObject(Object obj) { + return "<" + Objects.toIdentityString(obj) + ">"; } /** * Generate a thread dump in JSON format to the given output stream, UTF-8 encoded. - * * This method is invoked by HotSpotDiagnosticMXBean.dumpThreads. + * @throws IOException if an I/O error occurs */ - public static void dumpThreadsToJson(OutputStream out) { - BufferedOutputStream bos = new BufferedOutputStream(out); - PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8); + public static void dumpThreadsToJson(OutputStream out) throws IOException { + var writer = new TextWriter(out); try { - dumpThreadsToJson(ps); - } finally { - ps.flush(); // flushes underlying stream + dumpThreadsToJson(writer); + writer.flush(); + } catch (UncheckedIOException e) { + IOException ioe = e.getCause(); + throw ioe; } } /** - * Generate a thread dump to the given print stream in JSON format. + * Generate a thread dump to the given text stream in JSON format. + * @throws UncheckedIOException if an I/O error occurs */ - private static void dumpThreadsToJson(PrintStream out) { - out.println("{"); - out.println(" \"threadDump\": {"); + private static void dumpThreadsToJson(TextWriter textWriter) { + var jsonWriter = new JsonWriter(textWriter); - String now = Instant.now().toString(); - String runtimeVersion = Runtime.version().toString(); - out.format(" \"processId\": \"%d\",%n", processId()); - out.format(" \"time\": \"%s\",%n", escape(now)); - out.format(" \"runtimeVersion\": \"%s\",%n", escape(runtimeVersion)); + jsonWriter.startObject(); // top-level object - out.println(" \"threadContainers\": ["); - List containers = allContainers(); - Iterator iterator = containers.iterator(); - while (iterator.hasNext()) { - ThreadContainer container = iterator.next(); - boolean more = iterator.hasNext(); - dumpThreadsToJson(container, out, more); - } - out.println(" ]"); // end of threadContainers + jsonWriter.startObject("threadDump"); - out.println(" }"); // end threadDump - out.println("}"); // end object + jsonWriter.writeProperty("processId", processId()); + jsonWriter.writeProperty("time", Instant.now()); + jsonWriter.writeProperty("runtimeVersion", Runtime.version()); + + jsonWriter.startArray("threadContainers"); + dumpThreads(ThreadContainers.root(), jsonWriter); + jsonWriter.endArray(); + + jsonWriter.endObject(); // threadDump + + jsonWriter.endObject(); // end of top-level object } /** - * Dump the given thread container to the print stream in JSON format. + * Write a thread container to the given JSON writer. + * @throws UncheckedIOException if an I/O error occurs */ - private static void dumpThreadsToJson(ThreadContainer container, - PrintStream out, - boolean more) { - out.println(" {"); - out.format(" \"container\": \"%s\",%n", escape(container.toString())); - - ThreadContainer parent = container.parent(); - if (parent == null) { - out.format(" \"parent\": null,%n"); - } else { - out.format(" \"parent\": \"%s\",%n", escape(parent.toString())); - } + private static void dumpThreads(ThreadContainer container, JsonWriter jsonWriter) { + jsonWriter.startObject(); + jsonWriter.writeProperty("container", container); + jsonWriter.writeProperty("parent", container.parent()); Thread owner = container.owner(); - if (owner == null) { - out.format(" \"owner\": null,%n"); - } else { - out.format(" \"owner\": \"%d\",%n", owner.threadId()); - } + jsonWriter.writeProperty("owner", (owner != null) ? owner.threadId() : null); long threadCount = 0; - out.println(" \"threads\": ["); + jsonWriter.startArray("threads"); Iterator threads = container.threads().iterator(); while (threads.hasNext()) { Thread thread = threads.next(); - dumpThreadToJson(thread, out, threads.hasNext()); + dumpThread(thread, jsonWriter); threadCount++; } - out.println(" ],"); // end of threads + jsonWriter.endArray(); // threads // thread count if (!ThreadContainers.trackAllThreads()) { threadCount = Long.max(threadCount, container.threadCount()); } - out.format(" \"threadCount\": \"%d\"%n", threadCount); + jsonWriter.writeProperty("threadCount", threadCount); - if (more) { - out.println(" },"); - } else { - out.println(" }"); // last container, no trailing comma - } + jsonWriter.endObject(); + + // the children of the thread container follow + container.children().forEach(c -> dumpThreads(c, jsonWriter)); } /** - * Dump the given thread and its stack trace to the print stream in JSON format. + * Write a thread to the given JSON writer. + * @throws UncheckedIOException if an I/O error occurs */ - private static void dumpThreadToJson(Thread thread, PrintStream out, boolean more) { - out.println(" {"); - out.println(" \"tid\": \"" + thread.threadId() + "\","); - out.println(" \"name\": \"" + escape(thread.getName()) + "\","); - out.println(" \"stack\": ["); + private static void dumpThread(Thread thread, JsonWriter jsonWriter) { + Instant now = Instant.now(); + ThreadSnapshot snapshot = ThreadSnapshot.of(thread); + Thread.State state = snapshot.threadState(); + StackTraceElement[] stackTrace = snapshot.stackTrace(); - int i = 0; - StackTraceElement[] stackTrace = thread.getStackTrace(); - while (i < stackTrace.length) { - out.print(" \""); - out.print(escape(stackTrace[i].toString())); - out.print("\""); - i++; - if (i < stackTrace.length) { - out.println(","); - } else { - out.println(); // last element, no trailing comma + jsonWriter.startObject(); + jsonWriter.writeProperty("tid", thread.threadId()); + jsonWriter.writeProperty("time", now); + if (thread.isVirtual()) { + jsonWriter.writeProperty("virtual", Boolean.TRUE); + } + jsonWriter.writeProperty("name", snapshot.threadName()); + jsonWriter.writeProperty("state", state); + + // park blocker + Object parkBlocker = snapshot.parkBlocker(); + if (parkBlocker != null) { + // parkBlocker is an object to allow for exclusiveOwnerThread in the future + jsonWriter.startObject("parkBlocker"); + jsonWriter.writeProperty("object", Objects.toIdentityString(parkBlocker)); + jsonWriter.endObject(); + } + + // blocked on monitor enter or Object.wait + if (state == Thread.State.BLOCKED && snapshot.blockedOn() instanceof Object obj) { + jsonWriter.writeProperty("blockedOn", Objects.toIdentityString(obj)); + } else if ((state == Thread.State.WAITING || state == Thread.State.TIMED_WAITING) + && snapshot.waitingOn() instanceof Object obj) { + jsonWriter.writeProperty("waitingOn", Objects.toIdentityString(obj)); + } + + // stack trace + jsonWriter.startArray("stack"); + Arrays.stream(stackTrace).forEach(jsonWriter::writeProperty); + jsonWriter.endArray(); + + // monitors owned, skip if none + if (snapshot.ownsMonitors()) { + jsonWriter.startArray("monitorsOwned"); + int depth = 0; + while (depth < stackTrace.length) { + List objs = snapshot.ownedMonitorsAt(depth).toList(); + if (!objs.isEmpty()) { + jsonWriter.startObject(); + jsonWriter.writeProperty("depth", depth); + jsonWriter.startArray("locks"); + snapshot.ownedMonitorsAt(depth) + .map(o -> (o != null) ? Objects.toIdentityString(o) : null) + .forEach(jsonWriter::writeProperty); + jsonWriter.endArray(); + jsonWriter.endObject(); + } + depth++; + } + jsonWriter.endArray(); + } + + // thread identifier of carrier, when mounted + if (thread.isVirtual() && snapshot.carrierThread() instanceof Thread carrier) { + jsonWriter.writeProperty("carrier", carrier.threadId()); + } + + jsonWriter.endObject(); + } + + /** + * Simple JSON writer to stream objects/arrays to a TextWriter with formatting. + * This class is not intended to be a fully featured JSON writer. + */ + private static class JsonWriter { + private static class Node { + final boolean isArray; + int propertyCount; + Node(boolean isArray) { + this.isArray = isArray; + } + boolean isArray() { + return isArray; + } + int propertyCount() { + return propertyCount; + } + int getAndIncrementPropertyCount() { + int old = propertyCount; + propertyCount++; + return old; } } - out.println(" ]"); - if (more) { - out.println(" },"); - } else { - out.println(" }"); // last thread, no trailing comma + private final Deque stack = new ArrayDeque<>(); + private final TextWriter writer; + + JsonWriter(TextWriter writer) { + this.writer = writer; } - } - /** - * Returns a list of all thread containers that are "reachable" from - * the root container. - */ - private static List allContainers() { - List containers = new ArrayList<>(); - collect(ThreadContainers.root(), containers); - return containers; - } + private void indent() { + int indent = stack.size() * 2; + writer.print(" ".repeat(indent)); + } - private static void collect(ThreadContainer container, List containers) { - containers.add(container); - container.children().forEach(c -> collect(c, containers)); - } + /** + * Start of object or array. + */ + private void startObject(String name, boolean isArray) { + if (!stack.isEmpty()) { + Node node = stack.peek(); + if (node.getAndIncrementPropertyCount() > 0) { + writer.println(","); + } + } + indent(); + if (name != null) { + writer.print("\"" + name + "\": "); + } + writer.println(isArray ? "[" : "{"); + stack.push(new Node(isArray)); + } - /** - * Escape any characters that need to be escape in the JSON output. - */ - private static String escape(String value) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - switch (c) { - case '"' -> sb.append("\\\""); - case '\\' -> sb.append("\\\\"); - case '/' -> sb.append("\\/"); - case '\b' -> sb.append("\\b"); - case '\f' -> sb.append("\\f"); - case '\n' -> sb.append("\\n"); - case '\r' -> sb.append("\\r"); - case '\t' -> sb.append("\\t"); - default -> { - if (c <= 0x1f) { - sb.append(String.format("\\u%04x", c)); - } else { - sb.append(c); + /** + * End of object or array. + */ + private void endObject(boolean isArray) { + Node node = stack.pop(); + if (node.isArray() != isArray) + throw new IllegalStateException(); + if (node.propertyCount() > 0) { + writer.println(); + } + indent(); + writer.print(isArray ? "]" : "}"); + } + + /** + * Write a property. + * @param name the property name, null for an unnamed property + * @param obj the value or null + */ + void writeProperty(String name, Object obj) { + Node node = stack.peek(); + if (node.getAndIncrementPropertyCount() > 0) { + writer.println(","); + } + indent(); + if (name != null) { + writer.print("\"" + name + "\": "); + } + switch (obj) { + // Long may be larger than safe range of JSON integer value + case Long _ -> writer.print("\"" + obj + "\""); + case Number _ -> writer.print(obj); + case Boolean _ -> writer.print(obj); + case null -> writer.print("null"); + default -> writer.print("\"" + escape(obj.toString()) + "\""); + } + } + + /** + * Write an unnamed property. + */ + void writeProperty(Object obj) { + writeProperty(null, obj); + } + + /** + * Start named object. + */ + void startObject(String name) { + startObject(name, false); + } + + /** + * Start unnamed object. + */ + void startObject() { + startObject(null); + } + + /** + * End of object. + */ + void endObject() { + endObject(false); + } + + /** + * Start named array. + */ + void startArray(String name) { + startObject(name, true); + } + + /** + * End of array. + */ + void endArray() { + endObject(true); + } + + /** + * Escape any characters that need to be escape in the JSON output. + */ + private static String escape(String value) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + switch (c) { + case '"' -> sb.append("\\\""); + case '\\' -> sb.append("\\\\"); + case '/' -> sb.append("\\/"); + case '\b' -> sb.append("\\b"); + case '\f' -> sb.append("\\f"); + case '\n' -> sb.append("\\n"); + case '\r' -> sb.append("\\r"); + case '\t' -> sb.append("\\t"); + default -> { + if (c <= 0x1f) { + sb.append(String.format("\\u%04x", c)); + } else { + sb.append(c); + } } } } + return sb.toString(); } - return sb.toString(); } /** @@ -357,6 +560,56 @@ public class ThreadDumper { } } + /** + * Simple Writer implementation for printing text. The print/println methods + * throw UncheckedIOException if an I/O error occurs. + */ + private static class TextWriter extends Writer { + private final Writer delegate; + + TextWriter(OutputStream out) { + delegate = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + delegate.write(cbuf, off, len); + } + + void print(Object obj) { + String s = String.valueOf(obj); + try { + write(s, 0, s.length()); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + void println() { + print(System.lineSeparator()); + } + + void println(String s) { + print(s); + println(); + } + + void println(Object obj) { + print(obj); + println(); + } + + @Override + public void flush() throws IOException { + delegate.flush(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + } + /** * Returns the process ID or -1 if not supported. */ diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java index 205bfde5449..b5607059abc 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java @@ -52,9 +52,13 @@ class ThreadSnapshot { /** * Take a snapshot of a Thread to get all information about the thread. + * @throws UnsupportedOperationException if not supported by VM */ static ThreadSnapshot of(Thread thread) { ThreadSnapshot snapshot = create(thread); + if (snapshot == null) { + throw new UnsupportedOperationException(); + } if (snapshot.stackTrace == null) { snapshot.stackTrace = EMPTY_STACK; } diff --git a/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index fba64846155..067cfffb158 100644 --- a/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -116,6 +116,13 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { * {@code outputFile} parameter must be an absolute path to a file that * does not exist. * + *

        When the format is specified as {@link ThreadDumpFormat#JSON JSON}, the + * thread dump is generated in JavaScript Object Notation. + * threadDump.schema.json + * describes the thread dump format in draft + * + * JSON Schema Language version 2. + * *

        The thread dump will include output for all platform threads. It may * include output for some or all virtual threads. * @@ -151,6 +158,7 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { TEXT_PLAIN, /** * JSON (JavaScript Object Notation) format. + * @spec https://datatracker.ietf.org/doc/html/rfc8259 JavaScript Object Notation */ JSON, } diff --git a/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json b/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json new file mode 100644 index 00000000000..57ef5c8b859 --- /dev/null +++ b/src/jdk.management/share/classes/com/sun/management/doc-files/threadDump.schema.json @@ -0,0 +1,171 @@ +{ + "type": "object", + "properties": { + "threadDump": { + "type": "object", + "properties": { + "processId": { + "type": "string", + "description": "The native process id of the Java virtual machine." + }, + "time": { + "type": "string", + "description": "The time in ISO 8601 format when the thread dump was generated." + }, + "runtimeVersion": { + "type": "string", + "description": "The runtime version, see java.lang.Runtime.Version" + }, + "threadContainers": { + "type": "array", + "description": "The array of thread containers (thread groupings).", + "items": [ + { + "type": "object", + "properties": { + "container": { + "type": "string", + "description": "The container name. The container name is unique." + }, + "parent": { + "type": [ + "string", + "null" + ], + "description": "The parent container name or null for the root container." + }, + "owner": { + "type": [ + "string", + "null" + ], + "description": "The thread identifier of the owner thread if owned." + }, + "threads": { + "type": "array", + "description": "The array of threads in the thread container.", + "items": [ + { + "type": "object", + "properties": { + "tid": { + "type": "string", + "description": "The thread identifier." + }, + "time": { + "type": "string", + "description": "The time in ISO 8601 format that the thread was sampled." + }, + "name": { + "type": "string", + "description": "The thread name." + }, + "state": { + "type": "string", + "description": "The thread state (Thread::getState)." + }, + "virtual" : { + "type": "boolean", + "description": "true for a virtual thread." + }, + "parkBlocker": { + "type": [ + "object" + ], + "properties": { + "object": { + "type": "string", + "description": "The blocker object responsible for the thread parking." + } + }, + "required": [ + "object" + ] + }, + "blockedOn": { + "type": "string", + "description": "The object that the thread is blocked on waiting to enter/re-enter a synchronization block/method." + }, + "waitingOn": { + "type": "string", + "description": "The object that the thread is waiting to be notified (Object.wait)." + }, + "stack": { + "type": "array", + "description": "The thread stack. The first element is the top of the stack.", + "items": [ + { + "type": "string", + "description": "A stack trace element (java.lang.StackTraceElement)." + } + ] + }, + "monitorsOwned": { + "type": "array", + "description": "The objects for which monitors are owned by the thread.", + "items": { + "type": "object", + "properties": { + "depth": { + "type": "integer", + "description": "The stack depth at which the monitors are owned." + }, + "locks": { + "type": "array", + "items": { + "type": [ + "string", + null + ], + "description": "The object for which the monitor is owned by the thread, null if eliminated" + } + } + }, + "required": [ + "depth", + "locks" + ] + } + }, + "carrier": { + "type": "string", + "description": "The thread identifier of the carrier thread if mounted." + } + }, + "required": [ + "tid", + "time", + "name", + "state", + "stack" + ] + } + ] + }, + "threadCount": { + "type": "string", + "description": "The number of threads in the thread container." + } + }, + "required": [ + "container", + "parent", + "owner", + "threads" + ] + } + ] + } + }, + "required": [ + "processId", + "time", + "runtimeVersion", + "threadContainers" + ] + } + }, + "required": [ + "threadDump" + ] +} diff --git a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java index 855e800a794..4e5f20fa141 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -153,7 +153,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean { throw new IllegalArgumentException("'outputFile' not absolute path"); try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { - dumpThreads(out, format); + dumpThreads(out, format); } } diff --git a/test/hotspot/jtreg/serviceability/dcmd/thread/ThreadDumpToFileTest.java b/test/hotspot/jtreg/serviceability/dcmd/thread/ThreadDumpToFileTest.java index f6002a32968..1fcc609114a 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/thread/ThreadDumpToFileTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/thread/ThreadDumpToFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -25,6 +25,7 @@ * @test * @bug 8284161 8287008 * @summary Basic test for jcmd Thread.dump_to_file + * @modules jdk.jcmd * @library /test/lib * @run junit/othervm ThreadDumpToFileTest */ @@ -66,7 +67,8 @@ class ThreadDumpToFileTest { @Test void testJsonThreadDump() throws IOException { Path file = genThreadDumpPath(".json"); - jcmdThreadDumpToFile(file, "-format=json").shouldMatch("Created"); + jcmdThreadDumpToFile(file, "-format=json") + .shouldMatch("Created"); // parse the JSON text String jsonText = Files.readString(file); @@ -89,7 +91,8 @@ class ThreadDumpToFileTest { Path file = genThreadDumpPath(".txt"); Files.writeString(file, "xxx"); - jcmdThreadDumpToFile(file, "").shouldMatch("exists"); + jcmdThreadDumpToFile(file, "") + .shouldMatch("exists"); // file should not be overridden assertEquals("xxx", Files.readString(file)); @@ -102,7 +105,23 @@ class ThreadDumpToFileTest { void testOverwriteFile() throws IOException { Path file = genThreadDumpPath(".txt"); Files.writeString(file, "xxx"); - jcmdThreadDumpToFile(file, "-overwrite"); + jcmdThreadDumpToFile(file, "-overwrite") + .shouldMatch("Created"); + } + + /** + * Test output file cannot be created. + */ + @Test + void testFileCreateFails() throws IOException { + Path badFile = Path.of(".").toAbsolutePath() + .resolve("does-not-exist") + .resolve("does-not-exist") + .resolve("threads.bad"); + jcmdThreadDumpToFile(badFile, "-format=plain") + .shouldMatch("Failed"); + jcmdThreadDumpToFile(badFile, "-format=json") + .shouldMatch("Failed"); } /** diff --git a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreads.java b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreads.java index a4072f2f7ff..adf643749c7 100644 --- a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreads.java +++ b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,41 +21,64 @@ * questions. */ -/** +/* * @test - * @bug 8284161 8287008 8309406 + * @bug 8284161 8287008 8309406 8356870 * @summary Basic test for com.sun.management.HotSpotDiagnosticMXBean.dumpThreads * @requires vm.continuations - * @modules jdk.management + * @modules java.base/jdk.internal.vm jdk.management * @library /test/lib - * @run junit/othervm DumpThreads - * @run junit/othervm -Djdk.trackAllThreads DumpThreads - * @run junit/othervm -Djdk.trackAllThreads=true DumpThreads - * @run junit/othervm -Djdk.trackAllThreads=false DumpThreads + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run junit/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * --enable-native-access=ALL-UNNAMED DumpThreads + * @run junit/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * --enable-native-access=ALL-UNNAMED -Djdk.trackAllThreads DumpThreads + * @run junit/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * --enable-native-access=ALL-UNNAMED -Djdk.trackAllThreads=true DumpThreads + * @run junit/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * --enable-native-access=ALL-UNNAMED -Djdk.trackAllThreads=false DumpThreads */ import java.lang.management.ManagementFactory; +import java.lang.reflect.Method; +import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Path; -import java.util.Objects; import java.time.ZonedDateTime; +import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import com.sun.management.HotSpotDiagnosticMXBean; import com.sun.management.HotSpotDiagnosticMXBean.ThreadDumpFormat; import jdk.test.lib.threaddump.ThreadDump; +import jdk.test.lib.thread.VThreadPinner; +import jdk.test.lib.thread.VThreadRunner; +import jdk.test.whitebox.WhiteBox; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; class DumpThreads { private static boolean trackAllThreads; @@ -64,6 +87,56 @@ class DumpThreads { static void setup() throws Exception { String s = System.getProperty("jdk.trackAllThreads"); trackAllThreads = (s == null) || s.isEmpty() || Boolean.parseBoolean(s); + + // need >=2 carriers for testing pinning + VThreadRunner.ensureParallelism(2); + } + + /** + * Test thread dump in plain text format. + */ + @Test + void testPlainText() throws Exception { + List lines = dumpThreadsToPlainText(); + + // pid should be on the first line + String pid = Long.toString(ProcessHandle.current().pid()); + assertEquals(pid, lines.get(0)); + + // timestamp should be on the second line + String secondLine = lines.get(1); + ZonedDateTime.parse(secondLine); + + // runtime version should be on third line + String vs = Runtime.version().toString(); + assertEquals(vs, lines.get(2)); + + // dump should include current thread + Thread currentThread = Thread.currentThread(); + if (trackAllThreads || !currentThread.isVirtual()) { + ThreadFields fields = findThread(currentThread.threadId(), lines); + assertNotNull(fields, "current thread not found"); + assertEquals(currentThread.getName(), fields.name()); + assertEquals(currentThread.isVirtual(), fields.isVirtual()); + } + } + + /** + * Test thread dump in JSON format. + */ + @Test + void testJsonFormat() throws Exception { + ThreadDump threadDump = dumpThreadsToJson(); + + // dump should include current thread in the root container + Thread currentThread = Thread.currentThread(); + if (trackAllThreads || !currentThread.isVirtual()) { + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(currentThread.threadId()) + .orElse(null); + assertNotNull(ti, "current thread not found"); + assertEquals(currentThread.isVirtual(), ti.isVirtual()); + } } /** @@ -78,180 +151,438 @@ class DumpThreads { } /** - * Test thread dump in plain text format contains information about the current - * thread and a virtual thread created directly with the Thread API. - */ - @Test - void testRootContainerPlainTextFormat() throws Exception { - Thread vthread = Thread.ofVirtual().start(LockSupport::park); - try { - testDumpThreadsPlainText(vthread, trackAllThreads); - } finally { - LockSupport.unpark(vthread); - } - } - - /** - * Test thread dump in JSON format contains information about the current - * thread and a virtual thread created directly with the Thread API. - */ - @Test - void testRootContainerJsonFormat() throws Exception { - Thread vthread = Thread.ofVirtual().start(LockSupport::park); - try { - testDumpThreadsJson(null, vthread, trackAllThreads); - } finally { - LockSupport.unpark(vthread); - } - } - - /** - * Test thread dump in plain text format includes a thread executing a task in the - * given ExecutorService. + * Test that a thread container for an executor service is in the JSON format thread dump. */ @ParameterizedTest @MethodSource("executors") - void testExecutorServicePlainTextFormat(ExecutorService executor) throws Exception { + void testThreadContainer(ExecutorService executor) throws Exception { try (executor) { - Thread thread = forkParker(executor); - try { - testDumpThreadsPlainText(thread, true); - } finally { - LockSupport.unpark(thread); - } + testThreadContainer(executor, Objects.toIdentityString(executor)); } } /** - * Test thread dump in JSON format includes a thread executing a task in the - * given ExecutorService. - */ - @ParameterizedTest - @MethodSource("executors") - void testExecutorServiceJsonFormat(ExecutorService executor) throws Exception { - try (executor) { - Thread thread = forkParker(executor); - try { - testDumpThreadsJson(Objects.toIdentityString(executor), thread, true); - } finally { - LockSupport.unpark(thread); - } - } - } - - /** - * Test thread dump in JSON format includes a thread executing a task in the - * fork-join common pool. + * Test that a thread container for the common pool is in the JSON format thread dump. */ @Test - void testForkJoinPool() throws Exception { - ForkJoinPool pool = ForkJoinPool.commonPool(); - Thread thread = forkParker(pool); + void testCommonPool() throws Exception { + testThreadContainer(ForkJoinPool.commonPool(), "ForkJoinPool.commonPool"); + } + + /** + * Test that the JSON thread dump has a thread container for the given executor. + */ + private void testThreadContainer(ExecutorService executor, String name) throws Exception { + var threadRef = new AtomicReference(); + + executor.submit(() -> { + threadRef.set(Thread.currentThread()); + LockSupport.park(); + }); + + // capture Thread + Thread thread; + while ((thread = threadRef.get()) == null) { + Thread.sleep(20); + } + try { - testDumpThreadsJson("ForkJoinPool.commonPool", thread, true); + // dump threads to file and parse as JSON object + ThreadDump threadDump = dumpThreadsToJson(); + + // find the thread container corresponding to the executor + var container = threadDump.findThreadContainer(name).orElse(null); + assertNotNull(container, name + " not found"); + assertFalse(container.owner().isPresent()); + var parent = container.parent().orElse(null); + assertEquals(threadDump.rootThreadContainer(), parent); + + // find the thread in the thread container + ThreadDump.ThreadInfo ti = container.findThread(thread.threadId()).orElse(null); + assertNotNull(ti, "thread not found"); + } finally { LockSupport.unpark(thread); } } /** - * Invoke HotSpotDiagnosticMXBean.dumpThreads to create a thread dump in plain text - * format, then sanity check that the thread dump includes expected strings, the - * current thread, and maybe the given thread. - * @param thread the thread to test if included - * @param expectInDump true if the thread is expected to be included + * ThreadFactory implementations for tests. */ - private void testDumpThreadsPlainText(Thread thread, boolean expectInDump) throws Exception { - Path file = genOutputPath(".txt"); - var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - mbean.dumpThreads(file.toString(), ThreadDumpFormat.TEXT_PLAIN); - System.err.format("Dumped to %s%n", file); - - // pid should be on the first line - String line1 = line(file, 0); - String pid = Long.toString(ProcessHandle.current().pid()); - assertTrue(line1.contains(pid)); - - // timestamp should be on the second line - String line2 = line(file, 1); - ZonedDateTime.parse(line2); - - // runtime version should be on third line - String line3 = line(file, 2); - String vs = Runtime.version().toString(); - assertTrue(line3.contains(vs)); - - // test if thread is included in thread dump - assertEquals(expectInDump, isPresent(file, thread)); - - // current thread should be included if platform thread or tracking all threads - Thread currentThread = Thread.currentThread(); - boolean currentThreadExpected = trackAllThreads || !currentThread.isVirtual(); - assertEquals(currentThreadExpected, isPresent(file, currentThread)); + static Stream threadFactories() { + Stream s = Stream.of(Thread.ofPlatform().factory()); + if (trackAllThreads) { + return Stream.concat(s, Stream.of(Thread.ofVirtual().factory())); + } else { + return s; + } } /** - * Invoke HotSpotDiagnosticMXBean.dumpThreads to create a thread dump in JSON format. - * The thread dump is parsed as a JSON object and checked to ensure that it contains - * expected data, the current thread, and maybe the given thread. - * @param containerName the name of the container or null for the root container - * @param thread the thread to test if included - * @param expect true if the thread is expected to be included + * Test thread dump with a thread blocked on monitor enter. */ - private void testDumpThreadsJson(String containerName, - Thread thread, - boolean expectInDump) throws Exception { - Path file = genOutputPath(".json"); - var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - mbean.dumpThreads(file.toString(), ThreadDumpFormat.JSON); - System.err.format("Dumped to %s%n", file); + @ParameterizedTest + @MethodSource("threadFactories") + void testBlockedThread(ThreadFactory factory) throws Exception { + testBlockedThread(factory, false); + } - // parse the JSON text - String jsonText = Files.readString(file); - ThreadDump threadDump = ThreadDump.parse(jsonText); + /** + * Test thread dump with a thread blocked on monitor enter when pinned. + */ + @Test + void testBlockedThreadWhenPinned() throws Exception { + assumeTrue(trackAllThreads, "This test requires all threads to be tracked"); + testBlockedThread(Thread.ofVirtual().factory(), true); + } - // test threadDump/processId - assertTrue(threadDump.processId() == ProcessHandle.current().pid()); + void testBlockedThread(ThreadFactory factory, boolean pinned) throws Exception { + var lock = new Object(); + var started = new CountDownLatch(1); - // test threadDump/time can be parsed - ZonedDateTime.parse(threadDump.time()); + Thread thread = factory.newThread(() -> { + if (pinned) { + VThreadPinner.runPinned(() -> { + started.countDown(); + synchronized (lock) { } // blocks + }); + } else { + started.countDown(); + synchronized (lock) { } // blocks + } + }); - // test threadDump/runtimeVersion - assertEquals(Runtime.version().toString(), threadDump.runtimeVersion()); + try { + synchronized (lock) { + // start thread and wait for it to block + thread.start(); + started.await(); + await(thread, Thread.State.BLOCKED); - // test root container, has no parent and no owner - var rootContainer = threadDump.rootThreadContainer(); - assertFalse(rootContainer.owner().isPresent()); - assertFalse(rootContainer.parent().isPresent()); + long tid = thread.threadId(); + String lockAsString = Objects.toIdentityString(lock); - // test that the container contains the given thread - ThreadDump.ThreadContainer container; - if (containerName == null) { - // root container, the thread should be found if trackAllThreads is true - container = rootContainer; - } else { - // find the container - container = threadDump.findThreadContainer(containerName).orElse(null); - assertNotNull(container, containerName + " not found"); - assertFalse(container.owner().isPresent()); - assertTrue(container.parent().get() == rootContainer); + // thread dump in plain text should include thread + List lines = dumpThreadsToPlainText(); + ThreadFields fields = findThread(tid, lines); + assertNotNull(fields, "thread not found"); + assertEquals("BLOCKED", fields.state()); + assertTrue(contains(lines, "- waiting to lock <" + lockAsString)); + // thread dump in JSON format should include thread in root container + ThreadDump threadDump = dumpThreadsToJson(); + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(tid) + .orElse(null); + assertNotNull(ti, "thread not found"); + assertEquals("BLOCKED", ti.state()); + assertEquals(lockAsString, ti.blockedOn()); + if (pinned) { + long carrierTid = ti.carrier().orElse(-1L); + assertNotEquals(-1L, carrierTid, "carrier not found"); + assertForkJoinWorkerThread(carrierTid); + } + } + } finally { + thread.join(); } - boolean found = container.findThread(thread.threadId()).isPresent(); - assertEquals(expectInDump, found); + } - // current thread should be in root container if platform thread or tracking all threads - Thread currentThread = Thread.currentThread(); - boolean currentThreadExpected = trackAllThreads || !currentThread.isVirtual(); - found = rootContainer.findThread(currentThread.threadId()).isPresent(); - assertEquals(currentThreadExpected, found); + /** + * Test thread dump with a thread waiting in Object.wait. + */ + @ParameterizedTest + @MethodSource("threadFactories") + void testWaitingThread(ThreadFactory factory) throws Exception { + testWaitingThread(factory, false); + } + + /** + * Test thread dump with a thread waiting in Object.wait when pinned. + */ + @Test + void testWaitingThreadWhenPinned() throws Exception { + assumeTrue(trackAllThreads, "This test requires all threads to be tracked"); + testWaitingThread(Thread.ofVirtual().factory(), true); + } + + void testWaitingThread(ThreadFactory factory, boolean pinned) throws Exception { + var lock = new Object(); + var started = new CountDownLatch(1); + + Thread thread = factory.newThread(() -> { + try { + synchronized (lock) { + if (pinned) { + VThreadPinner.runPinned(() -> { + started.countDown(); + lock.wait(); + }); + } else { + started.countDown(); + lock.wait(); + } + } + } catch (InterruptedException e) { } + }); + + try { + // start thread and wait for it to wait in Object.wait + thread.start(); + started.await(); + await(thread, Thread.State.WAITING); + + long tid = thread.threadId(); + String lockAsString = Objects.toIdentityString(lock); + + // thread dump in plain text should include thread + List lines = dumpThreadsToPlainText(); + ThreadFields fields = findThread(tid, lines); + assertNotNull(fields, "thread not found"); + assertEquals("WAITING", fields.state()); + + // thread dump in JSON format should include thread in root container + ThreadDump threadDump = dumpThreadsToJson(); + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(thread.threadId()) + .orElse(null); + assertNotNull(ti, "thread not found"); + assertEquals(ti.isVirtual(), thread.isVirtual()); + assertEquals("WAITING", ti.state()); + if (pinned) { + long carrierTid = ti.carrier().orElse(-1L); + assertNotEquals(-1L, carrierTid, "carrier not found"); + assertForkJoinWorkerThread(carrierTid); + } + + // Compiled native frames have no locals. If Object.wait0 has been compiled + // then we don't have the object that the thread is waiting on + Method wait0 = Object.class.getDeclaredMethod("wait0", long.class); + boolean expectWaitingOn = !WhiteBox.getWhiteBox().isMethodCompiled(wait0); + if (expectWaitingOn) { + // plain text dump should have "waiting on" line + assertTrue(contains(lines, "- waiting on <" + lockAsString)); + + // JSON thread dump should have waitingOn property + assertEquals(lockAsString, ti.waitingOn()); + } + + } finally { + synchronized (lock) { + lock.notifyAll(); + } + thread.join(); + } + } + + /** + * Test thread dump with a thread parked on a j.u.c. lock. + */ + @ParameterizedTest + @MethodSource("threadFactories") + void testParkedThread(ThreadFactory factory) throws Exception { + testParkedThread(factory, false); + } + + /** + * Test thread dump with a thread parked on a j.u.c. lock and pinned. + */ + @Test + void testParkedThreadWhenPinned() throws Exception { + assumeTrue(trackAllThreads, "This test requires all threads to be tracked"); + testParkedThread(Thread.ofVirtual().factory(), true); + } + + void testParkedThread(ThreadFactory factory, boolean pinned) throws Exception { + var lock = new ReentrantLock(); + var started = new CountDownLatch(1); + + Thread thread = factory.newThread(() -> { + if (pinned) { + VThreadPinner.runPinned(() -> { + started.countDown(); + lock.lock(); + lock.unlock(); + }); + } else { + started.countDown(); + lock.lock(); + lock.unlock(); + } + }); + + lock.lock(); + try { + // start thread and wait for it to park + thread.start(); + started.await(); + await(thread, Thread.State.WAITING); + + long tid = thread.threadId(); + + // thread dump in plain text should include thread + List lines = dumpThreadsToPlainText(); + ThreadFields fields = findThread(tid, lines); + assertNotNull(fields, "thread not found"); + assertEquals("WAITING", fields.state()); + assertTrue(contains(lines, "- parking to wait for { + synchronized (lock) { + if (pinned) { + VThreadPinner.runPinned(() -> { + started.countDown(); + LockSupport.park(); + }); + } else { + started.countDown(); + LockSupport.park(); + } + } + }); + + try { + // start thread and wait for it to park + thread.start(); + started.await(); + await(thread, Thread.State.WAITING); + + long tid = thread.threadId(); + String lockAsString = Objects.toIdentityString(lock); + + // thread dump in plain text should include thread + List lines = dumpThreadsToPlainText(); + ThreadFields fields = findThread(tid, lines); + assertNotNull(fields, "thread not found"); + assertEquals("WAITING", fields.state()); + assertTrue(contains(lines, "- locked <" + lockAsString)); + + // thread dump in JSON format should include thread in root container + ThreadDump threadDump = dumpThreadsToJson(); + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(tid) + .orElse(null); + assertNotNull(ti, "thread not found"); + assertEquals(ti.isVirtual(), thread.isVirtual()); + + // the lock should be in the ownedMonitors array + Set ownedMonitors = ti.ownedMonitors().values() + .stream() + .flatMap(List::stream) + .collect(Collectors.toSet()); + assertTrue(ownedMonitors.contains(lockAsString), lockAsString + " not found"); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + + /** + * Test mounted virtual thread. + */ + @Test + void testMountedVirtualThread() throws Exception { + assumeTrue(trackAllThreads, "This test requires all threads to be tracked"); + + // start virtual thread that spins until done + var started = new AtomicBoolean(); + var done = new AtomicBoolean(); + var thread = Thread.ofVirtual().start(() -> { + started.set(true); + while (!done.get()) { + Thread.onSpinWait(); + } + }); + + try { + // wait for thread to start + awaitTrue(started); + long tid = thread.threadId(); + + // thread dump in plain text should include thread + List lines = dumpThreadsToPlainText(); + ThreadFields fields = findThread(tid, lines); + assertNotNull(fields, "thread not found"); + assertTrue(fields.isVirtual()); + + // thread dump in JSON format should include thread in root container + ThreadDump threadDump = dumpThreadsToJson(); + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(tid) + .orElse(null); + assertNotNull(ti, "thread not found"); + assertTrue(ti.isVirtual()); + long carrierTid = ti.carrier().orElse(-1L); + assertNotEquals(-1L, carrierTid, "carrier not found"); + assertForkJoinWorkerThread(carrierTid); + } finally { + done.set(true); + thread.join(); + } + } + + /** + * Asserts that the given thread identifier is a ForkJoinWorkerThread. + */ + private void assertForkJoinWorkerThread(long tid) { + Thread thread = Thread.getAllStackTraces() + .keySet() + .stream() + .filter(t -> t.threadId() == tid) + .findAny() + .orElse(null); + assertNotNull(thread, "thread " + tid + " not found"); + assertTrue(thread instanceof ForkJoinWorkerThread, "not a ForkJoinWorkerThread"); } /** * Test that dumpThreads throws if the output file already exists. */ @Test - void testFileAlreadyExsists() throws Exception { + void testFileAlreadyExists() throws Exception { var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); String file = Files.createFile(genOutputPath("txt")).toString(); assertThrows(FileAlreadyExistsException.class, @@ -260,11 +591,44 @@ class DumpThreads { () -> mbean.dumpThreads(file, ThreadDumpFormat.JSON)); } + /** + * Test that dumpThreads throws IOException when the output file cannot be created. + */ + @Test + void testFileCreateFails() { + var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + String badFile = Path.of(".").toAbsolutePath() + .resolve("does-not-exist") + .resolve("does-not-exist") + .resolve("threads.bad") + .toString(); + assertThrows(IOException.class, + () -> mbean.dumpThreads(badFile, ThreadDumpFormat.TEXT_PLAIN)); + assertThrows(IOException.class, + () -> mbean.dumpThreads(badFile, ThreadDumpFormat.JSON)); + } + + /** + * Test that dumpThreads throws IOException if writing to output file fails. + */ + @Test + void testFileWriteFails() { + var out = new OutputStream() { + @Override + public void write(int b) throws IOException { + throw new IOException("There is not enough space on the disk"); + } + }; + // need to invoke internal API directly to test this + assertThrows(IOException.class, () -> jdk.internal.vm.ThreadDumper.dumpThreads(out)); + assertThrows(IOException.class, () -> jdk.internal.vm.ThreadDumper.dumpThreadsToJson(out)); + } + /** * Test that dumpThreads throws if the file path is relative. */ @Test - void testRelativePath() throws Exception { + void testRelativePath() { var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); assertThrows(IllegalArgumentException.class, () -> mbean.dumpThreads("threads.txt", ThreadDumpFormat.TEXT_PLAIN)); @@ -276,7 +640,7 @@ class DumpThreads { * Test that dumpThreads throws with null parameters. */ @Test - void testNull() throws Exception { + void testNull() { var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); assertThrows(NullPointerException.class, () -> mbean.dumpThreads(null, ThreadDumpFormat.TEXT_PLAIN)); @@ -285,31 +649,63 @@ class DumpThreads { } /** - * Submits a parking task to the given executor, returns the Thread object of - * the parked thread. + * Represents the data for a thread found in a plain text thread dump. */ - private static Thread forkParker(ExecutorService executor) { - class Box { static volatile Thread thread;} - var latch = new CountDownLatch(1); - executor.submit(() -> { - Box.thread = Thread.currentThread(); - latch.countDown(); - LockSupport.park(); - }); - try { - latch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); + private record ThreadFields(long tid, String name, boolean isVirtual, String state) { } + + /** + * Find a thread in the lines of a plain text thread dump. + */ + private ThreadFields findThread(long tid, List lines) { + String line = lines.stream() + .filter(l -> l.startsWith("#" + tid + " ")) + .findFirst() + .orElse(null); + if (line == null) { + return null; } - return Box.thread; + + // #3 "main" RUNNABLE 2025-04-18T15:22:12.012450Z + // #36 "" virtual WAITING 2025-04-18T15:22:12.012450Z + Pattern pattern = Pattern.compile("#(\\d+)\\s+\"([^\"]*)\"\\s+(virtual\\s+)?(\\w+)\\s+(.*)"); + Matcher matcher = pattern.matcher(line); + assertTrue(matcher.matches()); + String name = matcher.group(2); + boolean isVirtual = "virtual ".equals(matcher.group(3)); + String state = matcher.group(4); + return new ThreadFields(tid, name, isVirtual, state); } /** - * Returns true if a Thread is present in a plain text thread dump. + * Returns true if lines of a plain text thread dump contain the given text. */ - private static boolean isPresent(Path file, Thread thread) throws Exception { - String expect = "#" + thread.threadId(); - return count(file, expect) > 0; + private boolean contains(List lines, String text) { + return lines.stream().map(String::trim) + .anyMatch(l -> l.contains(text)); + } + + /** + * Dump threads to a file in plain text format, return the lines in the file. + */ + private List dumpThreadsToPlainText() throws Exception { + Path file = genOutputPath(".txt"); + var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + mbean.dumpThreads(file.toString(), HotSpotDiagnosticMXBean.ThreadDumpFormat.TEXT_PLAIN); + System.err.format("Dumped to %s%n", file.getFileName()); + List lines = Files.readAllLines(file); + return lines; + } + + /** + * Dump threads to a file in JSON format, parse and return as JSON object. + */ + private static ThreadDump dumpThreadsToJson() throws Exception { + Path file = genOutputPath(".json"); + var mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + mbean.dumpThreads(file.toString(), HotSpotDiagnosticMXBean.ThreadDumpFormat.JSON); + System.err.format("Dumped to %s%n", file.getFileName()); + String jsonText = Files.readString(file); + return ThreadDump.parse(jsonText); } /** @@ -323,21 +719,23 @@ class DumpThreads { } /** - * Return the count of the number of files in the given file that contain - * the given character sequence. + * Waits for the given thread to get to a given state. */ - static long count(Path file, CharSequence cs) throws Exception { - try (Stream stream = Files.lines(file)) { - return stream.filter(line -> line.contains(cs)).count(); + private void await(Thread thread, Thread.State expectedState) throws InterruptedException { + Thread.State state = thread.getState(); + while (state != expectedState) { + assertTrue(state != Thread.State.TERMINATED, "Thread has terminated"); + Thread.sleep(10); + state = thread.getState(); } } /** - * Return line $n of the given file. + * Waits for the boolean value to become true. */ - private String line(Path file, long n) throws Exception { - try (Stream stream = Files.lines(file)) { - return stream.skip(n).findFirst().orElseThrow(); + private static void awaitTrue(AtomicBoolean ref) throws Exception { + while (!ref.get()) { + Thread.sleep(20); } } } diff --git a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreadsWithEliminatedLock.java b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreadsWithEliminatedLock.java new file mode 100644 index 00000000000..a2dce62792b --- /dev/null +++ b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreadsWithEliminatedLock.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8356870 + * @summary Test HotSpotDiagnosticMXBean.dumpThreads with a thread owning a monitor for + * an object that is scalar replaced + * @requires !vm.debug & (vm.compMode != "Xcomp") + * @requires (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) + * @modules jdk.management + * @library /test/lib + * @run main/othervm DumpThreadsWithEliminatedLock plain platform + * @run main/othervm DumpThreadsWithEliminatedLock plain virtual + * @run main/othervm DumpThreadsWithEliminatedLock json platform + * @run main/othervm DumpThreadsWithEliminatedLock json virtual + */ + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.List; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import com.sun.management.HotSpotDiagnosticMXBean; +import jdk.test.lib.threaddump.ThreadDump; +import jdk.test.lib.thread.VThreadRunner; + +public class DumpThreadsWithEliminatedLock { + + public static void main(String[] args) throws Exception { + boolean plain = switch (args[0]) { + case "plain" -> true; + case "json" -> false; + default -> throw new RuntimeException("Unknown dump format"); + }; + + ThreadFactory factory = switch (args[1]) { + case "platform" -> Thread.ofPlatform().factory(); + case "virtual" -> Thread.ofVirtual().factory(); + default -> throw new RuntimeException("Unknown thread kind"); + }; + + // need at least two carriers for JTREG_TEST_THREAD_FACTORY=Virtual + if (Thread.currentThread().isVirtual()) { + VThreadRunner.ensureParallelism(2); + } + + // A thread that spins creating and adding to a StringBuffer. StringBuffer is + // synchronized, assume object will be scalar replaced and the lock eliminated. + var done = new AtomicBoolean(); + var ref = new AtomicReference(); + Thread thread = factory.newThread(() -> { + while (!done.get()) { + StringBuffer sb = new StringBuffer(); + sb.append(System.currentTimeMillis()); + String s = sb.toString(); + ref.set(s); + } + }); + try { + thread.start(); + if (plain) { + testPlainFormat(); + } else { + testJsonFormat(thread.threadId()); + } + } finally { + done.set(true); + thread.join(); + } + } + + /** + * Invoke HotSpotDiagnosticMXBean.dumpThreads to generate a thread dump in plain text + * format until "lock is eliminated" is found in the output. + */ + private static void testPlainFormat() { + try { + Path file = genOutputPath(".txt"); + boolean found = false; + int attempts = 0; + while (!found) { + attempts++; + Files.deleteIfExists(file); + ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class) + .dumpThreads(file.toString(), HotSpotDiagnosticMXBean.ThreadDumpFormat.TEXT_PLAIN); + try (Stream stream = Files.lines(file)) { + found = stream.map(String::trim) + .anyMatch(l -> l.contains("- lock is eliminated")); + } + System.out.format("%s Attempt %d, found: %b%n", Instant.now(), attempts, found); + } + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + /** + * Invoke HotSpotDiagnosticMXBean.dumpThreads to generate a thread dump in JSON format + * until the monitorsOwned.locks array for the given thread has a null lock. + */ + private static void testJsonFormat(long tid) { + try { + Path file = genOutputPath(".json"); + boolean found = false; + int attempts = 0; + while (!found) { + attempts++; + Files.deleteIfExists(file); + ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class) + .dumpThreads(file.toString(), HotSpotDiagnosticMXBean.ThreadDumpFormat.JSON); + + // parse thread dump as JSON and find thread + String jsonText = Files.readString(file); + ThreadDump threadDump = ThreadDump.parse(jsonText); + ThreadDump.ThreadInfo ti = threadDump.rootThreadContainer() + .findThread(tid) + .orElse(null); + if (ti == null) { + throw new RuntimeException("Thread " + tid + " not found in thread dump"); + } + + // look for null element in ownedMonitors/locks array + found = ti.ownedMonitors() + .values() + .stream() + .flatMap(List::stream) + .anyMatch(o -> o == null); + System.out.format("%s Attempt %d, found: %b%n", Instant.now(), attempts, found); + } + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + /** + * Generate a file path with the given suffix to use as an output file. + */ + private static Path genOutputPath(String suffix) throws IOException { + Path dir = Path.of(".").toAbsolutePath(); + Path file = Files.createTempFile(dir, "dump", suffix); + Files.delete(file); + return file; + } +} \ No newline at end of file diff --git a/test/lib/jdk/test/lib/threaddump/ThreadDump.java b/test/lib/jdk/test/lib/threaddump/ThreadDump.java index 5e4f6ebc10f..f4964a9521f 100644 --- a/test/lib/jdk/test/lib/threaddump/ThreadDump.java +++ b/test/lib/jdk/test/lib/threaddump/ThreadDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package jdk.test.lib.threaddump; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -62,6 +63,7 @@ import jdk.test.lib.json.JSONValue; * { * "tid": "8", * "name": "Reference Handler", + * "state": "RUNNABLE", * "stack": [ * "java.base\/java.lang.ref.Reference.waitForReferencePendingList(Native Method)", * "java.base\/java.lang.ref.Reference.processPendingReferences(Reference.java:245)", @@ -113,23 +115,46 @@ import jdk.test.lib.json.JSONValue; * } */ public final class ThreadDump { - private final long processId; - private final String time; - private final String runtimeVersion; - private ThreadContainer rootThreadContainer; + private final ThreadContainer rootThreadContainer; + private final Map nameToThreadContainer; + private final JSONValue threadDumpObj; + + private ThreadDump(ThreadContainer rootThreadContainer, + Map nameToThreadContainer, + JSONValue threadDumpObj) { + this.rootThreadContainer = rootThreadContainer; + this.nameToThreadContainer = nameToThreadContainer; + this.threadDumpObj = threadDumpObj; + } /** * Represents an element in the threadDump/threadContainers array. */ public static class ThreadContainer { private final String name; - private long owner; - private ThreadContainer parent; - private Set threads; + private final ThreadContainer parent; private final Set children = new HashSet<>(); + private final JSONValue containerObj; - ThreadContainer(String name) { + ThreadContainer(String name, ThreadContainer parent, JSONValue containerObj) { this.name = name; + this.parent = parent; + this.containerObj = containerObj; + } + + /** + * Add a child thread container. + */ + void addChild(ThreadContainer container) { + children.add(container); + } + + /** + * Returns the value of a property of this thread container, as a string. + */ + private String getStringProperty(String propertyName) { + JSONValue value = containerObj.get(propertyName); + return (value != null) ? value.asString() : null; } /** @@ -143,7 +168,10 @@ public final class ThreadDump { * Return the thread identifier of the owner or empty OptionalLong if not owned. */ public OptionalLong owner() { - return (owner != 0) ? OptionalLong.of(owner) : OptionalLong.empty(); + String owner = getStringProperty("owner"); + return (owner != null) + ? OptionalLong.of(Long.parseLong(owner)) + : OptionalLong.empty(); } /** @@ -164,7 +192,12 @@ public final class ThreadDump { * Returns a stream of {@code ThreadInfo} objects for the threads in this container. */ public Stream threads() { - return threads.stream(); + JSONValue.JSONArray threadsObj = containerObj.get("threads").asArray(); + Set threadInfos = new HashSet<>(); + for (JSONValue threadObj : threadsObj) { + threadInfos.add(new ThreadInfo(threadObj)); + } + return threadInfos.stream(); } /** @@ -176,21 +209,6 @@ public final class ThreadDump { .findAny(); } - /** - * Helper method to recursively find a container with the given name. - */ - ThreadContainer findThreadContainer(String name) { - if (name().equals(name)) - return this; - if (name().startsWith(name + "/")) - return this; - return children() - .map(c -> c.findThreadContainer(name)) - .filter(c -> c != null) - .findAny() - .orElse(null); - } - @Override public int hashCode() { return name.hashCode(); @@ -216,13 +234,30 @@ public final class ThreadDump { */ public static final class ThreadInfo { private final long tid; - private final String name; - private final List stack; + private final JSONValue threadObj; - ThreadInfo(long tid, String name, List stack) { - this.tid = tid; - this.name = name; - this.stack = stack; + ThreadInfo(JSONValue threadObj) { + this.tid = Long.parseLong(threadObj.get("tid").asString()); + this.threadObj = threadObj; + } + + /** + * Returns the value of a property of this thread object, as a string. + */ + private String getStringProperty(String propertyName) { + JSONValue value = threadObj.get(propertyName); + return (value != null) ? value.asString() : null; + } + + /** + * Returns the value of a property of an object in this thread object, as a string. + */ + private String getStringProperty(String objectName, String propertyName) { + if (threadObj.get(objectName) instanceof JSONValue.JSONObject obj + && obj.get(propertyName) instanceof JSONValue value) { + return value.asString(); + } + return null; } /** @@ -236,16 +271,86 @@ public final class ThreadDump { * Returns the thread name. */ public String name() { - return name; + return getStringProperty("name"); + } + + /** + * Returns the thread state. + */ + public String state() { + return getStringProperty("state"); + } + + /** + * Returns true if virtual thread. + */ + public boolean isVirtual() { + String s = getStringProperty("virtual"); + return (s != null) ? Boolean.parseBoolean(s) : false; + } + + /** + * Returns the thread's parkBlocker. + */ + public String parkBlocker() { + return getStringProperty("parkBlocker", "object"); + } + + /** + * Returns the object that the thread is blocked entering its monitor. + */ + public String blockedOn() { + return getStringProperty("blockedOn"); + } + + /** + * Return the object that is the therad is waiting on with Object.wait. + */ + public String waitingOn() { + return getStringProperty("waitingOn"); } /** * Returns the thread stack. */ public Stream stack() { + JSONValue.JSONArray stackObj = threadObj.get("stack").asArray(); + List stack = new ArrayList<>(); + for (JSONValue steObject : stackObj) { + stack.add(steObject.asString()); + } return stack.stream(); } + /** + * Return a map of monitors owned. + */ + public Map> ownedMonitors() { + Map> ownedMonitors = new HashMap<>(); + JSONValue monitorsOwnedObj = threadObj.get("monitorsOwned"); + if (monitorsOwnedObj != null) { + for (JSONValue obj : monitorsOwnedObj.asArray()) { + int depth = Integer.parseInt(obj.get("depth").asString()); + for (JSONValue lock : obj.get("locks").asArray()) { + ownedMonitors.computeIfAbsent(depth, _ -> new ArrayList<>()) + .add(lock.asString()); + } + } + } + return ownedMonitors; + } + + /** + * If the thread is a mounted virtual thread, return the thread identifier of + * its carrier. + */ + public OptionalLong carrier() { + String s = getStringProperty("carrier"); + return (s != null) + ? OptionalLong.of(Long.parseLong(s)) + : OptionalLong.empty(); + } + @Override public int hashCode() { return Long.hashCode(tid); @@ -264,84 +369,42 @@ public final class ThreadDump { public String toString() { StringBuilder sb = new StringBuilder("#"); sb.append(tid); + String name = name(); if (name.length() > 0) { - sb.append(","); - sb.append(name); + sb.append(",") + .append(name); } return sb.toString(); } } /** - * Parses the given JSON text as a thread dump. + * Returns the value of a property of this thread dump, as a string. */ - private ThreadDump(String json) { - JSONValue threadDumpObj = JSONValue.parse(json).get("threadDump"); - - // maps container name to ThreadContainer - Map map = new HashMap<>(); - - // threadContainers array - JSONValue threadContainersObj = threadDumpObj.get("threadContainers"); - for (JSONValue containerObj : threadContainersObj.asArray()) { - String name = containerObj.get("container").asString(); - String parentName = containerObj.get("parent").asString(); - String owner = containerObj.get("owner").asString(); - JSONValue.JSONArray threadsObj = containerObj.get("threads").asArray(); - - // threads array - Set threadInfos = new HashSet<>(); - for (JSONValue threadObj : threadsObj) { - long tid = Long.parseLong(threadObj.get("tid").asString()); - String threadName = threadObj.get("name").asString(); - JSONValue.JSONArray stackObj = threadObj.get("stack").asArray(); - List stack = new ArrayList<>(); - for (JSONValue steObject : stackObj) { - stack.add(steObject.asString()); - } - threadInfos.add(new ThreadInfo(tid, threadName, stack)); - } - - // add to map if not already encountered - var container = map.computeIfAbsent(name, k -> new ThreadContainer(name)); - if (owner != null) - container.owner = Long.parseLong(owner); - container.threads = threadInfos; - - if (parentName == null) { - rootThreadContainer = container; - } else { - // add parent to map if not already encountered and add to its set of children - var parent = map.computeIfAbsent(parentName, k -> new ThreadContainer(parentName)); - container.parent = parent; - parent.children.add(container); - } - } - - this.processId = Long.parseLong(threadDumpObj.get("processId").asString()); - this.time = threadDumpObj.get("time").asString(); - this.runtimeVersion = threadDumpObj.get("runtimeVersion").asString(); + private String getStringProperty(String propertyName) { + JSONValue value = threadDumpObj.get(propertyName); + return (value != null) ? value.asString() : null; } /** * Returns the value of threadDump/processId. */ public long processId() { - return processId; + return Long.parseLong(getStringProperty("processId")); } /** * Returns the value of threadDump/time. */ public String time() { - return time; + return getStringProperty("time"); } /** * Returns the value of threadDump/runtimeVersion. */ public String runtimeVersion() { - return runtimeVersion; + return getStringProperty("runtimeVersion"); } /** @@ -355,8 +418,17 @@ public final class ThreadDump { * Finds a container in the threadDump/threadContainers array with the given name. */ public Optional findThreadContainer(String name) { - ThreadContainer container = rootThreadContainer.findThreadContainer(name); - return Optional.ofNullable(container); + ThreadContainer container = nameToThreadContainer.get(name); + if (container == null) { + // may be name/identity format + container = nameToThreadContainer.entrySet() + .stream() + .filter(e -> e.getKey().startsWith(name + "/")) + .map(e -> e.getValue()) + .findAny() + .orElse(null); + } + return Optional.of(container); } /** @@ -364,6 +436,36 @@ public final class ThreadDump { * @throws RuntimeException if an error occurs */ public static ThreadDump parse(String json) { - return new ThreadDump(json); + JSONValue threadDumpObj = JSONValue.parse(json).get("threadDump"); + + // threadContainers array, preserve insertion order (parents are added before children) + Map containerObjs = new LinkedHashMap<>(); + JSONValue threadContainersObj = threadDumpObj.get("threadContainers"); + for (JSONValue containerObj : threadContainersObj.asArray()) { + String name = containerObj.get("container").asString(); + containerObjs.put(name, containerObj); + } + + // find root and create tree of thread containers + ThreadContainer root = null; + Map map = new HashMap<>(); + for (String name : containerObjs.keySet()) { + JSONValue containerObj = containerObjs.get(name); + String parentName = containerObj.get("parent").asString(); + if (parentName == null) { + root = new ThreadContainer(name, null, containerObj); + map.put(name, root); + } else { + var parent = map.get(parentName); + if (parent == null) { + throw new RuntimeException("Thread container " + name + " found before " + parentName); + } + var container = new ThreadContainer(name, parent, containerObj); + parent.addChild(container); + map.put(name, container); + } + } + + return new ThreadDump(root, map, threadDumpObj); } -} +} \ No newline at end of file From b918dc84ec8364321a5a6d9f6835edcb1d9ad62f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 4 Jun 2025 06:02:49 +0000 Subject: [PATCH 125/216] 8357434: x86: Simplify Interpreter::profile_taken_branch Reviewed-by: kvn, vlivanov --- src/hotspot/cpu/x86/interp_masm_x86.cpp | 16 +++------------- src/hotspot/cpu/x86/interp_masm_x86.hpp | 2 +- src/hotspot/cpu/x86/templateTable_x86.cpp | 4 +--- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 6d638ab67ef..92233ee0d07 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1355,25 +1355,15 @@ void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { } -void InterpreterMacroAssembler::profile_taken_branch(Register mdp, - Register bumped_count) { +void InterpreterMacroAssembler::profile_taken_branch(Register mdp) { if (ProfileInterpreter) { Label profile_continue; // If no method data exists, go to profile_continue. - // Otherwise, assign to mdp test_method_data_pointer(mdp, profile_continue); // We are taking a branch. Increment the taken count. - // We inline increment_mdp_data_at to return bumped_count in a register - //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); - Address data(mdp, in_bytes(JumpData::taken_offset())); - movptr(bumped_count, data); - assert(DataLayout::counter_increment == 1, - "flow-free idiom only works with 1"); - addptr(bumped_count, DataLayout::counter_increment); - sbbptr(bumped_count, 0); - movptr(data, bumped_count); // Store back out + increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); // The method data pointer needs to be updated to reflect the new target. update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); @@ -1389,7 +1379,7 @@ void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) { // If no method data exists, go to profile_continue. test_method_data_pointer(mdp, profile_continue); - // We are taking a branch. Increment the not taken count. + // We are not taking a branch. Increment the not taken count. increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset())); // The method data pointer needs to be updated to correspond to diff --git a/src/hotspot/cpu/x86/interp_masm_x86.hpp b/src/hotspot/cpu/x86/interp_masm_x86.hpp index 47d54b54d7f..a36a697eebf 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.hpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.hpp @@ -236,7 +236,7 @@ class InterpreterMacroAssembler: public MacroAssembler { void update_mdp_by_constant(Register mdp_in, int constant); void update_mdp_for_ret(Register return_bci); - void profile_taken_branch(Register mdp, Register bumped_count); + void profile_taken_branch(Register mdp); void profile_not_taken_branch(Register mdp); void profile_call(Register mdp); void profile_final_call(Register mdp); diff --git a/src/hotspot/cpu/x86/templateTable_x86.cpp b/src/hotspot/cpu/x86/templateTable_x86.cpp index 9f568904ae2..82ca18d8a1f 100644 --- a/src/hotspot/cpu/x86/templateTable_x86.cpp +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp @@ -1687,8 +1687,7 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) { void TemplateTable::branch(bool is_jsr, bool is_wide) { __ get_method(rcx); // rcx holds method - __ profile_taken_branch(rax, rbx); // rax holds updated MDP, rbx - // holds bumped taken count + __ profile_taken_branch(rax); // rax holds updated MDP const ByteSize be_offset = MethodCounters::backedge_counter_offset() + InvocationCounter::counter_offset(); @@ -1739,7 +1738,6 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { if (UseLoopCounter) { // increment backedge counter for backward branches // rax: MDO - // rbx: MDO bumped taken-count // rcx: method // rdx: target offset // r13: target bcp From 683319f25cbea83e28b9a0ad22e1c3e781e78165 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 4 Jun 2025 06:04:05 +0000 Subject: [PATCH 126/216] 8357798: ReverseOrderListView uses Boolean boxes after JDK-8356080 Reviewed-by: liach, smarks --- .../share/classes/java/util/ReverseOrderListView.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/ReverseOrderListView.java b/src/java.base/share/classes/java/util/ReverseOrderListView.java index 75d69f38aaf..6ecbac66ed8 100644 --- a/src/java.base/share/classes/java/util/ReverseOrderListView.java +++ b/src/java.base/share/classes/java/util/ReverseOrderListView.java @@ -42,8 +42,7 @@ class ReverseOrderListView implements List { @Stable final List base; - @Stable - final Boolean modifiable; + final boolean modifiable; public static List of(List list, boolean modifiable) { if (list instanceof RandomAccess) { From b5cfd76c047392788b6a5c25ebadc463b2c8ce90 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Wed, 4 Jun 2025 06:38:06 +0000 Subject: [PATCH 127/216] 8358456: ZipFile.getInputStream(ZipEntry) throws unspecified IllegalArgumentException Reviewed-by: lancea --- .../share/classes/java/util/zip/ZipFile.java | 16 +-- .../ZipFile/InvalidCompressedSizeTest.java | 124 ++++++++++++++++++ 2 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 test/jdk/java/util/zip/ZipFile/InvalidCompressedSizeTest.java diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index b7d6f1ff714..17382181876 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -351,11 +351,11 @@ public class ZipFile implements ZipConstants, Closeable { case DEFLATED: // Inflater likes a bit of slack // MORE: Compute good size for inflater stream: - long size = CENSIZ(zsrc.cen, pos); - if (size > 65536) { - size = 8192; + long inputBufSize = CENSIZ(zsrc.cen, pos); + if (inputBufSize > 65536 || inputBufSize <= 0) { + inputBufSize = 8192; } - InputStream is = new ZipFileInflaterInputStream(in, res, (int) size); + InputStream is = new ZipFileInflaterInputStream(in, res, (int) inputBufSize); synchronized (istreams) { istreams.add(is); } @@ -416,14 +416,14 @@ public class ZipFile implements ZipConstants, Closeable { private final Cleanable cleanable; ZipFileInflaterInputStream(ZipFileInputStream zfin, - CleanableResource res, int size) { - this(zfin, res, res.getInflater(), size); + CleanableResource res, int inputBufSize) { + this(zfin, res, res.getInflater(), inputBufSize); } private ZipFileInflaterInputStream(ZipFileInputStream zfin, CleanableResource res, - Inflater inf, int size) { - super(zfin, inf, size); + Inflater inf, int inputBufSize) { + super(zfin, inf, inputBufSize); this.cleanable = CleanerFactory.cleaner().register(this, new InflaterCleanupAction(inf, res)); } diff --git a/test/jdk/java/util/zip/ZipFile/InvalidCompressedSizeTest.java b/test/jdk/java/util/zip/ZipFile/InvalidCompressedSizeTest.java new file mode 100644 index 00000000000..37c9916ee5e --- /dev/null +++ b/test/jdk/java/util/zip/ZipFile/InvalidCompressedSizeTest.java @@ -0,0 +1,124 @@ +/* + * 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. + * + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HexFormat; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.junit.jupiter.api.Test; +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/* + * @test + * @bug 8358456 + * @summary verify that ZipFile.getInputStream(ZipFile) doesn't throw an unspecified exception + * for invalid compressed size of an entry + * @run junit InvalidCompressedSizeTest + */ +class InvalidCompressedSizeTest { + + private static final String ENTRY_NAME = "foo-bar"; + private static final byte[] ENTRY_CONTENT = new byte[]{0x42, 0x42}; + + // created through a call to createZIPContent() + private static final String ZIP_CONTENT_HEX = """ + 504b03041400080808005053c35a00000000000000000000000007000000666f6f2d6261727 + 3720200504b0708c41f441b0400000002000000504b010214001400080808005053c35ac41f + 441b0400000002000000070000000000000000000000000000000000666f6f2d626172504b0 + 506000000000100010035000000390000000000 + """; + + + // 0039 CENTRAL HEADER #1 02014B50 + // ... + // 0043 Compression Method 0008 'Deflated' + // ... + // 004D Compressed Length 00000004 + // 0051 Uncompressed Length 00000002 + // ... + // 0067 Filename 'foo-bar' + // this is the offset in the ZIP content stream for the compressed size field + // for the entry of interest + private static final int COMP_SIZE_OFFSET = 0x004D; + + // intentionally unused but left here to allow for constructing newer/updated + // ZIP_CONTENT_HEX, when necessary + private static String createZIPContent() throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (final ZipOutputStream zos = new ZipOutputStream(baos)) { + final ZipEntry ze = new ZipEntry(ENTRY_NAME); + zos.putNextEntry(ze); + zos.write(ENTRY_CONTENT); + zos.closeEntry(); + } + return HexFormat.of().formatHex(baos.toByteArray()); + } + + /* + * Calls ZipFile.getInputStream(ZipEntry) on a ZIP entry whose compressed size is + * intentionally set to 0. The test then verifies that the call to getInputStream() + * doesn't throw an unspecified exception. + */ + @Test + void testInvalidCompressedSize() throws Exception { + final byte[] originalZIPContent = HexFormat.of().parseHex(ZIP_CONTENT_HEX.replace("\n", "")); + final ByteBuffer zipContent = ByteBuffer.wrap(originalZIPContent).order(LITTLE_ENDIAN); + + // overwrite the compressed size value in the entry's CEN to an invalid value of 0 + zipContent.position(COMP_SIZE_OFFSET); + final int invalidCompressedSize = 0; + zipContent.putInt(invalidCompressedSize); + zipContent.rewind(); + + // write out the ZIP content so that it can be read through ZipFile + final Path zip = Files.createTempFile(Path.of("."), "8358456-", ".zip"); + Files.write(zip, zipContent.array()); + System.out.println("created ZIP " + zip + " with an invalid compressed size for entry"); + + try (final ZipFile zf = new ZipFile(zip.toFile())) { + final ZipEntry entry = zf.getEntry(ENTRY_NAME); + assertNotNull(entry, "missing entry " + ENTRY_NAME + " in ZIP file " + zip); + // verify that we are indeed testing a ZIP file with an invalid + // compressed size for the entry + assertEquals(0, entry.getCompressedSize(), "unexpected compressed size"); + // merely open and close the InputStream to exercise the code which + // would incorrectly raise an exception. we don't read the contents + // of the stream because we have (intentionally) corrupted the metadata + // of the ZIP and that will cause the reading to fail. + try (final InputStream is = zf.getInputStream(entry)) { + System.out.println("successfully opened input stream " + is + + " for entry " + entry.getName()); + } + } + } +} From edf92721c2db4cfba091cf4901af603db8486951 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 4 Jun 2025 08:10:42 +0000 Subject: [PATCH 128/216] 8356977: UTF-8 cleanups Reviewed-by: naoto, prr --- src/java.base/share/classes/java/util/Locale.java | 4 ++-- src/java.base/share/classes/java/util/LocaleISOData.java | 2 +- .../share/classes/java/util/PropertyResourceBundle.java | 4 ++-- src/java.base/share/classes/sun/security/util/DomainName.java | 2 +- src/java.desktop/share/classes/javax/swing/Action.java | 2 +- test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java | 2 +- .../RemotePrinterStatusRefresh.java | 2 +- test/jdk/java/nio/file/Path/UriImportExport.java | 2 +- test/jdk/java/util/Currency/ValidateISO4217.java | 2 +- test/jdk/java/util/Locale/LocaleProvidersFormat.java | 2 +- .../jpackage/helpers/jdk/jpackage/test/FileAssociations.java | 2 +- .../langtools/jdk/javadoc/doclet/testRelativeLinks/pkg/C.java | 2 +- test/langtools/tools/javac/api/guide/Test.java | 2 +- 13 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index a5ac0ae5bf7..9c745c1731b 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -385,10 +385,10 @@ import sun.util.locale.provider.TimeZoneNameUtility; * {@snippet lang = java: * var number = 1000; * NumberFormat.getCurrencyInstance(Locale.US).format(number); // returns "$1,000.00" - * NumberFormat.getCurrencyInstance(Locale.JAPAN).format(number); // returns "\u00A51,000"" + * NumberFormat.getCurrencyInstance(Locale.JAPAN).format(number); // returns "¥1,000"" * var date = LocalDate.of(2024, 1, 1); * DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).localizedBy(Locale.US).format(date); // returns "January 1, 2024" - * DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).localizedBy(Locale.JAPAN).format(date); // returns "2024\u5e741\u67081\u65e5" + * DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).localizedBy(Locale.JAPAN).format(date); // returns "2024年1月1日" * } * *

        Locale Matching

        diff --git a/src/java.base/share/classes/java/util/LocaleISOData.java b/src/java.base/share/classes/java/util/LocaleISOData.java index 403e3f90bea..c2090d3be19 100644 --- a/src/java.base/share/classes/java/util/LocaleISOData.java +++ b/src/java.base/share/classes/java/util/LocaleISOData.java @@ -239,7 +239,7 @@ class LocaleISOData { + "AT" + "AUT" // Austria, Republic of + "AU" + "AUS" // Australia, Commonwealth of + "AW" + "ABW" // Aruba - + "AX" + "ALA" // \u00c5land Islands + + "AX" + "ALA" // Åland Islands + "AZ" + "AZE" // Azerbaijan, Republic of + "BA" + "BIH" // Bosnia and Herzegovina + "BB" + "BRB" // Barbados diff --git a/src/java.base/share/classes/java/util/PropertyResourceBundle.java b/src/java.base/share/classes/java/util/PropertyResourceBundle.java index d8cc1fac198..9b832a70577 100644 --- a/src/java.base/share/classes/java/util/PropertyResourceBundle.java +++ b/src/java.base/share/classes/java/util/PropertyResourceBundle.java @@ -81,7 +81,7 @@ import sun.util.ResourceBundleEnumeration; * Keys are case-sensitive. * {@snippet lang=properties : * # MessageFormat pattern - * s1=Die Platte \"{1}\" enth\u00E4lt {0}. + * s1=Die Platte \"{1}\" enthält {0}. * # location of {0} in pattern * s2=1 * # sample disk name @@ -93,7 +93,7 @@ import sun.util.ResourceBundleEnumeration; * # third ChoiceFormat choice * s6={0,number} Dateien * # sample date - * s7=3. M\u00E4rz 1996 + * s7=3. März 1996 * } * * @apiNote diff --git a/src/java.base/share/classes/sun/security/util/DomainName.java b/src/java.base/share/classes/sun/security/util/DomainName.java index 53a646c8102..4f577f1114c 100644 --- a/src/java.base/share/classes/sun/security/util/DomainName.java +++ b/src/java.base/share/classes/sun/security/util/DomainName.java @@ -61,7 +61,7 @@ import sun.security.ssl.SSLLogger; * co.uk * k12.ak.us * com.tw - * \u7db2\u8def.tw + * 網路.tw * * Public suffixes effectively denote registration authorities. * diff --git a/src/java.desktop/share/classes/javax/swing/Action.java b/src/java.desktop/share/classes/javax/swing/Action.java index 3942d3309d4..b1b092e2104 100644 --- a/src/java.desktop/share/classes/javax/swing/Action.java +++ b/src/java.desktop/share/classes/javax/swing/Action.java @@ -263,7 +263,7 @@ public interface Action extends ActionListener { * commonly used to specify a mnemonic. For example: * myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A) * sets the mnemonic of myAction to 'a', while - * myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar('\u0444')) + * myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar('ф')) * sets the mnemonic of myAction to Cyrillic letter "Ef". * * @since 1.3 diff --git a/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java index 6410fc4bad8..51fb3fedaba 100644 --- a/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java +++ b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java @@ -87,7 +87,7 @@ public class EscapeKeyTyped { public void keyPressed(KeyEvent e) { printKey(e); int keychar = e.getKeyChar(); - if (keychar == 27) { // Escape character is 27 or \u0021 + if (keychar == 27) { // Escape character is 27 or \u001b escapeKeyTypedReceived = true; } } diff --git a/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java b/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java index 7768c54481a..33fe9fc86d3 100644 --- a/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java +++ b/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java @@ -185,7 +185,7 @@ public class RemotePrinterStatusRefresh extends WindowAdapter { + "Step 3: Compare the list of printers in \"Before\" and " + "\"After\" lists.\n" + " Added printers are highlighted with " - + "green color, removed ones \u2014 with " + + "green color, removed ones with " + "red color.\n" + "Step 4: Click Pass if the list of printers is correctly " + "updated.\n" diff --git a/test/jdk/java/nio/file/Path/UriImportExport.java b/test/jdk/java/nio/file/Path/UriImportExport.java index 934098096b6..2ab93ee399e 100644 --- a/test/jdk/java/nio/file/Path/UriImportExport.java +++ b/test/jdk/java/nio/file/Path/UriImportExport.java @@ -128,7 +128,7 @@ public class UriImportExport { testUri("file:///foo/bar/doesnotexist"); testUri("file:/foo/bar/doesnotexist"); - // file:///foo/bar/\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian) + // file:///foo/bar/русский (Russian) testUri("file:///foo/bar/%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9"); // invalid diff --git a/test/jdk/java/util/Currency/ValidateISO4217.java b/test/jdk/java/util/Currency/ValidateISO4217.java index 6996045fc3a..67793dcbecb 100644 --- a/test/jdk/java/util/Currency/ValidateISO4217.java +++ b/test/jdk/java/util/Currency/ValidateISO4217.java @@ -131,7 +131,7 @@ public class ValidateISO4217 { */ {"GS", "GBP", "826", "2"}, // South Georgia And The South Sandwich Islands /* Not defined in ISO 4217 list, but defined in .properties file. */ - {"AX", "EUR", "978", "2"}, // \u00c5LAND ISLANDS + {"AX", "EUR", "978", "2"}, // ÅLAND ISLANDS {"PS", "ILS", "376", "2"}, // Palestinian Territory, Occupied /* Not defined in ISO 4217 list, but added in ISO 3166 country code list */ {"JE", "GBP", "826", "2"}, // Jersey diff --git a/test/jdk/java/util/Locale/LocaleProvidersFormat.java b/test/jdk/java/util/Locale/LocaleProvidersFormat.java index 5d3f1fc2e2e..157e92ce8a3 100644 --- a/test/jdk/java/util/Locale/LocaleProvidersFormat.java +++ b/test/jdk/java/util/Locale/LocaleProvidersFormat.java @@ -85,7 +85,7 @@ public class LocaleProvidersFormat { /* * 8027289: Ensure if underlying system format locale is zh_CN, the Window's currency - * symbol under HOST provider is \u00A5, the yen (yuan) sign. + * symbol under HOST provider is ¥, the yen (yuan) sign. */ @Test @EnabledOnOs(WINDOWS) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java index f8dc10c3dd0..ebdbb474006 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java @@ -135,7 +135,7 @@ public final class FileAssociations { // To test unicode arguments on Windows manually: // 1. add the following argument ("Hello" in Bulgarian) to the - // additionalArgs list: "\u0417\u0434\u0440\u0430\u0432\u0435\u0439\u0442\u0435" + // additionalArgs list: "Здравейте" // 2. in Control Panel -> Region -> Administrative -> Language for non-Unicode programs // change the system locale to "Bulgarian (Bulgaria)" // 3. reboot Windows and re-run the test diff --git a/test/langtools/jdk/javadoc/doclet/testRelativeLinks/pkg/C.java b/test/langtools/jdk/javadoc/doclet/testRelativeLinks/pkg/C.java index e2f2d1f6f43..79a09b4f240 100644 --- a/test/langtools/jdk/javadoc/doclet/testRelativeLinks/pkg/C.java +++ b/test/langtools/jdk/javadoc/doclet/testRelativeLinks/pkg/C.java @@ -33,7 +33,7 @@ package pkg; public class C { /** - * Here is a relative link in a field:\u0130 + * Here is a relative link in a field: * relative field link. */ public C field = null; diff --git a/test/langtools/tools/javac/api/guide/Test.java b/test/langtools/tools/javac/api/guide/Test.java index 64b2a304016..5bf881a590c 100644 --- a/test/langtools/tools/javac/api/guide/Test.java +++ b/test/langtools/tools/javac/api/guide/Test.java @@ -25,7 +25,7 @@ * @test * @bug 6427274 6347778 6469079 * @summary Various bugs fixed while writing Compiler API Guide - * @author Peter von der Ah\u0081 + * @author Peter von der Ahé * @library ../lib * @modules java.compiler * jdk.compiler From 955bfcd5502b3555c2c91db876be8e7535f2289a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Wed, 4 Jun 2025 08:19:24 +0000 Subject: [PATCH 129/216] 8357671: JFR: Remove JfrTraceIdEpoch synchronizing Reviewed-by: egahlin --- .../checkpoint/jfrCheckpointManager.cpp | 9 ++----- .../checkpoint/jfrCheckpointManager.hpp | 3 +-- .../types/traceid/jfrTraceIdEpoch.cpp | 21 +++------------ .../types/traceid/jfrTraceIdEpoch.hpp | 26 +++++++++---------- .../recorder/service/jfrRecorderService.cpp | 6 ++--- .../jfr/recorder/stringpool/jfrStringPool.cpp | 5 +--- .../classes/jdk/jfr/internal/StringPool.java | 4 +-- 7 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp index 7736d3f4565..b0f4461a82c 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp @@ -497,15 +497,10 @@ typedef CompositeOperation WriteRelease typedef VirtualThreadLocalCheckpointWriteOp VirtualThreadLocalCheckpointOperation; typedef MutexedWriteOp VirtualThreadLocalWriteOperation; -void JfrCheckpointManager::begin_epoch_shift() { - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - JfrTraceIdEpoch::begin_epoch_shift(); -} - -void JfrCheckpointManager::end_epoch_shift() { +void JfrCheckpointManager::shift_epoch() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); DEBUG_ONLY(const u1 current_epoch = JfrTraceIdEpoch::current();) - JfrTraceIdEpoch::end_epoch_shift(); + JfrTraceIdEpoch::shift_epoch(); assert(current_epoch != JfrTraceIdEpoch::current(), "invariant"); JfrStringPool::on_epoch_shift(); } diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp index 53fa064e267..f9f8f1c26cf 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.hpp @@ -96,8 +96,7 @@ class JfrCheckpointManager : public JfrCHeapObj { void clear_type_set(); void write_type_set(); - void begin_epoch_shift(); - void end_epoch_shift(); + void shift_epoch(); static void on_unloading_classes(); void on_rotation(); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp index 8c2b8cdd0ec..a4ada594700 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.cpp @@ -31,7 +31,7 @@ /* * The epoch generation is the range [1-32767]. * - * When the epoch value is stored in a thread object, + * When the epoch value is stored in a vthread object, * the most significant bit of the u2 is used to denote * thread exclusion, i.e 1 << 15 == 32768 denotes exclusion. */ @@ -39,32 +39,17 @@ u2 JfrTraceIdEpoch::_generation = 0; JfrSignal JfrTraceIdEpoch::_tag_state; bool JfrTraceIdEpoch::_method_tracer_state = false; bool JfrTraceIdEpoch::_epoch_state = false; -bool JfrTraceIdEpoch::_synchronizing = false; static constexpr const u2 epoch_generation_overflow = excluded_bit; -void JfrTraceIdEpoch::begin_epoch_shift() { +void JfrTraceIdEpoch::shift_epoch() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - _synchronizing = true; - OrderAccess::fence(); -} - -void JfrTraceIdEpoch::end_epoch_shift() { - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - assert(_synchronizing, "invariant"); _epoch_state = !_epoch_state; - ++_generation; - if (epoch_generation_overflow == _generation) { + if (++_generation == epoch_generation_overflow) { _generation = 1; } assert(_generation != 0, "invariant"); assert(_generation < epoch_generation_overflow, "invariant"); - OrderAccess::storestore(); - _synchronizing = false; -} - -bool JfrTraceIdEpoch::is_synchronizing() { - return Atomic::load_acquire(&_synchronizing); } void JfrTraceIdEpoch::set_method_tracer_tag_state() { diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp index 10ea9643971..9e2d2f0708a 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp @@ -26,7 +26,6 @@ #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDEPOCH_HPP #include "jfr/utilities/jfrSignal.hpp" -#include "jfr/utilities/jfrTypes.hpp" #include "memory/allStatic.hpp" #define BIT 1 @@ -41,16 +40,17 @@ #define EPOCH_0_METHOD_AND_CLASS_BITS (METHOD_AND_CLASS_BITS << EPOCH_0_SHIFT) #define EPOCH_1_METHOD_AND_CLASS_BITS (METHOD_AND_CLASS_BITS << EPOCH_1_SHIFT) - // Epoch alternation on each rotation allow for concurrent tagging. - // The epoch shift happens only during a safepoint. - // - // _synchronizing is a transition state, the purpose of which is to - // have JavaThreads that run _thread_in_native (i.e. Compiler threads) - // respect the current epoch shift in-progress during the safepoint. - // - // _changed_tag_state == true signals an incremental modification to artifact tagging - // (klasses, methods, CLDs, etc), purpose of which is to trigger collection of artifacts. - // +/* + * An epoch shift or alternation on each rotation enables concurrent tagging. + * The epoch shift happens only during a safepoint. + * + * _generation - mainly used with virtual threads, but also for the generational string pool in Java. + * _tag_state - signals an incremental modification to artifact tagging (klasses, methods, CLDs, etc) + * purpose of which is to trigger a collection of artifacts. + * _method_tracer_state - a special notification state only used with method timing and tracing. + * _epoch_state - the fundamental binary epoch state that shifts on each rotation during a safepoint. + */ + class JfrTraceIdEpoch : AllStatic { friend class JfrCheckpointManager; private: @@ -58,10 +58,8 @@ class JfrTraceIdEpoch : AllStatic { static JfrSignal _tag_state; static bool _method_tracer_state; static bool _epoch_state; - static bool _synchronizing; - static void begin_epoch_shift(); - static void end_epoch_shift(); + static void shift_epoch(); public: static bool epoch() { diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp index 07fe019c9af..7d1d7ac0a05 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp @@ -484,13 +484,12 @@ void JfrRecorderService::invoke_safepoint_clear() { void JfrRecorderService::safepoint_clear() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - _checkpoint_manager.begin_epoch_shift(); _storage.clear(); _checkpoint_manager.notify_threads(); _chunkwriter.set_time_stamp(); JfrDeprecationManager::on_safepoint_clear(); JfrStackTraceRepository::clear(); - _checkpoint_manager.end_epoch_shift(); + _checkpoint_manager.shift_epoch(); } void JfrRecorderService::post_safepoint_clear() { @@ -593,14 +592,13 @@ void JfrRecorderService::invoke_safepoint_write() { void JfrRecorderService::safepoint_write() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - _checkpoint_manager.begin_epoch_shift(); JfrStackTraceRepository::clear_leak_profiler(); _checkpoint_manager.on_rotation(); _storage.write_at_safepoint(); _chunkwriter.set_time_stamp(); JfrDeprecationManager::on_safepoint_write(); write_stacktrace(_stack_trace_repository, _chunkwriter, true); - _checkpoint_manager.end_epoch_shift(); + _checkpoint_manager.shift_epoch(); } void JfrRecorderService::post_safepoint_write() { diff --git a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp index a9e39094f79..dc28818b0f9 100644 --- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp +++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp @@ -44,8 +44,6 @@ static int generation_offset = invalid_offset; static jobject string_pool = nullptr; -static unsigned short generation = 0; - static bool setup_string_pool_offsets(TRAPS) { const char class_name[] = "jdk/jfr/internal/StringPool"; Symbol* const k_sym = SymbolTable::new_symbol(class_name); @@ -281,9 +279,8 @@ void JfrStringPool::register_full(BufferPtr buffer, Thread* thread) { void JfrStringPool::on_epoch_shift() { assert(SafepointSynchronize::is_at_safepoint(), "invariant"); - assert(!JfrTraceIdEpoch::is_synchronizing(), "invariant"); assert(string_pool != nullptr, "invariant"); oop mirror = JfrJavaSupport::resolve_non_null(string_pool); assert(mirror != nullptr, "invariant"); - mirror->short_field_put(generation_offset, generation++); + mirror->short_field_put(generation_offset, JfrTraceIdEpoch::epoch_generation()); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java index c0dc4e6ba58..41e8a48cfe6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -51,7 +51,7 @@ public final class StringPool { private static int preCacheOld = 0; /* max size bytes */ private static long currentSizeUTF16; - /* string pool generation (0-65535) set by the JVM on epoch shift. Not private to avoid being optimized away. */ + /* The string pool epoch generation is the range [1-32767] set by the JVM on epoch shift. Not private to avoid being optimized away. */ static short generation = 0; /* internalSid is a composite id [48-bit externalSid][16-bit generation]. */ From b6d60280e789436c7f9e3cd1447c8f77b77e77b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Wed, 4 Jun 2025 08:20:48 +0000 Subject: [PATCH 130/216] 8358429: JFR: minimize the time the Threads_lock is held for sampling Reviewed-by: egahlin --- .../periodic/sampling/jfrSampleMonitor.hpp | 74 +++++++++++++++ .../periodic/sampling/jfrSampleRequest.hpp | 9 +- .../periodic/sampling/jfrThreadSampler.cpp | 95 +++++++++++-------- .../periodic/sampling/jfrThreadSampling.cpp | 29 ++---- 4 files changed, 145 insertions(+), 62 deletions(-) create mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrSampleMonitor.hpp diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleMonitor.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleMonitor.hpp new file mode 100644 index 00000000000..a9e0b1728a3 --- /dev/null +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleMonitor.hpp @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +#ifndef SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEMONITOR_HPP +#define SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEMONITOR_HPP + +#include "jfr/periodic/sampling/jfrSampleRequest.hpp" +#include "jfr/utilities/jfrTime.hpp" +#include "memory/allocation.hpp" +#include "runtime/javaThread.hpp" +#include "runtime/mutex.hpp" + +class JfrSampleMonitor : public StackObj { + private: + JfrThreadLocal* const _tl; + Monitor* const _sample_monitor; + mutable bool _waiting; + public: + JfrSampleMonitor(JfrThreadLocal* tl) : + _tl(tl), _sample_monitor(tl->sample_monitor()), _waiting(false) { + assert(tl != nullptr, "invariant"); + assert(_sample_monitor != nullptr, "invariant"); + _sample_monitor->lock_without_safepoint_check(); + } + + bool is_waiting() const { + assert_lock_strong(_sample_monitor); + _waiting = _tl->sample_state() == WAITING_FOR_NATIVE_SAMPLE; + return _waiting; + } + + void install_java_sample_request() { + assert_lock_strong(_sample_monitor); + assert(_waiting, "invariant"); + assert(_tl->sample_state() == WAITING_FOR_NATIVE_SAMPLE, "invariant"); + JfrSampleRequest request; + request._sample_ticks = JfrTicks::now(); + _tl->set_sample_request(request); + _tl->set_sample_state(JAVA_SAMPLE); + _sample_monitor->notify_all(); + } + + ~JfrSampleMonitor() { + assert_lock_strong(_sample_monitor); + if (!_waiting) { + _tl->set_sample_state(NO_SAMPLE); + _sample_monitor->notify_all(); + } + _sample_monitor->unlock(); + } +}; + +#endif // SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEMONITOR_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp index 8cc2b66aa9e..6567e7f8bff 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp @@ -48,10 +48,11 @@ enum JfrSampleResult { }; enum JfrSampleRequestType { - NO_SAMPLE = 0, - NATIVE_SAMPLE = 1, - JAVA_SAMPLE = 2, - NOF_SAMPLE_TYPES + NO_SAMPLE, + JAVA_SAMPLE, + NATIVE_SAMPLE, + WAITING_FOR_NATIVE_SAMPLE, + NOF_SAMPLE_STATES }; struct JfrSampleRequest { diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp index 3efa0b0d581..4c44c43772d 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -24,6 +24,7 @@ #include "jfr/metadata/jfrSerializer.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" +#include "jfr/periodic/sampling/jfrSampleMonitor.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" #include "jfr/periodic/sampling/jfrThreadSampling.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" @@ -230,38 +231,41 @@ void JfrSamplerThread::task_stacktrace(JfrSampleRequestType type, JavaThread** l JavaThread* start = nullptr; elapsedTimer sample_time; sample_time.start(); - { - MutexLocker tlock(Threads_lock); - ThreadsListHandle tlh; - // Resolve a sample session relative start position index into the thread list array. - // In cases where the last sampled thread is null or not-null but stale, find_index() returns -1. - _cur_index = tlh.list()->find_index_of_JavaThread(*last_thread); - JavaThread* current = _cur_index != -1 ? *last_thread : nullptr; + ThreadsListHandle tlh; + // Resolve a sample session relative start position index into the thread list array. + // In cases where the last sampled thread is null or not-null but stale, find_index() returns -1. + _cur_index = tlh.list()->find_index_of_JavaThread(*last_thread); + JavaThread* current = _cur_index != -1 ? *last_thread : nullptr; - while (num_samples < sample_limit) { - current = next_thread(tlh.list(), start, current); - if (current == nullptr) { - break; - } - if (is_excluded(current)) { - continue; - } - if (start == nullptr) { - start = current; // remember the thread where we started to attempt sampling - } - bool success; - if (JAVA_SAMPLE == type) { - success = sample_java_thread(current); - } else { - assert(type == NATIVE_SAMPLE, "invariant"); - success = sample_native_thread(current); - } - if (success) { - num_samples++; - } + while (num_samples < sample_limit) { + current = next_thread(tlh.list(), start, current); + if (current == nullptr) { + break; + } + if (is_excluded(current)) { + continue; + } + if (start == nullptr) { + start = current; // remember the thread where we started to attempt sampling + } + bool success; + if (JAVA_SAMPLE == type) { + success = sample_java_thread(current); + } else { + assert(type == NATIVE_SAMPLE, "invariant"); + success = sample_native_thread(current); + } + if (success) { + num_samples++; + } + if (SafepointSynchronize::is_at_safepoint()) { + // For _thread_in_native, we cannot get the Threads_lock. + // For _thread_in_Java, well, there are none. + break; } - *last_thread = current; // remember the thread we last attempted to sample } + + *last_thread = current; // remember the thread we last attempted to sample sample_time.stop(); log_trace(jfr)("JFR thread sampling done in %3.7f secs with %d java %d native samples", sample_time.seconds(), type == JAVA_SAMPLE ? num_samples : 0, type == NATIVE_SAMPLE ? num_samples : 0); @@ -338,17 +342,32 @@ bool JfrSamplerThread::sample_native_thread(JavaThread* jt) { SafepointMechanism::arm_local_poll_release(jt); - // Barriers needed to keep the next read of thread state from floating up. - if (UseSystemMemoryBarrier) { - SystemMemoryBarrier::emit(); - } else { - OrderAccess::storeload(); + // Take the Threads_lock for two purposes: + // 1) Avoid sampling through a safepoint which could result + // in touching oops in case of virtual threads. + // 2) Prevent JFR from issuing an epoch rotation while the sampler thread + // is actively processing a thread in native, as both threads are now + // outside the safepoint protocol. + + // OrderAccess::fence() as part of acquiring the lock prevents loads from floating up. + JfrMutexTryLock threads_lock(Threads_lock); + + if (!threads_lock.acquired() || !jt->has_last_Java_frame()) { + // Remove the native sample request and release the potentially waiting thread. + JfrSampleMonitor jsm(tl); + return false; } - if (jt->thread_state() != _thread_in_native || !jt->has_last_Java_frame()) { - MonitorLocker lock(tl->sample_monitor(), Monitor::_no_safepoint_check_flag); - tl->set_sample_state(NO_SAMPLE); - lock.notify_all(); + if (jt->thread_state() != _thread_in_native) { + assert_lock_strong(Threads_lock); + JfrSampleMonitor jsm(tl); + if (jsm.is_waiting()) { + // The thread has already returned from native, + // now in _thread_in_vm and is waiting to be sampled. + // Convert the native sample request into a java sample request + // and let the thread process the ljf on its own. + jsm.install_java_sample_request(); + } return false; } diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp index 9bae25bcb3c..aa72c29cf50 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp @@ -28,6 +28,7 @@ #include "code/nmethod.hpp" #include "interpreter/interpreter.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/periodic/sampling/jfrSampleMonitor.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" #include "jfr/periodic/sampling/jfrThreadSampling.hpp" #include "jfr/recorder/stacktrace/jfrStackTrace.hpp" @@ -307,24 +308,6 @@ static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, Jav assert(!tl->has_enqueued_requests(), "invariant"); } -class SampleMonitor : public StackObj { - private: - JfrThreadLocal* const _tl; - Monitor* const _sample_monitor; - public: - SampleMonitor(JfrThreadLocal* tl) : _tl(tl), _sample_monitor(tl->sample_monitor()) { - assert(tl != nullptr, "invariant"); - assert(_sample_monitor != nullptr, "invariant"); - _sample_monitor->lock_without_safepoint_check(); - } - ~SampleMonitor() { - assert_lock_strong(_sample_monitor); - _tl->set_sample_state(NO_SAMPLE); - _sample_monitor->notify_all(); - _sample_monitor->unlock(); - } -}; - // Only entered by the JfrSampler thread. bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread) { assert(tl != nullptr, "invairant"); @@ -334,7 +317,9 @@ bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaTh assert(tl == jt->jfr_thread_local(), "invariant"); assert(jt != sampler_thread, "only asynchronous processing of native samples"); assert(jt->has_last_Java_frame(), "invariant"); - assert(tl->sample_state() == NATIVE_SAMPLE, "invariant"); + assert(tl->sample_state() >= NATIVE_SAMPLE, "invariant"); + + assert_lock_strong(Threads_lock); const JfrTicks start_time = JfrTicks::now(); @@ -342,7 +327,7 @@ bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaTh traceid sid; { - SampleMonitor sm(tl); + JfrSampleMonitor sm(tl); // Because the thread was in native, it is in a walkable state, because // it will hit a safepoint poll on the way back from native. To ensure timely @@ -384,10 +369,14 @@ void JfrThreadSampling::process_sample_request(JavaThread* jt) { for (;;) { const int sample_state = tl->sample_state(); if (sample_state == NATIVE_SAMPLE) { + tl->set_sample_state(WAITING_FOR_NATIVE_SAMPLE); // Wait until stack trace is processed. ml.wait(); } else if (sample_state == JAVA_SAMPLE) { tl->enqueue_request(); + } else if (sample_state == WAITING_FOR_NATIVE_SAMPLE) { + // Handle spurious wakeups. Again wait until stack trace is processed. + ml.wait(); } else { // State has been processed. break; From f141674d1619d95053d38a9cd8f93a8959b4a211 Mon Sep 17 00:00:00 2001 From: "He-Pin(kerr)" Date: Wed, 4 Jun 2025 08:28:29 +0000 Subject: [PATCH 131/216] 8347491: IllegalArgumentationException thrown by ThreadPoolExecutor doesn't have a useful message Reviewed-by: vklang, liach, pminborg --- .../concurrent/AbstractExecutorService.java | 19 +- .../concurrent/ExecutorCompletionService.java | 13 +- .../util/concurrent/ThreadPoolExecutor.java | 46 +-- .../tck/ThreadPoolExecutorTest.java | 269 +++++++++++++----- 4 files changed, 248 insertions(+), 99 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java index 1b1ba4b29a0..0d26607591d 100644 --- a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java +++ b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Objects; /** * Provides default implementations of {@link ExecutorService} @@ -119,7 +120,7 @@ public abstract class AbstractExecutorService implements ExecutorService { */ @Override public Future submit(Runnable task) { - if (task == null) throw new NullPointerException(); + Objects.requireNonNull(task, "task"); RunnableFuture ftask = newTaskFor(task, null); execute(ftask); return ftask; @@ -131,7 +132,7 @@ public abstract class AbstractExecutorService implements ExecutorService { */ @Override public Future submit(Runnable task, T result) { - if (task == null) throw new NullPointerException(); + Objects.requireNonNull(task, "task"); RunnableFuture ftask = newTaskFor(task, result); execute(ftask); return ftask; @@ -143,7 +144,7 @@ public abstract class AbstractExecutorService implements ExecutorService { */ @Override public Future submit(Callable task) { - if (task == null) throw new NullPointerException(); + Objects.requireNonNull(task, "task"); RunnableFuture ftask = newTaskFor(task); execute(ftask); return ftask; @@ -155,11 +156,10 @@ public abstract class AbstractExecutorService implements ExecutorService { private T doInvokeAny(Collection> tasks, boolean timed, long nanos) throws InterruptedException, ExecutionException, TimeoutException { - if (tasks == null) - throw new NullPointerException(); + Objects.requireNonNull(tasks, "tasks"); int ntasks = tasks.size(); if (ntasks == 0) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("tasks is empty"); ArrayList> futures = new ArrayList<>(ntasks); ExecutorCompletionService ecs = new ExecutorCompletionService(this); @@ -262,8 +262,7 @@ public abstract class AbstractExecutorService implements ExecutorService { @Override public List> invokeAll(Collection> tasks) throws InterruptedException { - if (tasks == null) - throw new NullPointerException(); + Objects.requireNonNull(tasks, "tasks"); ArrayList> futures = new ArrayList<>(tasks.size()); try { for (Callable t : tasks) { @@ -294,8 +293,8 @@ public abstract class AbstractExecutorService implements ExecutorService { public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { - if (tasks == null) - throw new NullPointerException(); + Objects.requireNonNull(tasks, "tasks"); + Objects.requireNonNull(unit, "unit"); final long nanos = unit.toNanos(timeout); final long deadline = System.nanoTime() + nanos; ArrayList> futures = new ArrayList<>(tasks.size()); diff --git a/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java b/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java index 3c09b4882d0..249c2ebf4d9 100644 --- a/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java +++ b/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java @@ -35,6 +35,8 @@ package java.util.concurrent; +import java.util.Objects; + /** * A {@link CompletionService} that uses a supplied {@link Executor} * to execute tasks. This class arranges that submitted tasks are, @@ -145,8 +147,7 @@ public class ExecutorCompletionService implements CompletionService { * @throws NullPointerException if executor is {@code null} */ public ExecutorCompletionService(Executor executor) { - if (executor == null) - throw new NullPointerException(); + Objects.requireNonNull(executor, "executor"); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; @@ -168,8 +169,8 @@ public class ExecutorCompletionService implements CompletionService { */ public ExecutorCompletionService(Executor executor, BlockingQueue> completionQueue) { - if (executor == null || completionQueue == null) - throw new NullPointerException(); + Objects.requireNonNull(executor, "executor"); + Objects.requireNonNull(completionQueue, "completionQueue"); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; @@ -181,7 +182,7 @@ public class ExecutorCompletionService implements CompletionService { * @throws NullPointerException {@inheritDoc} */ public Future submit(Callable task) { - if (task == null) throw new NullPointerException(); + Objects.requireNonNull(task, "task"); RunnableFuture f = newTaskFor(task); executor.execute(new QueueingFuture(f, completionQueue)); return f; @@ -192,7 +193,7 @@ public class ExecutorCompletionService implements CompletionService { * @throws NullPointerException {@inheritDoc} */ public Future submit(Runnable task, V result) { - if (task == null) throw new NullPointerException(); + Objects.requireNonNull(task, "task"); RunnableFuture f = newTaskFor(task, result); executor.execute(new QueueingFuture(f, completionQueue)); return f; diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 0bf5669b6e1..029e31ef9f6 100644 --- a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -1251,13 +1251,19 @@ public class ThreadPoolExecutor extends AbstractExecutorService { BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { - if (corePoolSize < 0 || - maximumPoolSize <= 0 || - maximumPoolSize < corePoolSize || - keepAliveTime < 0) - throw new IllegalArgumentException(); - if (workQueue == null || threadFactory == null || handler == null) - throw new NullPointerException(); + if (corePoolSize < 0) { + throw new IllegalArgumentException("corePoolSize must be non-negative"); + } else if (maximumPoolSize <= 0) { + throw new IllegalArgumentException("maximumPoolSize must be positive"); + } else if (maximumPoolSize < corePoolSize) { + throw new IllegalArgumentException("maximumPoolSize must be greater than or equal to corePoolSize"); + } else if (keepAliveTime < 0) { + throw new IllegalArgumentException("keepAliveTime must be non-negative"); + } + Objects.requireNonNull(unit, "unit"); + Objects.requireNonNull(workQueue, "workQueue"); + Objects.requireNonNull(threadFactory, "threadFactory"); + Objects.requireNonNull(handler, "handler"); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; @@ -1284,8 +1290,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @throws NullPointerException if {@code command} is null */ public void execute(Runnable command) { - if (command == null) - throw new NullPointerException(); + Objects.requireNonNull(command, "command"); /* * Proceed in 3 steps: * @@ -1446,8 +1451,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @see #getThreadFactory */ public void setThreadFactory(ThreadFactory threadFactory) { - if (threadFactory == null) - throw new NullPointerException(); + Objects.requireNonNull(threadFactory, "threadFactory"); this.threadFactory = threadFactory; } @@ -1469,8 +1473,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @see #getRejectedExecutionHandler */ public void setRejectedExecutionHandler(RejectedExecutionHandler handler) { - if (handler == null) - throw new NullPointerException(); + Objects.requireNonNull(handler, "handler"); this.handler = handler; } @@ -1498,8 +1501,11 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @see #getCorePoolSize */ public void setCorePoolSize(int corePoolSize) { - if (corePoolSize < 0 || maximumPoolSize < corePoolSize) - throw new IllegalArgumentException(); + if (corePoolSize < 0) { + throw new IllegalArgumentException("corePoolSize must be non-negative"); + } else if (corePoolSize > maximumPoolSize) { + throw new IllegalArgumentException("corePoolSize must be less than or equal to maximumPoolSize"); + } int delta = corePoolSize - this.corePoolSize; this.corePoolSize = corePoolSize; if (workerCountOf(ctl.get()) > corePoolSize) @@ -1623,8 +1629,11 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * @see #getMaximumPoolSize */ public void setMaximumPoolSize(int maximumPoolSize) { - if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize) - throw new IllegalArgumentException(); + if (maximumPoolSize <= 0) { + throw new IllegalArgumentException("maximumPoolSize must be positive"); + } else if (maximumPoolSize < corePoolSize) { + throw new IllegalArgumentException("maximumPoolSize must be greater than or equal to corePoolSize"); + } this.maximumPoolSize = maximumPoolSize; if (workerCountOf(ctl.get()) > maximumPoolSize) interruptIdleWorkers(); @@ -1658,9 +1667,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { */ public void setKeepAliveTime(long time, TimeUnit unit) { if (time < 0) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("time must be non-negative"); if (time == 0 && allowsCoreThreadTimeOut()) throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); + Objects.requireNonNull(unit, "unit"); long keepAliveTime = unit.toNanos(time); long delta = keepAliveTime - this.keepAliveTime; this.keepAliveTime = keepAliveTime; diff --git a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java index 73e6deda987..d9ce643a26d 100644 --- a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java +++ b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java @@ -41,22 +41,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.CancellationException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.*; import java.util.concurrent.ThreadPoolExecutor.AbortPolicy; import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy; @@ -66,6 +51,7 @@ import java.util.concurrent.atomic.AtomicReference; import junit.framework.Test; import junit.framework.TestSuite; +import org.junit.Assert; public class ThreadPoolExecutorTest extends JSR166TestCase { public static void main(String[] args) { @@ -304,7 +290,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setThreadFactory(null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("threadFactory", success.getMessage()); + } } } @@ -364,7 +352,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setRejectedExecutionHandler(null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("handler", success.getMessage()); + } } } @@ -737,7 +727,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(-1, 1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("corePoolSize must be non-negative", success.getMessage()); + } } /** @@ -748,7 +740,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(1, -1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -759,7 +753,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(1, 0, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -770,7 +766,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(1, 2, -1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("keepAliveTime must be non-negative", success.getMessage()); + } } /** @@ -781,7 +779,12 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(2, 1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } } /** @@ -792,7 +795,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ThreadPoolExecutor(1, 2, 1L, SECONDS, (BlockingQueue) null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("workQueue", success.getMessage()); + } } /** @@ -804,7 +809,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("corePoolSize must be non-negative", success.getMessage()); + } } /** @@ -816,7 +823,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -828,7 +837,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -840,7 +851,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("keepAliveTime must be non-negative", success.getMessage()); + } } /** @@ -852,7 +865,12 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } } /** @@ -864,7 +882,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { (BlockingQueue) null, new SimpleThreadFactory()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("workQueue", success.getMessage()); + } } /** @@ -876,7 +896,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), (ThreadFactory) null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("threadFactory", success.getMessage()); + } } /** @@ -888,7 +910,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("corePoolSize must be non-negative", success.getMessage()); + } } /** @@ -900,7 +924,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -912,7 +938,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -924,7 +952,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("keepAliveTime must be non-negative", success.getMessage()); + } } /** @@ -936,7 +966,12 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } } /** @@ -948,7 +983,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { (BlockingQueue) null, new NoOpREHandler()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("workQueue", success.getMessage()); + } } /** @@ -960,7 +997,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new ArrayBlockingQueue(10), (RejectedExecutionHandler) null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("handler", success.getMessage()); + } } /** @@ -973,7 +1012,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("corePoolSize must be non-negative", success.getMessage()); + } } /** @@ -986,7 +1027,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -999,7 +1042,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } /** @@ -1012,7 +1057,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("keepAliveTime must be non-negative", success.getMessage()); + } } /** @@ -1025,7 +1072,12 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } } /** @@ -1038,7 +1090,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), new NoOpREHandler()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("workQueue", success.getMessage()); + } } /** @@ -1051,7 +1105,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { new SimpleThreadFactory(), (RejectedExecutionHandler) null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("handler", success.getMessage()); + } } /** @@ -1064,7 +1120,24 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { (ThreadFactory) null, new NoOpREHandler()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("threadFactory", success.getMessage()); + } + } + + /** + * Constructor throws if unit is null + */ + public void testConstructorNullPointerException9() { + try { + new ThreadPoolExecutor(1, 2, 1L, (TimeUnit) null, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); + shouldThrow(); + } catch (NullPointerException success) { + assertEquals("unit", success.getMessage()); + } } /** @@ -1228,7 +1301,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setCorePoolSize(-1); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("corePoolSize must be non-negative", success.getMessage()); + } } } @@ -1245,7 +1320,12 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setMaximumPoolSize(1); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } } } @@ -1262,7 +1342,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setMaximumPoolSize(-1); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("maximumPoolSize must be positive", success.getMessage()); + } } } @@ -1282,13 +1364,25 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setMaximumPoolSize(s - 1); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + s == 1 + ? "maximumPoolSize must be positive" + : "maximumPoolSize must be greater than or equal to corePoolSize", + success.getMessage() + ); + } assertEquals(s, p.getCorePoolSize()); assertEquals(s, p.getMaximumPoolSize()); try { p.setCorePoolSize(s + 1); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals( + "corePoolSize must be less than or equal to maximumPoolSize", + success.getMessage() + ); + } assertEquals(s, p.getCorePoolSize()); assertEquals(s, p.getMaximumPoolSize()); } @@ -1299,7 +1393,7 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { * setKeepAliveTime throws IllegalArgumentException * when given a negative value */ - public void testKeepAliveTimeIllegalArgumentException() { + public void testKeepAliveTimeInvalidLengthIllegalArgumentException() { final ThreadPoolExecutor p = new ThreadPoolExecutor(2, 3, LONG_DELAY_MS, MILLISECONDS, @@ -1308,7 +1402,28 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { p.setKeepAliveTime(-1, MILLISECONDS); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("time must be non-negative", success.getMessage()); + } + } + } + + /** + * setKeepAliveTime throws IllegalArgumentException + * when given a null unit + */ + public void testKeepAliveTimeNullTimeUnitIllegalArgumentException() { + final ThreadPoolExecutor p = + new ThreadPoolExecutor(2, 3, + LONG_DELAY_MS, MILLISECONDS, + new ArrayBlockingQueue(10)); + try (PoolCleaner cleaner = cleaner(p)) { + try { + p.setKeepAliveTime(1, (TimeUnit) null); + shouldThrow(); + } catch (NullPointerException success) { + assertEquals("unit", success.getMessage()); + } } } @@ -1399,7 +1514,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("tasks", success.getMessage()); + } } } @@ -1415,7 +1532,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(new ArrayList>()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("tasks is empty", success.getMessage()); + } } } @@ -1435,7 +1554,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(l); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("task", success.getMessage()); + } latch.countDown(); } } @@ -1489,7 +1610,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAll(null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("tasks", success.getMessage()); + } } } @@ -1524,7 +1647,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAll(l); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals(null, success.getMessage()); + } } } @@ -1581,7 +1706,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(null, randomTimeout(), randomTimeUnit()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("tasks", success.getMessage()); + } } } @@ -1599,7 +1726,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(l, randomTimeout(), null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("Cannot invoke \"java.util.concurrent.TimeUnit.toNanos(long)\" because \"unit\" is null", success.getMessage()); + } } } @@ -1616,7 +1745,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { e.invokeAny(new ArrayList>(), randomTimeout(), randomTimeUnit()); shouldThrow(); - } catch (IllegalArgumentException success) {} + } catch (IllegalArgumentException success) { + assertEquals("tasks is empty", success.getMessage()); + } } } @@ -1636,7 +1767,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAny(l, randomTimeout(), randomTimeUnit()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("task", success.getMessage()); + } latch.countDown(); } } @@ -1694,7 +1827,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAll(null, randomTimeout(), randomTimeUnit()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("tasks", success.getMessage()); + } } } @@ -1712,7 +1847,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAll(l, randomTimeout(), null); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals("unit", success.getMessage()); + } } } @@ -1748,7 +1885,9 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { try { e.invokeAll(l, randomTimeout(), randomTimeUnit()); shouldThrow(); - } catch (NullPointerException success) {} + } catch (NullPointerException success) { + assertEquals(null, success.getMessage()); + } } } From ab235000349bfd268e80a7cb99bf07a229406119 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Wed, 4 Jun 2025 08:31:37 +0000 Subject: [PATCH 132/216] 8354636: [PPC64] Clean up comments regarding frame manager Reviewed-by: amitkumar, rrich --- src/hotspot/cpu/ppc/register_ppc.hpp | 4 ++-- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 2 +- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 18 ++++++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/hotspot/cpu/ppc/register_ppc.hpp b/src/hotspot/cpu/ppc/register_ppc.hpp index 2b5b25f449e..b7949750dcc 100644 --- a/src/hotspot/cpu/ppc/register_ppc.hpp +++ b/src/hotspot/cpu/ppc/register_ppc.hpp @@ -523,7 +523,7 @@ constexpr FloatRegister F11_ARG11 = F11; // volatile constexpr FloatRegister F12_ARG12 = F12; // volatile constexpr FloatRegister F13_ARG13 = F13; // volatile -// Register declarations to be used in frame manager assembly code. +// Register declarations to be used in template interpreter assembly code. // Use only non-volatile registers in order to keep values across C-calls. constexpr Register R14_bcp = R14; constexpr Register R15_esp = R15; // slot below top of expression stack for ld/st with update @@ -533,7 +533,7 @@ constexpr Register R17_tos = R17; // The interpreter's top of (expres constexpr Register R18_locals = R18; // address of first param slot (receiver). constexpr Register R19_method = R19; // address of current method -// Temporary registers to be used within frame manager. We can use +// Temporary registers to be used within template interpreter. We can use // the non-volatiles because the call stub has saved them. // Use only non-volatile registers in order to keep values across C-calls. constexpr Register R21_tmp1 = R21; diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index a7e759d770b..4ec2483b267 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -2935,7 +2935,7 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, __ cmpdi(CR0, number_of_frames_reg, 0); __ bne(CR0, loop); - // Get the return address pointing into the frame manager. + // Get the return address pointing into the template interpreter. __ ld(R0, 0, pcs_reg); // Store it in the top interpreter frame. __ std(R0, _abi0(lr), R1_SP); diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index 7fc807bb9ce..2624131033c 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -86,7 +86,7 @@ class StubGenerator: public StubCodeGenerator { // R10 - thread : Thread* // address generate_call_stub(address& return_address) { - // Setup a new c frame, copy java arguments, call frame manager or + // Setup a new c frame, copy java arguments, call template interpreter or // native_entry, and process result. StubGenStubId stub_id = StubGenStubId::call_stub_id; @@ -215,11 +215,10 @@ class StubGenerator: public StubCodeGenerator { } { - BLOCK_COMMENT("Call frame manager or native entry."); - // Call frame manager or native entry. + BLOCK_COMMENT("Call template interpreter or native entry."); assert_different_registers(r_arg_entry, r_top_of_arguments_addr, r_arg_method, r_arg_thread); - // Register state on entry to frame manager / native entry: + // Register state on entry to template interpreter / native entry: // // tos - intptr_t* sender tos (prepushed) Lesp = (SP) + copied_arguments_offset - 8 // R19_method - Method @@ -242,7 +241,7 @@ class StubGenerator: public StubCodeGenerator { // Set R15_prev_state to 0 for simplifying checks in callee. __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R0); - // Stack on entry to frame manager / native entry: + // Stack on entry to template interpreter / native entry: // // F0 [TOP_IJAVA_FRAME_ABI] // alignment (optional) @@ -262,7 +261,7 @@ class StubGenerator: public StubCodeGenerator { __ mr(R21_sender_SP, R1_SP); // Do a light-weight C-call here, r_arg_entry holds the address - // of the interpreter entry point (frame manager or native entry) + // of the interpreter entry point (template interpreter or native entry) // and save runtime-value of LR in return_address. assert(r_arg_entry != tos && r_arg_entry != R19_method && r_arg_entry != R16_thread, "trashed r_arg_entry"); @@ -270,11 +269,10 @@ class StubGenerator: public StubCodeGenerator { } { - BLOCK_COMMENT("Returned from frame manager or native entry."); - // Returned from frame manager or native entry. + BLOCK_COMMENT("Returned from template interpreter or native entry."); // Now pop frame, process result, and return to caller. - // Stack on exit from frame manager / native entry: + // Stack on exit from template interpreter / native entry: // // F0 [ABI] // ... @@ -295,7 +293,7 @@ class StubGenerator: public StubCodeGenerator { Register r_cr = R12_scratch2; // Reload some volatile registers which we've spilled before the call - // to frame manager / native entry. + // to template interpreter / native entry. // Access all locals via frame pointer, because we know nothing about // the topmost frame's size. __ ld(r_entryframe_fp, _abi0(callers_sp), R1_SP); // restore after call From cd16b6896222a623dc99b9e63bb917a9d2980e88 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 4 Jun 2025 09:06:46 +0000 Subject: [PATCH 133/216] 8357155: [asan] ZGC does not work (x86_64 and ppc64) Co-authored-by: Axel Boldt-Christmas Reviewed-by: mdoerr, aboldtch --- src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp | 5 +++++ src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp index 89417c4691d..20d96f6e937 100644 --- a/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zAddress_ppc.cpp @@ -93,10 +93,15 @@ static size_t probe_valid_max_address_bit() { size_t ZPlatformAddressOffsetBits() { static const size_t valid_max_address_offset_bits = probe_valid_max_address_bit() + 1; const size_t max_address_offset_bits = valid_max_address_offset_bits - 3; +#ifdef ADDRESS_SANITIZER + // The max supported value is 44 because of other internal data structures. + return MIN2(valid_max_address_offset_bits, (size_t)44); +#else const size_t min_address_offset_bits = max_address_offset_bits - 2; const size_t address_offset = ZGlobalsPointers::min_address_offset_request(); const size_t address_offset_bits = log2i_exact(address_offset); return clamp(address_offset_bits, min_address_offset_bits, max_address_offset_bits); +#endif } size_t ZPlatformAddressHeapBaseShift() { diff --git a/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp b/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp index 6b5b64d3036..db35a4efe08 100644 --- a/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zAddress_x86.cpp @@ -30,11 +30,15 @@ size_t ZPointerLoadShift; size_t ZPlatformAddressOffsetBits() { +#ifdef ADDRESS_SANITIZER + return 44; +#else const size_t min_address_offset_bits = 42; // 4TB const size_t max_address_offset_bits = 44; // 16TB const size_t address_offset = ZGlobalsPointers::min_address_offset_request(); const size_t address_offset_bits = log2i_exact(address_offset); return clamp(address_offset_bits, min_address_offset_bits, max_address_offset_bits); +#endif } size_t ZPlatformAddressHeapBaseShift() { From 42f48a39e867ae1683708dda3e158c24a6957180 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Wed, 4 Jun 2025 09:41:51 +0000 Subject: [PATCH 134/216] 8350689: Turn on timestamp and thread metadata by default for java.security.debug Reviewed-by: mullan --- .../doc-files/debug-system-property.html | 18 +--- .../classes/sun/security/util/Debug.java | 81 +++-------------- .../security/krb5/auto/LoginModuleDebug.java | 20 ++--- .../SSLLogger/DebugPropertyValuesTest.java | 18 ++-- .../sun/security/util/Debug/DebugOptions.java | 88 ++++++------------- 5 files changed, 55 insertions(+), 170 deletions(-) diff --git a/src/java.base/share/classes/java/security/doc-files/debug-system-property.html b/src/java.base/share/classes/java/security/doc-files/debug-system-property.html index 4ea34252b3c..ac325b2ef62 100644 --- a/src/java.base/share/classes/java/security/doc-files/debug-system-property.html +++ b/src/java.base/share/classes/java/security/doc-files/debug-system-property.html @@ -52,24 +52,10 @@

        To monitor security access, you can set the java.security.debug system property, which determines what trace messages are printed during execution. The value of the property is one or more options separated by a - comma. + comma. Each trace message includes the thread id, caller information, and + timestamp.

        -

        Printing Thread and Timestamp Information

        -

        - You can append the following strings to any option specified in the - java.security.debug system property to print additional - information: -

          -
        • +thread: Print thread and caller information
        • -
        • +timestamp: Print timestamp information
        • -
        -

        - For example, to add thread, caller, and timestamp information to all - debugging output, set the java.security.debug system property - on the command line as follows: -

        java -Djava.security.debug=all+thread+timestamp MyApp
        -

        The following table lists the java.security.debug options:

        diff --git a/src/java.base/share/classes/sun/security/util/Debug.java b/src/java.base/share/classes/sun/security/util/Debug.java index f6c0c523165..9f7649fc73c 100644 --- a/src/java.base/share/classes/sun/security/util/Debug.java +++ b/src/java.base/share/classes/sun/security/util/Debug.java @@ -41,14 +41,7 @@ import java.util.Locale; public class Debug { private String prefix; - private boolean printDateTime; - private boolean printThreadDetails; - private static String args; - private static boolean threadInfoAll; - private static boolean timeStampInfoAll; - private static final String TIMESTAMP_OPTION = "+timestamp"; - private static final String THREAD_OPTION = "+thread"; static { args = System.getProperty("java.security.debug"); @@ -66,16 +59,6 @@ public class Debug { args = args.toLowerCase(Locale.ENGLISH); if (args.equals("help")) { Help(); - } else if (args.contains("all")) { - // "all" option has special handling for decorator options - // If the thread or timestamp decorator option is detected - // with the "all" option, then it impacts decorator options - // for other categories - int beginIndex = args.lastIndexOf("all") + "all".length(); - int commaIndex = args.indexOf(',', beginIndex); - if (commaIndex == -1) commaIndex = args.length(); - threadInfoAll = args.substring(beginIndex, commaIndex).contains(THREAD_OPTION); - timeStampInfoAll = args.substring(beginIndex, commaIndex).contains(TIMESTAMP_OPTION); } } } @@ -106,11 +89,6 @@ public class Debug { System.err.println("ts timestamping"); System.err.println("x509 X.509 certificate debugging"); System.err.println(); - System.err.println("+timestamp can be appended to any of above options to print"); - System.err.println(" a timestamp for that debug option"); - System.err.println("+thread can be appended to any of above options to print"); - System.err.println(" thread and caller information for that debug option"); - System.err.println(); System.err.println("The following can be used with provider:"); System.err.println(); System.err.println("engine="); @@ -151,7 +129,6 @@ public class Debug { if (isOn(option)) { Debug d = new Debug(); d.prefix = prefix; - d.configureExtras(option); return d; } else { return null; @@ -166,32 +143,6 @@ public class Debug { .findFirst().orElse("unknown caller")); } - // parse an option string to determine if extra details, - // like thread and timestamp, should be printed - private void configureExtras(String option) { - // treat "all" as special case, only used for java.security.debug property - this.printDateTime = timeStampInfoAll; - this.printThreadDetails = threadInfoAll; - - if (printDateTime && printThreadDetails) { - // nothing left to configure - return; - } - - // args is converted to lower case for the most part via marshal method - int optionIndex = args.lastIndexOf(option); - if (optionIndex == -1) { - // option not in args list. Only here since "all" was present - // in debug property argument. "all" option already parsed - return; - } - int beginIndex = optionIndex + option.length(); - int commaIndex = args.indexOf(',', beginIndex); - if (commaIndex == -1) commaIndex = args.length(); - String subOpt = args.substring(beginIndex, commaIndex); - printDateTime = printDateTime || subOpt.contains(TIMESTAMP_OPTION); - printThreadDetails = printThreadDetails || subOpt.contains(THREAD_OPTION); - } /** * Get a Debug object corresponding to the given option on the given @@ -208,11 +159,6 @@ public class Debug { * Debug debug = Debug.of("login", property); * } * - * +timestamp string can be appended to property value - * to print timestamp information. (e.g. true+timestamp) - * +thread string can be appended to property value - * to print thread and caller information. (e.g. true+thread) - * * @param prefix the debug option name * @param property debug setting for this option * @return a new Debug object if the property is true @@ -221,8 +167,6 @@ public class Debug { if (property != null && property.toLowerCase(Locale.ROOT).startsWith("true")) { Debug d = new Debug(); d.prefix = prefix; - d.printThreadDetails = property.contains(THREAD_OPTION); - d.printDateTime = property.contains(TIMESTAMP_OPTION); return d; } return null; @@ -285,23 +229,18 @@ public class Debug { } /** - * If thread debug option enabled, include information containing - * hex value of threadId and the current thread name - * If timestamp debug option enabled, include timestamp string - * @return extra info if debug option enabled. + * Include information containing: + * - hex value of threadId + * - the current thread name + * - timestamp string + * @return String with above metadata */ private String extraInfo() { - String retString = ""; - if (printThreadDetails) { - retString = "0x" + Long.toHexString( - Thread.currentThread().threadId()).toUpperCase(Locale.ROOT) + - "|" + Thread.currentThread().getName() + "|" + formatCaller(); - } - if (printDateTime) { - retString += (retString.isEmpty() ? "" : "|") - + FormatHolder.DATE_TIME_FORMATTER.format(Instant.now()); - } - return retString.isEmpty() ? "" : "[" + retString + "]"; + return String.format("[0x%s|%s|%s|%s]", + Long.toHexString(Thread.currentThread().threadId()).toUpperCase(Locale.ROOT), + Thread.currentThread().getName(), + formatCaller(), + FormatHolder.DATE_TIME_FORMATTER.format(Instant.now())); } /** diff --git a/test/jdk/sun/security/krb5/auto/LoginModuleDebug.java b/test/jdk/sun/security/krb5/auto/LoginModuleDebug.java index 42ddf72ec50..b34e8b42282 100644 --- a/test/jdk/sun/security/krb5/auto/LoginModuleDebug.java +++ b/test/jdk/sun/security/krb5/auto/LoginModuleDebug.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,8 +47,8 @@ public class LoginModuleDebug { // debug option set to true - no extra info Arguments.of("debug", "true", - "krb5loginmodule:", - "krb5loginmodule\\["), + "krb5loginmodule\\[.*\\|main|" + DATE_REGEX + ".*\\]:", + "krb5loginmodule:"), // debug option set to false Arguments.of("debug", "false", @@ -59,19 +59,9 @@ public class LoginModuleDebug { "bar", "", "krb5loginmodule"), - // thread info only + // test for thread and timestamp info Arguments.of("debug", "true+thread", - "krb5loginmodule\\[.*\\|main|\\.*java.*]:", - "\\|" + DATE_REGEX + ".*\\]:"), - // timestamp info only - Arguments.of("debug", - "true+timestamp", - "krb5loginmodule\\[" + DATE_REGEX + ".*\\]", - "\\|main\\]:"), - // both thread and timestamp - Arguments.of("debug", - "true+timestamp+thread", "krb5loginmodule\\[.*\\|main|" + DATE_REGEX + ".*\\]:", "krb5loginmodule:") ); @@ -104,4 +94,4 @@ public class LoginModuleDebug { new Subject(), null, Map.of(), Map.of(args[0], args[1])); } } -} \ No newline at end of file +} diff --git a/test/jdk/sun/security/ssl/SSLLogger/DebugPropertyValuesTest.java b/test/jdk/sun/security/ssl/SSLLogger/DebugPropertyValuesTest.java index c9ad335a45e..424a460914c 100644 --- a/test/jdk/sun/security/ssl/SSLLogger/DebugPropertyValuesTest.java +++ b/test/jdk/sun/security/ssl/SSLLogger/DebugPropertyValuesTest.java @@ -51,8 +51,11 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate { private static final Path LOG_FILE = Path.of("logging.conf"); private static final HashMap> debugMessages = new HashMap<>(); + private static final String DATE_REGEX = "\\d{4}-\\d{2}-\\d{2}"; static { + + debugMessages.put("handshake", List.of("Produced ClientHello handshake message", "supported_versions")); @@ -74,10 +77,10 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate { debugMessages.put("help", List.of("print the help messages", "debugging can be widened with:")); - debugMessages.put("javax.net.debug", - List.of("properties: Initial security property:", - "certpath: Cert path validation succeeded")); - debugMessages.put("logger", + debugMessages.put("java.security.debug", + List.of("properties\\[.*\\|main\\|.*" + DATE_REGEX + ".*\\]:", + "certpath\\[.*\\|main\\|.*" + DATE_REGEX + ".*\\]:")); + debugMessages.put("javax.net.debug.logger", List.of("FINE: adding as trusted certificates", "FINE: WRITE: TLSv1.3 application_data")); } @@ -151,14 +154,15 @@ public class DebugPropertyValuesTest extends SSLSocketTemplate { // add in javax.net.debug sanity test Arguments.of(List.of("-Djavax.net.debug=ssl:trustmanager", "-Djava.security.debug=all"), - List.of("handshake", "javax.net.debug", "keymanager", + List.of("handshake", "java.security.debug", "keymanager", "record", "session", "ssl", "sslctx", "trustmanager", "verbose")), // empty invokes System.Logger use Arguments.of(List.of("-Djavax.net.debug", "-Djava.util.logging.config.file=" + LOG_FILE), - List.of("handshake", "keymanager", "logger", "packet", - "plaintext", "record", "session", "ssl", + List.of("handshake", "javax.net.debug.logger", + "keymanager", "packet", "plaintext", + "record", "session", "ssl", "sslctx", "trustmanager", "verbose")) ); } diff --git a/test/jdk/sun/security/util/Debug/DebugOptions.java b/test/jdk/sun/security/util/Debug/DebugOptions.java index a52566e7aeb..5fa02af5112 100644 --- a/test/jdk/sun/security/util/Debug/DebugOptions.java +++ b/test/jdk/sun/security/util/Debug/DebugOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8051959 + * @bug 8051959 8350689 * @summary Option to print extra information in java.security.debug output * @library /test/lib * @run junit DebugOptions @@ -43,75 +43,41 @@ import jdk.test.lib.process.ProcessTools; public class DebugOptions { static final String DATE_REGEX = "\\d{4}-\\d{2}-\\d{2}"; + static final String EXPECTED_PROP_REGEX = + "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:"; + static final String EXPECTED_PROP_KEYSTORE_REGEX = + "properties\\[.*\\|main|" + DATE_REGEX + + ".*\\Rkeystore\\[.*\\|main|" + DATE_REGEX + ".*\\]:"; + static final String EXPECTED_ALL_REGEX = + "properties\\[.*\\|main.*\\|" + DATE_REGEX + + ".*\\]((.*\\R)*)keystore\\[.*\\|main.*\\|" + + DATE_REGEX + ".*\\]:"; private static Stream patternMatches() { return Stream.of( - // no extra info present + // test for thread and timestamp info Arguments.of("properties", - "properties: Initial", - "properties\\["), - // thread info only + EXPECTED_PROP_REGEX, + "properties:"), + // test for thread and timestamp info Arguments.of("properties+thread", - "properties\\[.*\\|main\\|.*java.*]:", - "properties\\[" + DATE_REGEX), - // timestamp info only - Arguments.of("properties+timestamp", - "properties\\[" + DATE_REGEX + ".*\\]", - "\\|main\\]:"), - // both thread and timestamp - Arguments.of("properties+timestamp+thread", - "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:", + EXPECTED_PROP_REGEX, "properties:"), // flip the arguments of previous test Arguments.of("properties+thread+timestamp", - "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:", + EXPECTED_PROP_REGEX, "properties:"), - // comma not valid separator, ignore extra info printing request - Arguments.of("properties,thread,timestamp", - "properties:", - "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:"), - // no extra info for keystore debug prints - Arguments.of("properties+thread+timestamp,keystore", - "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:", - "keystore\\["), - // flip arguments around in last test - same outcome expected - Arguments.of("keystore,properties+thread+timestamp", - "properties\\[.*\\|main|" + DATE_REGEX + ".*\\]:", - "keystore\\["), - // turn on thread info for both keystore and properties components - Arguments.of("keystore+thread,properties+thread", - "properties\\[.*\\|main|.*\\Rkeystore\\[.*\\|main|.*\\]:", - "\\|" + DATE_REGEX + ".*\\]:"), - // same as above with erroneous comma at end of string. same output expected - Arguments.of("keystore+thread,properties+thread,", - "properties\\[.*\\|main|.*\\Rkeystore\\[.*\\|main|.*\\]:", - "\\|" + DATE_REGEX + ".*\\]:"), - // turn on thread info for properties and timestamp for keystore - Arguments.of("keystore+timestamp,properties+thread", - "properties\\[.*\\|main|.*\\Rkeystore\\[" + DATE_REGEX + ".*\\]:", - "properties\\[.*\\|" + DATE_REGEX + ".*\\]:"), - // turn on thread info for all components + // regular keystore,properties component string + Arguments.of("keystore,properties", + EXPECTED_PROP_KEYSTORE_REGEX, + "properties:"), + // turn on all + Arguments.of("all", + EXPECTED_ALL_REGEX, + "properties:"), + // expect thread and timestamp info Arguments.of("all+thread", - "properties\\[.*\\|main.*((.*\\R)*)keystore\\[.*\\|main.*java.*\\]:", - "properties\\[" + DATE_REGEX + ".*\\]:"), - // turn on thread info and timestamp for all components - Arguments.of("all+thread+timestamp", - "properties\\[.*\\|main.*\\|" + DATE_REGEX + - ".*\\]((.*\\R)*)keystore\\[.*\\|main.*\\|" + DATE_REGEX + ".*\\]:", - "properties:"), - // all decorator option should override other component options - Arguments.of("all+thread+timestamp,properties", - "properties\\[.*\\|main.*\\|" + DATE_REGEX + - ".*\\]((.*\\R)*)keystore\\[.*\\|main.*\\|" + DATE_REGEX + ".*\\]:", - "properties:"), - // thread details should only be printed for properties option - Arguments.of("properties+thread,all", - "properties\\[.*\\|main\\|.*\\]:", - "keystore\\[.*\\|main\\|.*\\]:"), - // thread details should be printed for all statements - Arguments.of("properties,all+thread", - "properties\\[.*\\|main.*java" + - ".*\\]((.*\\R)*)keystore\\[.*\\|main.*java.*\\]:", + EXPECTED_ALL_REGEX, "properties:") ); } From 7838321b74276e45b92c54904ea31ef70ed9e33f Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 4 Jun 2025 09:52:45 +0000 Subject: [PATCH 135/216] 8358496: Concurrent reading from Socket with timeout executes sequentially Reviewed-by: dfuchs --- .../classes/sun/nio/ch/NioSocketImpl.java | 23 +- test/jdk/java/net/Socket/Timeouts.java | 246 +++++++++++------- 2 files changed, 163 insertions(+), 106 deletions(-) diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index 6705134648d..dd81b356738 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -288,7 +288,7 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp * @throws SocketException if the socket is closed or a socket I/O error occurs * @throws SocketTimeoutException if the read timeout elapses */ - private int implRead(byte[] b, int off, int len) throws IOException { + private int implRead(byte[] b, int off, int len, long remainingNanos) throws IOException { int n = 0; FileDescriptor fd = beginRead(); try { @@ -296,11 +296,10 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp throw new SocketException("Connection reset"); if (isInputClosed) return -1; - int timeout = this.timeout; - configureNonBlockingIfNeeded(fd, timeout > 0); - if (timeout > 0) { + configureNonBlockingIfNeeded(fd, remainingNanos > 0); + if (remainingNanos > 0) { // read with timeout - n = timedRead(fd, b, off, len, MILLISECONDS.toNanos(timeout)); + n = timedRead(fd, b, off, len, remainingNanos); } else { // read, no timeout n = tryRead(fd, b, off, len); @@ -335,14 +334,24 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp if (len == 0) { return 0; } else { - readLock.lock(); + long remainingNanos = 0; + int timeout = this.timeout; + if (timeout > 0) { + remainingNanos = tryLock(readLock, timeout, MILLISECONDS); + if (remainingNanos <= 0) { + assert !readLock.isHeldByCurrentThread(); + throw new SocketTimeoutException("Read timed out"); + } + } else { + readLock.lock(); + } try { // emulate legacy behavior to return -1, even if socket is closed if (readEOF) return -1; // read up to MAX_BUFFER_SIZE bytes int size = Math.min(len, MAX_BUFFER_SIZE); - int n = implRead(b, off, size); + int n = implRead(b, off, size, remainingNanos); if (n == -1) readEOF = true; return n; diff --git a/test/jdk/java/net/Socket/Timeouts.java b/test/jdk/java/net/Socket/Timeouts.java index 83bf01ebf50..f8fcfb86d0f 100644 --- a/test/jdk/java/net/Socket/Timeouts.java +++ b/test/jdk/java/net/Socket/Timeouts.java @@ -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 @@ -23,11 +23,10 @@ /* * @test - * @bug 8221481 + * @bug 8221481 8358496 * @library /test/lib * @build jdk.test.lib.Utils - * @compile Timeouts.java - * @run testng/othervm/timeout=180 Timeouts + * @run junit/othervm/timeout=180 Timeouts * @summary Test Socket timeouts */ @@ -43,25 +42,27 @@ import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.testng.SkipException; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; import jdk.test.lib.Utils; -@Test -public class Timeouts { +class Timeouts { /** - * Test timed connect where connection is established + * Test timed connect where connection is established. */ - public void testTimedConnect1() throws IOException { + @Test + void testTimedConnect1() throws IOException { try (ServerSocket ss = boundServerSocket()) { try (Socket s = new Socket()) { s.connect(ss.getLocalSocketAddress(), 2000); @@ -70,21 +71,21 @@ public class Timeouts { } /** - * Test timed connect where connection is refused + * Test timed connect where connection is refused. */ - public void testTimedConnect2() throws IOException { + @Test + void testTimedConnect2() throws IOException { try (Socket s = new Socket()) { SocketAddress remote = Utils.refusingEndpoint(); - try { - s.connect(remote, 10000); - } catch (ConnectException expected) { } + assertThrows(ConnectException.class, () -> s.connect(remote, 10000)); } } /** - * Test connect with a timeout of Integer.MAX_VALUE + * Test connect with a timeout of Integer.MAX_VALUE. */ - public void testTimedConnect3() throws IOException { + @Test + void testTimedConnect3() throws IOException { try (ServerSocket ss = boundServerSocket()) { try (Socket s = new Socket()) { s.connect(ss.getLocalSocketAddress(), Integer.MAX_VALUE); @@ -95,141 +96,183 @@ public class Timeouts { /** * Test connect with a negative timeout. */ - public void testTimedConnect4() throws IOException { + @Test + void testTimedConnect4() throws IOException { try (ServerSocket ss = boundServerSocket()) { try (Socket s = new Socket()) { - expectThrows(IllegalArgumentException.class, + assertThrows(IllegalArgumentException.class, () -> s.connect(ss.getLocalSocketAddress(), -1)); } } } /** - * Test timed read where the read succeeds immediately + * Test timed read where the read succeeds immediately. */ - public void testTimedRead1() throws IOException { + @Test + void testTimedRead1() throws IOException { withConnection((s1, s2) -> { s1.getOutputStream().write(99); s2.setSoTimeout(30*1000); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** - * Test timed read where the read succeeds after a delay + * Test timed read where the read succeeds after a delay. */ - public void testTimedRead2() throws IOException { + @Test + void testTimedRead2() throws IOException { withConnection((s1, s2) -> { scheduleWrite(s1.getOutputStream(), 99, 2000); s2.setSoTimeout(30*1000); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** - * Test timed read where the read times out + * Test timed read where the read times out. */ - public void testTimedRead3() throws IOException { + @Test + void testTimedRead3() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(2000); long startMillis = millisTime(); - expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); + assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); int timeout = s2.getSoTimeout(); checkDuration(startMillis, timeout-100, timeout+20_000); }); } /** - * Test timed read that succeeds after a previous read has timed out + * Test timed read that succeeds after a previous read has timed out. */ - public void testTimedRead4() throws IOException { + @Test + void testTimedRead4() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(2000); - expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); + assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); s1.getOutputStream().write(99); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** * Test timed read that succeeds after a previous read has timed out and - * after a short delay + * after a short delay. */ - public void testTimedRead5() throws IOException { + @Test + void testTimedRead5() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(2000); - expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); + assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); s2.setSoTimeout(30*3000); scheduleWrite(s1.getOutputStream(), 99, 2000); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** - * Test untimed read that succeeds after a previous read has timed out + * Test untimed read that succeeds after a previous read has timed out. */ - public void testTimedRead6() throws IOException { + @Test + void testTimedRead6() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(2000); - expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); + assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); s1.getOutputStream().write(99); s2.setSoTimeout(0); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** * Test untimed read that succeeds after a previous read has timed out and - * after a short delay + * after a short delay. */ - public void testTimedRead7() throws IOException { + @Test + void testTimedRead7() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(2000); - expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); + assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read()); scheduleWrite(s1.getOutputStream(), 99, 2000); s2.setSoTimeout(0); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } /** - * Test async close of timed read + * Test async close of timed read. */ - public void testTimedRead8() throws IOException { + @Test + void testTimedRead8() throws IOException { withConnection((s1, s2) -> { s2.setSoTimeout(30*1000); scheduleClose(s2, 2000); - expectThrows(SocketException.class, () -> s2.getInputStream().read()); + assertThrows(SocketException.class, () -> s2.getInputStream().read()); }); } /** - * Test read with a timeout of Integer.MAX_VALUE + * Test read with a timeout of Integer.MAX_VALUE. */ - public void testTimedRead9() throws IOException { + @Test + void testTimedRead9() throws IOException { withConnection((s1, s2) -> { scheduleWrite(s1.getOutputStream(), 99, 2000); s2.setSoTimeout(Integer.MAX_VALUE); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); }); } + /** + * Test 100 threads concurrently reading the same Socket with a timeout of 2s. + * Each read should throw SocketTimeoutException after 2s, not 2s for the first, + * 4s for the second, 6s for the third, up to 200s for the last thread. + */ + @Test + void testTimedRead10() throws Exception { + var futures = new ArrayList>(); + withConnection((_, s) -> { + s.setSoTimeout(2000); + Callable timedReadTask = () -> { + long startMillis = millisTime(); + assertThrows(SocketTimeoutException.class, + () -> s.getInputStream().read()); + int timeout = s.getSoTimeout(); + checkDuration(startMillis, timeout-100, timeout+20_000); + return null; + }; + // start 100 virtual threads to read from the socket + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { + for (int i = 0; i < 100; i++) { + Future future = executor.submit(timedReadTask); + futures.add(future); + } + } + }); + for (Future future : futures) { + future.get(); + } + } + /** * Test writing after a timed read. */ - public void testTimedWrite1() throws IOException { + @Test + void testTimedWrite1() throws IOException { withConnection((s1, s2) -> { s1.getOutputStream().write(99); s2.setSoTimeout(3000); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); // schedule thread to read s1 to EOF scheduleReadToEOF(s1.getInputStream(), 3000); @@ -245,12 +288,13 @@ public class Timeouts { /** * Test async close of writer (after a timed read). */ - public void testTimedWrite2() throws IOException { + @Test + void testTimedWrite2() throws IOException { withConnection((s1, s2) -> { s1.getOutputStream().write(99); s2.setSoTimeout(3000); int b = s2.getInputStream().read(); - assertTrue(b == 99); + assertEquals(99, b); // schedule s2 to be closed scheduleClose(s2, 3000); @@ -266,9 +310,10 @@ public class Timeouts { } /** - * Test timed accept where a connection is established immediately + * Test timed accept where a connection is established immediately. */ - public void testTimedAccept1() throws IOException { + @Test + void testTimedAccept1() throws IOException { Socket s1 = null; Socket s2 = null; try (ServerSocket ss = boundServerSocket()) { @@ -283,9 +328,10 @@ public class Timeouts { } /** - * Test timed accept where a connection is established after a short delay + * Test timed accept where a connection is established after a short delay. */ - public void testTimedAccept2() throws IOException { + @Test + void testTimedAccept2() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(30*1000); scheduleConnect(ss.getLocalSocketAddress(), 2000); @@ -297,7 +343,8 @@ public class Timeouts { /** * Test timed accept where the accept times out */ - public void testTimedAccept3() throws IOException { + @Test + void testTimedAccept3() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(2000); long startMillis = millisTime(); @@ -316,7 +363,8 @@ public class Timeouts { * Test timed accept where a connection is established immediately after a * previous accept timed out. */ - public void testTimedAccept4() throws IOException { + @Test + void testTimedAccept4() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(2000); try { @@ -334,9 +382,10 @@ public class Timeouts { /** * Test untimed accept where a connection is established after a previous - * accept timed out + * accept timed out. */ - public void testTimedAccept5() throws IOException { + @Test + void testTimedAccept5() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(2000); try { @@ -355,9 +404,10 @@ public class Timeouts { /** * Test untimed accept where a connection is established after a previous - * accept timed out and after a short delay + * accept timed out and after a short delay. */ - public void testTimedAccept6() throws IOException { + @Test + void testTimedAccept6() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(2000); try { @@ -373,9 +423,10 @@ public class Timeouts { } /** - * Test async close of a timed accept + * Test async close of a timed accept. */ - public void testTimedAccept7() throws IOException { + @Test + void testTimedAccept7() throws IOException { try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(30*1000); long delay = 2000; @@ -393,9 +444,9 @@ public class Timeouts { /** * Test timed accept with the thread interrupt status set. */ - public void testTimedAccept8() throws IOException { - if (Thread.currentThread().isVirtual()) - throw new SkipException("Main test is a virtual thread"); + @Test + void testTimedAccept8() throws IOException { + assumeFalse(Thread.currentThread().isVirtual(), "Main test is a virtual thread"); try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(2000); Thread.currentThread().interrupt(); @@ -418,9 +469,9 @@ public class Timeouts { /** * Test interrupt of thread blocked in timed accept. */ - public void testTimedAccept9() throws IOException { - if (Thread.currentThread().isVirtual()) - throw new SkipException("Main test is a virtual thread"); + @Test + void testTimedAccept9() throws IOException { + assumeFalse(Thread.currentThread().isVirtual(), "Main test is a virtual thread"); try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(4000); // interrupt thread after 1 second @@ -445,7 +496,8 @@ public class Timeouts { /** * Test two threads blocked in timed accept where no connection is established. */ - public void testTimedAccept10() throws Exception { + @Test + void testTimedAccept10() throws Exception { ExecutorService pool = Executors.newFixedThreadPool(2); try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(4000); @@ -456,9 +508,9 @@ public class Timeouts { Future result2 = pool.submit(ss::accept); // both tasks should complete with SocketTimeoutException - Throwable e = expectThrows(ExecutionException.class, result1::get); + Throwable e = assertThrows(ExecutionException.class, result1::get); assertTrue(e.getCause() instanceof SocketTimeoutException); - e = expectThrows(ExecutionException.class, result2::get); + e = assertThrows(ExecutionException.class, result2::get); assertTrue(e.getCause() instanceof SocketTimeoutException); // should get here in 4 seconds, not 8 seconds @@ -472,7 +524,8 @@ public class Timeouts { /** * Test two threads blocked in timed accept where one connection is established. */ - public void testTimedAccept11() throws Exception { + @Test + void testTimedAccept11() throws Exception { ExecutorService pool = Executors.newFixedThreadPool(2); try (ServerSocket ss = boundServerSocket()) { ss.setSoTimeout(4000); @@ -514,25 +567,25 @@ public class Timeouts { /** * Test Socket setSoTimeout with a negative timeout. */ - @Test(expectedExceptions = { IllegalArgumentException.class }) - public void testBadTimeout1() throws IOException { + @Test + void testBadTimeout1() throws IOException { try (Socket s = new Socket()) { - s.setSoTimeout(-1); + assertThrows(IllegalArgumentException.class, () -> s.setSoTimeout(-1)); } } /** * Test ServerSocket setSoTimeout with a negative timeout. */ - @Test(expectedExceptions = { IllegalArgumentException.class }) - public void testBadTimeout2() throws IOException { + @Test + void testBadTimeout2() throws IOException { try (ServerSocket ss = new ServerSocket()) { - ss.setSoTimeout(-1); + assertThrows(IllegalArgumentException.class, () -> ss.setSoTimeout(-1)); } } /** - * Returns a ServerSocket bound to a port on the loopback address + * Returns a ServerSocket bound to a port on the loopback address. */ static ServerSocket boundServerSocket() throws IOException { var loopback = InetAddress.getLoopbackAddress(); @@ -542,14 +595,14 @@ public class Timeouts { } /** - * An operation that accepts two arguments and may throw IOException + * An operation that accepts two arguments and may throw IOException. */ interface ThrowingBiConsumer { void accept(T t, U u) throws IOException; } /** - * Invokes the consumer with a connected pair of sockets + * Invokes the consumer with a connected pair of sockets. */ static void withConnection(ThrowingBiConsumer consumer) throws IOException @@ -568,7 +621,7 @@ public class Timeouts { } /** - * Schedule c to be closed after a delay + * Schedule c to be closed after a delay. */ static void scheduleClose(Closeable c, long delay) { schedule(() -> { @@ -579,14 +632,14 @@ public class Timeouts { } /** - * Schedule thread to be interrupted after a delay + * Schedule thread to be interrupted after a delay. */ static Future scheduleInterrupt(Thread thread, long delay) { return schedule(() -> thread.interrupt(), delay); } /** - * Schedule a thread to connect to the given end point after a delay + * Schedule a thread to connect to the given end point after a delay. */ static void scheduleConnect(SocketAddress remote, long delay) { schedule(() -> { @@ -597,7 +650,7 @@ public class Timeouts { } /** - * Schedule a thread to read to EOF after a delay + * Schedule a thread to read to EOF after a delay. */ static void scheduleReadToEOF(InputStream in, long delay) { schedule(() -> { @@ -609,7 +662,7 @@ public class Timeouts { } /** - * Schedule a thread to write after a delay + * Schedule a thread to write after a delay. */ static void scheduleWrite(OutputStream out, byte[] data, long delay) { schedule(() -> { @@ -623,12 +676,7 @@ public class Timeouts { } static Future schedule(Runnable task, long delay) { - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - try { - return executor.schedule(task, delay, TimeUnit.MILLISECONDS); - } finally { - executor.shutdown(); - } + return ForkJoinPool.commonPool().schedule(task, delay, TimeUnit.MILLISECONDS); } /** @@ -640,7 +688,7 @@ public class Timeouts { } /** - * Check the duration of a task + * Check the duration of a task. * @param start start time, in milliseconds * @param min minimum expected duration, in milliseconds * @param max maximum expected duration, in milliseconds From dc961609f84a38164d10852cb92c005c3eb077e4 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Wed, 4 Jun 2025 12:43:23 +0000 Subject: [PATCH 136/216] 8356159: RISC-V: Add Zabha Reviewed-by: fyang, fjiang --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 292 +++++++--- src/hotspot/cpu/riscv/globals_riscv.hpp | 1 + .../cpu/riscv/macroAssembler_riscv.cpp | 40 +- .../cpu/riscv/macroAssembler_riscv.hpp | 16 +- src/hotspot/cpu/riscv/riscv.ad | 525 +++++++++++++----- .../gtest/riscv/test_assembler_riscv.cpp | 145 +++-- 6 files changed, 759 insertions(+), 260 deletions(-) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 3cdc9b70d52..3317ccc3b53 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -961,81 +961,239 @@ protected: #undef INSN -enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11}; + enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11}; -#define INSN(NAME, op, funct3, funct7) \ - void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { \ - unsigned insn = 0; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch_reg((address)&insn, 20, Rs2); \ - patch((address)&insn, 31, 27, funct7); \ - patch((address)&insn, 26, 25, memory_order); \ - emit(insn); \ + private: + + enum AmoWidthFunct3 : uint8_t { + AMO_WIDTH_BYTE = 0b000, // Zabha extension + AMO_WIDTH_HALFWORD = 0b001, // Zabha extension + AMO_WIDTH_WORD = 0b010, + AMO_WIDTH_DOUBLEWORD = 0b011, + AMO_WIDTH_QUADWORD = 0b100, + // 0b101 to 0b111 are reserved + }; + + enum AmoOperationFunct5 : uint8_t { + AMO_ADD = 0b00000, + AMO_SWAP = 0b00001, + AMO_LR = 0b00010, + AMO_SC = 0b00011, + AMO_XOR = 0b00100, + AMO_OR = 0b01000, + AMO_AND = 0b01100, + AMO_MIN = 0b10000, + AMO_MAX = 0b10100, + AMO_MINU = 0b11000, + AMO_MAXU = 0b11100, + AMO_CAS = 0b00101 // Zacas + }; + + static constexpr uint32_t OP_AMO_MAJOR = 0b0101111; + + template + void amo_base(Register Rd, Register Rs1, uint8_t Rs2, Aqrl memory_order = aqrl) { + assert(width > AMO_WIDTH_HALFWORD || UseZabha, "Must be"); + assert(funct5 != AMO_CAS || UseZacas, "Must be"); + unsigned insn = 0; + patch((address)&insn, 6, 0, OP_AMO_MAJOR); + patch_reg((address)&insn, 7, Rd); + patch((address)&insn, 14, 12, width); + patch_reg((address)&insn, 15, Rs1); + patch((address)&insn, 24, 20, Rs2); + patch((address)&insn, 26, 25, memory_order); + patch((address)&insn, 31, 27, funct5); + emit(insn); } - INSN(amoswap_w, 0b0101111, 0b010, 0b00001); - INSN(amoadd_w, 0b0101111, 0b010, 0b00000); - INSN(amoxor_w, 0b0101111, 0b010, 0b00100); - INSN(amoand_w, 0b0101111, 0b010, 0b01100); - INSN(amoor_w, 0b0101111, 0b010, 0b01000); - INSN(amomin_w, 0b0101111, 0b010, 0b10000); - INSN(amomax_w, 0b0101111, 0b010, 0b10100); - INSN(amominu_w, 0b0101111, 0b010, 0b11000); - INSN(amomaxu_w, 0b0101111, 0b010, 0b11100); - INSN(amoswap_d, 0b0101111, 0b011, 0b00001); - INSN(amoadd_d, 0b0101111, 0b011, 0b00000); - INSN(amoxor_d, 0b0101111, 0b011, 0b00100); - INSN(amoand_d, 0b0101111, 0b011, 0b01100); - INSN(amoor_d, 0b0101111, 0b011, 0b01000); - INSN(amomin_d, 0b0101111, 0b011, 0b10000); - INSN(amomax_d , 0b0101111, 0b011, 0b10100); - INSN(amominu_d, 0b0101111, 0b011, 0b11000); - INSN(amomaxu_d, 0b0101111, 0b011, 0b11100); - INSN(amocas_w, 0b0101111, 0b010, 0b00101); - INSN(amocas_d, 0b0101111, 0b011, 0b00101); -#undef INSN - -enum operand_size { int8, int16, int32, uint32, int64 }; - -#define INSN(NAME, op, funct3, funct7) \ - void NAME(Register Rd, Register Rs1, Aqrl memory_order = relaxed) { \ - unsigned insn = 0; \ - uint32_t val = memory_order & 0x3; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs1); \ - patch((address)&insn, 25, 20, 0b00000); \ - patch((address)&insn, 31, 27, funct7); \ - patch((address)&insn, 26, 25, val); \ - emit(insn); \ + template + void amo_base(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2->raw_encoding(), memory_order); } - INSN(lr_w, 0b0101111, 0b010, 0b00010); - INSN(lr_d, 0b0101111, 0b011, 0b00010); + public: -#undef INSN - -#define INSN(NAME, op, funct3, funct7) \ - void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = relaxed) { \ - unsigned insn = 0; \ - uint32_t val = memory_order & 0x3; \ - patch((address)&insn, 6, 0, op); \ - patch((address)&insn, 14, 12, funct3); \ - patch_reg((address)&insn, 7, Rd); \ - patch_reg((address)&insn, 15, Rs2); \ - patch_reg((address)&insn, 20, Rs1); \ - patch((address)&insn, 31, 27, funct7); \ - patch((address)&insn, 26, 25, val); \ - emit(insn); \ + void amoadd_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); } - INSN(sc_w, 0b0101111, 0b010, 0b00011); - INSN(sc_d, 0b0101111, 0b011, 0b00011); -#undef INSN + void amoadd_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoadd_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoadd_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoswap_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoswap_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoswap_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoswap_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoxor_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoxor_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoxor_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoxor_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoor_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoor_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoor_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoor_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoand_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoand_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoand_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amoand_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomin_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomin_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomin_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomin_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amominu_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amominu_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amominu_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amominu_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomax_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomax_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomax_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomax_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomaxu_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomaxu_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomaxu_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amomaxu_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + protected: + + void lr_w(Register Rd, Register Rs1, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, 0, memory_order); + } + + void lr_d(Register Rd, Register Rs1, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, 0, memory_order); + } + + void sc_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void sc_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amocas_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amocas_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amocas_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + void amocas_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { + amo_base(Rd, Rs1, Rs2, memory_order); + } + + public: + + enum operand_size { int8, int16, int32, uint32, int64 }; // Immediate Instruction #define INSN(NAME, op, funct3) \ diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index 3ef084d30fc..d67e05bbb6d 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -107,6 +107,7 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \ product(bool, UseZfhmin, false, DIAGNOSTIC, "Use Zfhmin instructions") \ product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \ + product(bool, UseZabha, false, EXPERIMENTAL, "Use UseZabha instructions") \ product(bool, UseZcb, false, EXPERIMENTAL, "Use Zcb instructions") \ product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \ product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \ diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index bc6bf88d0ad..c755d9ae23d 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3798,7 +3798,7 @@ void MacroAssembler::cmpxchg_obj_header(Register oldv, Register newv, Register o void MacroAssembler::load_reserved(Register dst, Register addr, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire) { switch (size) { case int64: @@ -3819,15 +3819,15 @@ void MacroAssembler::load_reserved(Register dst, void MacroAssembler::store_conditional(Register dst, Register new_val, Register addr, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl release) { switch (size) { case int64: - sc_d(dst, new_val, addr, release); + sc_d(dst, addr, new_val, release); break; case int32: case uint32: - sc_w(dst, new_val, addr, release); + sc_w(dst, addr, new_val, release); break; default: ShouldNotReachHere(); @@ -3836,7 +3836,7 @@ void MacroAssembler::store_conditional(Register dst, void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Register shift, Register mask, Register aligned_addr) { assert(size == int8 || size == int16, "unsupported operand size"); @@ -3866,10 +3866,11 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte // which are forced to work with 4-byte aligned address. void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, bool result_as_bool, Register tmp1, Register tmp2, Register tmp3) { + assert(!(UseZacas && UseZabha), "Use amocas"); assert_different_registers(addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1); Register scratch0 = t0, aligned_addr = t1; @@ -3902,13 +3903,13 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, notr(scratch1, mask); bind(retry); - lr_w(result, aligned_addr, acquire); + load_reserved(result, aligned_addr, operand_size::int32, acquire); andr(scratch0, result, mask); bne(scratch0, expected, fail); andr(scratch0, result, scratch1); // scratch1 is ~mask orr(scratch0, scratch0, new_val); - sc_w(scratch0, scratch0, aligned_addr, release); + store_conditional(scratch0, scratch0, aligned_addr, operand_size::int32, release); bnez(scratch0, retry); } @@ -3940,10 +3941,11 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, // failed. void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, Register tmp1, Register tmp2, Register tmp3) { + assert(!(UseZacas && UseZabha), "Use amocas"); assert_different_registers(addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1); Register scratch0 = t0, aligned_addr = t1; @@ -3974,13 +3976,13 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected, } else { notr(scratch1, mask); - lr_w(result, aligned_addr, acquire); + load_reserved(result, aligned_addr, operand_size::int32, acquire); andr(scratch0, result, mask); bne(scratch0, expected, fail); andr(scratch0, result, scratch1); // scratch1 is ~mask orr(scratch0, scratch0, new_val); - sc_w(scratch0, scratch0, aligned_addr, release); + store_conditional(scratch0, scratch0, aligned_addr, operand_size::int32, release); bnez(scratch0, fail); } @@ -3997,10 +3999,10 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected, void MacroAssembler::cmpxchg(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, bool result_as_bool) { - assert(size != int8 && size != int16, "unsupported operand size"); + assert((UseZacas && UseZabha) || (size != int8 && size != int16), "unsupported operand size"); assert_different_registers(addr, t0); assert_different_registers(expected, t0); assert_different_registers(new_val, t0); @@ -4058,10 +4060,10 @@ void MacroAssembler::cmpxchg(Register addr, Register expected, void MacroAssembler::weak_cmpxchg(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result) { - + assert((UseZacas && UseZabha) || (size != int8 && size != int16), "unsupported operand size"); assert_different_registers(addr, t0); assert_different_registers(expected, t0); assert_different_registers(new_val, t0); @@ -4134,7 +4136,7 @@ ATOMIC_XCHGU(xchgalwu, xchgalw) #undef ATOMIC_XCHGU void MacroAssembler::atomic_cas(Register prev, Register newv, Register addr, - enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) { + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) { switch (size) { case int64: amocas_d(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); @@ -4146,6 +4148,12 @@ void MacroAssembler::atomic_cas(Register prev, Register newv, Register addr, amocas_w(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); zext(prev, prev, 32); break; + case int16: + amocas_h(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); + break; + case int8: + amocas_b(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); + break; default: ShouldNotReachHere(); } diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 6f80a02ddc6..f302b3602ad 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1187,26 +1187,26 @@ public: void cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp, Label &succeed, Label *fail); void cmpxchg(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, bool result_as_bool = false); void weak_cmpxchg(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result); void cmpxchg_narrow_value_helper(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Register shift, Register mask, Register aligned_addr); void cmpxchg_narrow_value(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, bool result_as_bool, Register tmp1, Register tmp2, Register tmp3); void weak_cmpxchg_narrow_value(Register addr, Register expected, Register new_val, - enum operand_size size, + Assembler::operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, Register tmp1, Register tmp2, Register tmp3); @@ -1223,7 +1223,7 @@ public: void atomic_xchgwu(Register prev, Register newv, Register addr); void atomic_xchgalwu(Register prev, Register newv, Register addr); - void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size, + void atomic_cas(Register prev, Register newv, Register addr, Assembler::operand_size size, Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed); // Emit a far call/jump. Only invalidates the tmp register which @@ -1636,8 +1636,8 @@ private: int bitset_to_regs(unsigned int bitset, unsigned char* regs); Address add_memory_helper(const Address dst, Register tmp); - void load_reserved(Register dst, Register addr, enum operand_size size, Assembler::Aqrl acquire); - void store_conditional(Register dst, Register new_val, Register addr, enum operand_size size, Assembler::Aqrl release); + void load_reserved(Register dst, Register addr, Assembler::operand_size size, Assembler::Aqrl acquire); + void store_conditional(Register dst, Register new_val, Register addr, Assembler::operand_size size, Assembler::Aqrl release); public: void lightweight_lock(Register basic_lock, Register obj, Register tmp1, Register tmp2, Register tmp3, Label& slow); diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index c711d2db640..e838ee184fb 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -2304,42 +2304,6 @@ encode %{ } %} - enc_class riscv_enc_cmpxchgw(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, - /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - - enc_class riscv_enc_cmpxchgn(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, - /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - - enc_class riscv_enc_cmpxchg(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, - /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - - enc_class riscv_enc_cmpxchgw_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, - /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - - enc_class riscv_enc_cmpxchgn_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, - /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - - enc_class riscv_enc_cmpxchg_acq(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ - __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, - /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, - /*result as bool*/ true); - %} - // compare and branch instruction encodings enc_class riscv_enc_j(label lbl) %{ @@ -5250,18 +5214,20 @@ instruct prefetchalloc( memory mem ) %{ // standard CompareAndSwapX when we are using barriers // these have higher priority than the rules selected by a predicate -instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndSwapB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ + predicate(!UseZabha || !UseZacas); + match(Set res (CompareAndSwapB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); format %{ "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" - "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB_narrow" %} ins_encode %{ @@ -5273,18 +5239,42 @@ instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R1 ins_pipe(pipe_slow); %} -instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ + predicate(UseZabha && UseZacas); + + match(Set res (CompareAndSwapB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result as bool */); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndSwapS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate(!UseZabha || !UseZacas); + match(Set res (CompareAndSwapS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); format %{ "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" - "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS_narrow" %} ins_encode %{ @@ -5296,18 +5286,44 @@ instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R1 ins_pipe(pipe_slow); %} +instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate(UseZabha && UseZacas); + + match(Set res (CompareAndSwapS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result as bool */); + %} + + ins_pipe(pipe_slow); +%} + instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ match(Set res (CompareAndSwapI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapI" %} - ins_encode(riscv_enc_cmpxchgw(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5316,14 +5332,18 @@ instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval %{ match(Set res (CompareAndSwapL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapL" %} - ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5334,14 +5354,18 @@ instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval match(Set res (CompareAndSwapP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapP" %} - ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5349,35 +5373,40 @@ instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) %{ predicate(n->as_LoadStore()->barrier_data() == 0); + match(Set res (CompareAndSwapN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapN" %} - ins_encode(riscv_enc_cmpxchgn(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} // alternative CompareAndSwapX when we are eliding barriers -instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndSwapBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (CompareAndSwapB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" - "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq_narrow" %} ins_encode %{ @@ -5389,20 +5418,42 @@ instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI ins_pipe(pipe_slow); %} -instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (CompareAndSwapB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result as bool */); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndSwapSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (CompareAndSwapS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" - "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq_narrow" %} ins_encode %{ @@ -5414,20 +5465,46 @@ instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI ins_pipe(pipe_slow); %} +instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (CompareAndSwapS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" + "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, + true /* result as bool */); + %} + + ins_pipe(pipe_slow); +%} + instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ predicate(needs_acquiring_load_reserved(n)); match(Set res (CompareAndSwapI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapIAcq" %} - ins_encode(riscv_enc_cmpxchgw_acq(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5438,14 +5515,18 @@ instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL new match(Set res (CompareAndSwapL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapLAcq" %} - ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5456,14 +5537,18 @@ instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP new match(Set res (CompareAndSwapP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapPAcq" %} - ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5474,14 +5559,18 @@ instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN new match(Set res (CompareAndSwapN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapNAcq" %} - ins_encode(riscv_enc_cmpxchgn_acq(res, mem, oldval, newval)); + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, + /*result as bool*/ true); + %} ins_pipe(pipe_slow); %} @@ -5492,17 +5581,19 @@ instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN new // no trailing StoreLoad barrier emitted by C2. Unfortunately we // can't check the type of memory ordering here, so we always emit a // sc_d(w) with rl bit set. -instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndExchangeB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ + predicate(!UseZabha || !UseZacas); + match(Set res (CompareAndExchangeB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ - "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB" + "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB_narrow" %} ins_encode %{ @@ -5514,17 +5605,39 @@ instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iReg ins_pipe(pipe_slow); %} -instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ + predicate(UseZabha && UseZacas); + + match(Set res (CompareAndExchangeB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangeS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate(!UseZabha || !UseZacas); + match(Set res (CompareAndExchangeS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ - "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS" + "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS_narrow" %} ins_encode %{ @@ -5536,13 +5649,31 @@ instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iReg ins_pipe(pipe_slow); %} +instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate(UseZabha && UseZacas); + + match(Set res (CompareAndExchangeS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ match(Set res (CompareAndExchangeI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeI" @@ -5560,9 +5691,7 @@ instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL ne %{ match(Set res (CompareAndExchangeL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeL" @@ -5579,11 +5708,10 @@ instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL ne instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) %{ predicate(n->as_LoadStore()->barrier_data() == 0); + match(Set res (CompareAndExchangeN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 3); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN" @@ -5600,11 +5728,10 @@ instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN ne instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{ predicate(n->as_LoadStore()->barrier_data() == 0); + match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeP" @@ -5618,19 +5745,19 @@ instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP ne ins_pipe(pipe_slow); %} -instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndExchangeBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (CompareAndExchangeB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ - "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq" + "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq_narrow" %} ins_encode %{ @@ -5642,19 +5769,39 @@ instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, i ins_pipe(pipe_slow); %} -instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (CompareAndExchangeB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct compareAndExchangeSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (CompareAndExchangeS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ - "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq" + "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq_narrow" %} ins_encode %{ @@ -5666,15 +5813,33 @@ instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, i ins_pipe(pipe_slow); %} +instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (CompareAndExchangeS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq" + %} + + ins_encode %{ + __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ predicate(needs_acquiring_load_reserved(n)); match(Set res (CompareAndExchangeI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeIAcq" @@ -5694,9 +5859,7 @@ instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL match(Set res (CompareAndExchangeL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeLAcq" @@ -5716,9 +5879,7 @@ instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN match(Set res (CompareAndExchangeN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq" @@ -5738,9 +5899,7 @@ instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP match(Set res (CompareAndExchangeP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); - - effect(TEMP_DEF res); + ins_cost(2 * VOLATILE_REF_COST); format %{ "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq" @@ -5754,18 +5913,20 @@ instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP ins_pipe(pipe_slow); %} -instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct weakCompareAndSwapB_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ + predicate(!UseZabha || !UseZacas); + match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" - "# $res == 1 when success, #@weakCompareAndSwapB" + "# $res == 1 when success, #@weakCompareAndSwapB_narrow" %} ins_encode %{ @@ -5777,18 +5938,41 @@ instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iReg ins_pipe(pipe_slow); %} -instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ + predicate(UseZabha && UseZacas); + + match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "weak_cmpxchg $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" + "# $res == 1 when success, #@weakCompareAndSwapB" + %} + + ins_encode %{ + __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapS_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate(!UseZabha || !UseZacas); + match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" - "# $res == 1 when success, #@weakCompareAndSwapS" + "# $res == 1 when success, #@weakCompareAndSwapS_narrow" %} ins_encode %{ @@ -5800,11 +5984,32 @@ instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iReg ins_pipe(pipe_slow); %} +instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate(UseZabha && UseZacas); + + match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "weak_cmpxchg $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" + "# $res == 1 when success, #@weakCompareAndSwapS" + %} + + ins_encode %{ + __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5823,7 +6028,7 @@ instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL ne %{ match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5841,9 +6046,10 @@ instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL ne instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) %{ predicate(n->as_LoadStore()->barrier_data() == 0); + match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5861,9 +6067,10 @@ instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN ne instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) %{ predicate(n->as_LoadStore()->barrier_data() == 0); + match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5878,20 +6085,20 @@ instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne ins_pipe(pipe_slow); %} -instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct weakCompareAndSwapBAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" - "# $res == 1 when success, #@weakCompareAndSwapBAcq" + "# $res == 1 when success, #@weakCompareAndSwapBAcq_narrow" %} ins_encode %{ @@ -5903,20 +6110,41 @@ instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, i ins_pipe(pipe_slow); %} -instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, - iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ - predicate(needs_acquiring_load_reserved(n)); + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "weak_cmpxchg_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" + "# $res == 1 when success, #@weakCompareAndSwapBAcq" + %} + + ins_encode %{ + __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + +instruct weakCompareAndSwapSAcq_narrow(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, + iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) +%{ + predicate((!UseZabha || !UseZacas) && needs_acquiring_load_reserved(n)); match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); + ins_cost(2 * VOLATILE_REF_COST); effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" - "# $res == 1 when success, #@weakCompareAndSwapSAcq" + "# $res == 1 when success, #@weakCompareAndSwapSAcq_narrow" %} ins_encode %{ @@ -5928,13 +6156,34 @@ instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, i ins_pipe(pipe_slow); %} +instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) +%{ + predicate((UseZabha && UseZacas) && needs_acquiring_load_reserved(n)); + + match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); + + ins_cost(2 * VOLATILE_REF_COST); + + format %{ + "weak_cmpxchg_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" + "# $res == 1 when success, #@weakCompareAndSwapSAcq" + %} + + ins_encode %{ + __ weak_cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, + /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); + %} + + ins_pipe(pipe_slow); +%} + instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) %{ predicate(needs_acquiring_load_reserved(n)); match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5955,7 +6204,7 @@ instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5976,7 +6225,7 @@ instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" @@ -5997,7 +6246,7 @@ instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); - ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); + ins_cost(2 * VOLATILE_REF_COST); format %{ "weak_cmpxchg_acq $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" diff --git a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp index 45f0ed390bd..c6754eacae6 100644 --- a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp +++ b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp @@ -107,6 +107,14 @@ TEST_VM(RiscV, cmov) { } } +template +bool using_narrow() { + if (ASMSIZE == Assembler::int8 || ASMSIZE == Assembler::int16) { + return !(UseZacas && UseZabha); + } + return false; +} + template class CmpxchgTester { // The functions expect arguments to be type represented, not C-ABI argument representation. @@ -126,7 +134,7 @@ class CmpxchgTester { CodeBuffer code(_bb); MacroAssembler _masm(&code); address entry = _masm.pc(); - if (ASMSIZE == Assembler::int8 || ASMSIZE == Assembler::int16) { + if (using_narrow()) { address entry = _masm.pc(); _masm.cmpxchg_narrow_value(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/c_rarg2, ASMSIZE, Assembler::relaxed, Assembler::relaxed, @@ -176,7 +184,7 @@ class CmpxchgTester { } TESTSIZE cmpxchg(intptr_t addr, TESTSIZE expected, TESTSIZE new_value) { - if (ASMSIZE == Assembler::int8 || ASMSIZE == Assembler::int16) { + if (using_narrow()) { return _narrow(addr, expected, new_value, /* dummy result */ 67, -1, -1, -1); } else { return _func(addr, expected, new_value, /* dummy result */ 67); @@ -197,7 +205,7 @@ template static void run_plain_cmpxchg_tests() { TESTSIZE max = std::numeric_limits::max(); TESTSIZE min = std::numeric_limits::min(); - TESTSIZE val[] = {1337, min, max}; + TESTSIZE val[] = {37, min, max}; for (int i = 0; i < 3; i++) { // Normal plain_cmpxchg_test( 0 /* variant */ , val[i] /* start value */, @@ -205,7 +213,7 @@ static void run_plain_cmpxchg_tests() { val[i] /* return */ , 42 /* end value*/, false /* boolean ret*/); plain_cmpxchg_test( 0 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, val[i] /* return */ , val[i] /* end value */, false /* boolean ret*/); plain_cmpxchg_test( 0 /* variant */ , val[i] /* start value */, @@ -213,7 +221,7 @@ static void run_plain_cmpxchg_tests() { 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); plain_cmpxchg_test( 0 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, 0 /* return */ , val[i] /* end value */, true /* boolean ret*/); // result == expected register @@ -222,7 +230,7 @@ static void run_plain_cmpxchg_tests() { val[i] /* return */ , 42 /* end value*/, false /* boolean ret*/); plain_cmpxchg_test( 1 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, val[i] /* return */ , val[i] /* end value */, false /* boolean ret*/); plain_cmpxchg_test( 1 /* variant */ , val[i] /* start value */, @@ -230,7 +238,7 @@ static void run_plain_cmpxchg_tests() { 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); plain_cmpxchg_test( 1 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, 0 /* return */ , val[i] /* end value */, true /* boolean ret*/); // new_value == result register @@ -239,7 +247,7 @@ static void run_plain_cmpxchg_tests() { val[i] /* return */ , 42 /* end value*/, false /* boolean ret*/); plain_cmpxchg_test( 2 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, val[i] /* return */ , val[i] /* end value */, false /* boolean ret*/); plain_cmpxchg_test( 2 /* variant */ , val[i] /* start value */, @@ -247,7 +255,7 @@ static void run_plain_cmpxchg_tests() { 1 /* return */ , 42 /* end value*/, true /* boolean ret*/); plain_cmpxchg_test( 2 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, 0 /* return */ , val[i] /* end value */, true /* boolean ret*/); // expected == new_value register @@ -256,7 +264,7 @@ static void run_plain_cmpxchg_tests() { val[i] /* return */ , val[i] /* end value */, false /* boolean ret*/); plain_cmpxchg_test( 3 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, val[i] /* return */ , val[i] /* end value */, false /* boolean ret*/); plain_cmpxchg_test( 3 /* variant */ , val[i] /* start value */, @@ -264,7 +272,7 @@ static void run_plain_cmpxchg_tests() { 1 /* return */ , val[i] /* end value */, true /* boolean ret*/); plain_cmpxchg_test( 3 /* variant */ , val[i] /* start value */, - 1336 /* expected */, 42 /* new value */, + 36 /* expected */, 42 /* new value */, 0 /* return */ , val[i] /* end value */, true /* boolean ret*/); } } @@ -308,6 +316,18 @@ TEST_VM(RiscV, cmpxchg_uint32_maybe_zacas) { } } +TEST_VM(RiscV, cmpxchg_int16_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { + run_plain_cmpxchg_tests(); + } +} + +TEST_VM(RiscV, cmpxchg_int8_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { + run_plain_cmpxchg_tests(); + } +} + template static void run_narrow_cmpxchg_tests() { CmpxchgTester cmpxchg(0, false); @@ -320,7 +340,6 @@ static void run_narrow_cmpxchg_tests() { TESTSIZE val[] = {121, min, max}; for (int i = 0; i < 3; i++) { for (int j = 0; j < 7; j++) { - // printf("%lu %lX\n", (uint64_t)val[i], (uint64_t)val[i]); memset(data, -1, sizeof(data)); data[i] = val[i]; ret = cmpxchg.cmpxchg((intptr_t)&data[i], val[i], 42); @@ -345,29 +364,35 @@ static void run_narrow_cmpxchg_tests() { } } -TEST_VM(RiscV, cmpxchg_int16_lr_sc) { +TEST_VM(RiscV, cmpxchg_narrow_int16_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_narrow_cmpxchg_tests(); UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int16_maybe_zacas) { +TEST_VM(RiscV, cmpxchg_narrow_int16_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; run_narrow_cmpxchg_tests(); + UseZabha = zabha; } } -TEST_VM(RiscV, cmpxchg_int8_lr_sc) { +TEST_VM(RiscV, cmpxchg_narrow_int8_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_narrow_cmpxchg_tests(); UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int8_maybe_zacas) { +TEST_VM(RiscV, cmpxchg_narrow_int8_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; run_narrow_cmpxchg_tests(); + UseZabha = zabha; } } @@ -486,7 +511,7 @@ TEST_VM(RiscV, cmpxchg_uint32_concurrent_maybe_zacas) { } } -TEST_VM(RiscV, cmpxchg_int16_concurrent_lr_sc) { +TEST_VM(RiscV, cmpxchg_narrow_int16_concurrent_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_concurrent_cmpxchg_tests(); @@ -494,14 +519,17 @@ TEST_VM(RiscV, cmpxchg_int16_concurrent_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int16_concurrent_maybe_zacas) { +TEST_VM(RiscV, cmpxchg_narrow_int16_concurrent_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; run_concurrent_cmpxchg_tests(); run_concurrent_alt_cmpxchg_tests(); + UseZabha = zabha; } } -TEST_VM(RiscV, cmpxchg_int8_concurrent_lr_sc) { +TEST_VM(RiscV, cmpxchg_narrow_int8_concurrent_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_concurrent_cmpxchg_tests(); @@ -509,8 +537,25 @@ TEST_VM(RiscV, cmpxchg_int8_concurrent_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, cmpxchg_int8_concurrent_maybe_zacas) { +TEST_VM(RiscV, cmpxchg_narrow_int8_concurrent_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; + run_concurrent_cmpxchg_tests(); + run_concurrent_alt_cmpxchg_tests(); + UseZabha = zabha; + } +} + +TEST_VM(RiscV, cmpxchg_int16_concurrent_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { + run_concurrent_cmpxchg_tests(); + run_concurrent_alt_cmpxchg_tests(); + } +} + +TEST_VM(RiscV, cmpxchg_int8_concurrent_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { run_concurrent_cmpxchg_tests(); run_concurrent_alt_cmpxchg_tests(); } @@ -534,7 +579,7 @@ class WeakCmpxchgTester { _bb = BufferBlob::create("riscvTest", 128); CodeBuffer code(_bb); MacroAssembler _masm(&code); - if (ASMSIZE == Assembler::int8 || ASMSIZE == Assembler::int16) { + if (using_narrow()) { address entry = _masm.pc(); _masm.weak_cmpxchg_narrow_value(/*addr*/ c_rarg0, /*expected*/ c_rarg1, /*new_value*/ c_rarg2, ASMSIZE, Assembler::relaxed, Assembler::relaxed, @@ -554,7 +599,7 @@ class WeakCmpxchgTester { } TESTSIZE weak_cmpxchg(intptr_t addr, TESTSIZE expected, TESTSIZE new_value) { - if (ASMSIZE == Assembler::int8 || ASMSIZE == Assembler::int16) { + if (using_narrow()) { return _narrow_weak(addr, expected, new_value, /* dummy result */ 67, -1, -1, -1); } else { return _weak(addr, expected, new_value, /* dummy result */ 67); @@ -624,28 +669,46 @@ TEST_VM(RiscV, weak_cmpxchg_uint32_maybe_zacas) { } } -TEST_VM(RiscV, weak_cmpxchg_int16_lr_sc) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int16_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_weak_cmpxchg_tests(); UseZacas = zacas; } -TEST_VM(RiscV, weak_cmpxchg_int8_lr_sc) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int8_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_weak_cmpxchg_tests(); UseZacas = zacas; } -TEST_VM(RiscV, weak_cmpxchg_int16_maybe_zacas) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int16_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; + run_weak_cmpxchg_tests(); + UseZabha = zabha; + } +} + +TEST_VM(RiscV, weak_cmpxchg_narrow_int8_maybe_zacas) { + if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; + run_weak_cmpxchg_tests(); + UseZabha = zabha; + } +} + +TEST_VM(RiscV, weak_cmpxchg_int16_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { run_weak_cmpxchg_tests(); } } -TEST_VM(RiscV, weak_cmpxchg_int8_maybe_zacas) { - if (UseZacas) { +TEST_VM(RiscV, weak_cmpxchg_int8_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { run_weak_cmpxchg_tests(); } } @@ -724,7 +787,7 @@ TEST_VM(RiscV, weak_cmpxchg_int32_concurrent_maybe_zacas) { } } -TEST_VM(RiscV, weak_cmpxchg_int16_concurrent_lr_sc) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int16_concurrent_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_concurrent_weak_cmpxchg_tests(); @@ -732,14 +795,17 @@ TEST_VM(RiscV, weak_cmpxchg_int16_concurrent_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, weak_cmpxchg_int16_concurrent_maybe_zacas) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int16_concurrent_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; run_concurrent_weak_cmpxchg_tests(); run_concurrent_alt_weak_cmpxchg_tests(); + UseZabha = zabha; } } -TEST_VM(RiscV, weak_cmpxchg_int8_concurrent_lr_sc) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int8_concurrent_lr_sc) { bool zacas = UseZacas; UseZacas = false; run_concurrent_weak_cmpxchg_tests(); @@ -747,8 +813,25 @@ TEST_VM(RiscV, weak_cmpxchg_int8_concurrent_lr_sc) { UseZacas = zacas; } -TEST_VM(RiscV, weak_cmpxchg_int8_concurrent_maybe_zacas) { +TEST_VM(RiscV, weak_cmpxchg_narrow_int8_concurrent_maybe_zacas) { if (UseZacas) { + bool zabha = UseZabha; + UseZabha = false; + run_concurrent_weak_cmpxchg_tests(); + run_concurrent_alt_weak_cmpxchg_tests(); + UseZabha = zabha; + } +} + +TEST_VM(RiscV, weak_cmpxchg_int16_concurrent_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { + run_concurrent_weak_cmpxchg_tests(); + run_concurrent_alt_weak_cmpxchg_tests(); + } +} + +TEST_VM(RiscV, weak_cmpxchg_int8_concurrent_maybe_zacas_zabha) { + if (UseZacas && UseZabha) { run_concurrent_weak_cmpxchg_tests(); run_concurrent_alt_weak_cmpxchg_tests(); } From 09ec4de74d495560ffb9ec529df7ec818c1d617c Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Wed, 4 Jun 2025 12:56:18 +0000 Subject: [PATCH 137/216] 8358066: Non-ascii package names gives compilation error "import requires canonical name" Reviewed-by: jlahoda, naoto --- .../com/sun/tools/javac/util/Convert.java | 8 +-- .../javac/nametable/TestUtfNumChars.java | 70 +++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 test/langtools/tools/javac/nametable/TestUtfNumChars.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java index 16127224dc8..7d5f878b676 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -224,10 +224,8 @@ public class Convert { public static int utfNumChars(byte[] buf, int off, int len) { int numChars = 0; while (len-- > 0) { - int byte1 = buf[off++]; - if (byte1 < 0) - len -= ((byte1 & 0xe0) == 0xc0) ? 1 : 2; - numChars++; + if ((buf[off++] & 0xc0) != 0x80) + numChars++; } return numChars; } diff --git a/test/langtools/tools/javac/nametable/TestUtfNumChars.java b/test/langtools/tools/javac/nametable/TestUtfNumChars.java new file mode 100644 index 00000000000..de9530ec4c4 --- /dev/null +++ b/test/langtools/tools/javac/nametable/TestUtfNumChars.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8358066 + * @summary Test for bug in Convert.utfNumChars() + * @modules jdk.compiler/com.sun.tools.javac.util + * @run main TestUtfNumChars + */ + +import com.sun.tools.javac.util.Convert; + +import java.util.function.IntPredicate; +import java.util.stream.IntStream; + +public class TestUtfNumChars { + + public static void main(String[] args) { + + // This is the string "ab«cd≤ef🟢gh" + String s = "ab\u00ABcd\u2264ef\ud83d\udd34gh"; + + // This is its modified UTF-8 encoding + byte[] utf8 = Convert.string2utf(s); // UTF-8: 61 62 c2 ab 63 64 e2 89 a4 65 66 ed a0 bd ed b4 b4 67 68 + // Bytes: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 + // Chars: 00 01 02 .. 03 04 05 .. .. 06 07 08 .. .. 09 .. .. 10 11 + + // These are the offsets in "utf8" marking the boundaries of encoded Java charcters + int[] offsets = new int[] { + 0, 1, 2, 4, 5, 6, 9, 10, 11, 14, 17, 18 + }; + IntPredicate boundary = off -> off == utf8.length || IntStream.of(offsets).anyMatch(off2 -> off2 == off); + + // Check Convert.utfNumChars() on every subsequence + for (int i = 0; i < offsets.length; i++) { + int i_off = offsets[i]; + if (!boundary.test(i_off)) + continue; + for (int j = i; j < offsets.length; j++) { + int j_off = offsets[j]; + if (!boundary.test(j_off)) + continue; + int nchars = Convert.utfNumChars(utf8, i_off, j_off - i_off); + if (nchars != j - i) + throw new AssertionError(String.format("nchars %d != %d for [%d, %d)", nchars, j - i, i_off, j_off)); + } + } + } +} From 248341d372ba9c1031729a65eb10d8def52de641 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Wed, 4 Jun 2025 13:16:24 +0000 Subject: [PATCH 138/216] 8344942: Template-Based Testing Framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tobias Hartmann Co-authored-by: Tobias Holenstein Co-authored-by: Theo Weidmann Co-authored-by: Roberto Castañeda Lozano Co-authored-by: Christian Hagedorn Co-authored-by: Manuel Hässig Reviewed-by: chagedorn, mhaessig, rcastanedalo --- .../lib/template_framework/AddNameToken.java | 26 + .../compiler/lib/template_framework/Code.java | 51 + .../lib/template_framework/CodeFrame.java | 156 ++ .../lib/template_framework/DataName.java | 227 ++ .../compiler/lib/template_framework/Hook.java | 100 + .../template_framework/HookAnchorToken.java | 28 + .../template_framework/HookInsertToken.java | 26 + .../compiler/lib/template_framework/Name.java | 50 + .../lib/template_framework/NameSet.java | 151 ++ .../lib/template_framework/NothingToken.java | 26 + .../compiler/lib/template_framework/README.md | 12 + .../lib/template_framework/Renderer.java | 437 ++++ .../template_framework/RendererException.java | 35 + .../lib/template_framework/StringToken.java | 26 + .../template_framework/StructuralName.java | 200 ++ .../lib/template_framework/Template.java | 844 ++++++ .../template_framework/TemplateBinding.java | 70 + .../lib/template_framework/TemplateBody.java | 34 + .../lib/template_framework/TemplateFrame.java | 99 + .../lib/template_framework/TemplateToken.java | 169 ++ .../lib/template_framework/Token.java | 78 + .../lib/template_framework/library/Hooks.java | 46 + .../examples/TestAdvanced.java | 162 ++ .../examples/TestSimple.java | 78 + .../examples/TestTutorial.java | 1227 +++++++++ .../template_framework/tests/TestFormat.java | 111 + .../tests/TestTemplate.java | 2253 +++++++++++++++++ 27 files changed, 6722 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/AddNameToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Code.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/CodeFrame.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/DataName.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Hook.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/HookAnchorToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/HookInsertToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Name.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/NameSet.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/NothingToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/README.md create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Renderer.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/RendererException.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/StringToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/StructuralName.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Template.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/TemplateBinding.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/TemplateBody.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/TemplateFrame.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/TemplateToken.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/Token.java create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/library/Hooks.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestAdvanced.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestSimple.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestTutorial.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestFormat.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestTemplate.java diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/AddNameToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/AddNameToken.java new file mode 100644 index 00000000000..4f1f7e569bf --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/AddNameToken.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +record AddNameToken(Name name) implements Token {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Code.java b/test/hotspot/jtreg/compiler/lib/template_framework/Code.java new file mode 100644 index 00000000000..5806460ac88 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Code.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; + +/** + * This class collects code, i.e. {@link String}s or {@link List}s of {@link String}s. + * All the {@link String}s are later collected in a {@link StringBuilder}. If we used a {@link StringBuilder} + * directly to collect the {@link String}s, we could not as easily insert code at an "earlier" position, i.e. + * reaching out to a {@link Hook#anchor}. + */ +sealed interface Code permits Code.Token, Code.CodeList { + + record Token(String s) implements Code { + @Override + public void renderTo(StringBuilder builder) { + builder.append(s); + } + } + + record CodeList(List list) implements Code { + @Override + public void renderTo(StringBuilder builder) { + list.forEach(code -> code.renderTo(builder)); + } + } + + void renderTo(StringBuilder builder); +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/CodeFrame.java b/test/hotspot/jtreg/compiler/lib/template_framework/CodeFrame.java new file mode 100644 index 00000000000..5c4ff55614f --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/CodeFrame.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.HashMap; +import java.util.Map; +import java.util.ArrayList; +import java.util.List; + +/** + * The {@link CodeFrame} represents a frame (i.e. scope) of code, appending {@link Code} to the {@code 'codeList'} + * as {@link Token}s are rendered, and adding names to the {@link NameSet}s with {@link Template#addStructuralName}/ + * {@link Template#addDataName}. {@link Hook}s can be added to a frame, which allows code to be inserted at that + * location later. When a {@link Hook} is {@link Hook#anchor}ed, it separates the Template into an outer and inner + * {@link CodeFrame}, ensuring that names that are added inside the inner frame are only available inside that frame. + * + *

        + * On the other hand, each {@link TemplateFrame} represents the frame (or scope) of exactly one use of a + * Template. + * + *

        + * For simple Template nesting, the {@link CodeFrame}s and {@link TemplateFrame}s overlap exactly. + * However, when using {@link Hook#insert}, we simply nest {@link TemplateFrame}s, going further "in", + * but we jump to an outer {@link CodeFrame}, ensuring that we insert {@link Code} at the outer frame, + * and operating on the names of the outer frame. Once the {@link Hook#insert}ion is complete, we jump + * back to the caller {@link TemplateFrame} and {@link CodeFrame}. + */ +class CodeFrame { + public final CodeFrame parent; + private final List codeList = new ArrayList<>(); + private final Map hookCodeLists = new HashMap<>(); + + /** + * The {@link NameSet} is used for variable and fields etc. + */ + private final NameSet names; + + private CodeFrame(CodeFrame parent, boolean isTransparentForNames) { + this.parent = parent; + if (parent == null) { + // NameSet without any parent. + this.names = new NameSet(null); + } else if (isTransparentForNames) { + // We use the same NameSet as the parent - makes it transparent. + this.names = parent.names; + } else { + // New NameSet, to make sure we have a nested scope for the names. + this.names = new NameSet(parent.names); + } + } + + /** + * Creates a base frame, which has no {@link #parent}. + */ + public static CodeFrame makeBase() { + return new CodeFrame(null, false); + } + + /** + * Creates a normal frame, which has a {@link #parent} and which defines an inner + * {@link NameSet}, for the names that are generated inside this frame. Once this + * frame is exited, the name from inside this frame are not available anymore. + */ + public static CodeFrame make(CodeFrame parent) { + return new CodeFrame(parent, false); + } + + /** + * Creates a special frame, which has a {@link #parent} but uses the {@link NameSet} + * from the parent frame, allowing {@link Template#addDataName}/ + * {@link Template#addStructuralName} to persist in the outer frame when the current frame + * is exited. This is necessary for {@link Hook#insert}, where we would possibly want to + * make field or variable definitions during the insertion that are not just local to the + * insertion but affect the {@link CodeFrame} that we {@link Hook#anchor} earlier and are + * now {@link Hook#insert}ing into. + */ + public static CodeFrame makeTransparentForNames(CodeFrame parent) { + return new CodeFrame(parent, true); + } + + void addString(String s) { + codeList.add(new Code.Token(s)); + } + + void addCode(Code code) { + codeList.add(code); + } + + void addHook(Hook hook) { + if (hasHook(hook)) { + // This should never happen, as we add a dedicated CodeFrame for each hook. + throw new RuntimeException("Internal error: Duplicate Hook in CodeFrame: " + hook.name()); + } + hookCodeLists.put(hook, new Code.CodeList(new ArrayList<>())); + } + + private boolean hasHook(Hook hook) { + return hookCodeLists.containsKey(hook); + } + + CodeFrame codeFrameForHook(Hook hook) { + CodeFrame current = this; + while (current != null) { + if (current.hasHook(hook)) { + return current; + } + current = current.parent; + } + return null; + } + + void addName(Name name) { + names.add(name); + } + + Name sampleName(NameSet.Predicate predicate) { + return names.sample(predicate); + } + + int countNames(NameSet.Predicate predicate) { + return names.count(predicate); + } + + boolean hasAnyNames(NameSet.Predicate predicate) { + return names.hasAny(predicate); + } + + List listNames(NameSet.Predicate predicate) { + return names.toList(predicate); + } + + Code getCode() { + return new Code.CodeList(codeList); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/DataName.java b/test/hotspot/jtreg/compiler/lib/template_framework/DataName.java new file mode 100644 index 00000000000..f45a4db8a1e --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/DataName.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; + +/** + * {@link DataName}s represent things like fields and local variables, and can be added to the local + * scope with {@link Template#addDataName}, and accessed with {@link Template#dataNames}, to + * count, list or even sample random {@link DataName}s. Every {@link DataName} has a {@link DataName.Type}, + * so that sampling can be restricted to these types. + * + *

        + * For method and class names and alike, there are the analogous {@link StructuralName}s. + * + * @param name The {@link String} name used in code. + * @param type The type of the {@link DataName}. + * @param mutable Defines if the {@link DataName} is considered mutable or immutable. + * @param weight The weight of the {@link DataName}, it corresponds to the probability of choosing this + * {@link DataName} when sampling later on. + */ +public record DataName(String name, DataName.Type type, boolean mutable, int weight) implements Name { + + /** + * {@link Mutability} defines the possible states of {@link DataName}s, or the + * desired state when filtering. + */ + public enum Mutability { + /** + * Used for mutable fields and variables, i.e. writing is allowed. + */ + MUTABLE, + /** + * Used for immutable fields and variables, i.e. writing is not allowed, + * for example because the field or variable is final. + */ + IMMUTABLE, + /** + * When filtering, we sometimes want to indicate that we accept + * mutable and immutable fields and variables, for example when + * we are only reading, the mutability state does not matter. + */ + MUTABLE_OR_IMMUTABLE + } + + /** + * Creates a new {@link DataName}. + */ + public DataName { + } + + /** + * The interface for the type of a {@link DataName}. + */ + public interface Type extends Name.Type { + /** + * The name of the type, that can be used in code. + * + * @return The {@link String} representation of the type, that can be used in code. + */ + String name(); + + /** + * Defines the subtype relationship with other types, which is used to filter {@link DataName}s + * in {@link FilteredSet#exactOf}, {@link FilteredSet#subtypeOf}, and {@link FilteredSet#supertypeOf}. + * + * @param other The other type, where we check if it is the supertype of {@code 'this'}. + * @return If {@code 'this'} is a subtype of {@code 'other'}. + */ + boolean isSubtypeOf(DataName.Type other); + } + + /** + * The {@link FilteredSet} represents a filtered set of {@link DataName}s in the current scope. + * It can be obtained with {@link Template#dataNames}. It can be used to count the + * available {@link DataName}s, or sample a random {@link DataName} according to the + * weights of the {@link DataName}s in the filtered set. + * Note: The {@link FilteredSet} is only a filtered view on the set of {@link DataName}s, + * and may return different results in different contexts. + */ + public static final class FilteredSet { + private final Mutability mutability; + private final DataName.Type subtype; + private final DataName.Type supertype; + + FilteredSet(Mutability mutability, DataName.Type subtype, DataName.Type supertype) { + this.mutability = mutability; + this.subtype = subtype; + this.supertype = supertype; + } + + FilteredSet(Mutability mutability) { + this(mutability, null, null); + } + + NameSet.Predicate predicate() { + if (subtype == null && supertype == null) { + throw new UnsupportedOperationException("Must first call 'subtypeOf', 'supertypeOf', or 'exactOf'."); + } + return (Name name) -> { + if (!(name instanceof DataName dataName)) { return false; } + if (mutability == Mutability.MUTABLE && !dataName.mutable()) { return false; } + if (mutability == Mutability.IMMUTABLE && dataName.mutable()) { return false; } + if (subtype != null && !dataName.type().isSubtypeOf(subtype)) { return false; } + if (supertype != null && !supertype.isSubtypeOf(dataName.type())) { return false; } + return true; + }; + } + + /** + * Create a {@link FilteredSet}, where all {@link DataName}s must be subtypes of {@code type}. + * + * @param type The type of which all {@link DataName}s must be subtypes of. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #subtypeOf} or {@link #exactOf}. + */ + public FilteredSet subtypeOf(DataName.Type type) { + if (subtype != null) { + throw new UnsupportedOperationException("Cannot constrain to subtype " + type + ", is already constrained: " + subtype); + } + return new FilteredSet(mutability, type, supertype); + } + + /** + * Create a {@link FilteredSet}, where all {@link DataName}s must be supertypes of {@code type}. + * + * @param type The type of which all {@link DataName}s must be supertype of. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #supertypeOf} or {@link #exactOf}. + */ + public FilteredSet supertypeOf(DataName.Type type) { + if (supertype != null) { + throw new UnsupportedOperationException("Cannot constrain to supertype " + type + ", is already constrained: " + supertype); + } + return new FilteredSet(mutability, subtype, type); + } + + /** + * Create a {@link FilteredSet}, where all {@link DataName}s must be of exact {@code type}, + * hence it must be both subtype and supertype thereof. + * + * @param type The type of which all {@link DataName}s must be. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public FilteredSet exactOf(DataName.Type type) { + return subtypeOf(type).supertypeOf(type); + } + + /** + * Samples a random {@link DataName} from the filtered set, according to the weights + * of the contained {@link DataName}s. + * + * @return The sampled {@link DataName}. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + * @throws RendererException If the set was empty. + */ + public DataName sample() { + DataName n = (DataName)Renderer.getCurrent().sampleName(predicate()); + if (n == null) { + String msg1 = (subtype == null) ? "" : ", subtypeOf(" + subtype + ")"; + String msg2 = (supertype == null) ? "" : ", supertypeOf(" + supertype + ")"; + throw new RendererException("No variable: " + mutability + msg1 + msg2 + "."); + } + return n; + } + + /** + * Counts the number of {@link DataName}s in the filtered set. + * + * @return The number of {@link DataName}s in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public int count() { + return Renderer.getCurrent().countNames(predicate()); + } + + /** + * Checks if there are any {@link DataName}s in the filtered set. + * + * @return Returns {@code true} iff there is at least one {@link DataName} in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public boolean hasAny() { + return Renderer.getCurrent().hasAnyNames(predicate()); + } + + /** + * Collects all {@link DataName}s in the filtered set. + * + * @return A {@link List} of all {@link DataName}s in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public List toList() { + List list = Renderer.getCurrent().listNames(predicate()); + return list.stream().map(n -> (DataName)n).toList(); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Hook.java b/test/hotspot/jtreg/compiler/lib/template_framework/Hook.java new file mode 100644 index 00000000000..48f7852d509 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Hook.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +/** + * {@link Hook}s can be {@link #anchor}ed for a certain scope in a Template, and all nested + * Templates in this scope, and then from within this scope, any Template can + * {@link #insert} code to where the {@link Hook} was {@link #anchor}ed. This can be useful to reach + * "back" or to some outer scope, e.g. while generating code for a method, one can reach out + * to the class scope to insert fields. + * + *

        + * Example: + * {@snippet lang=java : + * var myHook = new Hook("MyHook"); + * + * var template1 = Template.make("name", (String name) -> body( + * """ + * public static int #name = 42; + * """ + * )); + * + * var template2 = Template.make(() -> body( + * """ + * public class Test { + * """, + * // Anchor the hook here. + * myHook.anchor( + * """ + * public static void main(String[] args) { + * System.out.println("$field: " + $field) + * """, + * // Reach out to where the hook was anchored, and insert the code of template1. + * myHook.insert(template1.asToken($("field"))), + * """ + * } + * """ + * ), + * """ + * } + * """ + * )); + * } + * + * @param name The name of the Hook, for debugging purposes only. + */ +public record Hook(String name) { + /** + * Anchor this {@link Hook} for the scope of the provided {@code 'tokens'}. + * From anywhere inside this scope, even in nested Templates, code can be + * {@link #insert}ed back to the location where this {@link Hook} was {@link #anchor}ed. + * + * @param tokens A list of tokens, which have the same restrictions as {@link Template#body}. + * @return A {@link Token} that captures the anchoring of the scope and the list of validated {@link Token}s. + */ + public Token anchor(Object... tokens) { + return new HookAnchorToken(this, Token.parse(tokens)); + } + + /** + * Inserts a {@link TemplateToken} to the innermost location where this {@link Hook} was {@link #anchor}ed. + * This could be in the same Template, or one nested further out. + * + * @param templateToken The Template with applied arguments to be inserted at the {@link Hook}. + * @return The {@link Token} which when used inside a {@link Template#body} performs the code insertion into the {@link Hook}. + */ + public Token insert(TemplateToken templateToken) { + return new HookInsertToken(this, templateToken); + } + + /** + * Checks if the {@link Hook} was {@link Hook#anchor}ed for the current scope or an outer scope. + * + * @return If the {@link Hook} was {@link Hook#anchor}ed for the current scope or an outer scope. + */ + public boolean isAnchored() { + return Renderer.getCurrent().isAnchored(this); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/HookAnchorToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/HookAnchorToken.java new file mode 100644 index 00000000000..b025c5ff041 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/HookAnchorToken.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; + +record HookAnchorToken(Hook hook, List tokens) implements Token {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/HookInsertToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/HookInsertToken.java new file mode 100644 index 00000000000..de8b60bbf24 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/HookInsertToken.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +record HookInsertToken(Hook hook, TemplateToken templateToken) implements Token {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Name.java b/test/hotspot/jtreg/compiler/lib/template_framework/Name.java new file mode 100644 index 00000000000..b969ecaa13a --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Name.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +sealed interface Name permits DataName, StructuralName { + /** + * The name of the name, that can be used in code. + * + * @return The {@link String} name of the name, that can be used in code. + */ + String name(); + + /** + * The type of the name, allowing for filtering by type. + * + * @return The type of the name. + */ + Type type(); + + /** + * The weight of the name, corresponds to the probability of + * choosing this name when sampling. + * + * @return The weight of the name. + */ + int weight(); + + interface Type {} +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/NameSet.java b/test/hotspot/jtreg/compiler/lib/template_framework/NameSet.java new file mode 100644 index 00000000000..ef79c33d48a --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/NameSet.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Optional; + +import jdk.test.lib.Utils; + +/** + * The {@link NameSet} defines a set of {@link Name}s (e.g. fields or variable names). They extend the + * set of the {@code 'parent'} set. + */ +class NameSet { + private static final Random RANDOM = Utils.getRandomInstance(); + + private final NameSet parent; + private final List children = new ArrayList<>(); + private final List names = new ArrayList<>(); + + interface Predicate { + boolean check(Name type); + } + + NameSet(NameSet parent) { + this.parent = parent; + if (parent != null) { parent.registerChild(this); } + } + + void registerChild(NameSet child) { + children.add(child); + } + + private long weight(Predicate predicate) { + long w = names.stream().filter(predicate::check).mapToInt(Name::weight).sum(); + if (parent != null) { w += parent.weight(predicate); } + return w; + } + + public int count(Predicate predicate) { + int c = (int)names.stream().filter(predicate::check).count(); + if (parent != null) { c += parent.count(predicate); } + return c; + } + + public boolean hasAny(Predicate predicate) { + return names.stream().anyMatch(predicate::check) || + (parent != null && parent.hasAny(predicate)); + } + + public List toList(Predicate predicate) { + List list = (parent != null) ? parent.toList(predicate) + : new ArrayList<>(); + list.addAll(names.stream().filter(predicate::check).toList()); + return list; + } + + /** + * Randomly sample a name from this set or a parent set, restricted to the predicate. + */ + public Name sample(Predicate predicate) { + long w = weight(predicate); + if (w <= 0) { + // Negative weight should never happen, as all names have positive weight. + if (w < 0) { + throw new RuntimeException("Negative weight not allowed: " + w); + } + // If the weight is zero, there is no matching Name available. + // Return null, and let the caller handle the situation, e.g. + // throw an exception. + return null; + } + + long r = RANDOM.nextLong(w); + return sample(predicate, r); + } + + private Name sample(Predicate predicate, long r) { + for (var name : names) { + if (predicate.check(name)) { + r -= name.weight(); + if (r < 0) { return name; } + } + } + return parent.sample(predicate, r); + } + + private Name findLocal(String name) { + Optional opt = names.stream().filter(n -> n.name().equals(name)).findAny(); + return opt.orElse(null); + } + + private Name findParents(String name) { + if (parent == null) { return null; } + Name n = parent.findLocal(name); + if (n != null) { return n; } + return parent.findParents(name); + } + + private Name findChildren(String name) { + for (NameSet child : children) { + Name n1 = child.findLocal(name); + if (n1 != null) { return n1; } + Name n2 = child.findChildren(name); + if (n2 != null) { return n2; } + } + return null; + } + + private Name find(String name) { + Name n1 = findLocal(name); + if (n1 != null) { return n1; } + Name n2 = findParents(name); + if (n2 != null) { return n2; } + return findChildren(name); + } + + /** + * Add a variable of a specified type to the set. + */ + public void add(Name name) { + Name other = find(name.name()); + if (other != null) { + throw new RendererException("Duplicate name: " + name + ", previously: " + other); + } + names.add(name); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/NothingToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/NothingToken.java new file mode 100644 index 00000000000..540eaf1e14c --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/NothingToken.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +record NothingToken() implements Token {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/README.md b/test/hotspot/jtreg/compiler/lib/template_framework/README.md new file mode 100644 index 00000000000..bc09d34b928 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/README.md @@ -0,0 +1,12 @@ +# Template Framework +The Template Framework allows the generation of code with Templates. The goal is that these Templates are easy to write, and allow regression tests to cover a larger scope, and to make template based fuzzing easy to extend. + +We want to make it easy to generate variants of tests. Often, we would like to have a set of tests, corresponding to a set of types, a set of operators, a set of constants, etc. Writing all the tests by hand is cumbersome or even impossible. When generating such tests with scripts, it would be preferable if the code generation happens automatically, and the generator script was checked into the code base. Code generation can go beyond simple regression tests, and one might want to generate random code from a list of possible templates, to fuzz individual Java features and compiler optimizations. + +The Template Framework provides a facility to generate code with Templates. Templates are essentially a list of tokens that are concatenated (i.e. rendered) to a String. The Templates can have "holes", which are filled (replaced) by different values at each Template instantiation. For example, these "holes" can be filled with different types, operators or constants. Templates can also be nested, allowing a modular use of Templates. + +Detailed documentation can be found in [Template.java](./Template.java). + +The Template Framework only generates code in the form of a String. This code can then be compiled and executed, for example with the help of the [Compile Framework](../compile_framework/README.md). + +The basic functionalities of the Template Framework are described in the [Template Interface](./Template.java), together with some examples. More examples can be found in [TestSimple.java](../../../testlibrary_tests/template_framework/examples/TestSimple.java), [TestAdvanced.java](../../../testlibrary_tests/template_framework/examples/TestAdvanced.java) and [TestTutorial.java](../../../testlibrary_tests/template_framework/examples/TestTutorial.java). diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Renderer.java b/test/hotspot/jtreg/compiler/lib/template_framework/Renderer.java new file mode 100644 index 00000000000..14adfc81d3f --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Renderer.java @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * The {@link Renderer} class renders a tokenized {@link Template} in the form of a {@link TemplateToken}. + * It also keeps track of the states during a nested Template rendering. There can only be a single + * {@link Renderer} active at any point, since there are static methods that reference + * {@link Renderer#getCurrent}. + * + *

        + * The {@link Renderer} instance keeps track of the current frames. + * + * @see TemplateFrame + * @see CodeFrame + */ +final class Renderer { + private static final String NAME_CHARACTERS = "[a-zA-Z_][a-zA-Z0-9_]*"; + private static final Pattern NAME_PATTERN = Pattern.compile( + // We are parsing patterns: + // #name + // #{name} + // $name + // ${name} + // But the "#" or "$" have already been removed, and the String + // starts at the character after that. + // The pattern must be at the beginning of the String part. + "^" + + // We either have "name" or "{name}" + "(?:" + // non-capturing group for the OR + // capturing group for "name" + "(" + NAME_CHARACTERS + ")" + + "|" + // OR + // We want to trim off the brackets, so have + // another non-capturing group. + "(?:\\{" + + // capturing group for "name" inside "{name}" + "(" + NAME_CHARACTERS + ")" + + "\\})" + + ")"); + private static final Pattern NAME_CHARACTERS_PATTERN = Pattern.compile("^" + NAME_CHARACTERS + "$"); + + static boolean isValidHashtagOrDollarName(String name) { + return NAME_CHARACTERS_PATTERN.matcher(name).find(); + } + + /** + * There can be at most one Renderer instance at any time. + * + *

        + * When using nested templates, the user of the Template Framework may be tempted to first render + * the nested template to a {@link String}, and then use this {@link String} as a token in an outer + * {@link Template#body}. This would be a bad pattern: the outer and nested {@link Template} would + * be rendered separately, and could not interact. For example, the nested {@link Template} would + * not have access to the scopes of the outer {@link Template}. The inner {@link Template} could + * not access {@link Name}s and {@link Hook}s from the outer {@link Template}. The user might assume + * that the inner {@link Template} has access to the outer {@link Template}, but they would actually + * be separated. This could lead to unexpected behavior or even bugs. + * + *

        + * Instead, the user should create a {@link TemplateToken} from the inner {@link Template}, and + * use that {@link TemplateToken} in the {@link Template#body} of the outer {@link Template}. + * This way, the inner and outer {@link Template}s get rendered together, and the inner {@link Template} + * has access to the {@link Name}s and {@link Hook}s of the outer {@link Template}. + * + *

        + * The {@link Renderer} instance exists during the whole rendering process. Should the user ever + * attempt to render a nested {@link Template} to a {@link String}, we would detect that there is + * already a {@link Renderer} instance for the outer {@link Template}, and throw a {@link RendererException}. + */ + private static Renderer renderer = null; + + private int nextTemplateFrameId; + private final TemplateFrame baseTemplateFrame; + private TemplateFrame currentTemplateFrame; + private final CodeFrame baseCodeFrame; + private CodeFrame currentCodeFrame; + + // We do not want any other instances, so we keep it private. + private Renderer(float fuel) { + nextTemplateFrameId = 0; + baseTemplateFrame = TemplateFrame.makeBase(nextTemplateFrameId++, fuel); + currentTemplateFrame = baseTemplateFrame; + baseCodeFrame = CodeFrame.makeBase(); + currentCodeFrame = baseCodeFrame; + } + + static Renderer getCurrent() { + if (renderer == null) { + throw new RendererException("A Template method such as '$', 'let', 'sample', 'count' etc. was called outside a template rendering."); + } + return renderer; + } + + static String render(TemplateToken templateToken) { + return render(templateToken, Template.DEFAULT_FUEL); + } + + static String render(TemplateToken templateToken, float fuel) { + // Check nobody else is using the Renderer. + if (renderer != null) { + throw new RendererException("Nested render not allowed. Please only use 'asToken' inside Templates, and call 'render' only once at the end."); + } + try { + renderer = new Renderer(fuel); + renderer.renderTemplateToken(templateToken); + renderer.checkFrameConsistencyAfterRendering(); + return renderer.collectCode(); + } finally { + // Release the Renderer. + renderer = null; + } + } + + private void checkFrameConsistencyAfterRendering() { + // Ensure CodeFrame consistency. + if (baseCodeFrame != currentCodeFrame) { + throw new RuntimeException("Internal error: Renderer did not end up at base CodeFrame."); + } + // Ensure TemplateFrame consistency. + if (baseTemplateFrame != currentTemplateFrame) { + throw new RuntimeException("Internal error: Renderer did not end up at base TemplateFrame."); + } + } + + private String collectCode() { + StringBuilder builder = new StringBuilder(); + baseCodeFrame.getCode().renderTo(builder); + return builder.toString(); + } + + String $(String name) { + return currentTemplateFrame.$(name); + } + + void addHashtagReplacement(String key, Object value) { + currentTemplateFrame.addHashtagReplacement(key, format(value)); + } + + private String getHashtagReplacement(String key) { + return currentTemplateFrame.getHashtagReplacement(key); + } + + float fuel() { + return currentTemplateFrame.fuel; + } + + void setFuelCost(float fuelCost) { + currentTemplateFrame.setFuelCost(fuelCost); + } + + Name sampleName(NameSet.Predicate predicate) { + return currentCodeFrame.sampleName(predicate); + } + + int countNames(NameSet.Predicate predicate) { + return currentCodeFrame.countNames(predicate); + } + + boolean hasAnyNames(NameSet.Predicate predicate) { + return currentCodeFrame.hasAnyNames(predicate); + } + + List listNames(NameSet.Predicate predicate) { + return currentCodeFrame.listNames(predicate); + } + + /** + * Formats values to {@link String} with the goal of using them in Java code. + * By default, we use the overrides of {@link Object#toString}. + * But for some boxed primitives we need to create a special formatting. + */ + static String format(Object value) { + return switch (value) { + case String s -> s; + case Integer i -> i.toString(); + // We need to append the "L" so that the values are not interpreted as ints, + // and then javac might complain that the values are too large for an int. + case Long l -> l.toString() + "L"; + // Some Float and Double values like Infinity and NaN need a special representation. + case Float f -> formatFloat(f); + case Double d -> formatDouble(d); + default -> value.toString(); + }; + } + + private static String formatFloat(Float f) { + if (Float.isFinite(f)) { + return f.toString() + "f"; + } else if (f.isNaN()) { + return "Float.intBitsToFloat(" + Float.floatToRawIntBits(f) + " /* NaN */)"; + } else if (f.isInfinite()) { + if (f > 0) { + return "Float.POSITIVE_INFINITY"; + } else { + return "Float.NEGATIVE_INFINITY"; + } + } else { + throw new RuntimeException("Not handled: " + f); + } + } + + private static String formatDouble(Double d) { + if (Double.isFinite(d)) { + return d.toString(); + } else if (d.isNaN()) { + return "Double.longBitsToDouble(" + Double.doubleToRawLongBits(d) + "L /* NaN */)"; + } else if (d.isInfinite()) { + if (d > 0) { + return "Double.POSITIVE_INFINITY"; + } else { + return "Double.NEGATIVE_INFINITY"; + } + } else { + throw new RuntimeException("Not handled: " + d); + } + } + + private void renderTemplateToken(TemplateToken templateToken) { + TemplateFrame templateFrame = TemplateFrame.make(currentTemplateFrame, nextTemplateFrameId++); + currentTemplateFrame = templateFrame; + + templateToken.visitArguments((name, value) -> addHashtagReplacement(name, format(value))); + TemplateBody body = templateToken.instantiate(); + renderTokenList(body.tokens()); + + if (currentTemplateFrame != templateFrame) { + throw new RuntimeException("Internal error: TemplateFrame mismatch!"); + } + currentTemplateFrame = currentTemplateFrame.parent; + } + + private void renderToken(Token token) { + switch (token) { + case StringToken(String s) -> { + renderStringWithDollarAndHashtagReplacements(s); + } + case NothingToken() -> { + // Nothing. + } + case HookAnchorToken(Hook hook, List tokens) -> { + CodeFrame outerCodeFrame = currentCodeFrame; + + // We need a CodeFrame to which the hook can insert code. That way, name + // definitions at the hook cannot escape the hookCodeFrame. + CodeFrame hookCodeFrame = CodeFrame.make(outerCodeFrame); + hookCodeFrame.addHook(hook); + + // We need a CodeFrame where the tokens can be rendered. That way, name + // definitions from the tokens cannot escape the innerCodeFrame to the + // hookCodeFrame. + CodeFrame innerCodeFrame = CodeFrame.make(hookCodeFrame); + currentCodeFrame = innerCodeFrame; + + renderTokenList(tokens); + + // Close the hookCodeFrame and innerCodeFrame. hookCodeFrame code comes before the + // innerCodeFrame code from the tokens. + currentCodeFrame = outerCodeFrame; + currentCodeFrame.addCode(hookCodeFrame.getCode()); + currentCodeFrame.addCode(innerCodeFrame.getCode()); + } + case HookInsertToken(Hook hook, TemplateToken templateToken) -> { + // Switch to hook CodeFrame. + CodeFrame callerCodeFrame = currentCodeFrame; + CodeFrame hookCodeFrame = codeFrameForHook(hook); + + // Use a transparent nested CodeFrame. We need a CodeFrame so that the code generated + // by the TemplateToken can be collected, and hook insertions from it can still + // be made to the hookCodeFrame before the code from the TemplateToken is added to + // the hookCodeFrame. + // But the CodeFrame must be transparent, so that its name definitions go out to + // the hookCodeFrame, and are not limited to the CodeFrame for the TemplateToken. + currentCodeFrame = CodeFrame.makeTransparentForNames(hookCodeFrame); + + renderTemplateToken(templateToken); + + hookCodeFrame.addCode(currentCodeFrame.getCode()); + + // Switch back from hook CodeFrame to caller CodeFrame. + currentCodeFrame = callerCodeFrame; + } + case TemplateToken templateToken -> { + // Use a nested CodeFrame. + CodeFrame callerCodeFrame = currentCodeFrame; + currentCodeFrame = CodeFrame.make(currentCodeFrame); + + renderTemplateToken(templateToken); + + callerCodeFrame.addCode(currentCodeFrame.getCode()); + currentCodeFrame = callerCodeFrame; + } + case AddNameToken(Name name) -> { + currentCodeFrame.addName(name); + } + } + } + + private void renderTokenList(List tokens) { + CodeFrame codeFrame = currentCodeFrame; + for (Token t : tokens) { + renderToken(t); + } + if (codeFrame != currentCodeFrame) { + throw new RuntimeException("Internal error: CodeFrame mismatch."); + } + } + + /** + * We split a {@link String} by "#" and "$", and then look at each part. + * Example: + * + * s: "abcdefghijklmnop #name abcdefgh${var_name} 12345#{name2}_con $field_name something" + * parts: --------0-------- ------1------ --------2------- ------3----- ----------4--------- + * start: ^ ^ ^ ^ ^ + * next: ^ ^ ^ ^ ^ + * none hashtag dollar hashtag dollar done + */ + private void renderStringWithDollarAndHashtagReplacements(final String s) { + int count = 0; // First part needs special handling + int start = 0; + boolean startIsAfterDollar = false; + do { + // Find the next "$" or "#", after start. + int dollar = s.indexOf("$", start); + int hashtag = s.indexOf("#", start); + // If the character was not found, we want to have the rest of the + // String s, so instead of "-1" take the end/length of the String. + dollar = (dollar == -1) ? s.length() : dollar; + hashtag = (hashtag == -1) ? s.length() : hashtag; + // Take the first one. + int next = Math.min(dollar, hashtag); + String part = s.substring(start, next); + + if (count == 0) { + // First part has no "#" or "$" before it. + currentCodeFrame.addString(part); + } else { + // All others must do the replacement. + renderStringWithDollarAndHashtagReplacementsPart(s, part, startIsAfterDollar); + } + + if (next == s.length()) { + // No new "#" or "$" was found, we just processed the rest of the String, + // terminate now. + return; + } + start = next + 1; // skip over the "#" or "$" + startIsAfterDollar = next == dollar; // remember which character we just split with + count++; + } while (true); + } + + /** + * We are parsing a part now. Before the part, there was either a "#" or "$": + * isDollar = false: + * "#part" + * "#name abcdefgh" + * ---- + * "#{name2}_con " + * ------- + * + * isDollar = true: + * "$part" + * "${var_name} 12345" + * ---------- + * "$field_name something" + * ---------- + * + * We now want to find the name pattern at the beginning of the part, and replace + * it according to the hashtag or dollar replacement strategy. + */ + private void renderStringWithDollarAndHashtagReplacementsPart(final String s, final String part, final boolean isDollar) { + Matcher matcher = NAME_PATTERN.matcher(part); + // If the string has a "#" or "$" that is not followed by a correct name + // pattern, then the matcher will not match. These can be cases like: + // "##name" -> the first hashtag leads to an empty part, and an empty name. + // "#1name" -> the name pattern does not allow a digit as the first character. + // "anything#" -> a hashtag at the end of the string leads to an empty name. + if (!matcher.find()) { + String replacement = isDollar ? "$" : "#"; + throw new RendererException("Is not a valid '" + replacement + "' replacement pattern: '" + + replacement + part + "' in '" + s + "'."); + } + // We know that there is a correct pattern, and now we replace it. + currentCodeFrame.addString(matcher.replaceFirst( + (MatchResult result) -> { + // There are two groups: (1) for "name" and (2) for "{name}" + String name = result.group(1) != null ? result.group(1) : result.group(2); + if (isDollar) { + return $(name); + } else { + // replaceFirst needs some special escaping of backslashes and ollar signs. + return getHashtagReplacement(name).replace("\\", "\\\\").replace("$", "\\$"); + } + } + )); + } + + boolean isAnchored(Hook hook) { + return currentCodeFrame.codeFrameForHook(hook) != null; + } + + private CodeFrame codeFrameForHook(Hook hook) { + CodeFrame codeFrame = currentCodeFrame.codeFrameForHook(hook); + if (codeFrame == null) { + throw new RendererException("Hook '" + hook.name() + "' was referenced but not found!"); + } + return codeFrame; + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/RendererException.java b/test/hotspot/jtreg/compiler/lib/template_framework/RendererException.java new file mode 100644 index 00000000000..2ab542b6fe8 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/RendererException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +/** + * This exception is thrown when something goes wrong during Template + * rendering, or in the use of any of its static methods. + * It most likely indicates a wrong use of the Templates. + */ +public class RendererException extends RuntimeException { + RendererException(String message) { + super(message); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/StringToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/StringToken.java new file mode 100644 index 00000000000..4926748e51a --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/StringToken.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +record StringToken(String value) implements Token {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/StructuralName.java b/test/hotspot/jtreg/compiler/lib/template_framework/StructuralName.java new file mode 100644 index 00000000000..866ac6dbfb8 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/StructuralName.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; + +/** + * {@link StructuralName}s represent things like method and class names, and can be added to the local + * scope with {@link Template#addStructuralName}, and accessed with {@link Template#structuralNames}, from where + * count, list or even sample random {@link StructuralName}s. Every {@link StructuralName} has a {@link StructuralName.Type}, + * so that sampling can be restricted to these types. + * + *

        + * For field and variable names and alike, there are the analogous {@link DataName}s. + * + * @param name The {@link String} name used in code. + * @param type The type of the {@link StructuralName}. + * @param weight The weight of the {@link StructuralName}, it corresponds to the probability of choosing this + * {@link StructuralName} when sampling later on. + */ +public record StructuralName(String name, StructuralName.Type type, int weight) implements Name { + + /** + * Creates a new {@link StructuralName}. + */ + public StructuralName { + } + + /** + * The interface for the type of a {@link StructuralName}. + */ + public interface Type extends Name.Type { + /** + * The name of the type, that can be used in code. + * + * @return The {@link String} representation of the type, that can be used in code. + */ + String name(); + + /** + * Defines the subtype relationship with other types, which is used to filter {@link StructuralName}s + * in {@link FilteredSet#exactOf}, {@link FilteredSet#subtypeOf}, and {@link FilteredSet#supertypeOf}. + * + * @param other The other type, where we check if it is the supertype of {@code 'this'}. + * @return If {@code 'this'} is a subtype of {@code 'other'}. + */ + boolean isSubtypeOf(StructuralName.Type other); + } + + /** + * The {@link FilteredSet} represents a filtered set of {@link StructuralName}s in the current scope. + * It can be obtained with {@link Template#structuralNames}. It can be used to count the + * available {@link StructuralName}s, or sample a random {@link StructuralName} according to the + * weights of the {@link StructuralName}s in the filtered set. + * Note: The {@link FilteredSet} is only a filtered view on the set of {@link StructuralName}s, + * and may return different results in different contexts. + */ + public static final class FilteredSet { + private final StructuralName.Type subtype; + private final StructuralName.Type supertype; + + FilteredSet(StructuralName.Type subtype, StructuralName.Type supertype) { + this.subtype = subtype; + this.supertype = supertype; + } + + FilteredSet() { + this(null, null); + } + + NameSet.Predicate predicate() { + if (subtype == null && supertype == null) { + throw new UnsupportedOperationException("Must first call 'subtypeOf', 'supertypeOf', or 'exactOf'."); + } + return (Name name) -> { + if (!(name instanceof StructuralName structuralName)) { return false; } + if (subtype != null && !structuralName.type().isSubtypeOf(subtype)) { return false; } + if (supertype != null && !supertype.isSubtypeOf(structuralName.type())) { return false; } + return true; + }; + } + + /** + * Create a {@link FilteredSet}, where all {@link StructuralName}s must be subtypes of {@code type}. + * + * @param type The type of which all {@link StructuralName}s must be subtypes of. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #subtypeOf} or {@link #exactOf}. + */ + public FilteredSet subtypeOf(StructuralName.Type type) { + if (subtype != null) { + throw new UnsupportedOperationException("Cannot constrain to subtype " + type + ", is already constrained: " + subtype); + } + return new FilteredSet(type, supertype); + } + + /** + * Create a {@link FilteredSet}, where all {@link StructuralName}s must be supertypes of {@code type}. + * + * @param type The type of which all {@link StructuralName}s must be supertype of. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #supertypeOf} or {@link #exactOf}. + */ + public FilteredSet supertypeOf(StructuralName.Type type) { + if (supertype != null) { + throw new UnsupportedOperationException("Cannot constrain to supertype " + type + ", is already constrained: " + supertype); + } + return new FilteredSet(subtype, type); + } + + /** + * Create a {@link FilteredSet}, where all {@link StructuralName}s must be of exact {@code type}, + * hence it must be both subtype and supertype thereof. + * + * @param type The type of which all {@link StructuralName}s must be. + * @return The updated filtered set. + * @throws UnsupportedOperationException If this {@link FilteredSet} was already filtered with + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public FilteredSet exactOf(StructuralName.Type type) { + return subtypeOf(type).supertypeOf(type); + } + + /** + * Samples a random {@link StructuralName} from the filtered set, according to the weights + * of the contained {@link StructuralName}s. + * + * @return The sampled {@link StructuralName}. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + * @throws RendererException If the set was empty. + */ + public StructuralName sample() { + StructuralName n = (StructuralName)Renderer.getCurrent().sampleName(predicate()); + if (n == null) { + String msg1 = (subtype == null) ? "" : " subtypeOf(" + subtype + ")"; + String msg2 = (supertype == null) ? "" : " supertypeOf(" + supertype + ")"; + throw new RendererException("No variable:" + msg1 + msg2 + "."); + } + return n; + } + + /** + * Counts the number of {@link StructuralName}s in the filtered set. + * + * @return The number of {@link StructuralName}s in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public int count() { + return Renderer.getCurrent().countNames(predicate()); + } + + /** + * Checks if there are any {@link StructuralName}s in the filtered set. + * + * @return Returns {@code true} iff there is at least one {@link StructuralName} in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public boolean hasAny() { + return Renderer.getCurrent().hasAnyNames(predicate()); + } + + /** + * Collects all {@link StructuralName}s in the filtered set. + * + * @return A {@link List} of all {@link StructuralName}s in the filtered set. + * @throws UnsupportedOperationException If the type was not constrained with either of + * {@link #subtypeOf}, {@link #supertypeOf} or {@link #exactOf}. + */ + public List toList() { + List list = Renderer.getCurrent().listNames(predicate()); + return list.stream().map(n -> (StructuralName)n).toList(); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Template.java b/test/hotspot/jtreg/compiler/lib/template_framework/Template.java new file mode 100644 index 00000000000..f01c5ccffd3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Template.java @@ -0,0 +1,844 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +import java.util.List; + +import compiler.lib.compile_framework.CompileFramework; +import compiler.lib.ir_framework.TestFramework; + +/** + * The Template Framework allows the generation of code with Templates. The goal is that these Templates are + * easy to write, and allow regression tests to cover a larger scope, and to make template based fuzzing easy + * to extend. + * + *

        + * Motivation: We want to make it easy to generate variants of tests. Often, we would like to + * have a set of tests, corresponding to a set of types, a set of operators, a set of constants, etc. Writing all + * the tests by hand is cumbersome or even impossible. When generating such tests with scripts, it would be + * preferable if the code generation happens automatically, and the generator script was checked into the code + * base. Code generation can go beyond simple regression tests, and one might want to generate random code from + * a list of possible templates, to fuzz individual Java features and compiler optimizations. + * + *

        + * The Template Framework provides a facility to generate code with Templates. A Template is essentially a list + * of tokens that are concatenated (i.e. rendered) to a {@link String}. The Templates can have "holes", which are + * filled (replaced) by different values at each Template instantiation. For example, these "holes" can + * be filled with different types, operators or constants. Templates can also be nested, allowing a modular + * use of Templates. + * + *

        + * Once we rendered the source code to a {@link String}, we can compile it with the {@link CompileFramework}. + * + *

        + * Example: + * The following snippets are from the example test {@code TestAdvanced.java}. + * First, we define a template that generates a {@code @Test} method for a given type, operator and + * constant generator. We define two constants {@code con1} and {@code con2}, and then use a multiline + * string with hashtags {@code #} (i.e. "holes") that are then replaced by the template arguments and the + * {@link #let} definitions. + * + *

        + * {@snippet lang=java : + * var testTemplate = Template.make("typeName", "operator", "generator", (String typeName, String operator, MyGenerator generator) -> body( + * let("con1", generator.next()), + * let("con2", generator.next()), + * """ + * // #typeName #operator #con1 #con2 + * public static #typeName $GOLD = $test(); + * + * @Test + * public static #typeName $test() { + * return (#typeName)(#con1 #operator #con2); + * } + * + * @Check(test = "$test") + * public static void $check(#typeName result) { + * Verify.checkEQ(result, $GOLD); + * } + * """ + * )); + * } + * + *

        + * To get an executable test, we define a {@link Template} that produces a class body with a main method. The Template + * takes a list of types, and calls the {@code testTemplate} defined above for each type and operator. We use + * the {@link TestFramework} to call our {@code @Test} methods. + * + *

        + * {@snippet lang=java : + * var classTemplate = Template.make("types", (List types) -> body( + * let("classpath", comp.getEscapedClassPathOfCompiledClasses()), + * """ + * package p.xyz; + * + * import compiler.lib.ir_framework.*; + * import compiler.lib.verify.*; + * + * public class InnerTest { + * public static void main() { + * // Set the classpath, so that the TestFramework test VM knows where + * // the CompileFramework put the class files of the compiled source code. + * TestFramework framework = new TestFramework(InnerTest.class); + * framework.addFlags("-classpath", "#classpath"); + * framework.start(); + * } + * + * """, + * // Call the testTemplate for each type and operator, generating a + * // list of lists of TemplateToken: + * types.stream().map((Type type) -> + * type.operators().stream().map((String operator) -> + * testTemplate.asToken(type.name(), operator, type.generator())).toList() + * ).toList(), + * """ + * } + * """ + * )); + * } + * + *

        + * Finally, we generate the list of types, and pass it to the class template: + * + *

        + * {@snippet lang=java : + * List types = List.of( + * new Type("byte", GEN_BYTE::next, List.of("+", "-", "*", "&", "|", "^")), + * new Type("char", GEN_CHAR::next, List.of("+", "-", "*", "&", "|", "^")), + * new Type("short", GEN_SHORT::next, List.of("+", "-", "*", "&", "|", "^")), + * new Type("int", GEN_INT::next, List.of("+", "-", "*", "&", "|", "^")), + * new Type("long", GEN_LONG::next, List.of("+", "-", "*", "&", "|", "^")), + * new Type("float", GEN_FLOAT::next, List.of("+", "-", "*", "/")), + * new Type("double", GEN_DOUBLE::next, List.of("+", "-", "*", "/")) + * ); + * + * // Use the template with one argument, and render it to a String. + * return classTemplate.render(types); + * } + * + *

        + * Details: + *

        + * A {@link Template} can have zero or more arguments. A template can be created with {@code make} methods like + * {@link Template#make(String, Function)}. For each number of arguments there is an implementation + * (e.g. {@link Template.TwoArgs} for two arguments). This allows the use of generics for the + * {@link Template} argument types which enables type checking of the {@link Template} arguments. + * It is currently only allowed to use up to three arguments. + * + *

        + * A {@link Template} can be rendered to a {@link String} (e.g. {@link Template.ZeroArgs#render()}). + * Alternatively, we can generate a {@link Token} (more specifically, a {@link TemplateToken}) with {@code asToken()} + * (e.g. {@link Template.ZeroArgs#asToken()}), and use the {@link Token} inside another {@link Template#body}. + * + *

        + * Ideally, we would have used string templates to inject these Template + * arguments into the strings. But since string templates are not (yet) available, the Templates provide + * hashtag replacements in the {@link String}s: the Template argument names are captured, and + * the argument values automatically replace any {@code "#name"} in the {@link String}s. See the different overloads + * of {@link #make} for examples. Additional hashtag replacements can be defined with {@link #let}. + * + *

        + * When using nested Templates, there can be collisions with identifiers (e.g. variable names and method names). + * For this, Templates provide dollar replacements, which automatically rename any + * {@code "$name"} in the {@link String} with a {@code "name_ID"}, where the {@code "ID"} is unique for every use of + * a Template. The dollar replacement can also be captured with {@link #$}, and passed to nested + * Templates, which allows sharing of these identifier names between Templates. + * + *

        + * The dollar and hashtag names must have at least one character. The first character must be a letter + * or underscore (i.e. {@code a-zA-Z_}), the other characters can also be digits (i.e. {@code a-zA-Z0-9_}). + * One can use them with or without curly braces, e.g. {@code #name}, {@code #{name}}, {@code $name}, or + * {@code #{name}}. + * + *

        + * A {@link TemplateToken} cannot just be used in {@link Template#body}, but it can also be + * {@link Hook#insert}ed to where a {@link Hook} was {@link Hook#anchor}ed earlier (in some outer scope of the code). + * For example, while generating code in a method, one can reach out to the scope of the class, and insert a + * new field, or define a utility method. + * + *

        + * A {@link TemplateBinding} allows the recursive use of Templates. With the indirection of such a binding, + * a Template can reference itself. + * + *

        + * The writer of recursive {@link Template}s must ensure that this recursion terminates. To unify the + * approach across {@link Template}s, we introduce the concept of {@link #fuel}. Templates are rendered starting + * with a limited amount of {@link #fuel} (default: 100, see {@link #DEFAULT_FUEL}), which is decreased at each + * Template nesting by a certain amount (default: 10, see {@link #DEFAULT_FUEL_COST}). The default fuel for a + * template can be changed when we {@code render()} it (e.g. {@link ZeroArgs#render(float)}) and the default + * fuel cost with {@link #setFuelCost}) when defining the {@link #body(Object...)}. Recursive templates are + * supposed to terminate once the {@link #fuel} is depleted (i.e. reaches zero). + * + *

        + * Code generation can involve keeping track of fields and variables, as well as the scopes in which they + * are available, and if they are mutable or immutable. We model fields and variables with {@link DataName}s, + * which we can add to the current scope with {@link #addDataName}. We can access the {@link DataName}s with + * {@link #dataNames}. We can filter for {@link DataName}s of specific {@link DataName.Type}s, and then + * we can call {@link DataName.FilteredSet#count}, {@link DataName.FilteredSet#sample}, + * {@link DataName.FilteredSet#toList}, etc. There are many use-cases for this mechanism, especially + * facilitating communication between the code of outer and inner {@link Template}s. Especially for fuzzing, + * it may be useful to be able to add fields and variables, and sample them randomly, to create a random data + * flow graph. + * + *

        + * Similarly, we may want to model method and class names, and possibly other structural names. We model + * these names with {@link StructuralName}, which works analogously to {@link DataName}, except that they + * are not concerned about mutability. + * + *

        + * When working with {@link DataName}s and {@link StructuralName}s, it is important to be aware of the + * relevant scopes, as well as the execution order of the {@link Template} lambdas and the evaluation + * of the {@link Template#body} tokens. When a {@link Template} is rendered, its lambda is invoked. In the + * lambda, we generate the tokens, and create the {@link Template#body}. Once the lambda returns, the + * tokens are evaluated one by one. While evaluating the tokens, the {@link Renderer} might encounter a nested + * {@link TemplateToken}, which in turn triggers the evaluation of that nested {@link Template}, i.e. + * the evaluation of its lambda and later the evaluation of its tokens. It is important to keep in mind + * that the lambda is always executed first, and the tokens are evaluated afterwards. A method like + * {@code dataNames(MUTABLE).exactOf(type).count()} is a method that is executed during the evaluation + * of the lambda. But a method like {@link #addDataName} returns a token, and does not immediately add + * the {@link DataName}. This ensures that the {@link DataName} is only inserted when the tokens are + * evaluated, so that it is inserted at the exact scope where we would expect it. + * + *

        + * Let us look at the following example to better understand the execution order. + * + *

        + * {@snippet lang=java : + * var testTemplate = Template.make(() -> body( + * // The lambda has just been invoked. + * // We count the DataNames and assign the count to the hashtag replacement "c1". + * let("c1", dataNames(MUTABLE).exactOf(someType).count()), + * // We want to define a DataName "v1", and create a token for it. + * addDataName($("v1"), someType, MUTABLE), + * // We count the DataNames again, but the count does NOT change compared to "c1". + * // This is because the token for "v1" is only evaluated later. + * let("c2", dataNames(MUTABLE).exactOf(someType).count()), + * // Create a nested scope. + * METHOD_HOOK.anchor( + * // We want to define a DataName "v2", which is only valid inside this + * // nested scope. + * addDataName($("v2"), someType, MUTABLE), + * // The count is still not different to "c1". + * let("c3", dataNames(MUTABLE).exactOf(someType).count()), + * // We nest a Template. This creates a TemplateToken, which is later evaluated. + * // By the time the TemplateToken is evaluated, the tokens from above will + * // be already evaluated. Hence, "v1" and "v2" are added by then, and if the + * // "otherTemplate" were to count the DataNames, the count would be increased + * // by 2 compared to "c1". + * otherTemplate.asToken() + * ), + * // After closing the scope, "v2" is no longer available. + * // The count is still the same as "c1", since "v1" is still only a token. + * let("c4", dataNames(MUTABLE).exactOf(someType).count()), + * // We nest another Template. Again, this creates a TemplateToken, which is only + * // evaluated later. By that time, the token for "v1" is evaluated, and so the + * // nested Template would observe an increment in the count. + * anotherTemplate.asToken() + * // By this point, all methods are called, and the tokens generated. + * // The lambda returns the "body", which is all of the tokens that we just + * // generated. After returning from the lambda, the tokens will be evaluated + * // one by one. + * )); + * } + + *

        + * More examples for these functionalities can be found in {@code TestTutorial.java}, {@code TestSimple.java}, + * and {@code TestAdvanced.java}, which all produce compilable Java code. Additional examples can be found in + * the tests, such as {@code TestTemplate.java} and {@code TestFormat.java}, which do not necessarily generate + * valid Java code, but generate deterministic Strings which are easier to verify, and may also serve as a + * reference when learning about these functionalities. + */ +public sealed interface Template permits Template.ZeroArgs, + Template.OneArg, + Template.TwoArgs, + Template.ThreeArgs { + + /** + * A {@link Template} with no arguments. + * + * @param function The {@link Supplier} that creates the {@link TemplateBody}. + */ + record ZeroArgs(Supplier function) implements Template { + TemplateBody instantiate() { + return function.get(); + } + + /** + * Creates a {@link TemplateToken} which can be used as a {@link Token} inside + * a {@link Template} for nested code generation. + * + * @return The {@link TemplateToken} to use the {@link Template} inside another + * {@link Template}. + */ + public TemplateToken asToken() { + return new TemplateToken.ZeroArgs(this); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render() { + return new TemplateToken.ZeroArgs(this).render(); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param fuel The amount of fuel provided for recursive Template instantiations. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(float fuel) { + return new TemplateToken.ZeroArgs(this).render(fuel); + } + } + + /** + * A {@link Template} with one argument. + * + * @param arg1Name The name of the (first) argument, used for hashtag replacements in the {@link Template}. + * @param The type of the (first) argument. + * @param function The {@link Function} that creates the {@link TemplateBody} given the template argument. + */ + record OneArg(String arg1Name, Function function) implements Template { + TemplateBody instantiate(T1 arg1) { + return function.apply(arg1); + } + + /** + * Creates a {@link TemplateToken} which can be used as a {@link Token} inside + * a {@link Template} for nested code generation. + * + * @param arg1 The value for the (first) argument. + * @return The {@link TemplateToken} to use the {@link Template} inside another + * {@link Template}. + */ + public TemplateToken asToken(T1 arg1) { + return new TemplateToken.OneArg<>(this, arg1); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(T1 arg1) { + return new TemplateToken.OneArg<>(this, arg1).render(); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @param fuel The amount of fuel provided for recursive Template instantiations. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(float fuel, T1 arg1) { + return new TemplateToken.OneArg<>(this, arg1).render(fuel); + } + } + + /** + * A {@link Template} with two arguments. + * + * @param arg1Name The name of the first argument, used for hashtag replacements in the {@link Template}. + * @param arg2Name The name of the second argument, used for hashtag replacements in the {@link Template}. + * @param The type of the first argument. + * @param The type of the second argument. + * @param function The {@link BiFunction} that creates the {@link TemplateBody} given the template arguments. + */ + record TwoArgs(String arg1Name, String arg2Name, BiFunction function) implements Template { + TemplateBody instantiate(T1 arg1, T2 arg2) { + return function.apply(arg1, arg2); + } + + /** + * Creates a {@link TemplateToken} which can be used as a {@link Token} inside + * a {@link Template} for nested code generation. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @return The {@link TemplateToken} to use the {@link Template} inside another + * {@link Template}. + */ + public TemplateToken asToken(T1 arg1, T2 arg2) { + return new TemplateToken.TwoArgs<>(this, arg1, arg2); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(T1 arg1, T2 arg2) { + return new TemplateToken.TwoArgs<>(this, arg1, arg2).render(); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @param fuel The amount of fuel provided for recursive Template instantiations. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(float fuel, T1 arg1, T2 arg2) { + return new TemplateToken.TwoArgs<>(this, arg1, arg2).render(fuel); + } + } + + /** + * Interface for function with three arguments. + * + * @param Type of the first argument. + * @param Type of the second argument. + * @param Type of the third argument. + * @param Type of the return value. + */ + @FunctionalInterface + interface TriFunction { + + /** + * Function definition for the three argument functions. + * + * @param t The first argument. + * @param u The second argument. + * @param v The third argument. + * @return Return value of the three argument function. + */ + R apply(T t, U u, V v); + } + + /** + * A {@link Template} with three arguments. + * + * @param arg1Name The name of the first argument, used for hashtag replacements in the {@link Template}. + * @param arg2Name The name of the second argument, used for hashtag replacements in the {@link Template}. + * @param arg3Name The name of the third argument, used for hashtag replacements in the {@link Template}. + * @param The type of the first argument. + * @param The type of the second argument. + * @param The type of the third argument. + * @param function The function with three arguments that creates the {@link TemplateBody} given the template arguments. + */ + record ThreeArgs(String arg1Name, String arg2Name, String arg3Name, TriFunction function) implements Template { + TemplateBody instantiate(T1 arg1, T2 arg2, T3 arg3) { + return function.apply(arg1, arg2, arg3); + } + + /** + * Creates a {@link TemplateToken} which can be used as a {@link Token} inside + * a {@link Template} for nested code generation. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @param arg3 The value for the third argument. + * @return The {@link TemplateToken} to use the {@link Template} inside another + * {@link Template}. + */ + public TemplateToken asToken(T1 arg1, T2 arg2, T3 arg3) { + return new TemplateToken.ThreeArgs<>(this, arg1, arg2, arg3); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @param arg3 The value for the third argument. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(T1 arg1, T2 arg2, T3 arg3) { + return new TemplateToken.ThreeArgs<>(this, arg1, arg2, arg3).render(); + } + + /** + * Renders the {@link Template} to a {@link String}. + * + * @param arg1 The value for the first argument. + * @param arg2 The value for the second argument. + * @param arg3 The value for the third argument. + * @param fuel The amount of fuel provided for recursive Template instantiations. + * @return The {@link String}, resulting from rendering the {@link Template}. + */ + public String render(float fuel, T1 arg1, T2 arg2, T3 arg3) { + return new TemplateToken.ThreeArgs<>(this, arg1, arg2, arg3).render(fuel); + } + } + + /** + * Creates a {@link Template} with no arguments. + * See {@link #body} for more details about how to construct a Template with {@link Token}s. + * + *

        + * Example: + * {@snippet lang=java : + * var template = Template.make(() -> body( + * """ + * Multi-line string or other tokens. + * """ + * )); + * } + * + * @param body The {@link TemplateBody} created by {@link Template#body}. + * @return A {@link Template} with zero arguments. + */ + static Template.ZeroArgs make(Supplier body) { + return new Template.ZeroArgs(body); + } + + /** + * Creates a {@link Template} with one argument. + * See {@link #body} for more details about how to construct a Template with {@link Token}s. + * Good practice but not enforced but not enforced: {@code arg1Name} should match the lambda argument name. + * + *

        + * Here is an example with template argument {@code 'a'}, captured once as string name + * for use in hashtag replacements, and captured once as lambda argument with the corresponding type + * of the generic argument. + * {@snippet lang=java : + * var template = Template.make("a", (Integer a) -> body( + * """ + * Multi-line string or other tokens. + * We can use the hashtag replacement #a to directly insert the String value of a. + * """, + * "We can also use the captured parameter of a: " + a + * )); + * } + * + * @param body The {@link TemplateBody} created by {@link Template#body}. + * @param Type of the (first) argument. + * @param arg1Name The name of the (first) argument for hashtag replacement. + * @return A {@link Template} with one argument. + */ + static Template.OneArg make(String arg1Name, Function body) { + return new Template.OneArg<>(arg1Name, body); + } + + /** + * Creates a {@link Template} with two arguments. + * See {@link #body} for more details about how to construct a Template with {@link Token}s. + * Good practice but not enforced: {@code arg1Name} and {@code arg2Name} should match the lambda argument names. + * + *

        + * Here is an example with template arguments {@code 'a'} and {@code 'b'}, captured once as string names + * for use in hashtag replacements, and captured once as lambda arguments with the corresponding types + * of the generic arguments. + * {@snippet lang=java : + * var template = Template.make("a", "b", (Integer a, String b) -> body( + * """ + * Multi-line string or other tokens. + * We can use the hashtag replacement #a and #b to directly insert the String value of a and b. + * """, + * "We can also use the captured parameter of a and b: " + a + " and " + b + * )); + * } + * + * @param body The {@link TemplateBody} created by {@link Template#body}. + * @param Type of the first argument. + * @param arg1Name The name of the first argument for hashtag replacement. + * @param Type of the second argument. + * @param arg2Name The name of the second argument for hashtag replacement. + * @return A {@link Template} with two arguments. + */ + static Template.TwoArgs make(String arg1Name, String arg2Name, BiFunction body) { + return new Template.TwoArgs<>(arg1Name, arg2Name, body); + } + + /** + * Creates a {@link Template} with three arguments. + * See {@link #body} for more details about how to construct a Template with {@link Token}s. + * Good practice but not enforced: {@code arg1Name}, {@code arg2Name}, and {@code arg3Name} should match the lambda argument names. + * + * @param body The {@link TemplateBody} created by {@link Template#body}. + * @param Type of the first argument. + * @param arg1Name The name of the first argument for hashtag replacement. + * @param Type of the second argument. + * @param arg2Name The name of the second argument for hashtag replacement. + * @param Type of the third argument. + * @param arg3Name The name of the third argument for hashtag replacement. + * @return A {@link Template} with three arguments. + */ + static Template.ThreeArgs make(String arg1Name, String arg2Name, String arg3Name, Template.TriFunction body) { + return new Template.ThreeArgs<>(arg1Name, arg2Name, arg3Name, body); + } + + /** + * Creates a {@link TemplateBody} from a list of tokens, which can be {@link String}s, + * boxed primitive types (for example {@link Integer} or auto-boxed {@code int}), any {@link Token}, + * or {@link List}s of any of these. + * + *

        + * {@snippet lang=java : + * var template = Template.make(() -> body( + * """ + * Multi-line string + * """, + * "normal string ", Integer.valueOf(3), 3, Float.valueOf(1.5f), 1.5f, + * List.of("abc", "def"), + * nestedTemplate.asToken(42) + * )); + * } + * + * @param tokens A list of tokens, which can be {@link String}s, boxed primitive types + * (for example {@link Integer}), any {@link Token}, or {@link List}s + * of any of these. + * @return The {@link TemplateBody} which captures the list of validated {@link Token}s. + * @throws IllegalArgumentException if the list of tokens contains an unexpected object. + */ + static TemplateBody body(Object... tokens) { + return new TemplateBody(Token.parse(tokens)); + } + + /** + * Retrieves the dollar replacement of the {@code 'name'} for the + * current Template that is being instantiated. It returns the same + * dollar replacement as the string use {@code "$name"}. + * + *

        + * Here is an example where a Template creates a local variable {@code 'var'}, + * with an implicit dollar replacement, and then captures that dollar replacement + * using {@link #$} for the use inside a nested template. + * {@snippet lang=java : + * var template = Template.make(() -> body( + * """ + * int $var = 42; + * """, + * otherTemplate.asToken($("var")) + * )); + * } + * + * @param name The {@link String} name of the name. + * @return The dollar replacement for the {@code 'name'}. + */ + static String $(String name) { + return Renderer.getCurrent().$(name); + } + + /** + * Define a hashtag replacement for {@code "#key"}, with a specific value. + * + *

        + * {@snippet lang=java : + * var template = Template.make("a", (Integer a) -> body( + * let("b", a * 5), + * """ + * System.out.println("Use a and b with hashtag replacement: #a and #b"); + * """ + * )); + * } + * + * @param key Name for the hashtag replacement. + * @param value The value that the hashtag is replaced with. + * @return A token that does nothing, so that the {@link #let} can easily be put in a list of tokens + * inside a {@link Template#body}. + * @throws RendererException if there is a duplicate hashtag {@code key}. + */ + static Token let(String key, Object value) { + Renderer.getCurrent().addHashtagReplacement(key, value); + return new NothingToken(); + } + + /** + * Define a hashtag replacement for {@code "#key"}, with a specific value, which is also captured + * by the provided {@code function} with type {@code }. + * + *

        + * {@snippet lang=java : + * var template = Template.make("a", (Integer a) -> let("b", a * 2, (Integer b) -> body( + * """ + * System.out.println("Use a and b with hashtag replacement: #a and #b"); + * """, + * "System.out.println(\"Use a and b as capture variables:\"" + a + " and " + b + ");\n" + * ))); + * } + * + * @param key Name for the hashtag replacement. + * @param value The value that the hashtag is replaced with. + * @param The type of the value. + * @param function The function that is applied with the provided {@code value}. + * @return A {@link TemplateBody}. + * @throws RendererException if there is a duplicate hashtag {@code key}. + */ + static TemplateBody let(String key, T value, Function function) { + Renderer.getCurrent().addHashtagReplacement(key, value); + return function.apply(value); + } + + /** + * Default amount of fuel for Template rendering. It guides the nesting depth of Templates. Can be changed when + * rendering a template with {@code render(fuel)} (e.g. {@link ZeroArgs#render(float)}). + */ + float DEFAULT_FUEL = 100.0f; + + /** + * The default amount of fuel spent per Template. It is subtracted from the current {@link #fuel} at every + * nesting level, and once the {@link #fuel} reaches zero, the nesting is supposed to terminate. Can be changed + * with {@link #setFuelCost(float)} inside {@link #body(Object...)}. + */ + float DEFAULT_FUEL_COST = 10.0f; + + /** + * The current remaining fuel for nested Templates. Every level of Template nesting + * subtracts a certain amount of fuel, and when it reaches zero, Templates are supposed to + * stop nesting, if possible. This is not a hard rule, but a guide, and a mechanism to ensure + * termination in recursive Template instantiations. + * + *

        + * Example of a recursive Template, which checks the remaining {@link #fuel} at every level, + * and terminates if it reaches zero. It also demonstrates the use of {@link TemplateBinding} for + * the recursive use of Templates. We {@link Template.OneArg#render} with {@code 30} total fuel, + * and spend {@code 5} fuel at each recursion level. + * + *

        + * {@snippet lang=java : + * var binding = new TemplateBinding>(); + * var template = Template.make("depth", (Integer depth) -> body( + * setFuelCost(5.0f), + * let("fuel", fuel()), + * """ + * System.out.println("Currently at depth #depth with fuel #fuel"); + * """, + * (fuel() > 0) ? binding.get().asToken(depth + 1) : + * "// terminate\n" + * )); + * binding.bind(template); + * String code = template.render(30.0f, 0); + * } + * + * @return The amount of fuel left for nested Template use. + */ + static float fuel() { + return Renderer.getCurrent().fuel(); + } + + /** + * Changes the amount of fuel used for the current Template, where the default is + * {@link Template#DEFAULT_FUEL_COST}. + * + * @param fuelCost The amount of fuel used for the current Template. + * @return A token for convenient use in {@link Template#body}. + */ + static Token setFuelCost(float fuelCost) { + Renderer.getCurrent().setFuelCost(fuelCost); + return new NothingToken(); + } + + /** + * Add a {@link DataName} in the current scope, that is the innermost of either + * {@link Template#body} or {@link Hook#anchor}. + * + * @param name The name of the {@link DataName}, i.e. the {@link String} used in code. + * @param type The type of the {@link DataName}. + * @param mutability Indicates if the {@link DataName} is to be mutable or immutable, + * i.e. if we intend to use the {@link DataName} only for reading + * or if we also allow it to be mutated. + * @param weight The weight of the {@link DataName}, which correlates to the probability + * of this {@link DataName} being chosen when we sample. + * Must be a value from 1 to 1000. + * @return The token that performs the defining action. + */ + static Token addDataName(String name, DataName.Type type, DataName.Mutability mutability, int weight) { + if (mutability != DataName.Mutability.MUTABLE && + mutability != DataName.Mutability.IMMUTABLE) { + throw new IllegalArgumentException("Unexpected mutability: " + mutability); + } + boolean mutable = mutability == DataName.Mutability.MUTABLE; + if (weight <= 0 || 1000 < weight) { + throw new IllegalArgumentException("Unexpected weight: " + weight); + } + return new AddNameToken(new DataName(name, type, mutable, weight)); + } + + /** + * Add a {@link DataName} in the current scope, that is the innermost of either + * {@link Template#body} or {@link Hook#anchor}, with a {@code weight} of 1. + * + * @param name The name of the {@link DataName}, i.e. the {@link String} used in code. + * @param type The type of the {@link DataName}. + * @param mutability Indicates if the {@link DataName} is to be mutable or immutable, + * i.e. if we intend to use the {@link DataName} only for reading + * or if we also allow it to be mutated. + * @return The token that performs the defining action. + */ + static Token addDataName(String name, DataName.Type type, DataName.Mutability mutability) { + return addDataName(name, type, mutability, 1); + } + + /** + * Access the set of {@link DataName}s, for sampling, counting, etc. + * + * @param mutability Indicates if we only sample from mutable, immutable or either {@link DataName}s. + * @return A view on the {@link DataName}s, on which we can sample, count, etc. + */ + static DataName.FilteredSet dataNames(DataName.Mutability mutability) { + return new DataName.FilteredSet(mutability); + } + + /** + * Add a {@link StructuralName} in the current scope, that is the innermost of either + * {@link Template#body} or {@link Hook#anchor}. + * + * @param name The name of the {@link StructuralName}, i.e. the {@link String} used in code. + * @param type The type of the {@link StructuralName}. + * @param weight The weight of the {@link StructuralName}, which correlates to the probability + * of this {@link StructuralName} being chosen when we sample. + * Must be a value from 1 to 1000. + * @return The token that performs the defining action. + */ + static Token addStructuralName(String name, StructuralName.Type type, int weight) { + if (weight <= 0 || 1000 < weight) { + throw new IllegalArgumentException("Unexpected weight: " + weight); + } + return new AddNameToken(new StructuralName(name, type, weight)); + } + + /** + * Add a {@link StructuralName} in the current scope, that is the innermost of either + * {@link Template#body} or {@link Hook#anchor}, with a {@code weight} of 1. + * + * @param name The name of the {@link StructuralName}, i.e. the {@link String} used in code. + * @param type The type of the {@link StructuralName}. + * @return The token that performs the defining action. + */ + static Token addStructuralName(String name, StructuralName.Type type) { + return addStructuralName(name, type, 1); + } + + /** + * Access the set of {@link StructuralName}s, for sampling, counting, etc. + * + * @return A view on the {@link StructuralName}s, on which we can sample, count, etc. + */ + static StructuralName.FilteredSet structuralNames() { + return new StructuralName.FilteredSet(); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBinding.java b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBinding.java new file mode 100644 index 00000000000..2073b788e71 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBinding.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +/** + * To facilitate recursive uses of Templates, for example where a template uses + * itself and needs to be referenced before it is fully defined, + * one can use the indirection of a {@link TemplateBinding}. The {@link TemplateBinding} + * is allocated first without any Template bound to it yet. At this stage, + * it can be used with {@link #get} inside a Template. Later, we can {@link #bind} + * a Template to the binding, such that {@link #get} returns that bound + * Template. + * + * @param Type of the template. + */ +public class TemplateBinding { + private T template = null; + + /** + * Creates a new {@link TemplateBinding} that has no Template bound to it yet. + */ + public TemplateBinding() {} + + /** + * Retrieve the Template that was previously bound to the binding. + * + * @return The Template that was previously bound with {@link #bind}. + * @throws RendererException if no Template was bound yet. + */ + public T get() { + if (template == null) { + throw new RendererException("Cannot 'get' before 'bind'."); + } + return template; + } + + /** + * Binds a Template for future reference using {@link #get}. + * + * @param template The Template to be bound. + * @throws RendererException if a Template was already bound. + */ + public void bind(T template) { + if (this.template != null) { + throw new RendererException("Duplicate 'bind' not allowed."); + } + this.template = template; + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBody.java b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBody.java new file mode 100644 index 00000000000..440766b3f79 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateBody.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.List; + +/** + * A Template generates a {@link TemplateBody}, which is a list of {@link Token}s, + * which are then later rendered to {@link String}s. + * + * @param tokens The list of {@link Token}s that are later rendered to {@link String}s. + */ +public record TemplateBody(List tokens) {} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/TemplateFrame.java b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateFrame.java new file mode 100644 index 00000000000..cf8c4afb321 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateFrame.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.HashMap; +import java.util.Map; + +/** + * The {@link TemplateFrame} is the frame for a {@link Template}, i.e. the corresponding + * {@link TemplateToken}. It ensures that each template use has its own unique {@link #id} + * used to deconflict names using {@link Template#$}. It also has a set of hashtag + * replacements, which combine the key-value pairs from the template argument and the + * {@link Template#let} definitions. The {@link #parent} relationship provides a trace + * for the use chain of templates. The {@link #fuel} is reduced over this chain, to give + * a heuristic on how much time is spent on the code from the template corresponding to + * the frame, and to give a termination criterion to avoid nesting templates too deeply. + * + *

        + * See also {@link CodeFrame} for more explanations about the frames. + */ +class TemplateFrame { + final TemplateFrame parent; + private final int id; + private final Map hashtagReplacements = new HashMap<>(); + final float fuel; + private float fuelCost; + + public static TemplateFrame makeBase(int id, float fuel) { + return new TemplateFrame(null, id, fuel, 0.0f); + } + + public static TemplateFrame make(TemplateFrame parent, int id) { + return new TemplateFrame(parent, id, parent.fuel - parent.fuelCost, Template.DEFAULT_FUEL_COST); + } + + private TemplateFrame(TemplateFrame parent, int id, float fuel, float fuelCost) { + this.parent = parent; + this.id = id; + this.fuel = fuel; + this.fuelCost = fuelCost; + } + + public String $(String name) { + if (name == null) { + throw new RendererException("A '$' name should not be null."); + } + if (!Renderer.isValidHashtagOrDollarName(name)) { + throw new RendererException("Is not a valid '$' name: '" + name + "'."); + } + return name + "_" + id; + } + + void addHashtagReplacement(String key, String value) { + if (key == null) { + throw new RendererException("A hashtag replacement should not be null."); + } + if (!Renderer.isValidHashtagOrDollarName(key)) { + throw new RendererException("Is not a valid hashtag replacement name: '" + key + "'."); + } + if (hashtagReplacements.putIfAbsent(key, value) != null) { + throw new RendererException("Duplicate hashtag replacement for #" + key); + } + } + + String getHashtagReplacement(String key) { + if (!Renderer.isValidHashtagOrDollarName(key)) { + throw new RendererException("Is not a valid hashtag replacement name: '" + key + "'."); + } + if (hashtagReplacements.containsKey(key)) { + return hashtagReplacements.get(key); + } + throw new RendererException("Missing hashtag replacement for #" + key); + } + + void setFuelCost(float fuelCost) { + this.fuelCost = fuelCost; + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/TemplateToken.java b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateToken.java new file mode 100644 index 00000000000..47262f152d4 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/TemplateToken.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +/** + * Represents a tokenized {@link Template} (after calling {@code asToken()}) ready for + * instantiation either as a {@link Token} inside another {@link Template} or as + * a {@link String} with {@link #render}. + */ +public sealed abstract class TemplateToken implements Token + permits TemplateToken.ZeroArgs, + TemplateToken.OneArg, + TemplateToken.TwoArgs, + TemplateToken.ThreeArgs +{ + private TemplateToken() {} + + /** + * Represents a tokenized zero-argument {@link Template} ready for instantiation + * either as a {@link Token} inside another {@link Template} or as a {@link String} + * with {@link #render}. + */ + static final class ZeroArgs extends TemplateToken implements Token { + private final Template.ZeroArgs zeroArgs; + + ZeroArgs(Template.ZeroArgs zeroArgs) { + this.zeroArgs = zeroArgs; + } + + @Override + public TemplateBody instantiate() { + return zeroArgs.instantiate(); + } + + @Override + public void visitArguments(ArgumentVisitor visitor) {} + } + + /** + * Represents a tokenized one-argument {@link Template}, already filled with arguments, ready for + * instantiation either as a {@link Token} inside another {@link Template} or as a {@link String} + * with {@link #render}. + * + * @param The type of the (first) argument. + */ + static final class OneArg extends TemplateToken implements Token { + private final Template.OneArg oneArgs; + private final T1 arg1; + + OneArg(Template.OneArg oneArgs, T1 arg1) { + this.oneArgs = oneArgs; + this.arg1 = arg1; + } + + @Override + public TemplateBody instantiate() { + return oneArgs.instantiate(arg1); + } + + @Override + public void visitArguments(ArgumentVisitor visitor) { + visitor.visit(oneArgs.arg1Name(), arg1); + } + } + + /** + * Represents a tokenized two-argument {@link Template}, already filled with arguments, ready for + * instantiation either as a {@link Token} inside another {@link Template} or as a {@link String} + * with {@link #render}. + * + * @param The type of the first argument. + * @param The type of the second argument. + */ + static final class TwoArgs extends TemplateToken implements Token { + private final Template.TwoArgs twoArgs; + private final T1 arg1; + private final T2 arg2; + + TwoArgs(Template.TwoArgs twoArgs, T1 arg1, T2 arg2) { + this.twoArgs = twoArgs; + this.arg1 = arg1; + this.arg2 = arg2; + } + + @Override + public TemplateBody instantiate() { + return twoArgs.instantiate(arg1, arg2); + } + + @Override + public void visitArguments(ArgumentVisitor visitor) { + visitor.visit(twoArgs.arg1Name(), arg1); + visitor.visit(twoArgs.arg2Name(), arg2); + } + } + + /** + * Represents a tokenized three-argument {@link TemplateToken}, already filled with arguments, ready for + * instantiation either as a {@link Token} inside another {@link Template} or as a {@link String} + * with {@link #render}. + * + * @param The type of the first argument. + * @param The type of the second argument. + * @param The type of the second argument. + */ + static final class ThreeArgs extends TemplateToken implements Token { + private final Template.ThreeArgs threeArgs; + private final T1 arg1; + private final T2 arg2; + private final T3 arg3; + + ThreeArgs(Template.ThreeArgs threeArgs, T1 arg1, T2 arg2, T3 arg3) { + this.threeArgs = threeArgs; + this.arg1 = arg1; + this.arg2 = arg2; + this.arg3 = arg3; + } + + @Override + public TemplateBody instantiate() { + return threeArgs.instantiate(arg1, arg2, arg3); + } + + @Override + public void visitArguments(ArgumentVisitor visitor) { + visitor.visit(threeArgs.arg1Name(), arg1); + visitor.visit(threeArgs.arg2Name(), arg2); + visitor.visit(threeArgs.arg3Name(), arg3); + } + } + + abstract TemplateBody instantiate(); + + @FunctionalInterface + interface ArgumentVisitor { + void visit(String name, Object value); + } + + abstract void visitArguments(ArgumentVisitor visitor); + + final String render() { + return Renderer.render(this); + } + + final String render(float fuel) { + return Renderer.render(this, fuel); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/Token.java b/test/hotspot/jtreg/compiler/lib/template_framework/Token.java new file mode 100644 index 00000000000..dc750c7f79f --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/Token.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; + +/** + * The {@link Template#body} and {@link Hook#anchor} are given a list of tokens, which are either + * {@link Token}s or {@link String}s or some permitted boxed primitives. These are then parsed + * and all non-{@link Token}s are converted to {@link StringToken}s. The parsing also flattens + * {@link List}s. + */ +sealed interface Token permits StringToken, + TemplateToken, + TemplateToken.ZeroArgs, + TemplateToken.OneArg, + TemplateToken.TwoArgs, + TemplateToken.ThreeArgs, + HookAnchorToken, + HookInsertToken, + AddNameToken, + NothingToken +{ + static List parse(Object[] objects) { + if (objects == null) { + throw new IllegalArgumentException("Unexpected tokens: null"); + } + List outputList = new ArrayList<>(); + parseToken(Arrays.asList(objects), outputList); + return outputList; + } + + private static void parseList(List inputList, List outputList) { + for (Object o : inputList) { + parseToken(o, outputList); + } + } + + private static void parseToken(Object o, List outputList) { + if (o == null) { + throw new IllegalArgumentException("Unexpected token: null"); + } + switch (o) { + case Token t -> outputList.add(t); + case String s -> outputList.add(new StringToken(Renderer.format(s))); + case Integer s -> outputList.add(new StringToken(Renderer.format(s))); + case Long s -> outputList.add(new StringToken(Renderer.format(s))); + case Double s -> outputList.add(new StringToken(Renderer.format(s))); + case Float s -> outputList.add(new StringToken(Renderer.format(s))); + case Boolean s -> outputList.add(new StringToken(Renderer.format(s))); + case List l -> parseList(l, outputList); + default -> throw new IllegalArgumentException("Unexpected token: " + o); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/Hooks.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/Hooks.java new file mode 100644 index 00000000000..410b790e3b5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/Hooks.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.lib.template_framework.library; + +import compiler.lib.template_framework.Hook; + +/** + * Provides a hook for class and method scopes, to be used in Templates. + */ +public final class Hooks { + private Hooks() {} // Avoid instantiation and need for documentation. + + /** + * Template {@link Hook} used by the Template Library for class scopes, to insert + * fields and methods. + */ + public static final Hook CLASS_HOOK = new Hook("Class"); + + /** + * Template {@link Hook} used by the Template Library for method scopes, to insert + * local variables, and computations for local variables at the beginning of a + * method. + */ + public static final Hook METHOD_HOOK = new Hook("Method"); +} diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestAdvanced.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestAdvanced.java new file mode 100644 index 00000000000..c5a4528f63d --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestAdvanced.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344942 + * @summary Test simple use of Templates with the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @compile ../../../compiler/lib/ir_framework/TestFramework.java + * @compile ../../../compiler/lib/verify/Verify.java + * @run main template_framework.examples.TestAdvanced + */ + +package template_framework.examples; + +import java.util.List; +import jdk.test.lib.Utils; + +import compiler.lib.generators.Generator; +import compiler.lib.generators.Generators; +import compiler.lib.generators.RestrictableGenerator; + +import compiler.lib.compile_framework.*; +import compiler.lib.template_framework.Template; +import static compiler.lib.template_framework.Template.body; +import static compiler.lib.template_framework.Template.let; + +/** + * This is a basic example for Templates, using them to cover a list of test variants. + *

        + * The "@compile" command for JTREG is required so that the frameworks used in the Template code + * are compiled and available for the Test-VM. + *

        + * Additionally, we must set the classpath for the Test-VM, so that it has access to all compiled + * classes (see {@link CompileFramework#getEscapedClassPathOfCompiledClasses}). + */ +public class TestAdvanced { + public static final RestrictableGenerator GEN_BYTE = Generators.G.safeRestrict(Generators.G.ints(), Byte.MIN_VALUE, Byte.MAX_VALUE); + public static final RestrictableGenerator GEN_CHAR = Generators.G.safeRestrict(Generators.G.ints(), Character.MIN_VALUE, Character.MAX_VALUE); + public static final RestrictableGenerator GEN_SHORT = Generators.G.safeRestrict(Generators.G.ints(), Short.MIN_VALUE, Short.MAX_VALUE); + public static final RestrictableGenerator GEN_INT = Generators.G.ints(); + public static final RestrictableGenerator GEN_LONG = Generators.G.longs(); + public static final Generator GEN_FLOAT = Generators.G.floats(); + public static final Generator GEN_DOUBLE = Generators.G.doubles(); + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("p.xyz.InnerTest", generate(comp)); + + // Compile the source file. + comp.compile(); + + // Object ret = p.xyz.InnerTest.main(); + comp.invoke("p.xyz.InnerTest", "main", new Object[] {}); + } + + interface MyGenerator { + Object next(); + } + + record Type(String name, MyGenerator generator, List operators) {} + + // Generate a source Java file as String + public static String generate(CompileFramework comp) { + + // The test template: + // - For a chosen type, operator, and generator. + // - The variable name "GOLD" and the test name "test" would get conflicts + // if we instantiate the template multiple times. Thus, we use the $ prefix + // so that the Template Framework can replace the names and make them unique + // for each Template instantiation. + // - The GOLD value is computed at the beginning, hopefully by the interpreter. + // - The test method is eventually compiled, and the values are verified by the + // check method. + var testTemplate = Template.make("typeName", "operator", "generator", (String typeName, String operator, MyGenerator generator) -> body( + let("con1", generator.next()), + let("con2", generator.next()), + """ + // #typeName #operator #con1 #con2 + public static #typeName $GOLD = $test(); + + @Test + public static #typeName $test() { + return (#typeName)(#con1 #operator #con2); + } + + @Check(test = "$test") + public static void $check(#typeName result) { + Verify.checkEQ(result, $GOLD); + } + """ + )); + + // Template for the Class. + var classTemplate = Template.make("types", (List types) -> body( + let("classpath", comp.getEscapedClassPathOfCompiledClasses()), + """ + package p.xyz; + + import compiler.lib.ir_framework.*; + import compiler.lib.verify.*; + + public class InnerTest { + public static void main() { + TestFramework framework = new TestFramework(InnerTest.class); + // Set the classpath, so that the TestFramework test VM knows where + // the CompileFramework put the class files of the compiled source code. + framework.addFlags("-classpath", "#classpath"); + framework.start(); + } + + """, + // Call the testTemplate for each type and operator, generating a + // list of lists of TemplateToken: + types.stream().map((Type type) -> + type.operators().stream().map((String operator) -> + testTemplate.asToken(type.name(), operator, type.generator())).toList() + ).toList(), + """ + } + """ + )); + + // For each type, we choose a list of operators that do not throw exceptions. + List types = List.of( + new Type("byte", GEN_BYTE::next, List.of("+", "-", "*", "&", "|", "^")), + new Type("char", GEN_CHAR::next, List.of("+", "-", "*", "&", "|", "^")), + new Type("short", GEN_SHORT::next, List.of("+", "-", "*", "&", "|", "^")), + new Type("int", GEN_INT::next, List.of("+", "-", "*", "&", "|", "^")), + new Type("long", GEN_LONG::next, List.of("+", "-", "*", "&", "|", "^")), + new Type("float", GEN_FLOAT::next, List.of("+", "-", "*", "/")), + new Type("double", GEN_DOUBLE::next, List.of("+", "-", "*", "/")) + ); + + // Use the template with one argument and render it to a String. + return classTemplate.render(types); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestSimple.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestSimple.java new file mode 100644 index 00000000000..e06671ca951 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestSimple.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344942 + * @summary Test simple use of Templates with the Compile Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run main template_framework.examples.TestSimple + */ + +package template_framework.examples; + +import compiler.lib.compile_framework.*; +import compiler.lib.template_framework.Template; +import static compiler.lib.template_framework.Template.body; + +public class TestSimple { + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add a java source file. + comp.addJavaSourceCode("p.xyz.InnerTest", generate()); + + // Compile the source file. + comp.compile(); + + // Object ret = p.xyz.InnerTest.test(); + Object ret = comp.invoke("p.xyz.InnerTest", "test", new Object[] {}); + System.out.println("res: " + ret); + + // Check that the return value is the sum of the two arguments. + if ((42 + 7) != (int)ret) { + throw new RuntimeException("Unexpected result"); + } + } + + // Generate a source Java file as String + public static String generate() { + // Create a Template with two arguments. + var template = Template.make("arg1", "arg2", (Integer arg1, String arg2) -> body( + """ + package p.xyz; + public class InnerTest { + public static int test() { + return #arg1 + #arg2; + } + } + """ + )); + + // Use the template with two arguments, and render it to a String. + return template.render(42, "7"); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestTutorial.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestTutorial.java new file mode 100644 index 00000000000..faa05b29d82 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestTutorial.java @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344942 + * @summary Demonstrate the use of Templates with the Compile Framework. + * It displays the use of most features in the Template Framework. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run main template_framework.examples.TestTutorial + */ + +package template_framework.examples; + +import java.util.Collections; +import java.util.List; + +import compiler.lib.compile_framework.*; + +import compiler.lib.template_framework.Template; +import compiler.lib.template_framework.Hook; +import compiler.lib.template_framework.TemplateBinding; +import compiler.lib.template_framework.DataName; +import compiler.lib.template_framework.StructuralName; +import static compiler.lib.template_framework.Template.body; +import static compiler.lib.template_framework.Template.let; +import static compiler.lib.template_framework.Template.$; +import static compiler.lib.template_framework.Template.fuel; +import static compiler.lib.template_framework.Template.addDataName; +import static compiler.lib.template_framework.Template.dataNames; +import static compiler.lib.template_framework.Template.addStructuralName; +import static compiler.lib.template_framework.Template.structuralNames; +import static compiler.lib.template_framework.DataName.Mutability.MUTABLE; +import static compiler.lib.template_framework.DataName.Mutability.IMMUTABLE; +import static compiler.lib.template_framework.DataName.Mutability.MUTABLE_OR_IMMUTABLE; + +import compiler.lib.template_framework.library.Hooks; + +public class TestTutorial { + + public static void main(String[] args) { + // Create a new CompileFramework instance. + CompileFramework comp = new CompileFramework(); + + // Add Java source files. + comp.addJavaSourceCode("p.xyz.InnerTest1", generateWithListOfTokens()); + comp.addJavaSourceCode("p.xyz.InnerTest2", generateWithTemplateArguments()); + comp.addJavaSourceCode("p.xyz.InnerTest3", generateWithHashtagAndDollarReplacements()); + comp.addJavaSourceCode("p.xyz.InnerTest3b", generateWithHashtagAndDollarReplacements2()); + comp.addJavaSourceCode("p.xyz.InnerTest4", generateWithCustomHooks()); + comp.addJavaSourceCode("p.xyz.InnerTest5", generateWithLibraryHooks()); + comp.addJavaSourceCode("p.xyz.InnerTest6", generateWithRecursionAndBindingsAndFuel()); + comp.addJavaSourceCode("p.xyz.InnerTest7", generateWithDataNamesSimple()); + comp.addJavaSourceCode("p.xyz.InnerTest8", generateWithDataNamesForFieldsAndVariables()); + comp.addJavaSourceCode("p.xyz.InnerTest9a", generateWithDataNamesAndScopes1()); + comp.addJavaSourceCode("p.xyz.InnerTest9b", generateWithDataNamesAndScopes2()); + comp.addJavaSourceCode("p.xyz.InnerTest10", generateWithDataNamesForFuzzing()); + comp.addJavaSourceCode("p.xyz.InnerTest11", generateWithStructuralNamesForMethods()); + + // Compile the source files. + // Hint: if you want to see the generated source code, you can enable + // printing of the source code that the CompileFramework receives, + // with -DCompileFrameworkVerbose=true + // The code may not be nicely formatted, especially regarding + // indentation. You might consider dumping the generated code + // into an IDE or other auto-formatting tool. + comp.compile(); + + comp.invoke("p.xyz.InnerTest1", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest2", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest3", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest3b", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest4", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest5", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest6", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest7", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest8", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest9a", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest9b", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest10", "main", new Object[] {}); + comp.invoke("p.xyz.InnerTest11", "main", new Object[] {}); + } + + // This example shows the use of various Tokens. + public static String generateWithListOfTokens() { + // A Template is essentially a function / lambda that produces a + // token body, which is a list of Tokens that are concatenated. + var templateClass = Template.make(() -> body( + // The "body" method is filled by a sequence of "Tokens". + // These can be Strings and multi-line Strings, but also + // boxed primitives. + """ + package p.xyz; + + public class InnerTest1 { + public static void main() { + System.out.println("Hello World!"); + """, + "int a = ", 1, ";\n", + "float b = ", 1.5f, ";\n", + // Special Float values are "smartly" formatted! + "float nan = ", Float.POSITIVE_INFINITY, ";\n", + "boolean c = ", true, ";\n", + // Lists of Tokens are also allowed: + List.of("int ", "d = 5", ";\n"), + // We can also stream / map over an existing list, or one created on + // the fly: + List.of(3, 5, 7, 11).stream().map(i -> "System.out.println(" + i + ");\n").toList(), + """ + System.out.println(a + " " + b + " " + nan + " " + c + " " + d); + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // This example shows the use of Templates, with and without arguments. + public static String generateWithTemplateArguments() { + // A Template with no arguments. + var templateHello = Template.make(() -> body( + """ + System.out.println("Hello"); + """ + )); + + // A Template with a single Integer argument. + var templateCompare = Template.make("arg", (Integer arg) -> body( + "System.out.println(", arg, ");\n", // capture arg via lambda argument + "System.out.println(#arg);\n", // capture arg via hashtag replacement + "System.out.println(#{arg});\n", // capture arg via hashtag replacement with brackets + // It would have been optimal to use Java String Templates to format + // argument values into Strings. However, since these are not (yet) + // available, the Template Framework provides two alternative ways of + // formatting Strings: + // 1) By appending to the comma-separated list of Tokens passed to body(). + // Appending as a Token works whenever one has a reference to the Object + // in Java code. But often, this is rather cumbersome and looks awkward, + // given all the additional quotes and commands required. Hence, it + // is encouraged to only use this method when necessary. + // 2) By hashtag replacements inside a single string. One can either + // use "#arg" directly, or use brackets "#{arg}". When possible, one + // should prefer avoiding the brackets, as they create additional + // noise. However, there are cases where they are useful, for + // example "#TYPE_CON" would be parsed as a hashtag replacement + // for the hashtag name "TYPE_CON", whereas "#{TYPE}_CON" is + // parsed as hashtag name "TYPE", followed by literal string "_CON". + // See also: generateWithHashtagAndDollarReplacements2 + // There are two ways to define the value of a hashtag replacement: + // a) Capturing Template arguments as Strings. + // b) Using a "let" definition (see examples further down). + // Which one should be preferred is a code style question. Generally, we + // prefer the use of hashtag replacements because that allows easy use of + // multiline strings (i.e. text blocks). + "if (#arg != ", arg, ") { throw new RuntimeException(\"mismatch\"); }\n" + )); + + // A Template that creates the body of the Class and main method, and then + // uses the two Templates above inside it. + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest2 { + public static void main() { + """, + templateHello.asToken(), + templateCompare.asToken(7), + templateCompare.asToken(42), + """ + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // Example with hashtag replacements (arguments and let), and $-name renamings. + // Note: hashtag replacements are a workaround for the missing string templates. + // If we had string templates, we could just capture the typed lambda + // arguments, and use them directly in the String via string templating. + public static String generateWithHashtagAndDollarReplacements() { + var template1 = Template.make("x", (Integer x) -> body( + // We have the "#x" hashtag replacement from the argument capture above. + // Additionally, we can define "#con" as a hashtag replacement from let: + let("con", 3 * x), + // In the code below, we use "var" as a local variable. But if we were + // to instantiate this template twice, the names could conflict. Hence, + // we automatically rename the names that have a $ prepended with + // var_1, var_2, etc. + """ + int $var = #con; + System.out.println("T1: #x, #con, " + $var); + """ + )); + + var template2 = Template.make("x", (Integer x) -> + // Sometimes it can be helpful to not just create a hashtag replacement + // with let, but also to capture the variable to use it as lambda parameter. + let("y", 11 * x, y -> + body( + """ + System.out.println("T2: #x, #y"); + """, + template1.asToken(y) + ) + ) + ); + + // This template generates an int variable and assigns it a value. + // Together with template4, we see that each template has a unique renaming + // for a $-name replacement. + var template3 = Template.make("name", "value", (String name, Integer value) -> body( + """ + int #name = #value; // Note: $var is not #name + """ + )); + + var template4 = Template.make(() -> body( + """ + // We will define the variable $var: + """, + // We can capture the $-name programmatically, and pass it to other templates: + template3.asToken($("var"), 42), + """ + if ($var != 42) { throw new RuntimeException("Wrong value!"); } + """ + )); + + var templateClass = Template.make(() -> body( + // The Template Framework API only guarantees that every Template use + // has a unique ID. When using the Templates, all we need is that + // variables from different Template uses do not conflict. But it can + // be helpful to understand how the IDs are produced. The implementation + // simply gives the first Template use the ID=1, and increments from there. + // + // In this example, the templateClass is the first Template use, and + // has ID=1. We never use a dollar replacement here, so the code will + // not show any "_1". + """ + package p.xyz; + + public class InnerTest3 { + public static void main() { + """, + // Second Template use: ID=2 -> var_2 + template1.asToken(1), + // Third Template use: ID=3 -> var_3 + template1.asToken(7), + // Fourth Template use with template2, no use of dollar, so + // no "_4" shows up in the generated code. Internally, it + // calls template1, which is the fifth Template use, with + // ID = 5 -> var_5 + template2.asToken(2), + // Sixth and Seventh Template use -> var_7 + template2.asToken(5), + // Eighth Template use with template4 -> var_8. + // Ninth Template use with internal call to template3, + // The local "$var" turns to "var_9", but the Template + // argument captured value = "var_8" from the outer + // template use of $("var"). + template4.asToken(), + """ + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // In some cases, you may want to transform string arguments. You may + // be working with types "int" and "long", and want to create names like + // "INT_CON" and "LONG_CON". + public static String generateWithHashtagAndDollarReplacements2() { + // Let us define some final static variables of a specific type. + var template1 = Template.make("type", (String type) -> body( + // The type (e.g. "int") is lower case, let us create the upper case "INT_CON" from it. + let("TYPE", type.toUpperCase()), + """ + static final #type #{TYPE}_CON = 42; + """ + )); + + // Let's write a simple class to demonstrate that this works, i.e. produces compilable code. + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest3b { + """, + template1.asToken("int"), + template1.asToken("long"), + """ + public static void main() { + if (INT_CON != 42 || LONG_CON != 42) { + throw new RuntimeException("Wrong result!"); + } + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // In this example, we look at the use of Hooks. They allow us to reach back, to outer + // scopes. For example, we can reach out from inside a method body to a hook anchored at + // the top of the class, and insert a field. + public static String generateWithCustomHooks() { + // We can define a custom hook. + // Note: generally we prefer using the pre-defined CLASS_HOOK and METHOD_HOOK from the library, + // whenever possible. See also the example after this one. + var myHook = new Hook("MyHook"); + + var template1 = Template.make("name", "value", (String name, Integer value) -> body( + """ + public static int #name = #value; + """ + )); + + var template2 = Template.make("x", (Integer x) -> body( + """ + // Let us go back to where we anchored the hook with anchor() and define a field named $field there. + // Note that in the Java code we have not defined anchor() on the hook, yet. But since it's a lambda + // expression, it is not evaluated, yet! Eventually, anchor() will be evaluated before insert() in + // this example. + """, + myHook.insert(template1.asToken($("field"), x)), + """ + System.out.println("$field: " + $field); + if ($field != #x) { throw new RuntimeException("Wrong value!"); } + """ + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest4 { + """, + // We anchor a Hook outside the main method, but inside the Class. + // Anchoring a Hook creates a scope, spanning the braces of the + // "anchor" call. Any Hook.insert that happens inside this scope + // goes to the top of that scope. + myHook.anchor( + // Any Hook.insert goes here. + // + // <-------- field_X = 5 ------------------+ + // <-------- field_Y = 7 -------------+ | + // | | + """ + public static void main() { + """, // ^ ^ + template2.asToken(5), // -------- | ---+ + template2.asToken(7), // ---------+ + """ + } + """ + ), // The Hook scope ends here. + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // We saw the use of custom hooks above, but now we look at the use of CLASS_HOOK and METHOD_HOOK. + // By convention, we use the CLASS_HOOK for class scopes, and METHOD_HOOK for method scopes. + // Whenever we open a class scope, we should anchor a CLASS_HOOK for that scope, and whenever we + // open a method, we should anchor a METHOD_HOOK. Conversely, this allows us to check if we are + // inside a class or method scope by querying "isAnchored". This convention helps us when building + // a large library of Templates. But if you are writing your own self-contained set of Templates, + // you do not have to follow this convention. + // + // Hooks are "re-entrant", that is we can anchor the same hook inside a scope that we already + // anchored it previously. The "Hook.insert" always goes to the innermost anchoring of that + // hook. There are cases where "re-entrant" Hooks are helpful such as nested classes, where + // there is a class scope inside another class scope. Similarly, we can nest lambda bodies + // inside method bodies, so also METHOD_HOOK can be used in such a "re-entrant" way. + public static String generateWithLibraryHooks() { + var templateStaticField = Template.make("name", "value", (String name, Integer value) -> body( + """ + static { System.out.println("Defining static field #name"); } + public static int #name = #value; + """ + )); + + var templateLocalVariable = Template.make("name", "value", (String name, Integer value) -> body( + """ + System.out.println("Defining local variable #name"); + int #name = #value; + """ + )); + + var templateMethodBody = Template.make(() -> body( + """ + // Let's define a local variable $var and a static field $field. + """, + Hooks.CLASS_HOOK.insert(templateStaticField.asToken($("field"), 5)), + Hooks.METHOD_HOOK.insert(templateLocalVariable.asToken($("var"), 11)), + """ + System.out.println("$field: " + $field); + System.out.println("$var: " + $var); + if ($field * $var != 55) { throw new RuntimeException("Wrong value!"); } + """ + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest5 { + """, + // Class Hook for fields. + Hooks.CLASS_HOOK.anchor( + """ + public static void main() { + """, + // Method Hook for local variables, and earlier computations. + Hooks.METHOD_HOOK.anchor( + """ + // This is the beginning of the "main" method body. + System.out.println("Welcome to main!"); + """, + templateMethodBody.asToken(), + """ + System.out.println("Going to call other..."); + other(); + """ + ), + """ + } + + private static void other() { + """, + // Have a separate method hook for other, so that it can insert + // its own local variables. + Hooks.METHOD_HOOK.anchor( + """ + System.out.println("Welcome to other!"); + """, + templateMethodBody.asToken(), + """ + System.out.println("Done with other."); + """ + ), + """ + } + """ + ), + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // This example shows the use of bindings to allow cyclic references of Templates, + // allowing recursive template generation. We also show the use of fuel to limit + // recursion. + public static String generateWithRecursionAndBindingsAndFuel() { + // Binding allows the use of template1 inside of template1, via the binding indirection. + var binding1 = new TemplateBinding>(); + var template1 = Template.make("depth", (Integer depth) -> body( + let("fuel", fuel()), + """ + System.out.println("At depth #depth with fuel #fuel."); + """, + // We cannot yet use template1 directly, as it is being defined. + // So we use binding1 instead. + // For every recursion depth, some fuel is automatically subtracted + // so that the fuel slowly depletes with the depth. + // We keep the recursion going until the fuel is depleted. + // + // Note: if we forget to check the fuel(), the renderer causes a + // StackOverflowException, because the recursion never ends. + (fuel() > 0) ? binding1.get().asToken(depth + 1) + : "System.out.println(\"Fuel depleted.\");\n", + """ + System.out.println("Exit depth #depth."); + """ + )); + binding1.bind(template1); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest6 { + public static void main() { + System.out.println("Welcome to main!"); + """, + template1.asToken(0), + """ + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // Below, we introduce the concept of "DataNames". Code generation often involves defining + // fields and variables, which are then available inside a defined scope. "DataNames" can + // be registered at a certain scope with addDataName. This "DataName" is then available + // in this scope, and in any nested scope, including nested Templates. This allows us to + // add some fields and variables in one Template, and later on, in another Template, we + // can access these fields and variables again with "dataNames()". + // + // Here are a few use-cases: + // - You are writing some inner Template, and would like to access a random field or + // variable from an outer Template. Luckily, the outer Templates have added their + // fields and variables, and you can now access them with "dataNames()". You can + // count them, get a list of them, or sample a random one. + // - You are writing some outer Template, and would like to generate a variable that + // an inner Template could read from or even write to. You can "addDataName" the + // variable, and the inner Template can then find that variable in "dataNames()". + // If the inner Template wants to find a random field or variable, it may sample + // from "dataNodes()", and with some probability, it would sample your variable. + // + // A "DataName" captures the name of the field or variable in a String. It also + // stores the type of the field or variable, as well as its "mutability", i.e. + // an indication if the field or variable is only for reading, or if writing to + // it is also allowed. If a field or variable is final, we must make sure that the + // "DataName" is immutable, otherwise we risk that some Template attempts to generate + // code that writes to the final field or variable, and then we get a compilation + // error from "javac" later on. + // + // To get started, we show an example where all DataNames have the same type, and where + // all Names are mutable. For simplicity, our type represents the primitive int type. + private record MySimpleInt() implements DataName.Type { + // The type is only subtype of itself. This is relevant when sampling or weighing + // DataNames, because we do not just sample from the given type, but also its subtypes. + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof MySimpleInt(); + } + + // The name of the type can later be accessed, and used in code. We are working + // with ints, so that is what we return. + @Override + public String name() { return "int"; } + } + private static final MySimpleInt mySimpleInt = new MySimpleInt(); + + // In this example, we generate 3 fields, and add their names to the + // current scope. In a nested Template, we can then sample one of these + // DataNames, which gives us one of the fields. We increment that randomly + // chosen field. At the end, we print all three fields. + public static String generateWithDataNamesSimple() { + var templateMain = Template.make(() -> body( + // Sample a random DataName, i.e. field, and assign its name to + // the hashtag replacement "#f". + // We are picking a mutable DataName, because we are not just + // reading but also writing to the field. + let("f", dataNames(MUTABLE).exactOf(mySimpleInt).sample().name()), + """ + // Let us now sample a random field #f, and increment it. + #f += 42; + """ + )); + + var templateClass = Template.make(() -> body( + // Let us define the names for the three fields. + // We can then sample from these names in a nested Template. + // We make all DataNames mutable, and with the same weight of 1, + // so that they have equal probability of being sampled. + // Note: the default weight is 1, so we can also omit the weight. + addDataName($("f1"), mySimpleInt, MUTABLE, 1), + addDataName($("f2"), mySimpleInt, MUTABLE, 1), + addDataName($("f3"), mySimpleInt, MUTABLE), // omit weight, default is 1. + """ + package p.xyz; + + public class InnerTest7 { + // Let us define some fields. + public static int $f1 = 0; + public static int $f2 = 0; + public static int $f3 = 0; + + public static void main() { + // Let us now call the nested template that samples + // a random field and increments it. + """, + templateMain.asToken(), + """ + // Now, we can print all three fields, and see which + // one was incremented. + System.out.println("f1: " + $f1); + System.out.println("f2: " + $f2); + System.out.println("f3: " + $f3); + // We have two zeros, and one 42. + if ($f1 + $f2 + $f3 != 42) { throw new RuntimeException("wrong result!"); } + } + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // In the example above, we could have easily kept track of the three fields ourselves, + // and would not have had to rely on the Template Framework's DataNames for this. However, + // with more complicated examples, this gets more and more difficult, if not impossible. + // + // In the example below, we make the scenario a little more realistic. We work with an + // int and a long type. In the main method, we add some fields and local variables, and + // register their DataNames. When sampling from the main method, we should be able to see + // both fields and variables that we just registered. But from another method, we should + // only see the fields, but the local variables from main should not be sampled. + // + // Let us now define the wrapper for primitive types such as int and long. + private record MyPrimitive(String name) implements DataName.Type { + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof MyPrimitive(String n) && n.equals(name()); + } + + // Note: the name method is automatically overridden by the record + // field accessor. + // But we would like to also directly use the type in the templates, + // hence we let "toString" return "int" or "long". + @Override + public String toString() { return name(); } + } + private static final MyPrimitive myInt = new MyPrimitive("int"); + private static final MyPrimitive myLong = new MyPrimitive("long"); + + public static String generateWithDataNamesForFieldsAndVariables() { + // Define a static field. + var templateStaticField = Template.make("type", (DataName.Type type) -> body( + addDataName($("field"), type, MUTABLE), + // Note: since we have overridden MyPrimitive::toString, we can use + // the type directly as "#type" in the template, which then + // gets hashtag replaced with "int" or "long". + """ + public static #type $field = 0; + """ + )); + + // Define a local variable. + var templateLocalVariable = Template.make("type", (DataName.Type type) -> body( + addDataName($("var"), type, MUTABLE), + """ + #type $var = 0; + """ + )); + + // Sample a random field or variable, from those that are available at + // the current scope. + var templateSample = Template.make("type", (DataName.Type type) -> body( + let("name", dataNames(MUTABLE).exactOf(type).sample().name()), + // Note: we could also sample from MUTABLE_OR_IMMUTABLE, we will + // cover the concept of mutability in an example further down. + """ + System.out.println("Sampling type #type: #name = " + #name); + """ + )); + + // Check how many fields and variables are available at the current scope. + var templateStatus = Template.make(() -> body( + let("ints", dataNames(MUTABLE).exactOf(myInt).count()), + let("longs", dataNames(MUTABLE).exactOf(myLong).count()), + // Note: we could also count the MUTABLE_OR_IMMUTABLE, we will + // cover the concept of mutability in an example further down. + """ + System.out.println("Status: #ints ints, #longs longs."); + """ + )); + + // Definition of the main method body. + var templateMain = Template.make(() -> body( + """ + System.out.println("Starting inside main..."); + """, + // Check the initial status, there should be nothing available. + templateStatus.asToken(), + // Define some local variables. We place them at the beginning of + // the method, by using the METHOD_HOOK. + Hooks.METHOD_HOOK.insert(templateLocalVariable.asToken(myInt)), + Hooks.METHOD_HOOK.insert(templateLocalVariable.asToken(myLong)), + // Define some static fields. We place them at the top of the class, + // by using the CLASS_HOOK. + Hooks.CLASS_HOOK.insert(templateStaticField.asToken(myInt)), + Hooks.CLASS_HOOK.insert(templateStaticField.asToken(myLong)), + // If we check the status now, we should see two int and two + // long names, corresponding to our two fields and variables. + templateStatus.asToken(), + // Now, we sample 5 int and 5 long names. We should get a mix + // of fields and variables. We have access to the fields because + // we inserted them to the class scope. We have access to the + // variables because we inserted them to the current method + // body. + Collections.nCopies(5, templateSample.asToken(myInt)), + Collections.nCopies(5, templateSample.asToken(myLong)), + // The status should not have changed since we last checked. + templateStatus.asToken(), + """ + System.out.println("Finishing inside main."); + """ + )); + + // Definition of another method's body. It is in the same class + // as the main method, so it has access to the same static fields. + var templateOther = Template.make(() -> body( + """ + System.out.println("Starting inside other..."); + """, + // We should see the fields defined in the main body, + // one int and one long field. + templateStatus.asToken(), + // Sampling 5 random int and 5 random long DataNames. We should + // only see the fields, and not the local variables from main. + Collections.nCopies(5, templateSample.asToken(myInt)), + Collections.nCopies(5, templateSample.asToken(myLong)), + // The status should not have changed since we last checked. + templateStatus.asToken(), + """ + System.out.println("Finishing inside other."); + """ + )); + + // Finally, we put it all together in a class. + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest8 { + """, + // Class Hook for fields. + Hooks.CLASS_HOOK.anchor( + """ + public static void main() { + """, + // Method Hook for local variables. + Hooks.METHOD_HOOK.anchor( + """ + // This is the beginning of the "main" method body. + System.out.println("Welcome to main!"); + """, + templateMain.asToken(), + """ + System.out.println("Going to call other..."); + other(); + """ + ), + """ + } + + private static void other() { + """, + // Have a separate method hook for other, where it could insert + // its own local variables (but happens not to). + Hooks.METHOD_HOOK.anchor( + """ + System.out.println("Welcome to other!"); + """, + templateOther.asToken(), + """ + System.out.println("Done with other."); + """ + ), + """ + } + """ + ), + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // Let us have a closer look at how DataNames interact with scopes created by + // Templates and Hooks. Additionally, we see how the execution order of the + // lambdas and token evaluation affects the availability of DataNames. + // + // We inject the results directly into verification inside the code, so it + // is relatively simple to see what the expected results are. + // + // For simplicity, we define a simple "list" function. It collects all + // field and variable names, and immediately returns the comma separated + // list of the names. We can use that to visualize the available names + // at any point. + public static String listNames() { + return "{" + String.join(", ", dataNames(MUTABLE).exactOf(myInt).toList() + .stream().map(DataName::name).toList()) + "}"; + } + + // Even simpler: count the available variables and return the count immediately. + public static int countNames() { + return dataNames(MUTABLE).exactOf(myInt).count(); + } + + // Having defined these helper methods, let us start with the first example. + // You should start reading this example bottom-up, starting at + // templateClass, then going to templateMain and last to templateInner. + public static String generateWithDataNamesAndScopes1() { + + var templateInner = Template.make(() -> body( + // We just got called from the templateMain. All tokens from there + // are already evaluated, so "v1" is now available: + let("l1", listNames()), + """ + if (!"{v1}".equals("#l1")) { throw new RuntimeException("l1 should have been '{v1}' but was '#l1'"); } + """ + )); + + var templateMain = Template.make(() -> body( + // So far, no names were defined. We expect "c1" to be zero. + let("c1", countNames()), + """ + if (#c1 != 0) { throw new RuntimeException("c1 was not zero but #c1"); } + """, + // We now add a local variable "v1" to the scope of this templateMain. + // This only generates a token, and does not immediately add the name. + // The name is only added once we evaluate the tokens, and arrive at + // this particular token. + addDataName("v1", myInt, MUTABLE), + // We count again with "c2". The variable "v1" is at this point still + // in token form, hence it is not yet made available while executing + // the template lambda of templateMain. + let("c2", countNames()), + """ + if (#c2 != 0) { throw new RuntimeException("c2 was not zero but #c2"); } + """, + // But now we call an inner Template. This is added as a TemplateToken. + // This means it is not evaluated immediately, but only once we evaluate + // the tokens. By that time, all tokens from above are already evaluated + // and we see that "v1" is available. + templateInner.asToken() + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest9a { + """, + Hooks.CLASS_HOOK.anchor( + """ + public static void main() { + """, + Hooks.METHOD_HOOK.anchor( + templateMain.asToken() + ), + """ + } + """ + ), + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + // Now that we understand this simple example, we go to a more complicated one + // where we use Hook.insert. Just as above, you should read this example + // bottom-up, starting at templateClass. + public static String generateWithDataNamesAndScopes2() { + + var templateFields = Template.make(() -> body( + // We were just called from templateMain. But the code is not + // generated into the main scope, rather into the class scope + // out in templateClass. + // Let us now add a field "f1". + addDataName("f1", myInt, MUTABLE), + // And let's also generate the code for it. + """ + public static int f1 = 42; + """, + // But why is this DataName now available inside the scope of + // templateInner? Does that not mean that "f1" escapes this + // templateFields here? Yes it does! + // For normal template nesting, the names do not escape the + // scope of the nested template. But this here is no normal + // template nesting, rather it is an insertion into a Hook, + // and we treat those differently. We make the scope of the + // inserted templateFields transparent, so that any added + // DataNames are added to the scope of the Hook we just + // inserted into, i.e. the CLASS_HOOK. This is very important, + // if we did not make that scope transparent, we could not + // add any DataNames to the class scope anymore, and we could + // not add any fields that would be available in the class + // scope. + Hooks.METHOD_HOOK.anchor( + // We now create a separate scope. This one is not the + // template scope from above, and it is not transparent. + // Hence, "f2" will not be available outside of this + // scope. + addDataName("f2", myInt, MUTABLE), + // And let's also generate the code for it. + """ + public static int f2 = 666; + """ + // Similarly, if we called any nested Template here, + // and added DataNames inside, this would happen inside + // nested scopes that are not transparent. If one wanted + // to add names to the CLASS_HOOK from there, one would + // have to do another Hook.insert, and make sure that + // the names are added from the outermost scope of that + // inserted Template, because only that outermost scope + // is transparent to the CLASS_HOOK. + ) + )); + + var templateInner = Template.make(() -> body( + // We just got called from the templateMain. All tokens from there + // are already evaluated, so there should be some fields available. + // We can see field "f1". + let("l1", listNames()), + """ + if (!"{f1}".equals("#l1")) { throw new RuntimeException("l1 should have been '{f1}' but was '#l1'"); } + """ + // Now go and have a look at templateFields, to understand how that + // field was added, and why not any others. + )); + + var templateMain = Template.make(() -> body( + // So far, no names were defined. We expect "c1" to be zero. + let("c1", countNames()), + """ + if (#c1 != 0) { throw new RuntimeException("c1 was not zero but #c1"); } + """, + // We would now like to add some fields to the class scope, out in the + // templateClass. This creates a token, which is only evaluated after + // the completion of the templateMain lambda. Before you go and look + // at templateFields, just assume that it does add some fields, and + // continue reading in templateMain. + Hooks.CLASS_HOOK.insert(templateFields.asToken()), + // We count again with "c2". The fields we wanted to add above are not + // yet available, because the token is not yet evaluated. Hence, we + // still only count zero names. + let("c2", countNames()), + """ + if (#c2 != 0) { throw new RuntimeException("c2 was not zero but #c2"); } + """, + // Now we call an inner Template. This also creates a token, and so it + // is not evaluated immediately. And by the time this token is evaluated + // the tokens from above are already evaluated, and so the fields should + // be available. Go have a look at templateInner now. + templateInner.asToken() + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest9b { + """, + Hooks.CLASS_HOOK.anchor( + """ + public static void main() { + """, + Hooks.METHOD_HOOK.anchor( + templateMain.asToken() + ), + """ + } + """ + ), + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + } + + + // There are two more concepts to understand more deeply with DataNames. + // + // One is the use of mutable and immutable DataNames. + // In some cases, we only want to sample DataNames that are mutable, because + // we want to store to a field or variable. We have to make sure that we + // do not generate code that tries to store to a final field or variable. + // In other cases, we only want to load, and we do not care if the + // fields or variables are final or non-final. + // + // Another concept is subtyping of DataName Types. With primitive types, this + // is irrelevant, but with instances of Objects, this becomes relevant. + // We may want to load an object of any field or variable of a certain + // class, or any subclass. When a value is of a given class, we can only + // store it to fields and variables of that class or any superclass. + // + // Let us look at an example that demonstrates these two concepts. + // + // First, we define a DataName Type that represents different classes, that + // may or may not be in a subtype relation. Subtypes start with the name + // of the super type. + private record MyClass(String name) implements DataName.Type { + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof MyClass(String n) && name().startsWith(n); + } + + @Override + public String toString() { return name(); } + } + private static final MyClass myClassA = new MyClass("MyClassA"); + private static final MyClass myClassA1 = new MyClass("MyClassA1"); + private static final MyClass myClassA2 = new MyClass("MyClassA2"); + private static final MyClass myClassA11 = new MyClass("MyClassA11"); + private static final MyClass myClassB = new MyClass("MyClassB"); + private static final List myClassList = List.of(myClassA, myClassA1, myClassA2, myClassA11, myClassB); + + public static String generateWithDataNamesForFuzzing() { + var templateStaticField = Template.make("type", "mutable", (DataName.Type type, Boolean mutable) -> body( + addDataName($("field"), type, mutable ? MUTABLE : IMMUTABLE), + let("isFinal", mutable ? "" : "final"), + """ + public static #isFinal #type $field = new #type(); + """ + )); + + var templateLoad = Template.make("type", (DataName.Type type) -> body( + // We only load from the field, so we do not need a mutable one, + // we can load from final and non-final fields. + // We want to find any field from which we can read the value and store + // it in our variable v of our given type. Hence, we can take a field + // of the given type or any subtype thereof. + let("field", dataNames(MUTABLE_OR_IMMUTABLE).subtypeOf(type).sample().name()), + """ + #type $v = #field; + System.out.println("#field: " + $v); + """ + )); + + var templateStore = Template.make("type", (DataName.Type type) -> body( + // We are storing to a field, so it better be non-final, i.e. mutable. + // We want to store a new instance of our given type to a field. This + // field must be of the given type or any supertype. + let("field", dataNames(MUTABLE).supertypeOf(type).sample().name()), + """ + #field = new #type(); + """ + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest10 { + // First, we define our classes. + public static class MyClassA {} + public static class MyClassA1 extends MyClassA {} + public static class MyClassA2 extends MyClassA {} + public static class MyClassA11 extends MyClassA1 {} + public static class MyClassB {} + + // Now, we define a list of static fields. Some of them are final, others not. + """, + // We must create a CLASS_HOOK and insert the fields to it. Otherwise, + // addDataName is restricted to the scope of the templateStaticField. But + // with the insertion to CLASS_HOOK, the addDataName goes through the scope + // of the templateStaticField out to the scope of the CLASS_HOOK. + Hooks.CLASS_HOOK.anchor( + myClassList.stream().map(c -> + (Object)Hooks.CLASS_HOOK.insert(templateStaticField.asToken(c, true)) + ).toList(), + myClassList.stream().map(c -> + (Object)Hooks.CLASS_HOOK.insert(templateStaticField.asToken(c, false)) + ).toList(), + """ + + public static void main() { + // All fields are still in their initial state. + """, + myClassList.stream().map(templateLoad::asToken).toList(), + """ + // Now let us mutate some fields. + """, + myClassList.stream().map(templateStore::asToken).toList(), + """ + // And now some fields are different than before. + """, + myClassList.stream().map(templateLoad::asToken).toList(), + """ + } + """ + ), + """ + } + """ + )); + + // Render templateClass to String. + return templateClass.render(); + + } + + // "DataNames" are useful for modeling fields and variables. They hold data, + // and we can read and write to them, they may be mutable or immutable. + // We now introduce another set of "Names", the "StructuralNames". They are + // useful for modeling method names and class names, and possibly more. Anything + // that has a fixed name in the Java code, for which mutability is inapplicable. + // Some use-cases for "StructuralNames": + // - Method names. The Type could represent the signature of the static method + // or the class of the non-static method. + // - Class names. Type could represent the signature of the constructor, so + // that we could instantiate random instances. + // - try/catch blocks. If a specific Exception is caught in the scope, we could + // register that Exception, and in the inner scope we can + // check if there is any "StructuralName" for an Exception + // and its subtypes - if so, we know the exception would be + // caught. + // + // Let us look at an example with Method names. But for simplicity, we assume they + // all have the same signature: they take two int arguments and return an int. + // + // Should you ever work on a test where there are methods with different signatures, + // then you would have to very carefully study and design the subtype relation between + // methods. You may want to read up about covariance and contravariance. This + // example ignores all of that, because we only have "(II)I" methods. + private record MyMethodType() implements StructuralName.Type { + @Override + public boolean isSubtypeOf(StructuralName.Type other) { + return other instanceof MyMethodType(); + } + + @Override + public String name() { return ""; } + } + private static final MyMethodType myMethodType = new MyMethodType(); + + public static String generateWithStructuralNamesForMethods() { + // Define a method, which takes two ints, returns the result of op. + var templateMethod = Template.make("op", (String op) -> body( + // Register the method name, so we can later sample. + addStructuralName($("methodName"), myMethodType), + """ + public static int $methodName(int a, int b) { + return a #op b; + } + """ + )); + + var templateSample = Template.make(() -> body( + // Sample a random method, and retrieve its name. + let("methodName", structuralNames().exactOf(myMethodType).sample().name()), + """ + System.out.println("Calling #methodName with inputs 7 and 11"); + System.out.println(" result: " + #methodName(7, 11)); + """ + )); + + var templateClass = Template.make(() -> body( + """ + package p.xyz; + + public class InnerTest11 { + // Let us define some methods that we can sample from later. + """, + // We must anchor a CLASS_HOOK here, and insert the method definitions to that hook. + Hooks.CLASS_HOOK.anchor( + // If we directly nest the templateMethod, then the addStructuralName goes to the nested + // scope, and is not available at the class scope, i.e. it is not visible + // for sampleStructuralName outside of the templateMethod. + // DO NOT DO THIS, the nested addStructuralName will not be visible: + "// We cannot sample from the following methods:\n", + templateMethod.asToken("+"), + templateMethod.asToken("-"), + // However, if we insert to the CLASS_HOOK, then the Renderer makes the + // scope of the inserted templateMethod transparent, and the addStructuralName + // goes out to the scope of the CLASS_HOOK (but no further than that). + // RATHER, DO THIS to ensure the addStructuralName is visible: + Hooks.CLASS_HOOK.insert(templateMethod.asToken("*")), + Hooks.CLASS_HOOK.insert(templateMethod.asToken("|")), + Hooks.CLASS_HOOK.insert(templateMethod.asToken("&")), + """ + + public static void main() { + // Now, we call some random methods, but only those that were inserted + // to the CLASS_HOOK. + """, + Collections.nCopies(10, templateSample.asToken()), + """ + } + } + """ + ) + )); + + // Render templateClass to String. + return templateClass.render(); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestFormat.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestFormat.java new file mode 100644 index 00000000000..fe267a3ff63 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestFormat.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344942 + * @summary Test formatting of Integer, Long, Float and Double. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run main template_framework.tests.TestFormat + */ + +package template_framework.tests; + +import java.util.List; +import java.util.ArrayList; + +import compiler.lib.compile_framework.*; +import compiler.lib.generators.*; +import compiler.lib.verify.*; +import compiler.lib.template_framework.Template; +import static compiler.lib.template_framework.Template.body; +import static compiler.lib.template_framework.Template.let; + +public class TestFormat { + record FormatInfo(int id, String type, Object value) {} + + public static void main(String[] args) { + List list = new ArrayList<>(); + + for (int i = 0; i < 1000; i++) { + int v = Generators.G.ints().next(); + list.add(new FormatInfo(i, "int", v)); + } + + for (int i = 1000; i < 2000; i++) { + long v = Generators.G.longs().next(); + list.add(new FormatInfo(i, "long", v)); + } + + for (int i = 2000; i < 3000; i++) { + float v = Generators.G.floats().next(); + list.add(new FormatInfo(i, "float", v)); + } + + for (int i = 3000; i < 4000; i++) { + double v = Generators.G.doubles().next(); + list.add(new FormatInfo(i, "double", v)); + } + + CompileFramework comp = new CompileFramework(); + comp.addJavaSourceCode("p.xyz.InnerTest", generate(list)); + comp.compile(); + + // Run each of the "get" methods, and check the result. + for (FormatInfo info : list) { + Object ret1 = comp.invoke("p.xyz.InnerTest", "get_let_" + info.id, new Object[] {}); + Object ret2 = comp.invoke("p.xyz.InnerTest", "get_token_" + info.id, new Object[] {}); + System.out.println("id: " + info.id + " -> " + info.value + " == " + ret1 + " == " + ret2); + Verify.checkEQ(ret1, info.value); + Verify.checkEQ(ret2, info.value); + } + } + + private static String generate(List list) { + // Generate 2 "get" methods, one that formats via "let" (hashtag), the other via direct token. + var template1 = Template.make("info", (FormatInfo info) -> body( + let("id", info.id()), + let("type", info.type()), + let("value", info.value()), + """ + public static #type get_let_#id() { return #value; } + """, + "public static #type get_token_#id() { return ", info.value(), "; }\n" + )); + + // For each FormatInfo in list, generate the "get" methods inside InnerTest class. + var template2 = Template.make(() -> body( + """ + package p.xyz; + public class InnerTest { + """, + list.stream().map(info -> template1.asToken(info)).toList(), + """ + } + """ + )); + + return template2.render(); + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestTemplate.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestTemplate.java new file mode 100644 index 00000000000..35d020b6080 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/tests/TestTemplate.java @@ -0,0 +1,2253 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8344942 + * @summary Test some basic Template instantiations. We do not necessarily generate correct + * java code, we just test that the code generation deterministically creates the + * expected String. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run main template_framework.tests.TestTemplate + */ + +package template_framework.tests; + +import java.util.Arrays; +import java.util.List; +import java.util.HashSet; + +import compiler.lib.template_framework.Template; +import compiler.lib.template_framework.DataName; +import compiler.lib.template_framework.StructuralName; +import compiler.lib.template_framework.Hook; +import compiler.lib.template_framework.TemplateBinding; +import compiler.lib.template_framework.RendererException; +import static compiler.lib.template_framework.Template.body; +import static compiler.lib.template_framework.Template.$; +import static compiler.lib.template_framework.Template.let; +import static compiler.lib.template_framework.Template.fuel; +import static compiler.lib.template_framework.Template.setFuelCost; +import static compiler.lib.template_framework.Template.addDataName; +import static compiler.lib.template_framework.Template.dataNames; +import static compiler.lib.template_framework.Template.addStructuralName; +import static compiler.lib.template_framework.Template.structuralNames; +import static compiler.lib.template_framework.DataName.Mutability.MUTABLE; +import static compiler.lib.template_framework.DataName.Mutability.IMMUTABLE; +import static compiler.lib.template_framework.DataName.Mutability.MUTABLE_OR_IMMUTABLE; + +/** + * The tests in this file are mostly there to ensure that the Template Rendering + * works correctly, and not that we produce compilable Java code. Rather, we + * produce deterministic output, and compare it to the expected String. + * Still, this file may be helpful for learning more about how Templates + * work and can be used. + * + * We assume that you have already studied {@code TestTutorial.java}. + */ +public class TestTemplate { + // Interface for failing tests. + interface FailingTest { + void run(); + } + + // Define a simple type to model primitive types. + private record MyPrimitive(String name) implements DataName.Type { + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof MyPrimitive(String n) && n.equals(name()); + } + + @Override + public String toString() { return name(); } + } + private static final MyPrimitive myInt = new MyPrimitive("int"); + private static final MyPrimitive myLong = new MyPrimitive("long"); + + // Simulate classes. Subtypes start with the name of the super type. + private record MyClass(String name) implements DataName.Type { + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof MyClass(String n) && name().startsWith(n); + } + + @Override + public String toString() { return name(); } + } + private static final MyClass myClassA = new MyClass("myClassA"); + private static final MyClass myClassA1 = new MyClass("myClassA1"); + private static final MyClass myClassA2 = new MyClass("myClassA2"); + private static final MyClass myClassA11 = new MyClass("myClassA11"); + private static final MyClass myClassB = new MyClass("myClassB"); + + // Simulate some structural types. + private record MyStructuralType(String name) implements StructuralName.Type { + @Override + public boolean isSubtypeOf(StructuralName.Type other) { + return other instanceof MyStructuralType(String n) && name().startsWith(n); + } + + @Override + public String toString() { return name(); } + } + private static final MyStructuralType myStructuralTypeA = new MyStructuralType("StructuralA"); + private static final MyStructuralType myStructuralTypeA1 = new MyStructuralType("StructuralA1"); + private static final MyStructuralType myStructuralTypeA2 = new MyStructuralType("StructuralA2"); + private static final MyStructuralType myStructuralTypeA11 = new MyStructuralType("StructuralA11"); + private static final MyStructuralType myStructuralTypeB = new MyStructuralType("StructuralB"); + + public static void main(String[] args) { + // The following tests all pass, i.e. have no errors during rendering. + testSingleLine(); + testMultiLine(); + testBodyTokens(); + testWithOneArgument(); + testWithTwoArguments(); + testWithThreeArguments(); + testNested(); + testHookSimple(); + testHookIsAnchored(); + testHookNested(); + testHookWithNestedTemplates(); + testHookRecursion(); + testDollar(); + testLet(); + testDollarAndHashtagBrackets(); + testSelector(); + testRecursion(); + testFuel(); + testFuelCustom(); + testDataNames1(); + testDataNames2(); + testDataNames3(); + testDataNames4(); + testDataNames5(); + testStructuralNames1(); + testStructuralNames2(); + testListArgument(); + + // The following tests should all fail, with an expected exception and message. + expectRendererException(() -> testFailingNestedRendering(), "Nested render not allowed."); + expectRendererException(() -> $("name"), "A Template method such as"); + expectRendererException(() -> let("x","y"), "A Template method such as"); + expectRendererException(() -> fuel(), "A Template method such as"); + expectRendererException(() -> setFuelCost(1.0f), "A Template method such as"); + expectRendererException(() -> dataNames(MUTABLE_OR_IMMUTABLE).exactOf(myInt).count(), "A Template method such as"); + expectRendererException(() -> dataNames(MUTABLE_OR_IMMUTABLE).exactOf(myInt).sample(), "A Template method such as"); + expectRendererException(() -> (new Hook("abc")).isAnchored(), "A Template method such as"); + expectRendererException(() -> testFailingDollarName1(), "Is not a valid '$' name: ''."); + expectRendererException(() -> testFailingDollarName2(), "Is not a valid '$' name: '#abc'."); + expectRendererException(() -> testFailingDollarName3(), "Is not a valid '$' name: 'abc#'."); + expectRendererException(() -> testFailingDollarName4(), "A '$' name should not be null."); + expectRendererException(() -> testFailingDollarName5(), "Is not a valid '$' replacement pattern: '$' in '$'."); + expectRendererException(() -> testFailingDollarName6(), "Is not a valid '$' replacement pattern: '$' in 'asdf$'."); + expectRendererException(() -> testFailingDollarName7(), "Is not a valid '$' replacement pattern: '$1' in 'asdf$1'."); + expectRendererException(() -> testFailingDollarName8(), "Is not a valid '$' replacement pattern: '$' in 'abc$$abc'."); + expectRendererException(() -> testFailingLetName1(), "A hashtag replacement should not be null."); + expectRendererException(() -> testFailingHashtagName1(), "Is not a valid hashtag replacement name: ''."); + expectRendererException(() -> testFailingHashtagName2(), "Is not a valid hashtag replacement name: 'abc#abc'."); + expectRendererException(() -> testFailingHashtagName3(), "Is not a valid hashtag replacement name: ''."); + expectRendererException(() -> testFailingHashtagName4(), "Is not a valid hashtag replacement name: 'xyz#xyz'."); + expectRendererException(() -> testFailingHashtagName5(), "Is not a valid '#' replacement pattern: '#' in '#'."); + expectRendererException(() -> testFailingHashtagName6(), "Is not a valid '#' replacement pattern: '#' in 'asdf#'."); + expectRendererException(() -> testFailingHashtagName7(), "Is not a valid '#' replacement pattern: '#1' in 'asdf#1'."); + expectRendererException(() -> testFailingHashtagName8(), "Is not a valid '#' replacement pattern: '#' in 'abc##abc'."); + expectRendererException(() -> testFailingDollarHashtagName1(), "Is not a valid '#' replacement pattern: '#' in '#$'."); + expectRendererException(() -> testFailingDollarHashtagName2(), "Is not a valid '$' replacement pattern: '$' in '$#'."); + expectRendererException(() -> testFailingDollarHashtagName3(), "Is not a valid '#' replacement pattern: '#' in '#$name'."); + expectRendererException(() -> testFailingDollarHashtagName4(), "Is not a valid '$' replacement pattern: '$' in '$#name'."); + expectRendererException(() -> testFailingHook(), "Hook 'Hook1' was referenced but not found!"); + expectRendererException(() -> testFailingSample1(), "No variable: MUTABLE, subtypeOf(int), supertypeOf(int)."); + expectRendererException(() -> testFailingHashtag1(), "Duplicate hashtag replacement for #a"); + expectRendererException(() -> testFailingHashtag2(), "Duplicate hashtag replacement for #a"); + expectRendererException(() -> testFailingHashtag3(), "Duplicate hashtag replacement for #a"); + expectRendererException(() -> testFailingHashtag4(), "Missing hashtag replacement for #a"); + expectRendererException(() -> testFailingBinding1(), "Duplicate 'bind' not allowed."); + expectRendererException(() -> testFailingBinding2(), "Cannot 'get' before 'bind'."); + expectIllegalArgumentException(() -> body(null), "Unexpected tokens: null"); + expectIllegalArgumentException(() -> body("x", null), "Unexpected token: null"); + expectIllegalArgumentException(() -> body(new Hook("Hook1")), "Unexpected token:"); + Hook hook1 = new Hook("Hook1"); + expectIllegalArgumentException(() -> hook1.anchor(null), "Unexpected tokens: null"); + expectIllegalArgumentException(() -> hook1.anchor("x", null), "Unexpected token: null"); + expectIllegalArgumentException(() -> hook1.anchor(hook1), "Unexpected token:"); + expectIllegalArgumentException(() -> testFailingAddDataName1(), "Unexpected mutability: MUTABLE_OR_IMMUTABLE"); + expectIllegalArgumentException(() -> testFailingAddDataName2(), "Unexpected weight: "); + expectIllegalArgumentException(() -> testFailingAddDataName3(), "Unexpected weight: "); + expectIllegalArgumentException(() -> testFailingAddDataName4(), "Unexpected weight: "); + expectIllegalArgumentException(() -> testFailingAddStructuralName1(), "Unexpected weight: "); + expectIllegalArgumentException(() -> testFailingAddStructuralName2(), "Unexpected weight: "); + expectIllegalArgumentException(() -> testFailingAddStructuralName3(), "Unexpected weight: "); + expectUnsupportedOperationException(() -> testFailingSample2(), "Must first call 'subtypeOf', 'supertypeOf', or 'exactOf'."); + expectRendererException(() -> testFailingAddNameDuplication1(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication2(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication3(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication4(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication5(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication6(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication7(), "Duplicate name:"); + expectRendererException(() -> testFailingAddNameDuplication8(), "Duplicate name:"); + } + + public static void testSingleLine() { + var template = Template.make(() -> body("Hello World!")); + String code = template.render(); + checkEQ(code, "Hello World!"); + } + + public static void testMultiLine() { + var template = Template.make(() -> body( + """ + Code on more + than a single line + """ + )); + String code = template.render(); + String expected = + """ + Code on more + than a single line + """; + checkEQ(code, expected); + } + + public static void testBodyTokens() { + // We can fill the body with Objects of different types, and they get concatenated. + // Lists get flattened into the body. + var template = Template.make(() -> body( + "start ", + Integer.valueOf(1), 1, + Long.valueOf(2), 2L, + Double.valueOf(3.4), 3.4, + Float.valueOf(5.6f), 5.6f, + List.of(" ", 1, " and ", 2), + " end" + )); + String code = template.render(); + checkEQ(code, "start 112L2L3.43.45.6f5.6f 1 and 2 end"); + } + + public static void testWithOneArgument() { + // Capture String argument via String name. + var template1 = Template.make("a", (String a) -> body("start #a end")); + checkEQ(template1.render("x"), "start x end"); + checkEQ(template1.render("a"), "start a end"); + checkEQ(template1.render("" ), "start end"); + + // Capture String argument via typed lambda argument. + var template2 = Template.make("a", (String a) -> body("start ", a, " end")); + checkEQ(template2.render("x"), "start x end"); + checkEQ(template2.render("a"), "start a end"); + checkEQ(template2.render("" ), "start end"); + + // Capture Integer argument via String name. + var template3 = Template.make("a", (Integer a) -> body("start #a end")); + checkEQ(template3.render(0 ), "start 0 end"); + checkEQ(template3.render(22 ), "start 22 end"); + checkEQ(template3.render(444), "start 444 end"); + + // Capture Integer argument via templated lambda argument. + var template4 = Template.make("a", (Integer a) -> body("start ", a, " end")); + checkEQ(template4.render(0 ), "start 0 end"); + checkEQ(template4.render(22 ), "start 22 end"); + checkEQ(template4.render(444), "start 444 end"); + + // Test Strings with backslashes: + var template5 = Template.make("a", (String a) -> body("start #a " + a + " end")); + checkEQ(template5.render("/"), "start / / end"); + checkEQ(template5.render("\\"), "start \\ \\ end"); + checkEQ(template5.render("\\\\"), "start \\\\ \\\\ end"); + } + + public static void testWithTwoArguments() { + // Capture 2 String arguments via String names. + var template1 = Template.make("a1", "a2", (String a1, String a2) -> body("start #a1 #a2 end")); + checkEQ(template1.render("x", "y"), "start x y end"); + checkEQ(template1.render("a", "b"), "start a b end"); + checkEQ(template1.render("", "" ), "start end"); + + // Capture 2 String arguments via typed lambda arguments. + var template2 = Template.make("a1", "a2", (String a1, String a2) -> body("start ", a1, " ", a2, " end")); + checkEQ(template2.render("x", "y"), "start x y end"); + checkEQ(template2.render("a", "b"), "start a b end"); + checkEQ(template2.render("", "" ), "start end"); + + // Capture 2 Integer arguments via String names. + var template3 = Template.make("a1", "a2", (Integer a1, Integer a2) -> body("start #a1 #a2 end")); + checkEQ(template3.render(0, 1 ), "start 0 1 end"); + checkEQ(template3.render(22, 33 ), "start 22 33 end"); + checkEQ(template3.render(444, 555), "start 444 555 end"); + + // Capture 2 Integer arguments via templated lambda arguments. + var template4 = Template.make("a1", "a2", (Integer a1, Integer a2) -> body("start ", a1, " ", a2, " end")); + checkEQ(template4.render(0, 1 ), "start 0 1 end"); + checkEQ(template4.render(22, 33 ), "start 22 33 end"); + checkEQ(template4.render(444, 555), "start 444 555 end"); + } + + public static void testWithThreeArguments() { + // Capture 3 String arguments via String names. + var template1 = Template.make("a1", "a2", "a3", (String a1, String a2, String a3) -> body("start #a1 #a2 #a3 end")); + checkEQ(template1.render("x", "y", "z"), "start x y z end"); + checkEQ(template1.render("a", "b", "c"), "start a b c end"); + checkEQ(template1.render("", "", "" ), "start end"); + + // Capture 3 String arguments via typed lambda arguments. + var template2 = Template.make("a1", "a2", "a3", (String a1, String a2, String a3) -> body("start ", a1, " ", a2, " ", a3, " end")); + checkEQ(template1.render("x", "y", "z"), "start x y z end"); + checkEQ(template1.render("a", "b", "c"), "start a b c end"); + checkEQ(template1.render("", "", "" ), "start end"); + + // Capture 3 Integer arguments via String names. + var template3 = Template.make("a1", "a2", "a3", (Integer a1, Integer a2, Integer a3) -> body("start #a1 #a2 #a3 end")); + checkEQ(template3.render(0, 1 , 2 ), "start 0 1 2 end"); + checkEQ(template3.render(22, 33 , 44 ), "start 22 33 44 end"); + checkEQ(template3.render(444, 555, 666), "start 444 555 666 end"); + + // Capture 2 Integer arguments via templated lambda arguments. + var template4 = Template.make("a1", "a2", "a3", (Integer a1, Integer a2, Integer a3) -> body("start ", a1, " ", a2, " ", a3, " end")); + checkEQ(template3.render(0, 1 , 2 ), "start 0 1 2 end"); + checkEQ(template3.render(22, 33 , 44 ), "start 22 33 44 end"); + checkEQ(template3.render(444, 555, 666), "start 444 555 666 end"); + } + + public static void testNested() { + var template1 = Template.make(() -> body("proton")); + + var template2 = Template.make("a1", "a2", (String a1, String a2) -> body( + "electron #a1\n", + "neutron #a2\n" + )); + + var template3 = Template.make("a1", "a2", (String a1, String a2) -> body( + "Universe ", template1.asToken(), " {\n", + template2.asToken("up", "down"), + template2.asToken(a1, a2), + "}\n" + )); + + var template4 = Template.make(() -> body( + template3.asToken("low", "high"), + "{\n", + template3.asToken("42", "24"), + "}" + )); + + String code = template4.render(); + String expected = + """ + Universe proton { + electron up + neutron down + electron low + neutron high + } + { + Universe proton { + electron up + neutron down + electron 42 + neutron 24 + } + }"""; + checkEQ(code, expected); + } + + public static void testHookSimple() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make(() -> body("Hello\n")); + + var template2 = Template.make(() -> body( + "{\n", + hook1.anchor( + "World\n", + // Note: "Hello" from the template below will be inserted + // above "World" above. + hook1.insert(template1.asToken()) + ), + "}" + )); + + String code = template2.render(); + String expected = + """ + { + Hello + World + }"""; + checkEQ(code, expected); + } + + public static void testHookIsAnchored() { + var hook1 = new Hook("Hook1"); + + var template0 = Template.make(() -> body("isAnchored: ", hook1.isAnchored(), "\n")); + + var template1 = Template.make(() -> body("Hello\n", template0.asToken())); + + var template2 = Template.make(() -> body( + "{\n", + template0.asToken(), + hook1.anchor( + "World\n", + template0.asToken(), + hook1.insert(template1.asToken()) + ), + template0.asToken(), + "}" + )); + + String code = template2.render(); + String expected = + """ + { + isAnchored: false + Hello + isAnchored: true + World + isAnchored: true + isAnchored: false + }"""; + checkEQ(code, expected); + } + + public static void testHookNested() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("a", (String a) -> body("x #a x\n")); + + // Test nested use of hooks in the same template. + var template2 = Template.make(() -> body( + "{\n", + hook1.anchor(), // empty + "zero\n", + hook1.anchor( + template1.asToken("one"), + template1.asToken("two"), + hook1.insert(template1.asToken("intoHook1a")), + hook1.insert(template1.asToken("intoHook1b")), + template1.asToken("three"), + hook1.anchor( + template1.asToken("four"), + hook1.insert(template1.asToken("intoHook1c")), + template1.asToken("five") + ), + template1.asToken("six"), + hook1.anchor(), // empty + template1.asToken("seven"), + hook1.insert(template1.asToken("intoHook1d")), + template1.asToken("eight"), + hook1.anchor( + template1.asToken("nine"), + hook1.insert(template1.asToken("intoHook1e")), + template1.asToken("ten") + ), + template1.asToken("eleven") + ), + "}" + )); + + String code = template2.render(); + String expected = + """ + { + zero + x intoHook1a x + x intoHook1b x + x intoHook1d x + x one x + x two x + x three x + x intoHook1c x + x four x + x five x + x six x + x seven x + x eight x + x intoHook1e x + x nine x + x ten x + x eleven x + }"""; + checkEQ(code, expected); + } + + public static void testHookWithNestedTemplates() { + var hook1 = new Hook("Hook1"); + var hook2 = new Hook("Hook2"); + + var template1 = Template.make("a", (String a) -> body("x #a x\n")); + + var template2 = Template.make("b", (String b) -> body( + "{\n", + template1.asToken(b + "A"), + hook1.insert(template1.asToken(b + "B")), + hook2.insert(template1.asToken(b + "C")), + template1.asToken(b + "D"), + hook1.anchor( + template1.asToken(b + "E"), + hook1.insert(template1.asToken(b + "F")), + hook2.insert(template1.asToken(b + "G")), + template1.asToken(b + "H"), + hook2.anchor( + template1.asToken(b + "I"), + hook1.insert(template1.asToken(b + "J")), + hook2.insert(template1.asToken(b + "K")), + template1.asToken(b + "L") + ), + template1.asToken(b + "M"), + hook1.insert(template1.asToken(b + "N")), + hook2.insert(template1.asToken(b + "O")), + template1.asToken(b + "O") + ), + template1.asToken(b + "P"), + hook1.insert(template1.asToken(b + "Q")), + hook2.insert(template1.asToken(b + "R")), + template1.asToken(b + "S"), + "}\n" + )); + + // Test use of hooks across templates. + var template3 = Template.make(() -> body( + "{\n", + "base-A\n", + hook1.anchor( + "base-B\n", + hook2.anchor( + "base-C\n", + template2.asToken("sub-"), + "base-D\n" + ), + "base-E\n" + ), + "base-F\n", + "}\n" + )); + + String code = template3.render(); + String expected = + """ + { + base-A + x sub-B x + x sub-Q x + base-B + x sub-C x + x sub-G x + x sub-O x + x sub-R x + base-C + { + x sub-A x + x sub-D x + x sub-F x + x sub-J x + x sub-N x + x sub-E x + x sub-H x + x sub-K x + x sub-I x + x sub-L x + x sub-M x + x sub-O x + x sub-P x + x sub-S x + } + base-D + base-E + base-F + } + """; + checkEQ(code, expected); + } + + public static void testHookRecursion() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("a", (String a) -> body("x #a x\n")); + + var template2 = Template.make("b", (String b) -> body( + "<\n", + template1.asToken(b + "A"), + hook1.insert(template1.asToken(b + "B")), // sub-B is rendered before template2. + template1.asToken(b + "C"), + "inner-hook-start\n", + hook1.anchor( + "inner-hook-end\n", + template1.asToken(b + "E"), + hook1.insert(template1.asToken(b + "E")), + template1.asToken(b + "F") + ), + ">\n" + )); + + // Test use of hooks across templates. + var template3 = Template.make(() -> body( + "{\n", + "hook-start\n", + hook1.anchor( + "hook-end\n", + hook1.insert(template2.asToken("sub-")), + "base-C\n" + ), + "base-D\n", + "}\n" + )); + + String code = template3.render(); + String expected = + """ + { + hook-start + x sub-B x + < + x sub-A x + x sub-C x + inner-hook-start + x sub-E x + inner-hook-end + x sub-E x + x sub-F x + > + hook-end + base-C + base-D + } + """; + checkEQ(code, expected); + } + + public static void testDollar() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("a", (String a) -> body("x $name #a x\n")); + + var template2 = Template.make("a", (String a) -> body( + "{\n", + "y $name #a y\n", + template1.asToken($("name")), + "}\n" + )); + + var template3 = Template.make(() -> body( + "{\n", + "$name\n", + "$name", "\n", + "z $name z\n", + "z$name z\n", + template1.asToken("name"), // does not capture -> literal "$name" + template1.asToken("$name"), // does not capture -> literal "$name" + template1.asToken($("name")), // capture replacement name "name_1" + hook1.anchor( + "$name\n" + ), + "break\n", + hook1.anchor( + "one\n", + hook1.insert(template1.asToken($("name"))), + "two\n", + template1.asToken($("name")), + "three\n", + hook1.insert(template2.asToken($("name"))), + "four\n" + ), + "}\n" + )); + + String code = template3.render(); + String expected = + """ + { + name_1 + name_1 + z name_1 z + zname_1 z + x name_2 name x + x name_3 $name x + x name_4 name_1 x + name_1 + break + x name_5 name_1 x + { + y name_7 name_1 y + x name_8 name_7 x + } + one + two + x name_6 name_1 x + three + four + } + """; + checkEQ(code, expected); + } + + public static void testLet() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("a", (String a) -> body( + "{\n", + "y #a y\n", + let("b", "<" + a + ">"), + "y #b y\n", + "}\n" + )); + + var template2 = Template.make("a", (Integer a) -> let("b", a * 10, b -> + body( + let("c", b * 3), + "abc = #a #b #c\n" + ) + )); + + var template3 = Template.make(() -> body( + "{\n", + let("x", "abc"), + template1.asToken("alpha"), + "break\n", + "x1 = #x\n", + hook1.anchor( + "x2 = #x\n", // leaks inside + template1.asToken("beta"), + let("y", "one"), + "y1 = #y\n" + ), + "break\n", + "y2 = #y\n", // leaks outside + "break\n", + template2.asToken(5), + "}\n" + )); + + String code = template3.render(); + String expected = + """ + { + { + y alpha y + y y + } + break + x1 = abc + x2 = abc + { + y beta y + y y + } + y1 = one + break + y2 = one + break + abc = 5 50 150 + } + """; + checkEQ(code, expected); + } + + public static void testDollarAndHashtagBrackets() { + var template1 = Template.make(() -> body( + let("xyz", "abc"), + let("xyz_", "def"), + let("xyz_klm", "ghi"), + let("klm", "jkl"), + """ + no bracket: #xyz #xyz_klm #xyz_#klm + no bracket: $var $var_two $var_$two + with bracket: #{xyz} #{xyz_klm} #{xyz}_#{klm} + with bracket: ${var} ${var_two} ${var}_${two} + """ + )); + + String code = template1.render(); + String expected = + """ + no bracket: abc ghi defjkl + no bracket: var_1 var_two_1 var__1two_1 + with bracket: abc ghi abc_jkl + with bracket: var_1 var_two_1 var_1_two_1 + """; + checkEQ(code, expected); + } + + public static void testSelector() { + var template1 = Template.make("a", (String a) -> body( + "<\n", + "x #a x\n", + ">\n" + )); + + var template2 = Template.make("a", (String a) -> body( + "<\n", + "y #a y\n", + ">\n" + )); + + var template3 = Template.make("a", (Integer a) -> body( + "[\n", + "z #a z\n", + // Select which template should be used: + a > 0 ? template1.asToken("A_" + a) + : template2.asToken("B_" + a), + "]\n" + )); + + var template4 = Template.make(() -> body( + "{\n", + template3.asToken(-1), + "break\n", + template3.asToken(0), + "break\n", + template3.asToken(1), + "break\n", + template3.asToken(2), + "}\n" + )); + + String code = template4.render(); + String expected = + """ + { + [ + z -1 z + < + y B_-1 y + > + ] + break + [ + z 0 z + < + y B_0 y + > + ] + break + [ + z 1 z + < + x A_1 x + > + ] + break + [ + z 2 z + < + x A_2 x + > + ] + } + """; + checkEQ(code, expected); + } + + public static void testRecursion() { + // Binding allows use of template1 inside template1, via the Binding indirection. + var binding1 = new TemplateBinding>(); + + var template1 = Template.make("i", (Integer i) -> body( + "[ #i\n", + // We cannot yet use the template1 directly, as it is being defined. + // So we use binding1 instead. + i < 0 ? "done\n" : binding1.get().asToken(i - 1), + "] #i\n" + )); + binding1.bind(template1); + + var template2 = Template.make(() -> body( + "{\n", + // Now, we can use template1 normally, as it is already defined. + template1.asToken(3), + "}\n" + )); + + String code = template2.render(); + String expected = + """ + { + [ 3 + [ 2 + [ 1 + [ 0 + [ -1 + done + ] -1 + ] 0 + ] 1 + ] 2 + ] 3 + } + """; + checkEQ(code, expected); + } + + public static void testFuel() { + var template1 = Template.make(() -> body( + let("f", fuel()), + + "<#f>\n" + )); + + // Binding allows use of template2 inside template2, via the Binding indirection. + var binding2 = new TemplateBinding>(); + var template2 = Template.make("i", (Integer i) -> body( + let("f", fuel()), + + "[ #i #f\n", + template1.asToken(), + fuel() <= 60.f ? "done" : binding2.get().asToken(i - 1), + "] #i #f\n" + )); + binding2.bind(template2); + + var template3 = Template.make(() -> body( + "{\n", + template2.asToken(3), + "}\n" + )); + + String code = template3.render(); + String expected = + """ + { + [ 3 90.0f + <80.0f> + [ 2 80.0f + <70.0f> + [ 1 70.0f + <60.0f> + [ 0 60.0f + <50.0f> + done] 0 60.0f + ] 1 70.0f + ] 2 80.0f + ] 3 90.0f + } + """; + checkEQ(code, expected); + } + + public static void testFuelCustom() { + var template1 = Template.make(() -> body( + setFuelCost(2.0f), + let("f", fuel()), + + "<#f>\n" + )); + + // Binding allows use of template2 inside template2, via the Binding indirection. + var binding2 = new TemplateBinding>(); + var template2 = Template.make("i", (Integer i) -> body( + setFuelCost(3.0f), + let("f", fuel()), + + "[ #i #f\n", + template1.asToken(), + fuel() <= 5.f ? "done\n" : binding2.get().asToken(i - 1), + "] #i #f\n" + )); + binding2.bind(template2); + + var template3 = Template.make(() -> body( + setFuelCost(5.0f), + let("f", fuel()), + + "{ #f\n", + template2.asToken(3), + "} #f\n" + )); + + String code = template3.render(20.0f); + String expected = + """ + { 20.0f + [ 3 15.0f + <12.0f> + [ 2 12.0f + <9.0f> + [ 1 9.0f + <6.0f> + [ 0 6.0f + <3.0f> + [ -1 3.0f + <0.0f> + done + ] -1 3.0f + ] 0 6.0f + ] 1 9.0f + ] 2 12.0f + ] 3 15.0f + } 20.0f + """; + checkEQ(code, expected); + } + + public static void testDataNames1() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make(() -> body( + "[", + dataNames(MUTABLE_OR_IMMUTABLE).exactOf(myInt).hasAny(), + ", ", + dataNames(MUTABLE_OR_IMMUTABLE).exactOf(myInt).count(), + ", names: {", + String.join(", ", dataNames(MUTABLE_OR_IMMUTABLE).exactOf(myInt).toList().stream().map(DataName::name).toList()), + "}]\n" + )); + + var template2 = Template.make("name", "type", (String name, DataName.Type type) -> body( + addDataName(name, type, MUTABLE), + "define #type #name\n", + template1.asToken() + )); + + var template3 = Template.make(() -> body( + "<\n", + hook1.insert(template2.asToken($("name"), myInt)), + "$name = 5\n", + ">\n" + )); + + var template4 = Template.make(() -> body( + "{\n", + template1.asToken(), + hook1.anchor( + template1.asToken(), + "something\n", + template3.asToken(), + "more\n", + template1.asToken(), + "more\n", + template2.asToken($("name"), myInt), + "more\n", + template1.asToken() + ), + template1.asToken(), + "}\n" + )); + + String code = template4.render(); + String expected = + """ + { + [false, 0, names: {}] + define int name_4 + [true, 1, names: {name_4}] + [false, 0, names: {}] + something + < + name_4 = 5 + > + more + [true, 1, names: {name_4}] + more + define int name_1 + [true, 2, names: {name_4, name_1}] + more + [true, 1, names: {name_4}] + [false, 0, names: {}] + } + """; + checkEQ(code, expected); + } + + public static void testDataNames2() { + var hook1 = new Hook("Hook1"); + + var template0 = Template.make("type", "mutability", (DataName.Type type, DataName.Mutability mutability) -> body( + " #mutability: [", + dataNames(mutability).exactOf(myInt).hasAny(), + ", ", + dataNames(mutability).exactOf(myInt).count(), + ", names: {", + String.join(", ", dataNames(mutability).exactOf(myInt).toList().stream().map(DataName::name).toList()), + "}]\n" + )); + + var template1 = Template.make("type", (DataName.Type type) -> body( + "[#type:\n", + template0.asToken(type, MUTABLE), + template0.asToken(type, IMMUTABLE), + template0.asToken(type, MUTABLE_OR_IMMUTABLE), + "]\n" + )); + + var template2 = Template.make("name", "type", (String name, DataName.Type type) -> body( + addDataName(name, type, MUTABLE), + "define mutable #type #name\n", + template1.asToken(type) + )); + + var template3 = Template.make("name", "type", (String name, DataName.Type type) -> body( + addDataName(name, type, IMMUTABLE), + "define immutable #type #name\n", + template1.asToken(type) + )); + + var template4 = Template.make("type", (DataName.Type type) -> body( + "{ $store\n", + hook1.insert(template2.asToken($("name"), type)), + "$name = 5\n", + "} $store\n" + )); + + var template5 = Template.make("type", (DataName.Type type) -> body( + "{ $load\n", + hook1.insert(template3.asToken($("name"), type)), + "blackhole($name)\n", + "} $load\n" + )); + + var template6 = Template.make("type", (DataName.Type type) -> body( + let("v", dataNames(MUTABLE).exactOf(type).sample().name()), + "{ $sample\n", + "#v = 7\n", + "} $sample\n" + )); + + var template7 = Template.make("type", (DataName.Type type) -> body( + let("v", dataNames(MUTABLE_OR_IMMUTABLE).exactOf(type).sample().name()), + "{ $sample\n", + "blackhole(#v)\n", + "} $sample\n" + )); + + var template8 = Template.make(() -> body( + "class $X {\n", + template1.asToken(myInt), + hook1.anchor( + "begin $body\n", + template1.asToken(myInt), + "start with immutable\n", + template5.asToken(myInt), + "then load from it\n", + template7.asToken(myInt), + template1.asToken(myInt), + "now make something mutable\n", + template4.asToken(myInt), + "then store to it\n", + template6.asToken(myInt), + template1.asToken(myInt) + ), + template1.asToken(myInt), + "}\n" + )); + + String code = template8.render(); + String expected = + """ + class X_1 { + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + define immutable int name_10 + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [true, 1, names: {name_10}] + MUTABLE_OR_IMMUTABLE: [true, 1, names: {name_10}] + ] + define mutable int name_21 + [int: + MUTABLE: [true, 1, names: {name_21}] + IMMUTABLE: [true, 1, names: {name_10}] + MUTABLE_OR_IMMUTABLE: [true, 2, names: {name_10, name_21}] + ] + begin body_1 + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + start with immutable + { load_10 + blackhole(name_10) + } load_10 + then load from it + { sample_16 + blackhole(name_10) + } sample_16 + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [true, 1, names: {name_10}] + MUTABLE_OR_IMMUTABLE: [true, 1, names: {name_10}] + ] + now make something mutable + { store_21 + name_21 = 5 + } store_21 + then store to it + { sample_27 + name_21 = 7 + } sample_27 + [int: + MUTABLE: [true, 1, names: {name_21}] + IMMUTABLE: [true, 1, names: {name_10}] + MUTABLE_OR_IMMUTABLE: [true, 2, names: {name_10, name_21}] + ] + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + } + """; + checkEQ(code, expected); + } + + public static void testDataNames3() { + var hook1 = new Hook("Hook1"); + + var template0 = Template.make("type", "mutability", (DataName.Type type, DataName.Mutability mutability) -> body( + " #mutability: [", + dataNames(mutability).exactOf(myInt).hasAny(), + ", ", + dataNames(mutability).exactOf(myInt).count(), + ", names: {", + String.join(", ", dataNames(mutability).exactOf(myInt).toList().stream().map(DataName::name).toList()), + "}]\n" + )); + + var template1 = Template.make("type", (DataName.Type type) -> body( + "[#type:\n", + template0.asToken(type, MUTABLE), + template0.asToken(type, IMMUTABLE), + template0.asToken(type, MUTABLE_OR_IMMUTABLE), + "]\n" + )); + + var template2 = Template.make(() -> body( + "class $Y {\n", + template1.asToken(myInt), + hook1.anchor( + "begin $body\n", + template1.asToken(myInt), + "define mutable $v1\n", + addDataName($("v1"), myInt, MUTABLE), + template1.asToken(myInt), + "define immutable $v2\n", + addDataName($("v2"), myInt, IMMUTABLE), + template1.asToken(myInt) + ), + template1.asToken(myInt), + "}\n" + )); + + String code = template2.render(); + String expected = + """ + class Y_1 { + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + begin body_1 + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + define mutable v1_1 + [int: + MUTABLE: [true, 1, names: {v1_1}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [true, 1, names: {v1_1}] + ] + define immutable v2_1 + [int: + MUTABLE: [true, 1, names: {v1_1}] + IMMUTABLE: [true, 1, names: {v2_1}] + MUTABLE_OR_IMMUTABLE: [true, 2, names: {v1_1, v2_1}] + ] + [int: + MUTABLE: [false, 0, names: {}] + IMMUTABLE: [false, 0, names: {}] + MUTABLE_OR_IMMUTABLE: [false, 0, names: {}] + ] + } + """; + checkEQ(code, expected); + } + + public static void testDataNames4() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("type", (DataName.Type type) -> body( + "[#type:\n", + " exact: ", + dataNames(MUTABLE).exactOf(type).hasAny(), + ", ", + dataNames(MUTABLE).exactOf(type).count(), + ", {", + String.join(", ", dataNames(MUTABLE).exactOf(type).toList().stream().map(DataName::name).toList()), + "}\n", + " subtype: ", + dataNames(MUTABLE).subtypeOf(type).hasAny(), + ", ", + dataNames(MUTABLE).subtypeOf(type).count(), + ", {", + String.join(", ", dataNames(MUTABLE).subtypeOf(type).toList().stream().map(DataName::name).toList()), + "}\n", + " supertype: ", + dataNames(MUTABLE).supertypeOf(type).hasAny(), + ", ", + dataNames(MUTABLE).supertypeOf(type).count(), + ", {", + String.join(", ", dataNames(MUTABLE).supertypeOf(type).toList().stream().map(DataName::name).toList()), + "}\n", + "]\n" + )); + + List types = List.of(myClassA, myClassA1, myClassA2, myClassA11, myClassB); + var template2 = Template.make(() -> body( + "DataNames:\n", + types.stream().map(t -> template1.asToken(t)).toList() + )); + + var template3 = Template.make("type", (DataName.Type type) -> body( + let("name", dataNames(MUTABLE).subtypeOf(type).sample()), + "Sample #type: #name\n" + )); + + var template4 = Template.make(() -> body( + "class $W {\n", + template2.asToken(), + hook1.anchor( + "Create name for myClassA11, should be visible for the super classes\n", + addDataName($("v1"), myClassA11, MUTABLE), + template3.asToken(myClassA11), + template3.asToken(myClassA1), + template3.asToken(myClassA), + "Create name for myClassA, should never be visible for the sub classes\n", + addDataName($("v2"), myClassA, MUTABLE), + template3.asToken(myClassA11), + template3.asToken(myClassA1), + template2.asToken() + ), + template2.asToken(), + "}\n" + )); + + String code = template4.render(); + String expected = + """ + class W_1 { + DataNames: + [myClassA: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA1: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA11: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + Create name for myClassA11, should be visible for the super classes + Sample myClassA11: DataName[name=v1_1, type=myClassA11, mutable=true, weight=1] + Sample myClassA1: DataName[name=v1_1, type=myClassA11, mutable=true, weight=1] + Sample myClassA: DataName[name=v1_1, type=myClassA11, mutable=true, weight=1] + Create name for myClassA, should never be visible for the sub classes + Sample myClassA11: DataName[name=v1_1, type=myClassA11, mutable=true, weight=1] + Sample myClassA1: DataName[name=v1_1, type=myClassA11, mutable=true, weight=1] + DataNames: + [myClassA: + exact: true, 1, {v2_1} + subtype: true, 2, {v1_1, v2_1} + supertype: true, 1, {v2_1} + ] + [myClassA1: + exact: false, 0, {} + subtype: true, 1, {v1_1} + supertype: true, 1, {v2_1} + ] + [myClassA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: true, 1, {v2_1} + ] + [myClassA11: + exact: true, 1, {v1_1} + subtype: true, 1, {v1_1} + supertype: true, 2, {v1_1, v2_1} + ] + [myClassB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + DataNames: + [myClassA: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA1: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassA11: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [myClassB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + } + """; + checkEQ(code, expected); + } + + // Test duplicate names in safe cases. + public static void testDataNames5() { + var hook1 = new Hook("Hook1"); + var hook2 = new Hook("Hook2"); + + // It is safe in separate Hook scopes. + var template1 = Template.make(() -> body( + hook1.anchor( + addDataName("name1", myInt, MUTABLE) + ), + hook1.anchor( + addDataName("name1", myInt, MUTABLE) + ) + )); + + // It is safe in separate Template scopes. + var template2 = Template.make(() -> body( + addDataName("name2", myInt, MUTABLE) + )); + var template3 = Template.make(() -> body( + template2.asToken(), + template2.asToken() + )); + + var template4 = Template.make(() -> body( + // The following is not safe, it would collide + // with (1), because it would be inserted to the + // hook1.anchor in template5, and hence be available + // inside the scope where (1) is available. + // See: testFailingAddNameDuplication8 + // addDataName("name", myInt, MUTABLE), + hook2.anchor( + // (2) This one is added second. Since it is + // inside the hook2.anchor, it does not go + // out to the hook1.anchor, and is not + // available inside the scope of (1). + addDataName("name3", myInt, MUTABLE) + ) + )); + var template5 = Template.make(() -> body( + hook1.anchor( + // (1) this is the first one we add. + addDataName("name3", myInt, MUTABLE) + ) + )); + + // Put it all together into a single test. + var template6 = Template.make(() -> body( + template1.asToken(), + template3.asToken(), + template5.asToken() + )); + + String code = template1.render(); + String expected = ""; + checkEQ(code, expected); + } + + public static void testStructuralNames1() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("type", (StructuralName.Type type) -> body( + "[#type:\n", + " exact: ", + structuralNames().exactOf(type).hasAny(), + ", ", + structuralNames().exactOf(type).count(), + ", {", + String.join(", ", structuralNames().exactOf(type).toList().stream().map(StructuralName::name).toList()), + "}\n", + " subtype: ", + structuralNames().subtypeOf(type).hasAny(), + ", ", + structuralNames().subtypeOf(type).count(), + ", {", + String.join(", ", structuralNames().subtypeOf(type).toList().stream().map(StructuralName::name).toList()), + "}\n", + " supertype: ", + structuralNames().supertypeOf(type).hasAny(), + ", ", + structuralNames().supertypeOf(type).count(), + ", {", + String.join(", ", structuralNames().supertypeOf(type).toList().stream().map(StructuralName::name).toList()), + "}\n", + "]\n" + )); + + List types = List.of(myStructuralTypeA, + myStructuralTypeA1, + myStructuralTypeA2, + myStructuralTypeA11, + myStructuralTypeB); + var template2 = Template.make(() -> body( + "StructuralNames:\n", + types.stream().map(t -> template1.asToken(t)).toList() + )); + + var template3 = Template.make("type", (StructuralName.Type type) -> body( + let("name", structuralNames().subtypeOf(type).sample()), + "Sample #type: #name\n" + )); + + var template4 = Template.make(() -> body( + "class $Q {\n", + template2.asToken(), + hook1.anchor( + "Create name for myStructuralTypeA11, should be visible for the supertypes\n", + addStructuralName($("v1"), myStructuralTypeA11), + template3.asToken(myStructuralTypeA11), + template3.asToken(myStructuralTypeA1), + template3.asToken(myStructuralTypeA), + "Create name for myStructuralTypeA, should never be visible for the subtypes\n", + addStructuralName($("v2"), myStructuralTypeA), + template3.asToken(myStructuralTypeA11), + template3.asToken(myStructuralTypeA1), + template2.asToken() + ), + template2.asToken(), + "}\n" + )); + + String code = template4.render(); + String expected = + """ + class Q_1 { + StructuralNames: + [StructuralA: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA1: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA11: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + Create name for myStructuralTypeA11, should be visible for the supertypes + Sample StructuralA11: StructuralName[name=v1_1, type=StructuralA11, weight=1] + Sample StructuralA1: StructuralName[name=v1_1, type=StructuralA11, weight=1] + Sample StructuralA: StructuralName[name=v1_1, type=StructuralA11, weight=1] + Create name for myStructuralTypeA, should never be visible for the subtypes + Sample StructuralA11: StructuralName[name=v1_1, type=StructuralA11, weight=1] + Sample StructuralA1: StructuralName[name=v1_1, type=StructuralA11, weight=1] + StructuralNames: + [StructuralA: + exact: true, 1, {v2_1} + subtype: true, 2, {v1_1, v2_1} + supertype: true, 1, {v2_1} + ] + [StructuralA1: + exact: false, 0, {} + subtype: true, 1, {v1_1} + supertype: true, 1, {v2_1} + ] + [StructuralA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: true, 1, {v2_1} + ] + [StructuralA11: + exact: true, 1, {v1_1} + subtype: true, 1, {v1_1} + supertype: true, 2, {v1_1, v2_1} + ] + [StructuralB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + StructuralNames: + [StructuralA: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA1: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA2: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralA11: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + [StructuralB: + exact: false, 0, {} + subtype: false, 0, {} + supertype: false, 0, {} + ] + } + """; + checkEQ(code, expected); + } + + public static void testStructuralNames2() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make("type", (StructuralName.Type type) -> body( + "[#type: ", + structuralNames().exactOf(type).hasAny(), + ", ", + structuralNames().exactOf(type).count(), + ", names: {", + String.join(", ", structuralNames().exactOf(type).toList().stream().map(StructuralName::name).toList()), + "}]\n" + )); + + var template2 = Template.make("name", "type", (String name, StructuralName.Type type) -> body( + addStructuralName(name, type), + "define #type #name\n" + )); + + var template3 = Template.make("type", (StructuralName.Type type) -> body( + "{ $access\n", + hook1.insert(template2.asToken($("name"), type)), + "$name = 5\n", + "} $access\n" + )); + + var template4 = Template.make("type", (StructuralName.Type type) -> body( + let("v", structuralNames().exactOf(type).sample().name()), + "{ $sample\n", + "blackhole(#v)\n", + "} $sample\n" + )); + + var template8 = Template.make(() -> body( + "class $X {\n", + template1.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeB), + hook1.anchor( + "begin $body\n", + template1.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeB), + "start with A\n", + template3.asToken(myStructuralTypeA), + "then access it\n", + template4.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeB), + "now make a B\n", + template3.asToken(myStructuralTypeB), + "then access to it\n", + template4.asToken(myStructuralTypeB), + template1.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeB) + ), + template1.asToken(myStructuralTypeA), + template1.asToken(myStructuralTypeB), + "}\n" + )); + + String code = template8.render(); + String expected = + """ + class X_1 { + [StructuralA: false, 0, names: {}] + [StructuralB: false, 0, names: {}] + define StructuralA name_6 + define StructuralB name_11 + begin body_1 + [StructuralA: false, 0, names: {}] + [StructuralB: false, 0, names: {}] + start with A + { access_6 + name_6 = 5 + } access_6 + then access it + { sample_8 + blackhole(name_6) + } sample_8 + [StructuralA: true, 1, names: {name_6}] + [StructuralB: false, 0, names: {}] + now make a B + { access_11 + name_11 = 5 + } access_11 + then access to it + { sample_13 + blackhole(name_11) + } sample_13 + [StructuralA: true, 1, names: {name_6}] + [StructuralB: true, 1, names: {name_11}] + [StructuralA: false, 0, names: {}] + [StructuralB: false, 0, names: {}] + } + """; + checkEQ(code, expected); + } + + record MyItem(DataName.Type type, String op) {} + + public static void testListArgument() { + var template1 = Template.make("item", (MyItem item) -> body( + let("type", item.type()), + let("op", item.op()), + "#type apply #op\n" + )); + + var template2 = Template.make("list", (List list) -> body( + "class $Z {\n", + // Use template1 for every item in the list. + list.stream().map(item -> template1.asToken(item)).toList(), + "}\n" + )); + + List list = List.of(new MyItem(myInt, "+"), + new MyItem(myInt, "-"), + new MyItem(myInt, "*"), + new MyItem(myInt, "/"), + new MyItem(myLong, "+"), + new MyItem(myLong, "-"), + new MyItem(myLong, "*"), + new MyItem(myLong, "/")); + + String code = template2.render(list); + String expected = + """ + class Z_1 { + int apply + + int apply - + int apply * + int apply / + long apply + + long apply - + long apply * + long apply / + } + """; + checkEQ(code, expected); + } + + public static void testFailingNestedRendering() { + var template1 = Template.make(() -> body( + "alpha\n" + )); + + var template2 = Template.make(() -> body( + "beta\n", + // Nested "render" call not allowed! + template1.render(), + "gamma\n" + )); + + String code = template2.render(); + } + + public static void testFailingDollarName1() { + var template1 = Template.make(() -> body( + let("x", $("")) // empty string not allowed + )); + String code = template1.render(); + } + + public static void testFailingDollarName2() { + var template1 = Template.make(() -> body( + let("x", $("#abc")) // "#" character not allowed + )); + String code = template1.render(); + } + + public static void testFailingDollarName3() { + var template1 = Template.make(() -> body( + let("x", $("abc#")) // "#" character not allowed + )); + String code = template1.render(); + } + + public static void testFailingDollarName4() { + var template1 = Template.make(() -> body( + let("x", $(null)) // Null input to dollar + )); + String code = template1.render(); + } + + public static void testFailingDollarName5() { + var template1 = Template.make(() -> body( + "$" // empty dollar name + )); + String code = template1.render(); + } + + public static void testFailingDollarName6() { + var template1 = Template.make(() -> body( + "asdf$" // empty dollar name + )); + String code = template1.render(); + } + + public static void testFailingDollarName7() { + var template1 = Template.make(() -> body( + "asdf$1" // Bad pattern after dollar + )); + String code = template1.render(); + } + + public static void testFailingDollarName8() { + var template1 = Template.make(() -> body( + "abc$$abc" // empty dollar name + )); + String code = template1.render(); + } + + public static void testFailingLetName1() { + var template1 = Template.make(() -> body( + let(null, $("abc")) // Null input for hashtag name + )); + String code = template1.render(); + } + + public static void testFailingHashtagName1() { + // Empty Template argument + var template1 = Template.make("", (String x) -> body( + )); + String code = template1.render("abc"); + } + + public static void testFailingHashtagName2() { + // "#" character not allowed in template argument + var template1 = Template.make("abc#abc", (String x) -> body( + )); + String code = template1.render("abc"); + } + + public static void testFailingHashtagName3() { + var template1 = Template.make(() -> body( + // Empty let hashtag name not allowed + let("", "abc") + )); + String code = template1.render(); + } + + public static void testFailingHashtagName4() { + var template1 = Template.make(() -> body( + // "#" character not allowed in let hashtag name + let("xyz#xyz", "abc") + )); + String code = template1.render(); + } + + public static void testFailingHashtagName5() { + var template1 = Template.make(() -> body( + "#" // empty hashtag name + )); + String code = template1.render(); + } + + public static void testFailingHashtagName6() { + var template1 = Template.make(() -> body( + "asdf#" // empty hashtag name + )); + String code = template1.render(); + } + + public static void testFailingHashtagName7() { + var template1 = Template.make(() -> body( + "asdf#1" // Bad pattern after hashtag + )); + String code = template1.render(); + } + + public static void testFailingHashtagName8() { + var template1 = Template.make(() -> body( + "abc##abc" // empty hashtag name + )); + String code = template1.render(); + } + + public static void testFailingDollarHashtagName1() { + var template1 = Template.make(() -> body( + "#$" // empty hashtag name + )); + String code = template1.render(); + } + + public static void testFailingDollarHashtagName2() { + var template1 = Template.make(() -> body( + "$#" // empty dollar name + )); + String code = template1.render(); + } + + public static void testFailingDollarHashtagName3() { + var template1 = Template.make(() -> body( + "#$name" // empty hashtag name + )); + String code = template1.render(); + } + + public static void testFailingDollarHashtagName4() { + var template1 = Template.make(() -> body( + "$#name" // empty dollar name + )); + String code = template1.render(); + } + + public static void testFailingHook() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make(() -> body( + "alpha\n" + )); + + var template2 = Template.make(() -> body( + "beta\n", + // Use hook without hook1.anchor + hook1.insert(template1.asToken()), + "gamma\n" + )); + + String code = template2.render(); + } + + public static void testFailingSample1() { + var template1 = Template.make(() -> body( + // No variable added yet. + let("v", dataNames(MUTABLE).exactOf(myInt).sample().name()), + "v is #v\n" + )); + + String code = template1.render(); + } + + public static void testFailingSample2() { + var template1 = Template.make(() -> body( + // no type restriction + let("v", dataNames(MUTABLE).sample().name()), + "v is #v\n" + )); + + String code = template1.render(); + } + + public static void testFailingHashtag1() { + // Duplicate hashtag definition from arguments. + var template1 = Template.make("a", "a", (String _, String _) -> body( + "nothing\n" + )); + + String code = template1.render("x", "y"); + } + + public static void testFailingHashtag2() { + var template1 = Template.make("a", (String _) -> body( + // Duplicate hashtag name + let("a", "x"), + "nothing\n" + )); + + String code = template1.render("y"); + } + + public static void testFailingHashtag3() { + var template1 = Template.make(() -> body( + let("a", "x"), + // Duplicate hashtag name + let("a", "y"), + "nothing\n" + )); + + String code = template1.render(); + } + + public static void testFailingHashtag4() { + var template1 = Template.make(() -> body( + // Missing hashtag name definition + "#a\n" + )); + + String code = template1.render(); + } + + public static void testFailingBinding1() { + var binding = new TemplateBinding(); + var template1 = Template.make(() -> body( + "nothing\n" + )); + binding.bind(template1); + // Duplicate bind + binding.bind(template1); + } + + public static void testFailingBinding2() { + var binding = new TemplateBinding(); + var template1 = Template.make(() -> body( + "nothing\n", + // binding was never bound. + binding.get() + )); + // Should have bound the binding here. + String code = template1.render(); + } + + public static void testFailingAddDataName1() { + var template1 = Template.make(() -> body( + // Must pick either MUTABLE or IMMUTABLE. + addDataName("name", myInt, MUTABLE_OR_IMMUTABLE) + )); + String code = template1.render(); + } + + public static void testFailingAddDataName2() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addDataName("name", myInt, MUTABLE, 0) + )); + String code = template1.render(); + } + + public static void testFailingAddDataName3() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addDataName("name", myInt, MUTABLE, -1) + )); + String code = template1.render(); + } + + public static void testFailingAddDataName4() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addDataName("name", myInt, MUTABLE, 1001) + )); + String code = template1.render(); + } + + public static void testFailingAddStructuralName1() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addStructuralName("name", myStructuralTypeA, 0) + )); + String code = template1.render(); + } + + public static void testFailingAddStructuralName2() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addStructuralName("name", myStructuralTypeA, -1) + )); + String code = template1.render(); + } + + public static void testFailingAddStructuralName3() { + var template1 = Template.make(() -> body( + // weight out of bounds [0..1000] + addStructuralName("name", myStructuralTypeA, 1001) + )); + String code = template1.render(); + } + + // Duplicate name in the same scope, name identical -> expect RendererException. + public static void testFailingAddNameDuplication1() { + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE), + addDataName("name", myInt, MUTABLE) + )); + String code = template1.render(); + } + + // Duplicate name in the same scope, names have different mutability -> expect RendererException. + public static void testFailingAddNameDuplication2() { + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE), + addDataName("name", myInt, IMMUTABLE) + )); + String code = template1.render(); + } + + // Duplicate name in the same scope, names have different type -> expect RendererException. + public static void testFailingAddNameDuplication3() { + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE), + addDataName("name", myLong, MUTABLE) + )); + String code = template1.render(); + } + + // Duplicate name in the same scope, name identical -> expect RendererException. + public static void testFailingAddNameDuplication4() { + var template1 = Template.make(() -> body( + addStructuralName("name", myStructuralTypeA), + addStructuralName("name", myStructuralTypeA) + )); + String code = template1.render(); + } + + // Duplicate name in the same scope, names have different type -> expect RendererException. + public static void testFailingAddNameDuplication5() { + var template1 = Template.make(() -> body( + addStructuralName("name", myStructuralTypeA), + addStructuralName("name", myStructuralTypeB) + )); + String code = template1.render(); + } + + // Duplicate name in inner Template, name identical -> expect RendererException. + public static void testFailingAddNameDuplication6() { + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE) + )); + var template2 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE), + template1.asToken() + )); + String code = template2.render(); + } + + // Duplicate name in Hook scope, name identical -> expect RendererException. + public static void testFailingAddNameDuplication7() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE), + hook1.anchor( + addDataName("name", myInt, MUTABLE) + ) + )); + String code = template1.render(); + } + + // Duplicate name in Hook.insert, name identical -> expect RendererException. + public static void testFailingAddNameDuplication8() { + var hook1 = new Hook("Hook1"); + + var template1 = Template.make(() -> body( + addDataName("name", myInt, MUTABLE) + )); + + var template2 = Template.make(() -> body( + hook1.anchor( + addDataName("name", myInt, MUTABLE), + hook1.insert(template1.asToken()) + ) + )); + String code = template2.render(); + } + + public static void expectRendererException(FailingTest test, String errorPrefix) { + try { + test.run(); + System.out.println("Should have thrown RendererException with prefix: " + errorPrefix); + throw new RuntimeException("Should have thrown!"); + } catch(RendererException e) { + if (!e.getMessage().startsWith(errorPrefix)) { + System.out.println("Should have thrown with prefix: " + errorPrefix); + System.out.println("got: " + e.getMessage()); + throw new RuntimeException("Prefix mismatch", e); + } + } + } + + public static void expectIllegalArgumentException(FailingTest test, String errorPrefix) { + try { + test.run(); + System.out.println("Should have thrown IllegalArgumentException with prefix: " + errorPrefix); + throw new RuntimeException("Should have thrown!"); + } catch(IllegalArgumentException e) { + if (!e.getMessage().startsWith(errorPrefix)) { + System.out.println("Should have thrown with prefix: " + errorPrefix); + System.out.println("got: " + e.getMessage()); + throw new RuntimeException("Prefix mismatch", e); + } + } + } + + public static void expectUnsupportedOperationException(FailingTest test, String errorPrefix) { + try { + test.run(); + System.out.println("Should have thrown UnsupportedOperationException with prefix: " + errorPrefix); + throw new RuntimeException("Should have thrown!"); + } catch(UnsupportedOperationException e) { + if (!e.getMessage().startsWith(errorPrefix)) { + System.out.println("Should have thrown with prefix: " + errorPrefix); + System.out.println("got: " + e.getMessage()); + throw new RuntimeException("Prefix mismatch", e); + } + } + } + + public static void checkEQ(String code, String expected) { + if (!code.equals(expected)) { + System.out.println("\"" + code + "\""); + System.out.println("\"" + expected + "\""); + throw new RuntimeException("Template rendering mismatch!"); + } + } +} From a653ff48933bfd72c7c3d004ccc5bd0d9c1162cb Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 4 Jun 2025 13:39:31 +0000 Subject: [PATCH 139/216] 8358536: jdk/jfr/api/consumer/TestRecordingFileWrite.java times out Reviewed-by: mgronlun --- .../classes/jdk/jfr/internal/tool/PrettyWriter.java | 9 ++++++--- test/jdk/ProblemList.txt | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java index 274a21d9b49..10f50095247 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java @@ -117,11 +117,11 @@ public final class PrettyWriter extends EventPrintWriter { // At the same time, a too large window, means it will take more time // before the first event is printed and the tool will feel unresponsive. private static final int EVENT_WINDOW_SIZE = 1_000_000; - private final PriorityQueue timeline = new PriorityQueue<>(EVENT_WINDOW_SIZE + 4); - private final Map typeInformation = new HashMap<>(); - private final Map> contexts = new HashMap<>(); private final boolean showExact; private RecordedEvent currentEvent; + private PriorityQueue timeline; + private Map typeInformation; + private Map> contexts; public PrettyWriter(PrintWriter destination, boolean showExact) { super(destination); @@ -133,6 +133,9 @@ public final class PrettyWriter extends EventPrintWriter { } void print(Path source) throws IOException { + timeline = new PriorityQueue<>(EVENT_WINDOW_SIZE + 4); + typeInformation = new HashMap<>(); + contexts = new HashMap<>(); printBegin(); int counter = 0; try (RecordingFile file = new RecordingFile(source)) { diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index f44dd5c7a7d..28bb2a1f033 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -774,7 +774,6 @@ jdk/jfr/event/compiler/TestCodeSweeper.java 8338127 generic- jdk/jfr/event/oldobject/TestShenandoah.java 8342951 generic-all jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64 jdk/jfr/jvm/TestWaste.java 8282427 generic-all -jdk/jfr/api/consumer/TestRecordingFileWrite.java 8358536 generic-all ############################################################################ From 0352477ff5977b0010e62000adbde88026a49a7e Mon Sep 17 00:00:00 2001 From: Tom Shull Date: Wed, 4 Jun 2025 13:50:36 +0000 Subject: [PATCH 140/216] 8357660: [JVMCI] Add support for retrieving all BootstrapMethodInvocations directly from ConstantPool Reviewed-by: dnsimon, yzheng --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 9 ++++ .../jdk/vm/ci/hotspot/CompilerToVM.java | 14 ++++- .../vm/ci/hotspot/HotSpotConstantPool.java | 51 +++++++++++++++++-- .../classes/jdk/vm/ci/meta/ConstantPool.java | 35 ++++++++++++- .../ci/hotspot/test/TestDynamicConstant.java | 47 +++++++++++++++-- 5 files changed, 144 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 4f6d4aaa099..d45036ced94 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -813,6 +813,14 @@ C2V_VMENTRY_NULL(jobject, lookupConstantInPool, (JNIEnv* env, jobject, ARGUMENT_ return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj)); C2V_END +C2V_VMENTRY_0(jint, getNumIndyEntries, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp))) + constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp)); + if (cp->cache()->resolved_indy_entries() == nullptr) { + return 0; + } + return cp->resolved_indy_entries_length(); +C2V_END + C2V_VMENTRY_NULL(jobjectArray, resolveBootstrapMethod, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index)) constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp)); constantTag tag = cp->tag_at(index); @@ -3320,6 +3328,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL2 "II)" OBJECTCONSTANT, FN_PTR(lookupAppendixInPool)}, {CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL2 "IB" HS_METHOD2 ")" HS_METHOD, FN_PTR(lookupMethodInPool)}, {CC "lookupConstantInPool", CC "(" HS_CONSTANT_POOL2 "IZ)" JAVACONSTANT, FN_PTR(lookupConstantInPool)}, + {CC "getNumIndyEntries", CC "(" HS_CONSTANT_POOL2 ")I", FN_PTR(getNumIndyEntries)}, {CC "resolveBootstrapMethod", CC "(" HS_CONSTANT_POOL2 "I)[" OBJECT, FN_PTR(resolveBootstrapMethod)}, {CC "bootstrapArgumentIndexAt", CC "(" HS_CONSTANT_POOL2 "II)I", FN_PTR(bootstrapArgumentIndexAt)}, {CC "getUncachedStringInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(getUncachedStringInPool)}, diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java index 045b1f0fc12..0cb56354498 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java @@ -468,9 +468,19 @@ final class CompilerToVM { */ int decodeMethodIndexToCPIndex(HotSpotConstantPool constantPool, int rawIndex) { return decodeMethodIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), rawIndex); - } + } - private native int decodeMethodIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex); + private native int decodeMethodIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex); + + /** + * Returns the number of {@code ResolvedIndyEntry}s present within this constant + * pool. + */ + int getNumIndyEntries(HotSpotConstantPool constantPool) { + return getNumIndyEntries(constantPool, constantPool.getConstantPoolPointer()); + } + + private native int getNumIndyEntries(HotSpotConstantPool constantPool, long constantPoolPointer); /** * Resolves the details for invoking the bootstrap method associated with the diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java index 84fb21d1948..20e3915527d 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java @@ -25,6 +25,7 @@ package jdk.vm.ci.hotspot; import java.util.AbstractList; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.IntStream; import jdk.vm.ci.common.JVMCIError; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; @@ -530,19 +531,21 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO } } - static class BootstrapMethodInvocationImpl implements BootstrapMethodInvocation { + class BootstrapMethodInvocationImpl implements BootstrapMethodInvocation { private final boolean indy; private final ResolvedJavaMethod method; private final String name; private final JavaConstant type; private final List staticArguments; + private final int cpiOrIndyIndex; - BootstrapMethodInvocationImpl(boolean indy, ResolvedJavaMethod method, String name, JavaConstant type, List staticArguments) { + BootstrapMethodInvocationImpl(boolean indy, ResolvedJavaMethod method, String name, JavaConstant type, List staticArguments, int cpiOrIndyIndex) { this.indy = indy; this.method = method; this.name = name; this.type = type; this.staticArguments = staticArguments; + this.cpiOrIndyIndex = cpiOrIndyIndex; } @Override @@ -570,6 +573,24 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO return staticArguments; } + @Override + public void resolve() { + if (isInvokeDynamic()) { + loadReferencedType(cpiOrIndyIndex, Bytecodes.INVOKEDYNAMIC); + } else { + lookupConstant(cpiOrIndyIndex, true); + } + } + + @Override + public JavaConstant lookup() { + if (isInvokeDynamic()) { + return lookupAppendix(cpiOrIndyIndex, Bytecodes.INVOKEDYNAMIC); + } else { + return (JavaConstant) lookupConstant(cpiOrIndyIndex, false); + } + } + @Override public String toString() { String static_args = staticArguments.stream().map(BootstrapMethodInvocationImpl::argumentAsString).collect(Collectors.joining(", ", "[", "]")); @@ -612,12 +633,36 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO int bss_index = bsciArgs[1]; staticArgumentsList = new CachedBSMArgs(this, bss_index, argCount); } - return new BootstrapMethodInvocationImpl(tag.name.equals("InvokeDynamic"), method, name, type, staticArgumentsList); + boolean isIndy = tag.name.equals("InvokeDynamic"); + return new BootstrapMethodInvocationImpl(isIndy, method, name, type, staticArgumentsList, isIndy ? index : cpi); default: return null; } } + private boolean isDynamicEntry(int cpi) { + JvmConstant tagAt = getTagAt(cpi); + return tagAt != null && tagAt.name.equals("Dynamic"); + } + + @Override + public List lookupBootstrapMethodInvocations(boolean invokeDynamic){ + if (invokeDynamic) { + int numIndys = compilerToVM().getNumIndyEntries(this); + if (numIndys == 0) { + return List.of(); + } + return IntStream.range(0, numIndys) + .mapToObj(i -> lookupBootstrapMethodInvocation(i, Bytecodes.INVOKEDYNAMIC)) + .toList(); + } else { + return IntStream.range(1, length()) + .filter(this::isDynamicEntry) + .mapToObj(cpi -> lookupBootstrapMethodInvocation(cpi, -1)) + .toList(); + } + } + /** * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of a field. */ diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java index 2273b256f03..0b7fd70762d 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java @@ -186,11 +186,28 @@ public interface ConstantPool { * } * * - * The other types of entries are already resolved an can be used directly. + * The other types of entries are already resolved and can be used directly. * * @jvms 5.4.3.6 */ List getStaticArguments(); + + /** + * Resolves the element corresponding to this bootstrap. If + * {@code isInvokeDynamic()}, then the corresponding invoke dynamic is resolved. + * If {@code !isInvokeDynamic()}, then the dynamic constant pool entry will be + * resolved. + * + * @jvms 5.4.3.6 + */ + void resolve(); + + /** + * If {@code isInvokeDynamic()}, then this method looks up the corresponding + * invoke dynamic's appendix. If {@code !isInvokeDynamic()}, then this will + * return the constant pool entry's value. + */ + JavaConstant lookup(); } /** @@ -204,13 +221,27 @@ public interface ConstantPool { * @param opcode must be {@code Bytecodes.INVOKEDYNAMIC}, or -1 if * {@code index} was not decoded from a bytecode stream * @return the bootstrap method invocation details or {@code null} if the entry specified by {@code index} - * is not a {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info} + * is not a {@code CONSTANT_Dynamic_info} or {@code CONSTANT_InvokeDynamic_info} * @jvms 4.7.23 The {@code BootstrapMethods} Attribute */ default BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int opcode) { throw new UnsupportedOperationException(); } + /** + * Returns either the BootstrapMethodInvocation instances for all invokedynamic + * bytecodes which reference this constant pool, or all + * {@code CONSTANT_Dynamic_info} BootstrapMethodInvocations within this constant + * pool. The returned List is unmodifiable; calls to any mutator method will + * always cause {@code UnsupportedOperationException} to be thrown. + * + * @param invokeDynamic when true, return all invokedynamic + * BootstrapMethodInvocations; otherwise, return all + * {@code CONSTANT_Dynamic_info} + * BootstrapMethodInvocations. + */ + List lookupBootstrapMethodInvocations(boolean invokeDynamic); + /** * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks * specific to the bytecode it denotes are performed if the type is already resolved. Should any diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java index b22cb01d81a..b6e4f9cf2ef 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java @@ -49,7 +49,7 @@ import java.lang.invoke.StringConcatFactory; import java.lang.reflect.Method; import java.nio.file.Files; import java.util.List; -import java.util.Set; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.Test; @@ -376,9 +376,10 @@ public class TestDynamicConstant implements Opcodes { ResolvedJavaMethod concat = metaAccess.lookupJavaMethod(m); ConstantPool cp = concat.getConstantPool(); - Set expectedBSMs = Set.of( - "jdk.vm.ci.hotspot.test.TestDynamicConstant.shouldNotBeCalledBSM", - "java.lang.invoke.StringConcatFactory.makeConcatWithConstants" + // Contains a map of (bootstrap method names, resolvable) values. + Map expectedIndyBSMs = Map.of( + "jdk.vm.ci.hotspot.test.TestDynamicConstant.shouldNotBeCalledBSM", false, + "java.lang.invoke.StringConcatFactory.makeConcatWithConstants", true ); for (int cpi = 1; cpi < cp.length(); cpi++) { @@ -389,9 +390,10 @@ public class TestDynamicConstant implements Opcodes { String bsm = bsmi.getMethod().format("%H.%n"); if (tag.equals("InvokeDynamic")) { Assert.assertTrue(bsmi.isInvokeDynamic()); - Assert.assertTrue(expectedBSMs.contains(bsm), expectedBSMs.toString()); + Assert.assertTrue(expectedIndyBSMs.containsKey(bsm), expectedIndyBSMs.toString()); } else { Assert.assertFalse(bsmi.isInvokeDynamic()); + Assert.assertNull(bsmi.lookup()); checkBsmName(condyType, bsm); List staticArguments = bsmi.getStaticArguments(); for (int i = 0; i < staticArguments.size(); ++i) { @@ -423,6 +425,41 @@ public class TestDynamicConstant implements Opcodes { } testLoadReferencedType(concat, cp); + + testLookupBootstrapMethodInvocations(condyType, cp, expectedIndyBSMs); + } + + private static void testLookupBootstrapMethodInvocations(CondyType condyType, ConstantPool cp, Map expectedIndyBSMs) { + List indyBSMs = cp.lookupBootstrapMethodInvocations(true); + Assert.assertEquals(indyBSMs.size(), 2); + for (var bsmi : indyBSMs) { + String bsm = bsmi.getMethod().format("%H.%n"); + Assert.assertTrue(expectedIndyBSMs.containsKey(bsm), expectedIndyBSMs.toString()); + Assert.assertTrue(bsmi.isInvokeDynamic()); + if (expectedIndyBSMs.get(bsm)) { + bsmi.resolve(); + Assert.assertNotNull(bsmi.lookup()); + } else { + try { + bsmi.resolve(); + } catch (BootstrapMethodError bme) { + // expected error + } + Assert.assertNull(bsmi.lookup()); + } + } + + List condyBSMs = cp.lookupBootstrapMethodInvocations(false); + int expectedNumCondys = switch(condyType) { + case CALL_DIRECT_BSM, CALL_INDIRECT_BSM -> 1; + case CALL_DIRECT_WITH_ARGS_BSM, CALL_INDIRECT_WITH_ARGS_BSM -> 2; + }; + Assert.assertEquals(condyBSMs.size(), expectedNumCondys); + for (var bsmi : condyBSMs) { + Assert.assertTrue(!bsmi.isInvokeDynamic()); + bsmi.resolve(); + Assert.assertNotNull(bsmi.lookup()); + } } private static void checkBsmName(CondyType condyType, String bsm) { From ae1892fb0fb6b7646f9ca60067d6945ccea7f888 Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Wed, 4 Jun 2025 14:07:49 +0000 Subject: [PATCH 141/216] 8358003: KlassTrainingData initializer reads garbage holder Reviewed-by: coleenp, shade, vlivanov --- src/hotspot/share/oops/trainingData.cpp | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/oops/trainingData.cpp b/src/hotspot/share/oops/trainingData.cpp index 543462b1182..2ae1ac18699 100644 --- a/src/hotspot/share/oops/trainingData.cpp +++ b/src/hotspot/share/oops/trainingData.cpp @@ -432,24 +432,11 @@ void KlassTrainingData::print_on(outputStream* st, bool name_only) const { } KlassTrainingData::KlassTrainingData(InstanceKlass* klass) : TrainingData(klass) { - if (holder() == klass) { - return; // no change to make - } - - jobject hmj = _holder_mirror; - if (hmj != nullptr) { // clear out previous handle, if any - _holder_mirror = nullptr; - assert(JNIHandles::is_global_handle(hmj), ""); - JNIHandles::destroy_global(hmj); - } - - if (klass != nullptr) { - Handle hm(JavaThread::current(), klass->java_mirror()); - hmj = JNIHandles::make_global(hm); - Atomic::release_store(&_holder_mirror, hmj); - } - - Atomic::release_store(&_holder, const_cast(klass)); + assert(klass != nullptr, ""); + Handle hm(JavaThread::current(), klass->java_mirror()); + jobject hmj = JNIHandles::make_global(hm); + _holder_mirror = hmj; + _holder = klass; assert(holder() == klass, ""); } From a2723d91dfba2850e3070083fa94dc3fecc46a00 Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Wed, 4 Jun 2025 14:16:20 +0000 Subject: [PATCH 142/216] 8345347: Test runtime/cds/TestDefaultArchiveLoading.java should accept VM flags or be marked as flagless Reviewed-by: lmesnik, stefank, ccheung --- .../jtreg/runtime/cds/TestDefaultArchiveLoading.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java b/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java index ddc3603b16d..d90618b51f2 100644 --- a/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java +++ b/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,6 +26,7 @@ * @test id=nocoops_nocoh * @summary Test Loading of default archives in all configurations * @requires vm.cds + * @requires vm.cds.write.archived.java.heap * @requires vm.bits == 64 * @library /test/lib * @modules java.base/jdk.internal.misc @@ -37,6 +38,7 @@ * @test id=nocoops_coh * @summary Test Loading of default archives in all configurations (requires --enable-cds-archive-coh) * @requires vm.cds + * @requires vm.cds.write.archived.java.heap * @requires vm.bits == 64 * @library /test/lib * @modules java.base/jdk.internal.misc @@ -48,6 +50,7 @@ * @test id=coops_nocoh * @summary Test Loading of default archives in all configurations * @requires vm.cds + * @requires vm.cds.write.archived.java.heap * @requires vm.bits == 64 * @library /test/lib * @modules java.base/jdk.internal.misc @@ -59,6 +62,7 @@ * @test id=coops_coh * @summary Test Loading of default archives in all configurations (requires --enable-cds-archive-coh) * @requires vm.cds + * @requires vm.cds.write.archived.java.heap * @requires vm.bits == 64 * @library /test/lib * @modules java.base/jdk.internal.misc @@ -131,7 +135,7 @@ public class TestDefaultArchiveLoading { default: throw new RuntimeException("Invalid argument " + args[0]); } - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:" + coh + "UseCompactObjectHeaders", "-XX:" + coops + "UseCompressedOops", "-Xlog:cds", From 4e314cb9e025672b2f7b68cc021fa516ee219ad8 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 4 Jun 2025 14:21:34 +0000 Subject: [PATCH 143/216] 8356000: C1/C2-only modes use 2 compiler threads on low CPU count machines Reviewed-by: kvn, dfenacci, galder --- .../share/compiler/compilationPolicy.cpp | 11 +- .../arguments/TestCompilerCounts.java | 177 ++++++++++++++++++ 2 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/arguments/TestCompilerCounts.java diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index d95debeda44..39c90281c79 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -550,6 +550,7 @@ void CompilationPolicy::initialize() { int count = CICompilerCount; bool c1_only = CompilerConfig::is_c1_only(); bool c2_only = CompilerConfig::is_c2_or_jvmci_compiler_only(); + int min_count = (c1_only || c2_only) ? 1 : 2; #ifdef _LP64 // Turn on ergonomic compiler count selection @@ -560,7 +561,7 @@ void CompilationPolicy::initialize() { // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n int log_cpu = log2i(os::active_processor_count()); int loglog_cpu = log2i(MAX2(log_cpu, 1)); - count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2); + count = MAX2(log_cpu * loglog_cpu * 3 / 2, min_count); // Make sure there is enough space in the code cache to hold all the compiler buffers size_t c1_size = 0; #ifdef COMPILER1 @@ -574,7 +575,7 @@ void CompilationPolicy::initialize() { int max_count = (ReservedCodeCacheSize - (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3))) / (int)buffer_size; if (count > max_count) { // Lower the compiler count such that all buffers fit into the code cache - count = MAX2(max_count, c1_only ? 1 : 2); + count = MAX2(max_count, min_count); } FLAG_SET_ERGO(CICompilerCount, count); } @@ -593,9 +594,10 @@ void CompilationPolicy::initialize() { #endif if (c1_only) { - // No C2 compiler thread required + // No C2 compiler threads are needed set_c1_count(count); } else if (c2_only) { + // No C1 compiler threads are needed set_c2_count(count); } else { #if INCLUDE_JVMCI @@ -613,6 +615,9 @@ void CompilationPolicy::initialize() { } assert(count == c1_count() + c2_count(), "inconsistent compiler thread count"); set_increase_threshold_at_ratio(); + } else { + // Interpreter mode creates no compilers + FLAG_SET_ERGO(CICompilerCount, 0); } set_start_time(nanos_to_millis(os::javaTimeNanos())); } diff --git a/test/hotspot/jtreg/compiler/arguments/TestCompilerCounts.java b/test/hotspot/jtreg/compiler/arguments/TestCompilerCounts.java new file mode 100644 index 00000000000..420dc2b3414 --- /dev/null +++ b/test/hotspot/jtreg/compiler/arguments/TestCompilerCounts.java @@ -0,0 +1,177 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @library /test/lib / + * @bug 8356000 + * @requires vm.flagless + * @requires vm.bits == "64" + * @run driver compiler.arguments.TestCompilerCounts + */ + +package compiler.arguments; + +import java.io.IOException; +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.function.Function; +import jdk.test.lib.Asserts; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.cli.CommandLineOptionTest; + +public class TestCompilerCounts { + + // Try not to go over max CPU count on the machine, since we do not + // know if the rest of runtime would accept it. + // For local testing, feel free to override this to a larger value + // if you want to see how heuristics works on even larger machines. + static final int MAX_CPUS = Runtime.getRuntime().availableProcessors(); + + // Test at most 16 CPUs linearly, to limit test execution time. + // After this limit, go for exponential steps. + static final int MAX_LINEAR_CPUS = Math.min(16, MAX_CPUS); + + public static void main(String[] args) throws Throwable { + // CICompilerCount=0 is incorrect in default modes. + fail("-XX:CICompilerCount=0"); + + // Interpreter-only mode accepts all values, but sets 0 threads + pass(0, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=0"); + + // C1/C2 only modes accept CICompilerCount=1 + pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=1"); + pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=2"); + pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=3"); + pass(1, "-XX:CICompilerCount=1", "-XX:-TieredCompilation"); + + // C1+C2 modes need at least 2 threads + fail("-XX:CICompilerCount=1"); + fail("-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=4"); + + // Overriding the CICompilerCount overrides compiler counts hard. + for (int count = 2; count <= MAX_CPUS; count += (count >= MAX_LINEAR_CPUS ? count : 1)) { + String opt = "-XX:CICompilerCount=" + count; + + // Interpreter-only mode always sets 0 threads + pass(0, opt, "-XX:TieredStopAtLevel=0"); + + // All compiled modes accept reasonable CICompilerCount + pass(count, opt); + pass(count, opt, "-XX:TieredStopAtLevel=1"); + pass(count, opt, "-XX:TieredStopAtLevel=2"); + pass(count, opt, "-XX:TieredStopAtLevel=3"); + pass(count, opt, "-XX:TieredStopAtLevel=4"); + pass(count, opt, "-XX:-TieredCompilation"); + } + + // Per CPU heuristics is disabled, we are going to set up defaults. + + for (int cpus = 2; cpus <= MAX_CPUS; cpus += (cpus >= MAX_LINEAR_CPUS ? cpus : 1)) { + String opt = "-XX:ActiveProcessorCount=" + cpus; + String opt2 = "-XX:-CICompilerCountPerCPU"; + + // Interpreter-only mode always set 0 threads + pass(0, opt, opt2, "-XX:TieredStopAtLevel=0"); + + // All compiled modes default to 2 threads, statically compiled in + pass(2, opt, opt2); + pass(2, opt, opt2, "-XX:TieredStopAtLevel=1"); + pass(2, opt, opt2, "-XX:TieredStopAtLevel=2"); + pass(2, opt, opt2, "-XX:TieredStopAtLevel=3"); + pass(2, opt, opt2, "-XX:TieredStopAtLevel=4"); + pass(2, opt, opt2, "-XX:-TieredCompilation"); + } + + // Otherwise, we set CICompilerCount heuristically. + + // Check hitting the lower values exactly first. + for (int cpus = 1; cpus <= 3; cpus++) { + String opt = "-XX:ActiveProcessorCount=" + cpus; + + // Interpreter-only mode always set 0 threads + pass(0, opt, "-XX:TieredStopAtLevel=0"); + + // Non-tiered modes set 1 thread + pass(1, opt, "-XX:TieredStopAtLevel=1"); + pass(1, opt, "-XX:TieredStopAtLevel=2"); + pass(1, opt, "-XX:TieredStopAtLevel=3"); + pass(1, opt, "-XX:-TieredCompilation"); + + // Tiered modes set 2 threads + pass(2, opt); + pass(2, opt, "-XX:TieredStopAtLevel=4"); + } + + // Check what heuristics sets past the trivial number of CPUs. + for (int cpus = 4; cpus <= MAX_CPUS; cpus += (cpus >= MAX_LINEAR_CPUS ? cpus : 1)) { + String opt = "-XX:ActiveProcessorCount=" + cpus; + + // Interpreter-only mode always set 0 threads + pass(0, opt, "-XX:TieredStopAtLevel=0"); + + // Non-tiered modes + int nonTieredCount = heuristicCount(cpus, false); + pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=1"); + pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=2"); + pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=3"); + pass(nonTieredCount, opt, "-XX:-TieredCompilation"); + + // Tiered modes + int tieredCount = heuristicCount(cpus, true); + pass(tieredCount, opt); + pass(tieredCount, opt, "-XX:TieredStopAtLevel=4"); + + // Also check that heuristics did not set up more threads than CPUs available + Asserts.assertTrue(nonTieredCount <= cpus, + "Non-tiered count is larger than number of CPUs: " + nonTieredCount + " > " + cpus); + Asserts.assertTrue(tieredCount <= cpus, + "Tiered count is larger than number of CPUs: " + tieredCount + " > " + cpus); + } + } + + // Direct translation from CompilationPolicy::initialize: + public static int heuristicCount(int cpus, boolean tiered) { + int log_cpu = log2(cpus); + int loglog_cpu = log2(Math.max(log_cpu, 1)); + int min_count = tiered ? 2 : 1; + return Math.max(log_cpu * loglog_cpu * 3 / 2, min_count); + } + + public static int log2(int v) { + return (int)(Math.log(v) / Math.log(2)); + } + + public static void pass(int count, String... args) throws Throwable { + CommandLineOptionTest.verifyOptionValueForSameVM("CICompilerCount", "" + count, "", args); + } + + public static void fail(String... args) throws Throwable { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotHaveExitValue(0); + } + +} From c90921644643bc731cab4c014a5144a74e670df1 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Wed, 4 Jun 2025 14:56:20 +0000 Subject: [PATCH 144/216] 8357443: ZGC: Optimize old page iteration in remap remembered phase Reviewed-by: aboldtch, eosterlund --- src/hotspot/share/gc/z/zGeneration.cpp | 19 ++-- src/hotspot/share/gc/z/zGeneration.hpp | 6 ++ src/hotspot/share/gc/z/zRemembered.cpp | 120 +++++++++++++------------ src/hotspot/share/gc/z/zRemembered.hpp | 22 +++++ 4 files changed, 101 insertions(+), 66 deletions(-) diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 78860bbe4cb..772c5a0a98b 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -948,6 +948,14 @@ void ZGenerationYoung::register_with_remset(ZPage* page) { _remembered.register_found_old(page); } +ZRemembered* ZGenerationYoung::remembered() { + return &_remembered; +} + +void ZGenerationYoung::remap_current_remset(ZRemsetTableIterator* iter) { + _remembered.remap_current(iter); +} + ZGenerationTracer* ZGenerationYoung::jfr_tracer() { return &_jfr_tracer; } @@ -1435,7 +1443,7 @@ typedef ClaimingCLDToOopClosure ZRemapCLDClosure; class ZRemapYoungRootsTask : public ZTask { private: - ZGenerationPagesParallelIterator _old_pages_parallel_iterator; + ZRemsetTableIterator _remset_table_iterator; ZRootsIteratorAllColored _roots_colored; ZRootsIteratorAllUncolored _roots_uncolored; @@ -1449,7 +1457,7 @@ private: public: ZRemapYoungRootsTask(ZPageTable* page_table, ZPageAllocator* page_allocator) : ZTask("ZRemapYoungRootsTask"), - _old_pages_parallel_iterator(page_table, ZGenerationId::old, page_allocator), + _remset_table_iterator(ZGeneration::young()->remembered(), false /* previous */), _roots_colored(ZGenerationIdOptional::old), _roots_uncolored(ZGenerationIdOptional::old), _cl_colored(), @@ -1472,11 +1480,8 @@ public: { ZStatTimerWorker timer(ZSubPhaseConcurrentRemapRememberedOld); - _old_pages_parallel_iterator.do_pages([&](ZPage* page) { - // Visit all object fields that potentially pointing into young generation - page->oops_do_current_remembered(ZBarrier::load_barrier_on_oop_field); - return true; - }); + // Visit all object fields that potentially pointing into young generation + ZGeneration::young()->remap_current_remset(&_remset_table_iterator); } } }; diff --git a/src/hotspot/share/gc/z/zGeneration.hpp b/src/hotspot/share/gc/z/zGeneration.hpp index 922efe5ef9e..13adc06b123 100644 --- a/src/hotspot/share/gc/z/zGeneration.hpp +++ b/src/hotspot/share/gc/z/zGeneration.hpp @@ -191,6 +191,7 @@ class ZGenerationYoung : public ZGeneration { friend class VM_ZMarkStartYoung; friend class VM_ZMarkStartYoungAndOld; friend class VM_ZRelocateStartYoung; + friend class ZRemapYoungRootsTask; friend class ZYoungTypeSetter; private: @@ -219,6 +220,8 @@ private: void pause_relocate_start(); void concurrent_relocate(); + ZRemembered* remembered(); + public: ZGenerationYoung(ZPageTable* page_table, const ZForwardingTable* old_forwarding_table, @@ -252,6 +255,9 @@ public: // Register old pages with remembered set void register_with_remset(ZPage* page); + // Remap the oops of the current remembered set + void remap_current_remset(ZRemsetTableIterator* iter); + // Serviceability ZGenerationTracer* jfr_tracer(); diff --git a/src/hotspot/share/gc/z/zRemembered.cpp b/src/hotspot/share/gc/z/zRemembered.cpp index b94d676242c..815b914dd8d 100644 --- a/src/hotspot/share/gc/z/zRemembered.cpp +++ b/src/hotspot/share/gc/z/zRemembered.cpp @@ -392,69 +392,71 @@ struct ZRemsetTableEntry { ZForwarding* _forwarding; }; -class ZRemsetTableIterator { -private: - ZRemembered* const _remembered; - ZPageTable* const _page_table; - const ZForwardingTable* const _old_forwarding_table; - volatile BitMap::idx_t _claimed; - -public: - ZRemsetTableIterator(ZRemembered* remembered) - : _remembered(remembered), - _page_table(remembered->_page_table), - _old_forwarding_table(remembered->_old_forwarding_table), - _claimed(0) {} +ZRemsetTableIterator::ZRemsetTableIterator(ZRemembered* remembered, bool previous) + : _remembered(remembered), + _bm(previous + ? _remembered->_found_old.previous_bitmap() + : _remembered->_found_old.current_bitmap()), + _page_table(remembered->_page_table), + _old_forwarding_table(remembered->_old_forwarding_table), + _claimed(0) {} // This iterator uses the "found old" optimization. - bool next(ZRemsetTableEntry* entry_addr) { - BitMap* const bm = _remembered->_found_old.previous_bitmap(); +bool ZRemsetTableIterator::next(ZRemsetTableEntry* entry_addr) { + BitMap::idx_t prev = Atomic::load(&_claimed); - BitMap::idx_t prev = Atomic::load(&_claimed); - - for (;;) { - if (prev == bm->size()) { - return false; - } - - const BitMap::idx_t page_index = bm->find_first_set_bit(_claimed); - if (page_index == bm->size()) { - Atomic::cmpxchg(&_claimed, prev, page_index, memory_order_relaxed); - return false; - } - - const BitMap::idx_t res = Atomic::cmpxchg(&_claimed, prev, page_index + 1, memory_order_relaxed); - if (res != prev) { - // Someone else claimed - prev = res; - continue; - } - - // Found bit - look around for page or forwarding to scan - - ZForwarding* forwarding = nullptr; - if (ZGeneration::old()->is_phase_relocate()) { - forwarding = _old_forwarding_table->at(page_index); - } - - ZPage* page = _page_table->at(page_index); - if (page != nullptr && !page->is_old()) { - page = nullptr; - } - - if (page == nullptr && forwarding == nullptr) { - // Nothing to scan - continue; - } - - // Found old page or old forwarding - entry_addr->_forwarding = forwarding; - entry_addr->_page = page; - - return true; + for (;;) { + if (prev == _bm->size()) { + return false; } + + const BitMap::idx_t page_index = _bm->find_first_set_bit(_claimed); + if (page_index == _bm->size()) { + Atomic::cmpxchg(&_claimed, prev, page_index, memory_order_relaxed); + return false; + } + + const BitMap::idx_t res = Atomic::cmpxchg(&_claimed, prev, page_index + 1, memory_order_relaxed); + if (res != prev) { + // Someone else claimed + prev = res; + continue; + } + + // Found bit - look around for page or forwarding to scan + + ZForwarding* forwarding = nullptr; + if (ZGeneration::old()->is_phase_relocate()) { + forwarding = _old_forwarding_table->at(page_index); + } + + ZPage* page = _page_table->at(page_index); + if (page != nullptr && !page->is_old()) { + page = nullptr; + } + + if (page == nullptr && forwarding == nullptr) { + // Nothing to scan + continue; + } + + // Found old page or old forwarding + entry_addr->_forwarding = forwarding; + entry_addr->_page = page; + + return true; } -}; +} + +void ZRemembered::remap_current(ZRemsetTableIterator* iter) { + for (ZRemsetTableEntry entry; iter->next(&entry);) { + assert(entry._forwarding == nullptr, "Shouldn't be looking for forwardings"); + assert(entry._page != nullptr, "Must have found a page"); + assert(entry._page->is_old(), "Should only have found old pages"); + + entry._page->oops_do_current_remembered(ZBarrier::load_barrier_on_oop_field); + } +} // This task scans the remembered set and follows pointers when possible. // Interleaving remembered set scanning with marking makes the marking times @@ -470,7 +472,7 @@ public: : ZRestartableTask("ZRememberedScanMarkFollowTask"), _remembered(remembered), _mark(mark), - _remset_table_iterator(remembered) { + _remset_table_iterator(remembered, true /* previous */) { _mark->prepare_work(); _remembered->_page_allocator->enable_safe_destroy(); } diff --git a/src/hotspot/share/gc/z/zRemembered.hpp b/src/hotspot/share/gc/z/zRemembered.hpp index 1400472f2bc..6cc76f5dc26 100644 --- a/src/hotspot/share/gc/z/zRemembered.hpp +++ b/src/hotspot/share/gc/z/zRemembered.hpp @@ -35,7 +35,9 @@ class ZMark; class ZPage; class ZPageAllocator; class ZPageTable; +class ZRemsetTableIterator; struct ZRememberedSetContaining; +struct ZRemsetTableEntry; class ZRemembered { friend class ZRememberedScanMarkFollowTask; @@ -99,6 +101,26 @@ public: // Register pages with the remembered set void register_found_old(ZPage* page); + + // Remap the current remembered set + void remap_current(ZRemsetTableIterator* iter); +}; + +// This iterator uses the "found old" optimization to skip having to iterate +// over the entire page table. Make sure to check where and how the FoundOld +// data is cycled before using this iterator. +class ZRemsetTableIterator { +private: + ZRemembered* const _remembered; + BitMap* const _bm; + ZPageTable* const _page_table; + const ZForwardingTable* const _old_forwarding_table; + volatile BitMap::idx_t _claimed; + +public: + ZRemsetTableIterator(ZRemembered* remembered, bool previous); + + bool next(ZRemsetTableEntry* entry_addr); }; #endif // SHARE_GC_Z_ZREMEMBERED_HPP From ef47635d5a27b003937d865ad9067dbd151db888 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Wed, 4 Jun 2025 16:14:31 +0000 Subject: [PATCH 145/216] 8358015: Fix SequencedMap sequenced view method specifications Reviewed-by: jpai, bchristi --- .../share/classes/java/util/AbstractMap.java | 8 +++ .../share/classes/java/util/SequencedMap.java | 65 +++++++++++++++++-- .../util/SequencedCollection/BasicMap.java | 10 +-- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 7c0b4d9dd1b..afc5b339354 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -877,6 +877,14 @@ public abstract class AbstractMap implements Map { */ /* non-public */ abstract static class ViewCollection implements Collection { UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } + // convert null entry return values into NSEE + static > T nsee(T entry) { + if (entry == null) { + throw new NoSuchElementException(); + } else { + return entry; + } + } abstract Collection view(); public boolean add(E t) { throw uoe(); } diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java index 6bff204b65d..cf27b82896b 100644 --- a/src/java.base/share/classes/java/util/SequencedMap.java +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -263,8 +263,15 @@ public interface SequencedMap extends Map { * * @implSpec * The implementation in this interface returns a {@code SequencedSet} instance - * that behaves as follows. Its {@link SequencedSet#add add} and {@link - * SequencedSet#addAll addAll} methods throw {@link UnsupportedOperationException}. + * that behaves as follows. Its {@link SequencedSet#add add}, {@link + * SequencedSet#addAll addAll}, {@link SequencedSet#addFirst addFirst}, and {@link + * SequencedSet#addLast addLast} methods throw {@link UnsupportedOperationException}. + * Its {@link SequencedSet#getFirst getFirst} and {@link SequencedSet#getLast getLast} + * methods are implemented in terms of the {@link #firstEntry firstEntry} and {@link + * #lastEntry lastEntry} methods of this interface, respectively. Its {@link + * SequencedSet#removeFirst removeFirst} and {@link SequencedSet#removeLast removeLast} + * methods are implemented in terms of the {@link #pollFirstEntry pollFirstEntry} and + * {@link #pollLastEntry pollLastEntry} methods of this interface, respectively. * Its {@link SequencedSet#reversed reversed} method returns the {@link * #sequencedKeySet sequencedKeySet} view of the {@link #reversed reversed} view of * this map. Each of its other methods calls the corresponding method of the {@link @@ -286,6 +293,16 @@ public interface SequencedMap extends Map { public int hashCode() { return view().hashCode(); } + public void addFirst(K k) { throw new UnsupportedOperationException(); } + public void addLast(K k) { throw new UnsupportedOperationException(); } + public K getFirst() { return nsee(SequencedMap.this.firstEntry()).getKey(); } + public K getLast() { return nsee(SequencedMap.this.lastEntry()).getKey(); } + public K removeFirst() { + return nsee(SequencedMap.this.pollFirstEntry()).getKey(); + } + public K removeLast() { + return nsee(SequencedMap.this.pollLastEntry()).getKey(); + } } return new SeqKeySet(); } @@ -295,8 +312,15 @@ public interface SequencedMap extends Map { * * @implSpec * The implementation in this interface returns a {@code SequencedCollection} instance - * that behaves as follows. Its {@link SequencedCollection#add add} and {@link - * SequencedCollection#addAll addAll} methods throw {@link UnsupportedOperationException}. + * that behaves as follows. Its {@link SequencedCollection#add add}, {@link + * SequencedCollection#addAll addAll}, {@link SequencedCollection#addFirst addFirst}, and {@link + * SequencedCollection#addLast addLast} methods throw {@link UnsupportedOperationException}. + * Its {@link SequencedCollection#getFirst getFirst} and {@link SequencedCollection#getLast getLast} + * methods are implemented in terms of the {@link #firstEntry firstEntry} and {@link + * #lastEntry lastEntry} methods of this interface, respectively. Its {@link + * SequencedCollection#removeFirst removeFirst} and {@link SequencedCollection#removeLast removeLast} + * methods are implemented in terms of the {@link #pollFirstEntry pollFirstEntry} and + * {@link #pollLastEntry pollLastEntry} methods of this interface, respectively. * Its {@link SequencedCollection#reversed reversed} method returns the {@link * #sequencedValues sequencedValues} view of the {@link #reversed reversed} view of * this map. Its {@link Object#equals equals} and {@link Object#hashCode hashCode} methods @@ -313,6 +337,16 @@ public interface SequencedMap extends Map { public SequencedCollection reversed() { return SequencedMap.this.reversed().sequencedValues(); } + public void addFirst(V v) { throw new UnsupportedOperationException(); } + public void addLast(V v) { throw new UnsupportedOperationException(); } + public V getFirst() { return nsee(SequencedMap.this.firstEntry()).getValue(); } + public V getLast() { return nsee(SequencedMap.this.lastEntry()).getValue(); } + public V removeFirst() { + return nsee(SequencedMap.this.pollFirstEntry()).getValue(); + } + public V removeLast() { + return nsee(SequencedMap.this.pollLastEntry()).getValue(); + } } return new SeqValues(); } @@ -322,8 +356,15 @@ public interface SequencedMap extends Map { * * @implSpec * The implementation in this interface returns a {@code SequencedSet} instance - * that behaves as follows. Its {@link SequencedSet#add add} and {@link - * SequencedSet#addAll addAll} methods throw {@link UnsupportedOperationException}. + * that behaves as follows. Its {@link SequencedSet#add add}, {@link + * SequencedSet#addAll addAll}, {@link SequencedSet#addFirst addFirst}, and {@link + * SequencedSet#addLast addLast} methods throw {@link UnsupportedOperationException}. + * Its {@link SequencedSet#getFirst getFirst} and {@link SequencedSet#getLast getLast} + * methods are implemented in terms of the {@link #firstEntry firstEntry} and {@link + * #lastEntry lastEntry} methods of this interface, respectively. Its {@link + * SequencedSet#removeFirst removeFirst} and {@link SequencedSet#removeLast removeLast} + * methods are implemented in terms of the {@link #pollFirstEntry pollFirstEntry} and + * {@link #pollLastEntry pollLastEntry} methods of this interface, respectively. * Its {@link SequencedSet#reversed reversed} method returns the {@link * #sequencedEntrySet sequencedEntrySet} view of the {@link #reversed reversed} view of * this map. Each of its other methods calls the corresponding method of the {@link @@ -346,6 +387,16 @@ public interface SequencedMap extends Map { public int hashCode() { return view().hashCode(); } + public void addFirst(Map.Entry e) { throw new UnsupportedOperationException(); } + public void addLast(Map.Entry e) { throw new UnsupportedOperationException(); } + public Map.Entry getFirst() { return nsee(SequencedMap.this.firstEntry()); } + public Map.Entry getLast() { return nsee(SequencedMap.this.lastEntry()); } + public Map.Entry removeFirst() { + return nsee(SequencedMap.this.pollFirstEntry()); + } + public Map.Entry removeLast() { + return nsee(SequencedMap.this.pollLastEntry()); + } } return new SeqEntrySet(); } diff --git a/test/jdk/java/util/SequencedCollection/BasicMap.java b/test/jdk/java/util/SequencedCollection/BasicMap.java index 028ae4e42c2..40bc2aa99dd 100644 --- a/test/jdk/java/util/SequencedCollection/BasicMap.java +++ b/test/jdk/java/util/SequencedCollection/BasicMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -563,12 +563,12 @@ public class BasicMap { SequencedMap objMap = (SequencedMap)(SequencedMap)map; assertThrows(CCE, () -> { objMap.put(new Object(), 99); }); assertThrows(CCE, () -> { objMap.put("x", new Object()); }); - assertThrows(CCE, () -> { objMap.sequencedEntrySet().getFirst().setValue(new Object()); }); - assertThrows(CCE, () -> { objMap.sequencedEntrySet().reversed().getFirst().setValue(new Object()); }); + assertThrows(CCE, () -> { objMap.sequencedEntrySet().iterator().next().setValue(new Object()); }); + assertThrows(CCE, () -> { objMap.sequencedEntrySet().reversed().iterator().next().setValue(new Object()); }); assertThrows(CCE, () -> { objMap.reversed().put(new Object(), 99); }); assertThrows(CCE, () -> { objMap.reversed().put("x", new Object()); }); - assertThrows(CCE, () -> { objMap.reversed().sequencedEntrySet().getFirst().setValue(new Object()); }); - assertThrows(CCE, () -> { objMap.reversed().sequencedEntrySet().reversed().getFirst().setValue(new Object()); }); + assertThrows(CCE, () -> { objMap.reversed().sequencedEntrySet().iterator().next().setValue(new Object()); }); + assertThrows(CCE, () -> { objMap.reversed().sequencedEntrySet().reversed().iterator().next().setValue(new Object()); }); } public void checkEntry(Map.Entry entry, String key, Integer value) { From 8a79ac88639c35a6938f82a391c4b5d77e6eda32 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Wed, 4 Jun 2025 16:40:22 +0000 Subject: [PATCH 146/216] 8358449: Locale.getISOCountries does not specify the returned set is unmodifiable Reviewed-by: naoto --- src/java.base/share/classes/java/util/Locale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index 9c745c1731b..993495ff5ab 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -1310,7 +1310,7 @@ public final class Locale implements Cloneable, Serializable { } /** - * {@return a {@code Set} of ISO3166 country codes for the specified type} + * {@return an unmodifiable {@code Set} of ISO3166 country codes for the specified type} * * @param type {@link Locale.IsoCountryCode} specified ISO code type. * @see java.util.Locale.IsoCountryCode From fd0ab043677d103628afde628e3e75e23fb518b2 Mon Sep 17 00:00:00 2001 From: Ashutosh Mehra Date: Wed, 4 Jun 2025 16:52:38 +0000 Subject: [PATCH 147/216] 8358330: AsmRemarks and DbgStrings clear() method may not get called before their destructor Reviewed-by: kvn --- src/hotspot/share/asm/codeBuffer.cpp | 14 ++++++++++++-- src/hotspot/share/asm/codeBuffer.hpp | 4 ++++ src/hotspot/share/code/aotCodeCache.cpp | 18 +++++++----------- src/hotspot/share/code/codeBlob.cpp | 11 ----------- src/hotspot/share/code/codeBlob.hpp | 7 +------ 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index ca25cf56be0..3d2d97d1e45 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -1099,7 +1099,8 @@ CHeapString::~CHeapString() { // offset is a byte offset into an instruction stream (CodeBuffer, CodeBlob or // other memory buffer) and remark is a string (comment). // -AsmRemarks::AsmRemarks() : _remarks(new AsmRemarkCollection()) { +AsmRemarks::AsmRemarks() { + init(); assert(_remarks != nullptr, "Allocation failure!"); } @@ -1107,6 +1108,10 @@ AsmRemarks::~AsmRemarks() { assert(_remarks == nullptr, "Must 'clear()' before deleting!"); } +void AsmRemarks::init() { + _remarks = new AsmRemarkCollection(); +} + const char* AsmRemarks::insert(uint offset, const char* remstr) { precond(remstr != nullptr); return _remarks->insert(offset, remstr); @@ -1151,7 +1156,8 @@ uint AsmRemarks::print(uint offset, outputStream* strm) const { // Acting as interface to reference counted collection of (debug) strings used // in the code generated, and thus requiring a fixed address. // -DbgStrings::DbgStrings() : _strings(new DbgStringCollection()) { +DbgStrings::DbgStrings() { + init(); assert(_strings != nullptr, "Allocation failure!"); } @@ -1159,6 +1165,10 @@ DbgStrings::~DbgStrings() { assert(_strings == nullptr, "Must 'clear()' before deleting!"); } +void DbgStrings::init() { + _strings = new DbgStringCollection(); +} + const char* DbgStrings::insert(const char* dbgstr) { const char* str = _strings->lookup(dbgstr); return str != nullptr ? str : _strings->insert(dbgstr); diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index e6dac484649..96e9a77a923 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -426,6 +426,8 @@ class AsmRemarks { AsmRemarks(); ~AsmRemarks(); + void init(); + const char* insert(uint offset, const char* remstr); bool is_empty() const; @@ -452,6 +454,8 @@ class DbgStrings { DbgStrings(); ~DbgStrings(); + void init(); + const char* insert(const char* dbgstr); bool is_empty() const; diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index 674d71d1bfc..6d8faa10a38 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -915,26 +915,22 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co oop_maps = read_oop_map_set(); } -#ifndef PRODUCT - AsmRemarks asm_remarks; - read_asm_remarks(asm_remarks); - DbgStrings dbg_strings; - read_dbg_strings(dbg_strings); -#endif // PRODUCT - CodeBlob* code_blob = CodeBlob::create(archived_blob, stored_name, reloc_data, oop_maps -#ifndef PRODUCT - , asm_remarks - , dbg_strings -#endif ); if (code_blob == nullptr) { // no space left in CodeCache return nullptr; } +#ifndef PRODUCT + code_blob->asm_remarks().init(); + read_asm_remarks(code_blob->asm_remarks()); + code_blob->dbg_strings().init(); + read_dbg_strings(code_blob->dbg_strings()); +#endif // PRODUCT + fix_relocations(code_blob); // Read entries offsets diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 185b6c06598..5bb37c198d0 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -281,10 +281,6 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, const char* name, address archived_reloc_data, ImmutableOopMapSet* archived_oop_maps -#ifndef PRODUCT - , AsmRemarks& archived_asm_remarks - , DbgStrings& archived_dbg_strings -#endif // PRODUCT ) { ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock @@ -303,13 +299,6 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, archived_oop_maps); assert(blob != nullptr, "sanity check"); -#ifndef PRODUCT - blob->use_remarks(archived_asm_remarks); - archived_asm_remarks.clear(); - blob->use_strings(archived_dbg_strings); - archived_dbg_strings.clear(); -#endif // PRODUCT - // Flush the code block ICache::invalidate_range(blob->code_begin(), blob->code_size()); CodeCache::commit(blob); // Count adapters diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index f813752e01e..f1920a829fc 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -318,12 +318,7 @@ public: static CodeBlob* create(CodeBlob* archived_blob, const char* name, address archived_reloc_data, - ImmutableOopMapSet* archived_oop_maps -#ifndef PRODUCT - , AsmRemarks& archived_asm_remarks - , DbgStrings& archived_dbg_strings -#endif // PRODUCT - ); + ImmutableOopMapSet* archived_oop_maps); }; //---------------------------------------------------------------------------------------------------- From 8939acc8ab0e45b82252f0f2de37e9bd5c3e1493 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 4 Jun 2025 17:53:17 +0000 Subject: [PATCH 148/216] 8358057: Update validation of ICC_Profile header data Reviewed-by: honkar --- .../classes/java/awt/color/ICC_Profile.java | 42 +++----- .../java/awt/image/ColorConvertOp.java | 13 +-- .../RenderingIntentStressTest.java | 97 +++++++++++++++++++ .../ValidateICCHeaderData.java | 21 +++- 4 files changed, 135 insertions(+), 38 deletions(-) create mode 100644 test/jdk/java/awt/color/ICC_Profile/RenderingIntentStressTest.java diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index a3e60217d15..c641e469972 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java @@ -811,12 +811,12 @@ public sealed class ICC_Profile implements Serializable } try { - if (getColorSpaceType(p) == ColorSpace.TYPE_GRAY + if (getColorSpaceType(data) == ColorSpace.TYPE_GRAY && getData(p, icSigMediaWhitePointTag) != null && getData(p, icSigGrayTRCTag) != null) { return new ICC_ProfileGray(p); } - if (getColorSpaceType(p) == ColorSpace.TYPE_RGB + if (getColorSpaceType(data) == ColorSpace.TYPE_RGB && getData(p, icSigMediaWhitePointTag) != null && getData(p, icSigRedColorantTag) != null && getData(p, icSigGreenColorantTag) != null @@ -1028,13 +1028,8 @@ public sealed class ICC_Profile implements Serializable if (info != null) { return info.colorSpaceType; } - return getColorSpaceType(cmmProfile()); - } - - private static int getColorSpaceType(Profile p) { - byte[] theHeader = getData(p, icSigHead); - int theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace); - return iccCStoJCS(theColorSpaceSig); + byte[] theHeader = getData(cmmProfile(), icSigHead); + return getColorSpaceType(theHeader); } private static int getColorSpaceType(byte[] theHeader) { @@ -1057,8 +1052,7 @@ public sealed class ICC_Profile implements Serializable */ public int getPCSType() { byte[] theHeader = getData(icSigHead); - int thePCSSig = intFromBigEndian(theHeader, icHdrPcs); - return iccCStoJCS(thePCSSig); + return getPCSType(theHeader); } private static int getPCSType(byte[] theHeader) { @@ -1189,23 +1183,19 @@ public sealed class ICC_Profile implements Serializable checkRenderingIntent(data); } - private static boolean checkRenderingIntent(byte[] header) { + private static void checkRenderingIntent(byte[] header) { int index = ICC_Profile.icHdrRenderingIntent; - - /* According to ICC spec, only the least-significant 16 bits shall be - * used to encode the rendering intent. The most significant 16 bits - * shall be set to zero. Thus, we are ignoring two most significant - * bytes here. Please refer ICC Spec Document for more details. + /* + * ICC spec: only the least-significant 16 bits encode the rendering + * intent. The most significant 16 bits must be zero and can be ignored. + * https://www.color.org/specification/ICC.1-2022-05.pdf, section 7.2.15 */ - int renderingIntent = ((header[index+2] & 0xff) << 8) | - (header[index+3] & 0xff); - - switch (renderingIntent) { - case icPerceptual, icMediaRelativeColorimetric, - icSaturation, icAbsoluteColorimetric -> { - return true; - } - default -> throw new IllegalArgumentException("Unknown Rendering Intent"); + // Extract 16-bit unsigned rendering intent (0–65535) + int intent = (header[index + 2] & 0xff) << 8 | header[index + 3] & 0xff; + // Only check upper bound since intent can't be negative + if (intent > icICCAbsoluteColorimetric) { + throw new IllegalArgumentException( + "Unknown Rendering Intent: %d".formatted(intent)); } } diff --git a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java index 3202d2d690d..c1c60397198 100644 --- a/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java +++ b/src/java.desktop/share/classes/java/awt/image/ColorConvertOp.java @@ -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 @@ -684,13 +684,10 @@ public class ColorConvertOp implements BufferedImageOp, RasterOp { private int getRenderingIntent (ICC_Profile profile) { byte[] header = profile.getData(ICC_Profile.icSigHead); int index = ICC_Profile.icHdrRenderingIntent; - - /* According to ICC spec, only the least-significant 16 bits shall be - * used to encode the rendering intent. The most significant 16 bits - * shall be set to zero. Thus, we are ignoring two most significant - * bytes here. - * - * See https://www.color.org/ICC1v42_2006-05.pdf, section 7.2.15. + /* + * ICC spec: only the least-significant 16 bits encode the rendering + * intent. The most significant 16 bits must be zero and can be ignored. + * https://www.color.org/specification/ICC.1-2022-05.pdf, section 7.2.15 */ return ((header[index+2] & 0xff) << 8) | (header[index+3] & 0xff); diff --git a/test/jdk/java/awt/color/ICC_Profile/RenderingIntentStressTest.java b/test/jdk/java/awt/color/ICC_Profile/RenderingIntentStressTest.java new file mode 100644 index 00000000000..05ec6d0d112 --- /dev/null +++ b/test/jdk/java/awt/color/ICC_Profile/RenderingIntentStressTest.java @@ -0,0 +1,97 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; + +import static java.awt.color.ICC_Profile.icAbsoluteColorimetric; +import static java.awt.color.ICC_Profile.icICCAbsoluteColorimetric; +import static java.awt.color.ICC_Profile.icMediaRelativeColorimetric; +import static java.awt.color.ICC_Profile.icPerceptual; +import static java.awt.color.ICC_Profile.icRelativeColorimetric; +import static java.awt.color.ICC_Profile.icSaturation; + +/** + * @test + * @bug 8358057 + * @summary Stress test for ICC_Profile rendering intent parsing and validation + */ +public final class RenderingIntentStressTest { + + public static void main(String[] args) { + ICC_Profile builtin = ICC_Profile.getInstance(ColorSpace.CS_sRGB); + ICC_Profile profile = ICC_Profile.getInstance(builtin.getData()); + // some random combinations that should be ignored + int[] upperBytes = {0x0000, 0xFFFF, 0xA5A5, 0x8000, 0x0001, 0x8080, + 0x0101, 0xAA55, 0x550A, 0xFF00}; + for (int up : upperBytes) { + for (int low = 0; low <= 0xFFFF; low++) { + test(profile, up, low); + } + } + } + + private static int getRenderingIntent(byte[] header) { + // replicate the logic we have in jdk + int index = ICC_Profile.icHdrRenderingIntent; + return (header[index + 2] & 0xff) << 8 | header[index + 3] & 0xff; + } + + private static void test(ICC_Profile profile, int up, int low) { + byte[] header = profile.getData(ICC_Profile.icSigHead); + // These bytes should be ignored + header[ICC_Profile.icHdrRenderingIntent + 0] = (byte) (up >> 8 & 0xFF); + header[ICC_Profile.icHdrRenderingIntent + 1] = (byte) (up & 0xFF); + // This is the actual intent + header[ICC_Profile.icHdrRenderingIntent + 2] = (byte) (low >> 8 & 0xFF); + header[ICC_Profile.icHdrRenderingIntent + 3] = (byte) (low & 0xFF); + + boolean isValid = isValidIntent(low); + try { + profile.setData(ICC_Profile.icSigHead, header); + if (!isValid) { + throw new RuntimeException("IAE is expected"); + } + } catch (IllegalArgumentException e) { + if (isValid) { + throw e; + } + return; + } + // verify that the intent is correctly stored in the profile by the CMM + byte[] data = profile.getData(ICC_Profile.icSigHead); + int actualIntent = getRenderingIntent(data); + if (actualIntent != low) { + System.out.println("Expected: " + low); + System.out.println("Actual: " + actualIntent); + throw new RuntimeException("Unexpected intent"); + } + } + + private static boolean isValidIntent(int intent) { + return intent == icPerceptual || intent == icRelativeColorimetric + || intent == icMediaRelativeColorimetric + || intent == icSaturation || intent == icAbsoluteColorimetric + || intent == icICCAbsoluteColorimetric; + } +} diff --git a/test/jdk/java/awt/color/ICC_Profile/ValidateICCHeaderData/ValidateICCHeaderData.java b/test/jdk/java/awt/color/ICC_Profile/ValidateICCHeaderData/ValidateICCHeaderData.java index 28831a422b0..9867b727a09 100644 --- a/test/jdk/java/awt/color/ICC_Profile/ValidateICCHeaderData/ValidateICCHeaderData.java +++ b/test/jdk/java/awt/color/ICC_Profile/ValidateICCHeaderData/ValidateICCHeaderData.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8337703 + * @bug 8347377 8358057 * @summary To verify if ICC_Profile's setData() and getInstance() methods * validate header data and throw IAE for invalid values. * @run main ValidateICCHeaderData @@ -144,9 +144,7 @@ public class ValidateICCHeaderData { System.out.println("CASE 10: Passed \n"); System.out.println("CASE 11: Testing INVALID Rendering Intent ..."); - //valid rendering intent values are 0-3 - int invalidRenderIntent = 5; - testInvalidHeaderData(invalidRenderIntent, RENDER_INTENT_START_INDEX, 4); + testInvalidIntent(); System.out.println("CASE 11: Passed \n"); System.out.println("CASE 12: Testing INVALID Header Size ..."); @@ -187,6 +185,21 @@ public class ValidateICCHeaderData { } } + private static void testInvalidIntent() { + //valid rendering intent values are 0-3 + int invalidRenderIntent = 5; + try { + setTag(invalidRenderIntent, RENDER_INTENT_START_INDEX, 4); + throw new RuntimeException("Test Failed ! Expected IAE NOT thrown"); + } catch (IllegalArgumentException iae) { + String message = iae.getMessage(); + System.out.println("Expected IAE thrown: " + message); + if (!message.contains(": " + invalidRenderIntent)) { + throw new RuntimeException("Test Failed ! Unexpected text"); + } + } + } + private static void setTag(int value, int startIndex, int fieldLength) { byte[] byteArray; if (startIndex == RENDER_INTENT_START_INDEX) { From 5ed246d17d9f40489ed715b7df104ec6a832841e Mon Sep 17 00:00:00 2001 From: Matthew Donovan Date: Wed, 4 Jun 2025 18:07:07 +0000 Subject: [PATCH 149/216] 8357592: Update output parsing in test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java Reviewed-by: rhalade --- .../tools/jarsigner/compatibility/Compatibility.java | 6 +++--- test/jdk/sun/security/tools/jarsigner/warnings/Test.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java index 3be1e74d972..25bb67c230b 100644 --- a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java +++ b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java @@ -516,7 +516,7 @@ public class Compatibility { String line; while ((line = reader.readLine()) != null) { String item = line.trim(); - if (!item.isEmpty()) { + if (!item.isEmpty() && !item.startsWith("#")) { list.add(item); } } @@ -718,8 +718,8 @@ public class Compatibility { String match = "^ (" + " Signature algorithm: " + signItem.certInfo. expectedSigalg(signItem) + ", " + signItem.certInfo. - expectedKeySize() + "-bit " + signItem.certInfo. - expectedKeyAlgorithm() + " key" + expectedKeySize() + "-bit (" + signItem.certInfo. + expectedKeyAlgorithm() + " key|key)" + ")|(" + " Digest algorithm: " + signItem.expectedDigestAlg() + (isWeakAlg(signItem.expectedDigestAlg()) ? " \\(weak\\)" : "") diff --git a/test/jdk/sun/security/tools/jarsigner/warnings/Test.java b/test/jdk/sun/security/tools/jarsigner/warnings/Test.java index 0683c03c10c..224fa754eec 100644 --- a/test/jdk/sun/security/tools/jarsigner/warnings/Test.java +++ b/test/jdk/sun/security/tools/jarsigner/warnings/Test.java @@ -149,7 +149,7 @@ public abstract class Test { + "This algorithm will be disabled in a future update."; static final String WEAK_KEY_WARNING - = "It will be disabled in a future update."; + = "will be disabled in a future update."; static final String JAR_SIGNED = "jar signed."; From 8f821175cc4484d651151818cc518ef608ebcc83 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Wed, 4 Jun 2025 18:46:31 +0000 Subject: [PATCH 150/216] 8358170: Repurpose testCompat in test/jdk/java/util/TimeZone/Bug8167143.java Reviewed-by: naoto --- test/jdk/java/util/TimeZone/Bug8167143.java | 56 +++++++-------------- 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/test/jdk/java/util/TimeZone/Bug8167143.java b/test/jdk/java/util/TimeZone/Bug8167143.java index fb94c94214f..c1b9b5a813a 100644 --- a/test/jdk/java/util/TimeZone/Bug8167143.java +++ b/test/jdk/java/util/TimeZone/Bug8167143.java @@ -23,14 +23,14 @@ /* * @test - * @bug 8167143 8174269 + * @bug 8167143 8174269 8358170 * @summary Test * Timezone parsing works for all locales for default providers preference * CLDR implicit locales are correctly reflected, * th_TH bundle is not wrongly cached in DateFormatSymbols, * correct candidate locale list is retrieved for * zh_Hant and zh_Hans and - * Implicit COMPAT Locales nn-NO, nb-NO are reflected in available locales + * Implicit FALLBACK Locales nn-NO, nb-NO are reflected in available locales * @modules java.base/sun.util.locale.provider * java.base/sun.util.spi * jdk.localedata @@ -38,6 +38,7 @@ * @run main Bug8167143 testCldr * @run main Bug8167143 testCache * @run main Bug8167143 testCandidateLocales + * @run main Bug8167143 testFallback */ import java.text.ParseException; import java.text.SimpleDateFormat; @@ -64,7 +65,7 @@ public class Bug8167143 { Locale.forLanguageTag("zh-Hant-TW"), Locale.forLanguageTag("zh-Hant-MO")); - private static final List COMPAT_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("nn-NO"), + private static final List FALLBACK_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("nn-NO"), Locale.forLanguageTag("nb-NO")); /** * List of candidate locales for zh_Hant @@ -97,8 +98,8 @@ public class Bug8167143 { case "testCandidateLocales": testCandidateLocales(); break; - case "testCompat": - testImplicitCompatLocales(); + case "testFallback": + testImplicitFallbackLocales(); break; default: throw new RuntimeException("no test was specified."); @@ -230,45 +231,26 @@ public class Bug8167143 { } /** - * checks that locales nn-NO and nb-NO should be present in list of supported locales for - * all Providers for COMPAT. + * Checks that locales (nn-NO and nb-NO) implicitly supported in FALLBACK + * provider should be present in output of getAvailableLocales() for + * BreakIteratorProvider and CollatorProvider. */ - private static void testImplicitCompatLocales() { - LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE(); - checkPresenceCompat("BreakIteratorProvider", - jre.getBreakIteratorProvider().getAvailableLocales()); - checkPresenceCompat("CollatorProvider", - jre.getCollatorProvider().getAvailableLocales()); - checkPresenceCompat("DateFormatProvider", - jre.getDateFormatProvider().getAvailableLocales()); - checkPresenceCompat("DateFormatSymbolsProvider", - jre.getDateFormatSymbolsProvider().getAvailableLocales()); - checkPresenceCompat("DecimalFormatSymbolsProvider", - jre.getDecimalFormatSymbolsProvider().getAvailableLocales()); - checkPresenceCompat("NumberFormatProvider", - jre.getNumberFormatProvider().getAvailableLocales()); - checkPresenceCompat("CurrencyNameProvider", - jre.getCurrencyNameProvider().getAvailableLocales()); - checkPresenceCompat("LocaleNameProvider", - jre.getLocaleNameProvider().getAvailableLocales()); - checkPresenceCompat("TimeZoneNameProvider", - jre.getTimeZoneNameProvider().getAvailableLocales()); - checkPresenceCompat("CalendarDataProvider", - jre.getCalendarDataProvider().getAvailableLocales()); - checkPresenceCompat("CalendarNameProvider", - jre.getCalendarNameProvider().getAvailableLocales()); - checkPresenceCompat("CalendarProvider", - jre.getCalendarProvider().getAvailableLocales()); + private static void testImplicitFallbackLocales() { + LocaleProviderAdapter fallback = LocaleProviderAdapter.forType(Type.FALLBACK); + checkPresenceFallback("BreakIteratorProvider", + fallback.getBreakIteratorProvider().getAvailableLocales()); + checkPresenceFallback("CollatorProvider", + fallback.getCollatorProvider().getAvailableLocales()); } - private static void checkPresenceCompat(String testName, Locale[] got) { + private static void checkPresenceFallback(String testName, Locale[] got) { List gotLocalesList = Arrays.asList(got); List gotList = new ArrayList<>(gotLocalesList); - if (!gotList.removeAll(COMPAT_IMPLICIT_LOCS)) { + if (!gotList.removeAll(FALLBACK_IMPLICIT_LOCS)) { // check which Implicit locale are not present in retrievedLocales List. - List implicitLocales = new ArrayList<>(COMPAT_IMPLICIT_LOCS); + List implicitLocales = new ArrayList<>(FALLBACK_IMPLICIT_LOCS); implicitLocales.removeAll(gotList); - throw new RuntimeException("Locales those not correctly reflected are " + throw new RuntimeException("Locale(s) not correctly reflected are " + implicitLocales + " for test " + testName); } } From 901144ee0d3e984aa8b8f047498440450942f3e5 Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Wed, 4 Jun 2025 19:46:30 +0000 Subject: [PATCH 151/216] 8358217: jdk/incubator/vector/PreferredSpeciesTest.java#id0 failures - expected [128] but found [256] Co-authored-by: Paul Sandoz Co-authored-by: Jaikiran Pai Reviewed-by: syan, psandoz --- test/jdk/ProblemList.txt | 1 - .../jdk/incubator/vector/PreferredSpeciesTest.java | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 28bb2a1f033..c1303377ddb 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -764,7 +764,6 @@ sun/tools/jstat/jstatLineCounts4.sh 8248691,8268211 jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586 jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows-x64 -jdk/incubator/vector/PreferredSpeciesTest.java#id0 8358217 generic-all ############################################################################ diff --git a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java index eb8b0358538..32d44d28ee1 100644 --- a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java +++ b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java @@ -133,25 +133,18 @@ public class PreferredSpeciesTest { void testLargestShapeFor(Class c) { final int S_64_BITS = 64; int elemSize = 0; - VectorSpecies maxVectorSpecies; if (c == byte.class) { elemSize = Byte.SIZE; - maxVectorSpecies = ByteVector.SPECIES_MAX; } else if (c == short.class) { elemSize = Short.SIZE; - maxVectorSpecies = ShortVector.SPECIES_MAX; } else if (c == int.class) { elemSize = Integer.SIZE; - maxVectorSpecies = IntVector.SPECIES_MAX; } else if (c == long.class) { elemSize = Long.SIZE; - maxVectorSpecies = LongVector.SPECIES_MAX; } else if (c == float.class) { elemSize = Float.SIZE; - maxVectorSpecies = FloatVector.SPECIES_MAX; } else if (c == double.class) { elemSize = Double.SIZE; - maxVectorSpecies = DoubleVector.SPECIES_MAX; } else { throw new IllegalArgumentException("Bad vector element type: " + c.getName()); } @@ -161,11 +154,6 @@ public class PreferredSpeciesTest { int maxLaneCount = VectorSupport.getMaxLaneCount(c); int max = Math.max(maxLaneCount * elemSize, S_64_BITS); - //Assert we're using the same element when comparing shapes - Assert.assertEquals(c, maxVectorSpecies.elementType()); - Assert.assertEquals(vs.vectorBitSize(), max); - Assert.assertEquals(vs.vectorBitSize(), maxVectorSpecies.vectorBitSize()); - } } From 77c110c309739c2e10c9b321914309affe749e6d Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 4 Jun 2025 20:03:48 +0000 Subject: [PATCH 152/216] 8357000: Write overview documentation for start of release changes Reviewed-by: erikj, iris, ihse, dholmes --- doc/starting-next-release.html | 127 +++++++++++++++++++++++++++++++++ doc/starting-next-release.md | 68 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 doc/starting-next-release.html create mode 100644 doc/starting-next-release.md diff --git a/doc/starting-next-release.html b/doc/starting-next-release.html new file mode 100644 index 00000000000..421229f9fbc --- /dev/null +++ b/doc/starting-next-release.html @@ -0,0 +1,127 @@ + + + + + + + Explanation of start of release changes + + + + + +

        +

        Explanation of start of release changes

        +
        + +

        Overview

        +

        The start of release changes, the changes that turn JDK N +into JDK (N+1), are primarily small updates to various files +along with new files to store symbol information to allow +javac --release N ... to run on JDK (N+1).

        +

        The updates include changes to files holding meta-data about the +release, files under the src directory for API and tooling +updates, and incidental updates under the test +directory.

        +

        Details and file updates

        +

        As a matter of policy, there are a number of semantically distinct +concepts which get incremented separately at the start of a new +release:

        +
          +
        • Feature value of Runtime.version()
        • +
        • Highest source version modeled by +javax.lang.model.SourceVersion
        • +
        • Highest class file format major version recognized by the +platform
        • +
        • Highest +-source/-target/--release +argument recognized by javac and related tools
        • +
        +

        The expected file updates are listed below. Additional files may need +to be updated for a particular release.

        +

        Meta-data files

        +
          +
        • jcheck/conf: update meta-data used by +jcheck and the Skara tooling
        • +
        • make/conf/version-numbers.conf: update to meta-data +used in the build
        • +
        +

        src files

        +
          +
        • src/hotspot/share/classfile/classFileParser.cpp: add a +#define for the new version
        • +
        • src/java.base/share/classes/java/lang/classfile/ClassFile.java: +add a constant for the new class file format version
        • +
        • src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java: +add an enum constant for the new class file format +version
        • +
        • src/java.compiler/share/classes/javax/lang/model/SourceVersion.java: +add an enum constant for the new source version
        • +
        • src/java.compiler/share/classes/javax/lang/model/util/* +visitors: Update @SupportedSourceVersion annotations to +latest value. Note this update is done in lieu of introducing another +set of visitors for each Java SE release.
        • +
        • src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java: +add an enum constant for the new source version internal to +javac
        • +
        • src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java: +add an enum constant for the new class file format version +internal to javac
        • +
        • src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java: +add an enum constant for the new target version internal to +javac
        • +
        • src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java +update printing processor to support the new source version
        • +
        • The symbol information for --release is stored as new +text files in the src/jdk.compiler/share/data/symbols +directory, one file per module. The README file in that directory +contains directions on how to create the files.
        • +
        +

        test files

        +
          +
        • test/langtools/tools/javac/api/TestGetSourceVersions.java: +add new SourceVersion constant to test matrix.
        • +
        • test/langtools/tools/javac/classfiles/ClassVersionChecker.java: +add new enum constant for the new class file version
        • +
        • test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java +update annotation processor extended by javac tests to +cover the new source version
        • +
        • test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out +and +test/langtools/tools/javac/preview/classReaderTest/Client.preview.out: +update expected messages for preview errors and warnings
        • +
        + + diff --git a/doc/starting-next-release.md b/doc/starting-next-release.md new file mode 100644 index 00000000000..10bc364a3e4 --- /dev/null +++ b/doc/starting-next-release.md @@ -0,0 +1,68 @@ +% Explanation of start of release changes + +## Overview + +The start of release changes, the changes that turn JDK _N_ into JDK +(_N_+1), are primarily small updates to various files along with new files to +store symbol information to allow `javac --release N ...` to run on +JDK (_N_+1). + +The updates include changes to files holding meta-data about the +release, files under the `src` directory for API and tooling updates, +and incidental updates under the `test` directory. + +## Details and file updates + +As a matter of policy, there are a number of semantically distinct +concepts which get incremented separately at the start of a new +release: + +* Feature value of `Runtime.version()` +* Highest source version modeled by `javax.lang.model.SourceVersion` +* Highest class file format major version recognized by the platform +* Highest `-source`/`-target`/`--release` argument recognized by + `javac` and related tools + +The expected file updates are listed below. Additional files may need +to be updated for a particular release. + +### Meta-data files + +* `jcheck/conf`: update meta-data used by `jcheck` and the Skara tooling +* `make/conf/version-numbers.conf`: update to meta-data used in the build + +### `src` files + +* `src/hotspot/share/classfile/classFileParser.cpp`: add a `#define` + for the new version +* `src/java.base/share/classes/java/lang/classfile/ClassFile.java`: + add a constant for the new class file format version +* `src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java`: + add an `enum` constant for the new class file format version +* `src/java.compiler/share/classes/javax/lang/model/SourceVersion.java`: + add an `enum` constant for the new source version +* `src/java.compiler/share/classes/javax/lang/model/util/*` visitors: Update + `@SupportedSourceVersion` annotations to latest value. Note this update + is done in lieu of introducing another set of visitors for each Java + SE release. +* `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java`: + add an `enum` constant for the new source version internal to `javac` +* `src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java`: + add an `enum` constant for the new class file format version internal to `javac` +* `src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java`: + add an `enum` constant for the new target version internal to `javac` +* `src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java` + update printing processor to support the new source version +* The symbol information for `--release` is stored as new text files in the + `src/jdk.compiler/share/data/symbols` directory, one file per + module. The README file in that directory contains directions on how + to create the files. + +### `test` files + +* `test/langtools/tools/javac/api/TestGetSourceVersions.java`: add new `SourceVersion` constant to test matrix. +* `test/langtools/tools/javac/classfiles/ClassVersionChecker.java`: add new enum constant for the new class file version +* `test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java` + update annotation processor extended by `javac` tests to cover the new source version +* `test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out` and `test/langtools/tools/javac/preview/classReaderTest/Client.preview.out`: update expected messages for preview errors and warnings + From 3cf3e4bbec26a84d77cb7a3125a60ba1e1e4ee97 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 4 Jun 2025 21:32:29 +0000 Subject: [PATCH 153/216] 8358339: Handle MethodCounters::_method backlinks after JDK-8355003 Reviewed-by: coleenp, kvn, iveresov --- src/hotspot/share/asm/codeBuffer.cpp | 7 +++++++ src/hotspot/share/code/nmethod.cpp | 2 ++ src/hotspot/share/oops/metadata.hpp | 1 + 3 files changed, 10 insertions(+) diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 3d2d97d1e45..81bfc932147 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -29,6 +29,7 @@ #include "compiler/disassembler.hpp" #include "logging/log.hpp" #include "oops/klass.inline.hpp" +#include "oops/methodCounters.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" #include "runtime/icache.hpp" @@ -537,6 +538,9 @@ void CodeBuffer::finalize_oop_references(const methodHandle& mh) { if (m->is_methodData()) { m = ((MethodData*)m)->method(); } + if (m->is_methodCounters()) { + m = ((MethodCounters*)m)->method(); + } if (m->is_method()) { m = ((Method*)m)->method_holder(); } @@ -561,6 +565,9 @@ void CodeBuffer::finalize_oop_references(const methodHandle& mh) { if (m->is_methodData()) { m = ((MethodData*)m)->method(); } + if (m->is_methodCounters()) { + m = ((MethodCounters*)m)->method(); + } if (m->is_method()) { m = ((Method*)m)->method_holder(); } diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index d82e31fd855..510160a6667 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -788,6 +788,8 @@ class CheckClass : public MetadataClosure { klass = ((Method*)md)->method_holder(); } else if (md->is_methodData()) { klass = ((MethodData*)md)->method()->method_holder(); + } else if (md->is_methodCounters()) { + klass = ((MethodCounters*)md)->method()->method_holder(); } else { md->print(); ShouldNotReachHere(); diff --git a/src/hotspot/share/oops/metadata.hpp b/src/hotspot/share/oops/metadata.hpp index ff18cef60a7..5a890a27fa1 100644 --- a/src/hotspot/share/oops/metadata.hpp +++ b/src/hotspot/share/oops/metadata.hpp @@ -44,6 +44,7 @@ class Metadata : public MetaspaceObj { virtual bool is_method() const { return false; } virtual bool is_methodData() const { return false; } virtual bool is_constantPool() const { return false; } + virtual bool is_methodCounters() const { return false; } virtual int size() const = 0; virtual MetaspaceObj::Type type() const = 0; virtual const char* internal_name() const = 0; From 5b27e9c2df8b386b38b0553d941469cd8aa65c28 Mon Sep 17 00:00:00 2001 From: Johannes Bechberger Date: Wed, 4 Jun 2025 22:08:58 +0000 Subject: [PATCH 154/216] 8342818: Implement JEP 509: JFR CPU-Time Profiling Reviewed-by: mgronlun, mdoerr, pchilanomate, apangin, shade --- src/hotspot/os/posix/signals_posix.cpp | 8 + src/hotspot/os/posix/signals_posix.hpp | 2 + src/hotspot/share/jfr/jfr.inline.hpp | 3 +- src/hotspot/share/jfr/jni/jfrJniMethod.cpp | 6 + src/hotspot/share/jfr/jni/jfrJniMethod.hpp | 2 + .../jfr/jni/jfrJniMethodRegistration.cpp | 1 + src/hotspot/share/jfr/metadata/metadata.xml | 16 + .../sampling/jfrCPUTimeThreadSampler.cpp | 769 ++++++++++++++++++ .../sampling/jfrCPUTimeThreadSampler.hpp | 152 ++++ .../periodic/sampling/jfrSampleRequest.cpp | 33 +- .../periodic/sampling/jfrSampleRequest.hpp | 5 + .../periodic/sampling/jfrThreadSampling.cpp | 92 ++- .../periodic/sampling/jfrThreadSampling.hpp | 2 + .../share/jfr/recorder/jfrRecorder.cpp | 15 + .../share/jfr/recorder/jfrRecorder.hpp | 1 + .../recorder/service/jfrEventThrottler.cpp | 12 +- .../share/jfr/support/jfrThreadLocal.cpp | 98 ++- .../share/jfr/support/jfrThreadLocal.hpp | 53 ++ src/hotspot/share/runtime/thread.hpp | 1 + src/hotspot/share/runtime/vmOperation.hpp | 2 + src/hotspot/share/utilities/ticks.hpp | 1 + .../jdk/jfr/internal/EventControl.java | 4 + .../share/classes/jdk/jfr/internal/JVM.java | 10 + .../jdk/jfr/internal/PlatformEventType.java | 19 + .../classes/jdk/jfr/internal/query/view.ini | 25 +- .../internal/settings/CPUThrottleSetting.java | 89 ++ .../classes/jdk/jfr/internal/util/Rate.java | 4 + .../jdk/jfr/internal/util/TimespanRate.java | 68 ++ src/jdk.jfr/share/conf/jfr/default.jfc | 10 + src/jdk.jfr/share/conf/jfr/profile.jfc | 10 + .../metadata/TestLookForUntestedEvents.java | 9 +- .../profiling/BaseTestFullStackTrace.java | 176 ++++ .../TestCPUTimeAndExecutionSample.java | 65 ++ .../TestCPUTimeSampleFullStackTrace.java | 41 + .../TestCPUTimeSampleMultipleRecordings.java | 70 ++ .../profiling/TestCPUTimeSampleNative.java | 66 ++ .../TestCPUTimeSampleThrottling.java | 111 +++ .../TestCPUTimeSamplingLongPeriod.java | 58 ++ .../event/profiling/TestFullStackTrace.java | 131 +-- .../classes/test/RecursiveMethods.java | 76 ++ test/lib/jdk/test/lib/jfr/EventNames.java | 2 + 41 files changed, 2178 insertions(+), 140 deletions(-) create mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp create mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java create mode 100644 test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java create mode 100644 test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index e900d5695ae..0157d354f40 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -1505,6 +1505,14 @@ bool PosixSignals::is_sig_ignored(int sig) { } } +void* PosixSignals::get_signal_handler_for_signal(int sig) { + struct sigaction oact; + if (sigaction(sig, (struct sigaction*)nullptr, &oact) == -1) { + return nullptr; + } + return get_signal_handler(&oact); +} + static void signal_sets_init() { sigemptyset(&preinstalled_sigs); diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index 9deade4db18..c1cb70df153 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -52,6 +52,8 @@ public: static bool is_sig_ignored(int sig); + static void* get_signal_handler_for_signal(int sig); + static void hotspot_sigmask(Thread* thread); static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); diff --git a/src/hotspot/share/jfr/jfr.inline.hpp b/src/hotspot/share/jfr/jfr.inline.hpp index bdb47f600e6..5b6fc62d0ea 100644 --- a/src/hotspot/share/jfr/jfr.inline.hpp +++ b/src/hotspot/share/jfr/jfr.inline.hpp @@ -32,7 +32,8 @@ inline bool Jfr::has_sample_request(JavaThread* jt) { assert(jt != nullptr, "invariant"); - return jt->jfr_thread_local()->has_sample_request(); + JfrThreadLocal* tl = jt->jfr_thread_local(); + return tl->has_sample_request() || tl->has_cpu_time_jfr_requests(); } inline void Jfr::check_and_process_sample_request(JavaThread* jt) { diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index 6f1c1936574..bc2412a90c1 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -24,6 +24,7 @@ #include "jfr/jfr.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrEventSetting.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -169,6 +170,11 @@ NO_TRANSITION(jboolean, jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_ty return JNI_TRUE; NO_TRANSITION_END +JVM_ENTRY_NO_ENV(void, jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt)) + JfrEventSetting::set_enabled(JfrCPUTimeSampleEvent, rate > 0); + JfrCPUTimeThreadSampling::set_rate(rate, auto_adapt == JNI_TRUE); +JVM_END + NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong event_type_id, jlong value)) JfrEventSetting::set_miscellaneous(event_type_id, value); const JfrEventId typed_event_id = (JfrEventId)event_type_id; diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index 9c78c6239d4..dbea7f0180d 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -129,6 +129,8 @@ jlong JNICALL jfr_get_unloaded_event_classes_count(JNIEnv* env, jclass jvm); jboolean JNICALL jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms); +void JNICALL jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt); + void JNICALL jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong id, jlong value); void JNICALL jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean, jboolean); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index 33a564dee2f..82ef93d95b2 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -83,6 +83,7 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"getUnloadedEventClassCount", (char*)"()J", (void*)jfr_get_unloaded_event_classes_count, (char*)"setMiscellaneous", (char*)"(JJ)V", (void*)jfr_set_miscellaneous, (char*)"setThrottle", (char*)"(JJJ)Z", (void*)jfr_set_throttle, + (char*)"setCPUThrottle", (char*)"(DZ)V", (void*)jfr_set_cpu_throttle, (char*)"emitOldObjectSamples", (char*)"(JZZ)V", (void*)jfr_emit_old_object_samples, (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk, (char*)"exclude", (char*)"(Ljava/lang/Thread;)V", (void*)jfr_exclude_thread, diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 9c04ec3dca1..03daca946f6 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -962,6 +962,22 @@ + + + + + + + + + + + + + diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp new file mode 100644 index 00000000000..ae8877ee3f2 --- /dev/null +++ b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp @@ -0,0 +1,769 @@ +/* + * Copyright (c) 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 + * 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 "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" +#include "logging/log.hpp" + + +#if defined(LINUX) +#include "jfr/periodic/sampling/jfrThreadSampling.hpp" +#include "jfr/support/jfrThreadLocal.hpp" +#include "jfr/utilities/jfrTime.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" +#include "jfr/utilities/jfrTypes.hpp" +#include "jfrfiles/jfrEventClasses.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/atomic.hpp" +#include "runtime/javaThread.hpp" +#include "runtime/osThread.hpp" +#include "runtime/safepointMechanism.inline.hpp" +#include "runtime/threadSMR.hpp" +#include "runtime/vmOperation.hpp" +#include "runtime/vmThread.hpp" +#include "utilities/ticks.hpp" + +#include "signals_posix.hpp" + +static const int64_t AUTOADAPT_INTERVAL_MS = 100; + +static bool is_excluded(JavaThread* jt) { + return jt->is_hidden_from_external_view() || + jt->jfr_thread_local()->is_excluded() || + jt->is_JfrRecorder_thread(); +} + +static JavaThread* get_java_thread_if_valid() { + Thread* raw_thread = Thread::current_or_null_safe(); + if (raw_thread == nullptr) { + // probably while shutting down + return nullptr; + } + assert(raw_thread->is_Java_thread(), "invariant"); + JavaThread* jt = JavaThread::cast(raw_thread); + if (is_excluded(jt) || jt->is_exiting()) { + return nullptr; + } + return jt; +} + +JfrCPUTimeTraceQueue::JfrCPUTimeTraceQueue(u4 capacity) : + _capacity(capacity), _head(0), _lost_samples(0) { + _data = JfrCHeapObj::new_array(capacity); +} + +JfrCPUTimeTraceQueue::~JfrCPUTimeTraceQueue() { + JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); +} + +bool JfrCPUTimeTraceQueue::enqueue(JfrCPUTimeSampleRequest& request) { + assert(JavaThread::current()->jfr_thread_local()->is_cpu_time_jfr_enqueue_locked(), "invariant"); + assert(&JavaThread::current()->jfr_thread_local()->cpu_time_jfr_queue() == this, "invariant"); + u4 elementIndex; + do { + elementIndex = Atomic::load_acquire(&_head); + if (elementIndex >= _capacity) { + return false; + } + } while (Atomic::cmpxchg(&_head, elementIndex, elementIndex + 1) != elementIndex); + _data[elementIndex] = request; + return true; +} + +JfrCPUTimeSampleRequest& JfrCPUTimeTraceQueue::at(u4 index) { + assert(index < _head, "invariant"); + return _data[index]; +} + +static volatile u4 _lost_samples_sum = 0; + +u4 JfrCPUTimeTraceQueue::size() const { + return Atomic::load_acquire(&_head); +} + +void JfrCPUTimeTraceQueue::set_size(u4 size) { + Atomic::release_store(&_head, size); +} + +u4 JfrCPUTimeTraceQueue::capacity() const { + return _capacity; +} + +void JfrCPUTimeTraceQueue::set_capacity(u4 capacity) { + _head = 0; + JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); + _data = JfrCHeapObj::new_array(capacity); + _capacity = capacity; +} + +bool JfrCPUTimeTraceQueue::is_empty() const { + return Atomic::load_acquire(&_head) == 0; +} + +u4 JfrCPUTimeTraceQueue::lost_samples() const { + return Atomic::load(&_lost_samples); +} + +void JfrCPUTimeTraceQueue::increment_lost_samples() { + Atomic::inc(&_lost_samples_sum); + Atomic::inc(&_lost_samples); +} + +u4 JfrCPUTimeTraceQueue::get_and_reset_lost_samples() { + return Atomic::xchg(&_lost_samples, (u4)0); +} + +void JfrCPUTimeTraceQueue::resize(u4 capacity) { + if (capacity != _capacity) { + set_capacity(capacity); + } +} + +void JfrCPUTimeTraceQueue::resize_for_period(u4 period_millis) { + u4 capacity = CPU_TIME_QUEUE_CAPACITY; + if (period_millis > 0 && period_millis < 10) { + capacity = (u4) ((double) capacity * 10 / period_millis); + } + resize(capacity); +} + +void JfrCPUTimeTraceQueue::clear() { + Atomic::release_store(&_head, (u4)0); +} + +static int64_t compute_sampling_period(double rate) { + if (rate == 0) { + return 0; + } + return os::active_processor_count() * 1000000000.0 / rate; +} + +class JfrCPUSamplerThread : public NonJavaThread { + friend class JfrCPUTimeThreadSampling; + private: + Semaphore _sample; + NonJavaThread* _sampler_thread; + double _rate; + bool _auto_adapt; + volatile int64_t _current_sampling_period_ns; + volatile bool _disenrolled; + // top bit is used to indicate that no signal handler should proceed + volatile u4 _active_signal_handlers; + volatile bool _is_async_processing_of_cpu_time_jfr_requests_triggered; + volatile bool _warned_about_timer_creation_failure; + volatile bool _signal_handler_installed; + + static const u4 STOP_SIGNAL_BIT = 0x80000000; + + JfrCPUSamplerThread(double rate, bool auto_adapt); + + void start_thread(); + + void enroll(); + void disenroll(); + void update_all_thread_timers(); + + void auto_adapt_period_if_needed(); + + void set_rate(double rate, bool auto_adapt); + int64_t get_sampling_period() const { return Atomic::load(&_current_sampling_period_ns); }; + + void sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now); + + // process the queues for all threads that are in native state (and requested to be processed) + void stackwalk_threads_in_native(); + bool create_timer_for_thread(JavaThread* thread, timer_t &timerid); + + void stop_signal_handlers(); + + // returns false if the stop signal bit was set, true otherwise + bool increment_signal_handler_count(); + + void decrement_signal_handler_count(); + + void initialize_active_signal_handler_counter(); + +protected: + virtual void post_run(); +public: + virtual const char* name() const { return "JFR CPU Sampler Thread"; } + virtual const char* type_name() const { return "JfrCPUTimeSampler"; } + void run(); + void on_javathread_create(JavaThread* thread); + void on_javathread_terminate(JavaThread* thread); + + void handle_timer_signal(siginfo_t* info, void* context); + bool init_timers(); + void stop_timer(); + + void trigger_async_processing_of_cpu_time_jfr_requests(); +}; + +JfrCPUSamplerThread::JfrCPUSamplerThread(double rate, bool auto_adapt) : + _sample(), + _sampler_thread(nullptr), + _rate(rate), + _auto_adapt(auto_adapt), + _current_sampling_period_ns(compute_sampling_period(rate)), + _disenrolled(true), + _active_signal_handlers(STOP_SIGNAL_BIT), + _is_async_processing_of_cpu_time_jfr_requests_triggered(false), + _warned_about_timer_creation_failure(false), + _signal_handler_installed(false) { + assert(rate >= 0, "invariant"); +} + +void JfrCPUSamplerThread::trigger_async_processing_of_cpu_time_jfr_requests() { + Atomic::release_store(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true); +} + +void JfrCPUSamplerThread::on_javathread_create(JavaThread* thread) { + if (thread->is_hidden_from_external_view() || thread->is_JfrRecorder_thread() || + !Atomic::load_acquire(&_signal_handler_installed)) { + return; + } + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + tl->cpu_time_jfr_queue().resize_for_period(_current_sampling_period_ns / 1000000); + timer_t timerid; + if (create_timer_for_thread(thread, timerid)) { + tl->set_cpu_timer(&timerid); + } else { + if (!Atomic::or_then_fetch(&_warned_about_timer_creation_failure, true)) { + log_warning(jfr)("Failed to create timer for a thread"); + } + tl->deallocate_cpu_time_jfr_queue(); + } +} + +void JfrCPUSamplerThread::on_javathread_terminate(JavaThread* thread) { + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + timer_t* timer = tl->cpu_timer(); + if (timer == nullptr) { + return; // no timer was created for this thread + } + tl->unset_cpu_timer(); + tl->deallocate_cpu_time_jfr_queue(); + s4 lost_samples = tl->cpu_time_jfr_queue().lost_samples(); + if (lost_samples > 0) { + JfrCPUTimeThreadSampling::send_lost_event(JfrTicks::now(), JfrThreadLocal::thread_id(thread), lost_samples); + } +} + +void JfrCPUSamplerThread::start_thread() { + if (os::create_thread(this, os::os_thread)) { + os::start_thread(this); + } else { + log_error(jfr)("Failed to create thread for thread sampling"); + } +} + +void JfrCPUSamplerThread::enroll() { + if (Atomic::cmpxchg(&_disenrolled, true, false)) { + Atomic::store(&_warned_about_timer_creation_failure, false); + initialize_active_signal_handler_counter(); + log_trace(jfr)("Enrolling CPU thread sampler"); + _sample.signal(); + if (!init_timers()) { + log_error(jfr)("Failed to initialize timers for CPU thread sampler"); + disenroll(); + return; + } + log_trace(jfr)("Enrolled CPU thread sampler"); + } +} + +void JfrCPUSamplerThread::disenroll() { + if (!Atomic::cmpxchg(&_disenrolled, false, true)) { + log_trace(jfr)("Disenrolling CPU thread sampler"); + if (Atomic::load_acquire(&_signal_handler_installed)) { + stop_timer(); + stop_signal_handlers(); + } + _sample.wait(); + log_trace(jfr)("Disenrolled CPU thread sampler"); + } +} + +void JfrCPUSamplerThread::run() { + assert(_sampler_thread == nullptr, "invariant"); + _sampler_thread = this; + int64_t last_auto_adapt_check = os::javaTimeNanos(); + while (true) { + if (!_sample.trywait()) { + // disenrolled + _sample.wait(); + } + _sample.signal(); + + if (os::javaTimeNanos() - last_auto_adapt_check > AUTOADAPT_INTERVAL_MS * 1000000) { + auto_adapt_period_if_needed(); + last_auto_adapt_check = os::javaTimeNanos(); + } + + if (Atomic::cmpxchg(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true, false)) { + stackwalk_threads_in_native(); + } + os::naked_sleep(100); + } +} + +void JfrCPUSamplerThread::stackwalk_threads_in_native() { + ResourceMark rm; + // Required to prevent JFR from sampling through an ongoing safepoint + MutexLocker tlock(Threads_lock); + ThreadsListHandle tlh; + Thread* current = Thread::current(); + for (size_t i = 0; i < tlh.list()->length(); i++) { + JavaThread* jt = tlh.list()->thread_at(i); + JfrThreadLocal* tl = jt->jfr_thread_local(); + if (tl->wants_async_processing_of_cpu_time_jfr_requests()) { + if (jt->thread_state() != _thread_in_native || !tl->try_acquire_cpu_time_jfr_dequeue_lock()) { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + continue; + } + if (jt->has_last_Java_frame()) { + JfrThreadSampling::process_cpu_time_request(jt, tl, current, false); + } else { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + } + tl->release_cpu_time_jfr_queue_lock(); + } + } +} + +static volatile size_t count = 0; + +void JfrCPUTimeThreadSampling::send_empty_event(const JfrTicks &start_time, traceid tid, Tickspan cpu_time_period) { + EventCPUTimeSample event(UNTIMED); + event.set_failed(true); + event.set_starttime(start_time); + event.set_eventThread(tid); + event.set_stackTrace(0); + event.set_samplingPeriod(cpu_time_period); + event.set_biased(false); + event.commit(); +} + + +static volatile size_t biased_count = 0; + +void JfrCPUTimeThreadSampling::send_event(const JfrTicks &start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased) { + EventCPUTimeSample event(UNTIMED); + event.set_failed(false); + event.set_starttime(start_time); + event.set_eventThread(tid); + event.set_stackTrace(sid); + event.set_samplingPeriod(cpu_time_period); + event.set_biased(biased); + event.commit(); + Atomic::inc(&count); + if (biased) { + Atomic::inc(&biased_count); + } + if (Atomic::load(&count) % 1000 == 0) { + log_debug(jfr)("CPU thread sampler sent %zu events, lost %d, biased %zu\n", Atomic::load(&count), Atomic::load(&_lost_samples_sum), Atomic::load(&biased_count)); + } +} + +void JfrCPUTimeThreadSampling::send_lost_event(const JfrTicks &time, traceid tid, s4 lost_samples) { + if (!EventCPUTimeSamplesLost::is_enabled()) { + return; + } + EventCPUTimeSamplesLost event(UNTIMED); + event.set_starttime(time); + event.set_lostSamples(lost_samples); + event.set_eventThread(tid); + event.commit(); +} + +void JfrCPUSamplerThread::post_run() { + this->NonJavaThread::post_run(); + delete this; +} + +static JfrCPUTimeThreadSampling* _instance = nullptr; + +JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { + return *_instance; +} + +JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { + assert(_instance == nullptr, "invariant"); + _instance = new JfrCPUTimeThreadSampling(); + return _instance; +} + +void JfrCPUTimeThreadSampling::destroy() { + if (_instance != nullptr) { + delete _instance; + _instance = nullptr; + } +} + +JfrCPUTimeThreadSampling::JfrCPUTimeThreadSampling() : _sampler(nullptr) {} + +JfrCPUTimeThreadSampling::~JfrCPUTimeThreadSampling() { + if (_sampler != nullptr) { + _sampler->disenroll(); + } +} + +void JfrCPUTimeThreadSampling::create_sampler(double rate, bool auto_adapt) { + assert(_sampler == nullptr, "invariant"); + _sampler = new JfrCPUSamplerThread(rate, auto_adapt); + _sampler->start_thread(); + _sampler->enroll(); +} + +void JfrCPUTimeThreadSampling::update_run_state(double rate, bool auto_adapt) { + if (rate != 0) { + if (_sampler == nullptr) { + create_sampler(rate, auto_adapt); + } else { + _sampler->set_rate(rate, auto_adapt); + _sampler->enroll(); + } + return; + } + if (_sampler != nullptr) { + _sampler->set_rate(rate /* 0 */, auto_adapt); + _sampler->disenroll(); + } +} + +void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { + assert(rate >= 0, "invariant"); + if (_instance == nullptr) { + return; + } + instance().set_rate_value(rate, auto_adapt); +} + +void JfrCPUTimeThreadSampling::set_rate_value(double rate, bool auto_adapt) { + if (_sampler != nullptr) { + _sampler->set_rate(rate, auto_adapt); + } + update_run_state(rate, auto_adapt); +} + +void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread *thread) { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->on_javathread_create(thread); + } +} + +void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread *thread) { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->on_javathread_terminate(thread); + } +} + +void JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests() { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->trigger_async_processing_of_cpu_time_jfr_requests(); + } +} + +void handle_timer_signal(int signo, siginfo_t* info, void* context) { + assert(_instance != nullptr, "invariant"); + _instance->handle_timer_signal(info, context); +} + + +void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* context) { + if (info->si_code != SI_TIMER) { + // not the signal we are interested in + return; + } + assert(_sampler != nullptr, "invariant"); + + if (!_sampler->increment_signal_handler_count()) { + return; + } + _sampler->handle_timer_signal(info, context); + _sampler->decrement_signal_handler_count(); +} + +void JfrCPUSamplerThread::sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now) { + JfrSampleRequestBuilder::build_cpu_time_sample_request(request, ucontext, jt, jt->jfr_thread_local(), now); +} + +static bool check_state(JavaThread* thread) { + switch (thread->thread_state()) { + case _thread_in_Java: + case _thread_in_native: + return true; + default: + return false; + } +} + +void JfrCPUSamplerThread::handle_timer_signal(siginfo_t* info, void* context) { + JfrTicks now = JfrTicks::now(); + JavaThread* jt = get_java_thread_if_valid(); + if (jt == nullptr) { + return; + } + JfrThreadLocal* tl = jt->jfr_thread_local(); + JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); + if (!check_state(jt)) { + queue.increment_lost_samples(); + return; + } + if (!tl->try_acquire_cpu_time_jfr_enqueue_lock()) { + queue.increment_lost_samples(); + return; + } + + JfrCPUTimeSampleRequest request; + // the sampling period might be too low for the current Linux configuration + // so samples might be skipped and we have to compute the actual period + int64_t period = get_sampling_period() * (info->si_overrun + 1); + request._cpu_time_period = Ticks(period / 1000000000.0 * JfrTime::frequency()) - Ticks(0); + sample_thread(request._request, context, jt, tl, now); + + if (queue.enqueue(request)) { + if (queue.size() == 1) { + tl->set_has_cpu_time_jfr_requests(true); + SafepointMechanism::arm_local_poll_release(jt); + } + } else { + queue.increment_lost_samples(); + } + + if (jt->thread_state() == _thread_in_native) { + if (!tl->wants_async_processing_of_cpu_time_jfr_requests()) { + tl->set_do_async_processing_of_cpu_time_jfr_requests(true); + JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests(); + } + } else { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + } + + tl->release_cpu_time_jfr_queue_lock(); +} + +static const int SIG = SIGPROF; + +static void set_timer_time(timer_t timerid, int64_t period_nanos) { + struct itimerspec its; + if (period_nanos == 0) { + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + } else { + its.it_interval.tv_sec = period_nanos / NANOSECS_PER_SEC; + its.it_interval.tv_nsec = period_nanos % NANOSECS_PER_SEC; + } + its.it_value = its.it_interval; + if (timer_settime(timerid, 0, &its, nullptr) == -1) { + warning("Failed to set timer for thread sampling: %s", os::strerror(os::get_last_error())); + } +} + +bool JfrCPUSamplerThread::create_timer_for_thread(JavaThread* thread, timer_t& timerid) { + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_signo = SIG; + sev.sigev_value.sival_ptr = nullptr; + ((int*)&sev.sigev_notify)[1] = thread->osthread()->thread_id(); + clockid_t clock; + int err = pthread_getcpuclockid(thread->osthread()->pthread_id(), &clock); + if (err != 0) { + log_error(jfr)("Failed to get clock for thread sampling: %s", os::strerror(err)); + return false; + } + if (timer_create(clock, &sev, &timerid) < 0) { + return false; + } + int64_t period = get_sampling_period(); + if (period != 0) { + set_timer_time(timerid, period); + } + return true; +} + + +void JfrCPUSamplerThread::stop_signal_handlers() { + // set the stop signal bit + Atomic::or_then_fetch(&_active_signal_handlers, STOP_SIGNAL_BIT, memory_order_acq_rel); + while (Atomic::load_acquire(&_active_signal_handlers) > STOP_SIGNAL_BIT) { + // wait for all signal handlers to finish + os::naked_short_nanosleep(1000); + } +} + +// returns false if the stop signal bit was set, true otherwise +bool JfrCPUSamplerThread::increment_signal_handler_count() { + // increment the count of active signal handlers + u4 old_value = Atomic::fetch_then_add(&_active_signal_handlers, (u4)1, memory_order_acq_rel); + if ((old_value & STOP_SIGNAL_BIT) != 0) { + // if the stop signal bit was set, we are not allowed to increment + Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); + return false; + } + return true; +} + +void JfrCPUSamplerThread::decrement_signal_handler_count() { + Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); +} + +void JfrCPUSamplerThread::initialize_active_signal_handler_counter() { + Atomic::release_store(&_active_signal_handlers, (u4)0); +} + +class VM_JFRInitializeCPUTimeSampler : public VM_Operation { + private: + JfrCPUSamplerThread* const _sampler; + + public: + VM_JFRInitializeCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} + + VMOp_Type type() const { return VMOp_JFRInitializeCPUTimeSampler; } + void doit() { + JfrJavaThreadIterator iter; + while (iter.has_next()) { + _sampler->on_javathread_create(iter.next()); + } + }; +}; + +bool JfrCPUSamplerThread::init_timers() { + // install sig handler for sig + void* prev_handler = PosixSignals::get_signal_handler_for_signal(SIG); + if ((prev_handler != SIG_DFL && prev_handler != SIG_IGN && prev_handler != (void*)::handle_timer_signal) || + PosixSignals::install_generic_signal_handler(SIG, (void*)::handle_timer_signal) == (void*)-1) { + log_error(jfr)("Conflicting SIGPROF handler found: %p. CPUTimeSample events will not be recorded", prev_handler); + return false; + } + Atomic::release_store(&_signal_handler_installed, true); + VM_JFRInitializeCPUTimeSampler op(this); + VMThread::execute(&op); + return true; +} + +class VM_JFRTerminateCPUTimeSampler : public VM_Operation { + private: + JfrCPUSamplerThread* const _sampler; + + public: + VM_JFRTerminateCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} + + VMOp_Type type() const { return VMOp_JFRTerminateCPUTimeSampler; } + void doit() { + JfrJavaThreadIterator iter; + while (iter.has_next()) { + JavaThread *thread = iter.next(); + JfrThreadLocal* tl = thread->jfr_thread_local(); + timer_t* timer = tl->cpu_timer(); + if (timer == nullptr) { + continue; + } + timer_delete(*timer); + tl->deallocate_cpu_time_jfr_queue(); + tl->unset_cpu_timer(); + } + }; +}; + +void JfrCPUSamplerThread::stop_timer() { + VM_JFRTerminateCPUTimeSampler op(this); + VMThread::execute(&op); +} + +void JfrCPUSamplerThread::auto_adapt_period_if_needed() { + int64_t current_period = get_sampling_period(); + if (_auto_adapt || current_period == -1) { + int64_t period = compute_sampling_period(_rate); + if (period != current_period) { + Atomic::store(&_current_sampling_period_ns, period); + update_all_thread_timers(); + } + } +} + +void JfrCPUSamplerThread::set_rate(double rate, bool auto_adapt) { + _rate = rate; + _auto_adapt = auto_adapt; + if (_rate > 0 && Atomic::load_acquire(&_disenrolled) == false) { + auto_adapt_period_if_needed(); + } else { + Atomic::store(&_current_sampling_period_ns, compute_sampling_period(rate)); + } +} + +void JfrCPUSamplerThread::update_all_thread_timers() { + int64_t period_millis = get_sampling_period(); + ThreadsListHandle tlh; + for (size_t i = 0; i < tlh.length(); i++) { + JavaThread* thread = tlh.thread_at(i); + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + timer_t* timer = tl->cpu_timer(); + if (timer != nullptr) { + set_timer_time(*timer, period_millis); + } + } +} + +#else + +static void warn() { + static bool displayed_warning = false; + if (!displayed_warning) { + warning("CPU time method sampling not supported in JFR on your platform"); + displayed_warning = true; + } +} + +static JfrCPUTimeThreadSampling* _instance = nullptr; + +JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { + return *_instance; +} + +JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { + _instance = new JfrCPUTimeThreadSampling(); + return _instance; +} + +void JfrCPUTimeThreadSampling::destroy() { + delete _instance; + _instance = nullptr; +} + +void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { + if (rate != 0) { + warn(); + } +} + +void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread* thread) { +} + +void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread* thread) { +} + +#endif // defined(LINUX) && defined(INCLUDE_JFR) diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp new file mode 100644 index 00000000000..7c0545f4772 --- /dev/null +++ b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 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 + * 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. + * + */ + +#ifndef SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP +#define SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP + +#include "jfr/utilities/jfrAllocation.hpp" + +class JavaThread; + +#if defined(LINUX) + +#include "jfr/periodic/sampling/jfrSampleRequest.hpp" +#include "jfr/utilities/jfrTypes.hpp" + +struct JfrCPUTimeSampleRequest { + JfrSampleRequest _request; + Tickspan _cpu_time_period; + + JfrCPUTimeSampleRequest() {} +}; + +// Fixed size async-signal-safe SPSC linear queue backed by an array. +// Designed to be only used under lock and read linearly +class JfrCPUTimeTraceQueue { + + // the default queue capacity, scaled if the sampling period is smaller than 10ms + // when the thread is started + static const u4 CPU_TIME_QUEUE_CAPACITY = 500; + + JfrCPUTimeSampleRequest* _data; + u4 _capacity; + // next unfilled index + volatile u4 _head; + + volatile u4 _lost_samples; + +public: + JfrCPUTimeTraceQueue(u4 capacity); + + ~JfrCPUTimeTraceQueue(); + + // signal safe, but can't be interleaved with dequeue + bool enqueue(JfrCPUTimeSampleRequest& trace); + + JfrCPUTimeSampleRequest& at(u4 index); + + u4 size() const; + + void set_size(u4 size); + + u4 capacity() const; + + // deletes all samples in the queue + void set_capacity(u4 capacity); + + bool is_empty() const; + + u4 lost_samples() const; + + void increment_lost_samples(); + + // returns the previous lost samples count + u4 get_and_reset_lost_samples(); + + void resize(u4 capacity); + + void resize_for_period(u4 period_millis); + + void clear(); + +}; + + +class JfrCPUSamplerThread; + +class JfrCPUTimeThreadSampling : public JfrCHeapObj { + friend class JfrRecorder; + private: + + JfrCPUSamplerThread* _sampler; + + void create_sampler(double rate, bool auto_adapt); + void set_rate_value(double rate, bool auto_adapt); + + JfrCPUTimeThreadSampling(); + ~JfrCPUTimeThreadSampling(); + + static JfrCPUTimeThreadSampling& instance(); + static JfrCPUTimeThreadSampling* create(); + static void destroy(); + + void update_run_state(double rate, bool auto_adapt); + + public: + static void set_rate(double rate, bool auto_adapt); + + static void on_javathread_create(JavaThread* thread); + static void on_javathread_terminate(JavaThread* thread); + void handle_timer_signal(siginfo_t* info, void* context); + + static void send_empty_event(const JfrTicks& start_time, traceid tid, Tickspan cpu_time_period); + static void send_event(const JfrTicks& start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased); + static void send_lost_event(const JfrTicks& time, traceid tid, s4 lost_samples); + + static void trigger_async_processing_of_cpu_time_jfr_requests(); +}; + +#else + +// a basic implementation on other platforms that +// emits warnings + +class JfrCPUTimeThreadSampling : public JfrCHeapObj { + friend class JfrRecorder; +private: + static JfrCPUTimeThreadSampling& instance(); + static JfrCPUTimeThreadSampling* create(); + static void destroy(); + + public: + static void set_rate(double rate, bool auto_adapt); + + static void on_javathread_create(JavaThread* thread); + static void on_javathread_terminate(JavaThread* thread); +}; + +#endif // defined(LINUX) + + +#endif // SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp index f8e63e2e344..7049df0198b 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp @@ -24,6 +24,7 @@ #include "asm/codeBuffer.hpp" #include "interpreter/interpreter.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" +#include "jfr/utilities/jfrTime.hpp" #include "runtime/continuationEntry.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.inline.hpp" @@ -171,7 +172,7 @@ static bool build(JfrSampleRequest& request, intptr_t* fp, JavaThread* jt) { assert(request._sample_sp != nullptr, "invariant"); assert(request._sample_pc != nullptr, "invariant"); assert(jt != nullptr, "invariant"); - assert(jt->thread_state() == _thread_in_Java, "invariant"); + assert(jt->thread_state() == _thread_in_Java || jt->thread_state() == _thread_in_native, "invariant"); // 1. Interpreter frame? if (is_interpreter(request)) { @@ -303,3 +304,33 @@ JfrSampleResult JfrSampleRequestBuilder::build_java_sample_request(const void* u } return set_biased_java_sample(request, tl, jt); } + + +// A biased sample request is denoted by an empty bcp and an empty pc. +static inline void set_cpu_time_biased_sample(JfrSampleRequest& request, JavaThread* jt) { + if (request._sample_bcp != nullptr) { + request._sample_bcp = nullptr; + } + assert(request._sample_bcp == nullptr, "invariant"); + request._sample_pc = nullptr; +} + +void JfrSampleRequestBuilder::build_cpu_time_sample_request(JfrSampleRequest& request, + void* ucontext, + JavaThread* jt, + JfrThreadLocal* tl, + JfrTicks& now) { + assert(jt != nullptr, "invariant"); + request._sample_ticks = now; + + // Prioritize the ljf, if one exists. + request._sample_sp = jt->last_Java_sp(); + if (request._sample_sp == nullptr || !build_from_ljf(request, tl, jt)) { + intptr_t* fp; + request._sample_pc = os::fetch_frame_from_context(ucontext, reinterpret_cast(&request._sample_sp), &fp); + assert(sp_in_stack(request, jt), "invariant"); + if (!build(request, fp, jt)) { + set_cpu_time_biased_sample(request, jt); + } + } +} diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp index 6567e7f8bff..20e737e0cbf 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp @@ -81,6 +81,11 @@ class JfrSampleRequestBuilder : AllStatic { static JfrSampleResult build_java_sample_request(const void* ucontext, JfrThreadLocal* tl, JavaThread* jt); + static void build_cpu_time_sample_request(JfrSampleRequest &request, + void* ucontext, + JavaThread* jt, + JfrThreadLocal* tl, + JfrTicks& now); }; #endif // SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEREQUEST_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp index aa72c29cf50..ddc9d59b295 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp @@ -28,6 +28,7 @@ #include "code/nmethod.hpp" #include "interpreter/interpreter.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrSampleMonitor.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" #include "jfr/periodic/sampling/jfrThreadSampling.hpp" @@ -161,7 +162,7 @@ static inline bool is_valid(const PcDesc* pc_desc) { return pc_desc != nullptr && pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null; } -static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt) { +static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt, bool& biased) { assert(jt != nullptr, "invariant"); if (!jt->has_last_Java_frame()) { @@ -178,6 +179,7 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, // A biased sample is requested or no code blob. top_frame = jt->last_frame(); in_continuation = is_in_continuation(top_frame, jt); + biased = true; return true; } @@ -227,6 +229,8 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, assert(!stream.current()->is_safepoint_blob_frame(), "invariant"); + biased = true; + // Search the first frame that is above the sampled sp. for (; !stream.is_done(); stream.next()) { frame* const current = stream.current(); @@ -250,6 +254,7 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, const PcDesc* const pc_desc = get_pc_desc(sampled_nm, sampled_pc); if (is_valid(pc_desc)) { current->adjust_pc(pc_desc->real_pc(sampled_nm)); + biased = false; } } } @@ -270,8 +275,9 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick assert(current != nullptr, "invariant"); frame top_frame; + bool biased = false; bool in_continuation; - if (!compute_top_frame(request, top_frame, in_continuation, jt)) { + if (!compute_top_frame(request, top_frame, in_continuation, jt, biased)) { return; } @@ -293,6 +299,42 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick } } +#ifdef LINUX +static void record_cpu_time_thread(const JfrCPUTimeSampleRequest& request, const JfrTicks& now, const JfrThreadLocal* tl, JavaThread* jt, Thread* current) { + assert(jt != nullptr, "invariant"); + assert(tl != nullptr, "invariant"); + assert(current != nullptr, "invariant"); + frame top_frame; + bool biased = false; + bool in_continuation = false; + bool could_compute_top_frame = compute_top_frame(request._request, top_frame, in_continuation, jt, biased); + const traceid tid = in_continuation ? tl->vthread_id_with_epoch_update(jt) : JfrThreadLocal::jvm_thread_id(jt); + + if (!could_compute_top_frame) { + JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); + return; + } + traceid sid; + { + ResourceMark rm(current); + JfrStackTrace stacktrace; + if (!stacktrace.record(jt, top_frame, in_continuation, request._request)) { + // Unable to record stacktrace. Fail. + JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); + return; + } + sid = JfrStackTraceRepository::add(stacktrace); + } + assert(sid != 0, "invariant"); + + + JfrCPUTimeThreadSampling::send_event(request._request._sample_ticks, sid, tid, request._cpu_time_period, biased); + if (current == jt) { + send_safepoint_latency_event(request._request, now, sid, jt); + } +} +#endif + static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { assert(tl != nullptr, "invariant"); assert(jt != nullptr, "invariant"); @@ -308,6 +350,49 @@ static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, Jav assert(!tl->has_enqueued_requests(), "invariant"); } +static void drain_enqueued_cpu_time_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current, bool lock) { + assert(tl != nullptr, "invariant"); + assert(jt != nullptr, "invariant"); + assert(current != nullptr, "invariant"); +#ifdef LINUX + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + if (lock) { + tl->acquire_cpu_time_jfr_dequeue_lock(); + } + JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); + for (u4 i = 0; i < queue.size(); i++) { + record_cpu_time_thread(queue.at(i), now, tl, jt, current); + } + queue.clear(); + assert(queue.is_empty(), "invariant"); + tl->set_has_cpu_time_jfr_requests(false); + if (queue.lost_samples() > 0) { + JfrCPUTimeThreadSampling::send_lost_event( now, JfrThreadLocal::thread_id(jt), queue.get_and_reset_lost_samples()); + } + if (lock) { + tl->release_cpu_time_jfr_queue_lock(); + } +#endif +} + +// Entry point for a thread that has been sampled in native code and has a pending JFR CPU time request. +void JfrThreadSampling::process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock) { + assert(jt != nullptr, "invariant"); + + const JfrTicks now = JfrTicks::now(); + drain_enqueued_cpu_time_requests(now, tl, jt, current, lock); +} + +static void drain_all_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { + assert(tl != nullptr, "invariant"); + assert(jt != nullptr, "invariant"); + assert(current != nullptr, "invariant"); + drain_enqueued_requests(now, tl, jt, current); + if (tl->has_cpu_time_jfr_requests()) { + drain_enqueued_cpu_time_requests(now, tl, jt, current, true); + } +} + // Only entered by the JfrSampler thread. bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread) { assert(tl != nullptr, "invairant"); @@ -382,5 +467,6 @@ void JfrThreadSampling::process_sample_request(JavaThread* jt) { break; } } - drain_enqueued_requests(now, tl, jt, jt); + drain_all_enqueued_requests(now, tl, jt, jt); } + diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp index d4c4bc0d873..3c4d1a126b0 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp @@ -33,8 +33,10 @@ class Thread; class JfrThreadSampling : AllStatic { friend class JfrSamplerThread; + friend class JfrCPUSamplerThread; private: static bool process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread); + static void process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock); public: static void process_sample_request(JavaThread* jt); }; diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp index 384305862ca..dd75cb2929f 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp @@ -29,6 +29,7 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/periodic/jfrOSInterface.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" @@ -304,6 +305,9 @@ bool JfrRecorder::create_components() { if (!create_thread_sampler()) { return false; } + if (!create_cpu_time_thread_sampling()) { + return false; + } if (!create_event_throttler()) { return false; } @@ -318,6 +322,7 @@ static JfrStackTraceRepository* _stack_trace_repository; static JfrStringPool* _stringpool = nullptr; static JfrOSInterface* _os_interface = nullptr; static JfrThreadSampler* _thread_sampler = nullptr; +static JfrCPUTimeThreadSampling* _cpu_time_thread_sampling = nullptr; static JfrCheckpointManager* _checkpoint_manager = nullptr; bool JfrRecorder::create_java_event_writer() { @@ -390,6 +395,12 @@ bool JfrRecorder::create_thread_sampler() { return _thread_sampler != nullptr; } +bool JfrRecorder::create_cpu_time_thread_sampling() { + assert(_cpu_time_thread_sampling == nullptr, "invariant"); + _cpu_time_thread_sampling = JfrCPUTimeThreadSampling::create(); + return _cpu_time_thread_sampling != nullptr; +} + bool JfrRecorder::create_event_throttler() { return JfrEventThrottler::create(); } @@ -428,6 +439,10 @@ void JfrRecorder::destroy_components() { JfrThreadSampler::destroy(); _thread_sampler = nullptr; } + if (_cpu_time_thread_sampling != nullptr) { + JfrCPUTimeThreadSampling::destroy(); + _cpu_time_thread_sampling = nullptr; + } JfrEventThrottler::destroy(); } diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp index b917904c5fb..3099c8ad344 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp @@ -54,6 +54,7 @@ class JfrRecorder : public JfrCHeapObj { static bool create_storage(); static bool create_stringpool(); static bool create_thread_sampler(); + static bool create_cpu_time_thread_sampling(); static bool create_event_throttler(); static bool create_components(); static void destroy_components(); diff --git a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp index 0befaae7751..f660a01c04c 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp @@ -34,6 +34,7 @@ constexpr static const JfrSamplerParams _disabled_params = { false // reconfigure }; +static JfrEventThrottler* _disabled_cpu_time_sample_throttler = nullptr; static JfrEventThrottler* _object_allocation_throttler = nullptr; static JfrEventThrottler* _safepoint_latency_throttler = nullptr; @@ -48,6 +49,9 @@ JfrEventThrottler::JfrEventThrottler(JfrEventId event_id) : _update(false) {} bool JfrEventThrottler::create() { + assert(_disabled_cpu_time_sample_throttler == nullptr, "invariant"); + _disabled_cpu_time_sample_throttler = new JfrEventThrottler(JfrCPUTimeSampleEvent); + _disabled_cpu_time_sample_throttler->_disabled = true; assert(_object_allocation_throttler == nullptr, "invariant"); _object_allocation_throttler = new JfrEventThrottler(JfrObjectAllocationSampleEvent); if (_object_allocation_throttler == nullptr || !_object_allocation_throttler->initialize()) { @@ -59,6 +63,8 @@ bool JfrEventThrottler::create() { } void JfrEventThrottler::destroy() { + delete _disabled_cpu_time_sample_throttler; + _disabled_cpu_time_sample_throttler = nullptr; delete _object_allocation_throttler; _object_allocation_throttler = nullptr; delete _safepoint_latency_throttler; @@ -69,15 +75,19 @@ void JfrEventThrottler::destroy() { // and another for the SamplingLatency event. // When introducing many more throttlers, consider adding a lookup map keyed by event id. JfrEventThrottler* JfrEventThrottler::for_event(JfrEventId event_id) { + assert(_disabled_cpu_time_sample_throttler != nullptr, "Disabled CPU time throttler has not been properly initialized"); assert(_object_allocation_throttler != nullptr, "ObjectAllocation throttler has not been properly initialized"); assert(_safepoint_latency_throttler != nullptr, "SafepointLatency throttler has not been properly initialized"); - assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent, "Event type has an unconfigured throttler"); + assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent || event_id == JfrCPUTimeSampleEvent, "Event type has an unconfigured throttler"); if (event_id == JfrObjectAllocationSampleEvent) { return _object_allocation_throttler; } if (event_id == JfrSafepointLatencyEvent) { return _safepoint_latency_throttler; } + if (event_id == JfrCPUTimeSampleEvent) { + return _disabled_cpu_time_sample_throttler; + } return nullptr; } diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp index 503aa85e02f..4b805a98a32 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp @@ -26,6 +26,7 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" #include "jfr/periodic/jfrThreadCPULoadEvent.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrOopTraceId.inline.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -78,7 +79,15 @@ JfrThreadLocal::JfrThreadLocal() : _enqueued_requests(false), _vthread(false), _notified(false), - _dead(false) { + _dead(false) +#ifdef LINUX + ,_cpu_timer(nullptr), + _cpu_time_jfr_locked(UNLOCKED), + _has_cpu_time_jfr_requests(false), + _cpu_time_jfr_queue(0), + _do_async_processing_of_cpu_time_jfr_requests(false) +#endif + { Thread* thread = Thread::current_or_null(); _parent_trace_id = thread != nullptr ? jvm_thread_id(thread) : (traceid)0; } @@ -129,7 +138,9 @@ void JfrThreadLocal::on_start(Thread* t) { if (JfrRecorder::is_recording()) { JfrCheckpointManager::write_checkpoint(t); if (t->is_Java_thread()) { - send_java_thread_start_event(JavaThread::cast(t)); + JavaThread *const jt = JavaThread::cast(t); + JfrCPUTimeThreadSampling::on_javathread_create(jt); + send_java_thread_start_event(jt); } } if (t->jfr_thread_local()->has_cached_stack_trace()) { @@ -221,6 +232,7 @@ void JfrThreadLocal::on_exit(Thread* t) { if (t->is_Java_thread()) { JavaThread* const jt = JavaThread::cast(t); send_java_thread_end_event(jt, JfrThreadLocal::jvm_thread_id(jt)); + JfrCPUTimeThreadSampling::on_javathread_terminate(jt); JfrThreadCPULoadEvent::send_event_for_thread(jt); } release(tl, Thread::current()); // because it could be that Thread::current() != t @@ -537,3 +549,85 @@ Arena* JfrThreadLocal::dcmd_arena(JavaThread* jt) { tl->_dcmd_arena = arena; return arena; } + + +#ifdef LINUX + +void JfrThreadLocal::set_cpu_timer(timer_t* timer) { + if (_cpu_timer == nullptr) { + _cpu_timer = JfrCHeapObj::new_array(1); + } + *_cpu_timer = *timer; +} + +void JfrThreadLocal::unset_cpu_timer() { + if (_cpu_timer != nullptr) { + timer_delete(*_cpu_timer); + JfrCHeapObj::free(_cpu_timer, sizeof(timer_t)); + _cpu_timer = nullptr; + } +} + +timer_t* JfrThreadLocal::cpu_timer() const { + return _cpu_timer; +} + +bool JfrThreadLocal::is_cpu_time_jfr_enqueue_locked() { + return Atomic::load_acquire(&_cpu_time_jfr_locked) == ENQUEUE; +} + +bool JfrThreadLocal::is_cpu_time_jfr_dequeue_locked() { + return Atomic::load_acquire(&_cpu_time_jfr_locked) == DEQUEUE; +} + +bool JfrThreadLocal::try_acquire_cpu_time_jfr_enqueue_lock() { + return Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, ENQUEUE) == UNLOCKED; +} + +bool JfrThreadLocal::try_acquire_cpu_time_jfr_dequeue_lock() { + CPUTimeLockState got; + while (true) { + CPUTimeLockState got = Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE); + if (got == UNLOCKED) { + return true; // successfully locked for dequeue + } + if (got == DEQUEUE) { + return false; // already locked for dequeue + } + // else wait for the lock to be released from a signal handler + } +} + +void JfrThreadLocal::acquire_cpu_time_jfr_dequeue_lock() { + while (Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE) != UNLOCKED); +} + +void JfrThreadLocal::release_cpu_time_jfr_queue_lock() { + Atomic::release_store(&_cpu_time_jfr_locked, UNLOCKED); +} + +void JfrThreadLocal::set_has_cpu_time_jfr_requests(bool has_requests) { + Atomic::release_store(&_has_cpu_time_jfr_requests, has_requests); +} + +bool JfrThreadLocal::has_cpu_time_jfr_requests() { + return Atomic::load_acquire(&_has_cpu_time_jfr_requests); +} + +JfrCPUTimeTraceQueue& JfrThreadLocal::cpu_time_jfr_queue() { + return _cpu_time_jfr_queue; +} + +void JfrThreadLocal::deallocate_cpu_time_jfr_queue() { + cpu_time_jfr_queue().resize(0); +} + +void JfrThreadLocal::set_do_async_processing_of_cpu_time_jfr_requests(bool wants) { + Atomic::release_store(&_do_async_processing_of_cpu_time_jfr_requests, wants); +} + +bool JfrThreadLocal::wants_async_processing_of_cpu_time_jfr_requests() { + return Atomic::load_acquire(&_do_async_processing_of_cpu_time_jfr_requests); +} + +#endif diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp index 8e545d9c429..715a2c44f93 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp @@ -33,6 +33,10 @@ #include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" +#ifdef LINUX +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" +#endif + class Arena; class JavaThread; class JfrBuffer; @@ -79,6 +83,22 @@ class JfrThreadLocal { bool _dead; bool _sampling_critical_section; +#ifdef LINUX + timer_t* _cpu_timer; + + enum CPUTimeLockState { + UNLOCKED, + // locked for enqueuing + ENQUEUE, + // locked for dequeuing + DEQUEUE + }; + volatile CPUTimeLockState _cpu_time_jfr_locked; + volatile bool _has_cpu_time_jfr_requests; + JfrCPUTimeTraceQueue _cpu_time_jfr_queue; + volatile bool _do_async_processing_of_cpu_time_jfr_requests; +#endif + JfrBuffer* install_native_buffer() const; JfrBuffer* install_java_buffer() const; void release(Thread* t); @@ -342,6 +362,39 @@ class JfrThreadLocal { void set_thread_blob(const JfrBlobHandle& handle); const JfrBlobHandle& thread_blob() const; + // CPU time sampling +#ifdef LINUX + void set_cpu_timer(timer_t* timer); + void unset_cpu_timer(); + timer_t* cpu_timer() const; + + // The CPU time JFR lock has three different states: + // - ENQUEUE: lock for enqueuing CPU time requests + // - DEQUEUE: lock for dequeuing CPU time requests + // - UNLOCKED: no lock held + // This ensures that we can safely enqueue and dequeue CPU time requests, + // without interleaving + + bool is_cpu_time_jfr_enqueue_locked(); + bool is_cpu_time_jfr_dequeue_locked(); + + bool try_acquire_cpu_time_jfr_enqueue_lock(); + bool try_acquire_cpu_time_jfr_dequeue_lock(); + void acquire_cpu_time_jfr_dequeue_lock(); + void release_cpu_time_jfr_queue_lock(); + + void set_has_cpu_time_jfr_requests(bool has_events); + bool has_cpu_time_jfr_requests(); + + JfrCPUTimeTraceQueue& cpu_time_jfr_queue(); + void deallocate_cpu_time_jfr_queue(); + + void set_do_async_processing_of_cpu_time_jfr_requests(bool wants); + bool wants_async_processing_of_cpu_time_jfr_requests(); +#else + bool has_cpu_time_jfr_requests() { return false; } +#endif + // Hooks static void on_start(Thread* t); static void on_exit(Thread* t); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index f3a06d5efd2..772ef7bbe82 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -78,6 +78,7 @@ class JavaThread; // - WorkerThread // - WatcherThread // - JfrThreadSampler +// - JfrCPUSamplerThread // - LogAsyncWriter // // All Thread subclasses must be either JavaThread or NonJavaThread. diff --git a/src/hotspot/share/runtime/vmOperation.hpp b/src/hotspot/share/runtime/vmOperation.hpp index 50d85944485..ac5d37381f9 100644 --- a/src/hotspot/share/runtime/vmOperation.hpp +++ b/src/hotspot/share/runtime/vmOperation.hpp @@ -115,6 +115,8 @@ template(JFROldObject) \ template(JvmtiPostObjectFree) \ template(RendezvousGCThreads) \ + template(JFRInitializeCPUTimeSampler) \ + template(JFRTerminateCPUTimeSampler) \ template(ReinitializeMDO) class Thread; diff --git a/src/hotspot/share/utilities/ticks.hpp b/src/hotspot/share/utilities/ticks.hpp index 8d2bbc7ce1f..88dc9a787f9 100644 --- a/src/hotspot/share/utilities/ticks.hpp +++ b/src/hotspot/share/utilities/ticks.hpp @@ -236,6 +236,7 @@ class TimeInstant : public Rep { friend class TimePartitionsTest; friend class GCTimerTest; friend class CompilerEvent; + friend class JfrCPUSamplerThread; }; #if INCLUDE_JFR diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index f43e45b724e..2ea4725abc8 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -51,6 +51,7 @@ import jdk.jfr.internal.settings.EnabledSetting; import jdk.jfr.internal.settings.LevelSetting; import jdk.jfr.internal.settings.MethodSetting; import jdk.jfr.internal.settings.PeriodSetting; +import jdk.jfr.internal.settings.CPUThrottleSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; import jdk.jfr.internal.settings.ThrottleSetting; @@ -326,6 +327,9 @@ public final class EventControl { private static Control defineThrottle(PlatformEventType type) { String def = type.getAnnotationValue(Throttle.class, ThrottleSetting.DEFAULT_VALUE); type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THROTTLE, Throttle.NAME, def, Collections.emptyList())); + if (type.getName().equals("jdk.CPUTimeSample")) { + return new Control(new CPUThrottleSetting(type), def); + } return new Control(new ThrottleSetting(type, def), def); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index e0eaef74b4c..b91f0c337b2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -270,6 +270,16 @@ public final class JVM { */ public static native void setMethodSamplingPeriod(long type, long periodMillis); + /** + * Set the maximum event emission rate for the CPU time sampler + * + * Setting rate to 0 turns off the CPU time sampler. + * + * @param rate the new rate in events per second + * @param autoAdapt true if the rate should be adapted automatically + */ + public static native void setCPUThrottle(double rate, boolean autoAdapt); + /** * Sets the file where data should be written. * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java index 32b59bca4c0..769e7055305 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java @@ -30,8 +30,10 @@ import java.util.List; import java.util.Objects; import jdk.jfr.SettingDescriptor; +import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.ImplicitFields; +import jdk.jfr.internal.util.TimespanRate; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.tracing.Modification; @@ -45,6 +47,7 @@ public final class PlatformEventType extends Type { private final boolean isJVM; private final boolean isJDK; private final boolean isMethodSampling; + private final boolean isCPUTimeMethodSampling; private final List settings = new ArrayList<>(5); private final boolean dynamicSettings; private final int stackTraceOffset; @@ -56,6 +59,7 @@ public final class PlatformEventType extends Type { private boolean stackTraceEnabled = true; private long thresholdTicks = 0; private long period = 0; + private TimespanRate cpuRate; private boolean hasHook; private boolean beginChunk; @@ -75,6 +79,7 @@ public final class PlatformEventType extends Type { this.dynamicSettings = dynamicSettings; this.isJVM = Type.isDefinedByJVM(id); this.isMethodSampling = determineMethodSampling(); + this.isCPUTimeMethodSampling = isJVM && name.equals(Type.EVENT_NAME_PREFIX + "CPUTimeSample"); this.isJDK = isJDK; this.stackTraceOffset = determineStackTraceOffset(); } @@ -191,6 +196,13 @@ public final class PlatformEventType extends Type { } } + public void setCPUThrottle(TimespanRate rate) { + if (isCPUTimeMethodSampling) { + this.cpuRate = rate; + JVM.setCPUThrottle(rate.rate(), rate.autoAdapt()); + } + } + public void setHasPeriod(boolean hasPeriod) { this.hasPeriod = hasPeriod; } @@ -251,6 +263,9 @@ public final class PlatformEventType extends Type { if (isMethodSampling) { long p = enabled ? period : 0; JVM.setMethodSamplingPeriod(getId(), p); + } else if (isCPUTimeMethodSampling) { + TimespanRate r = enabled ? cpuRate : new TimespanRate(0, false); + JVM.setCPUThrottle(r.rate(), r.autoAdapt()); } else { JVM.setEnabled(getId(), enabled); } @@ -388,6 +403,10 @@ public final class PlatformEventType extends Type { return isMethodSampling; } + public boolean isCPUTimeMethodSampling() { + return isCPUTimeMethodSampling; + } + public void setStackFilterId(long id) { startFilterId = id; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini index a6192db1ab0..a2ac74142f4 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini @@ -39,7 +39,8 @@ label = "Active Settings" table = "COLUMN 'Event Type', 'Enabled', 'Threshold', 'Stack Trace','Period','Cutoff', 'Throttle' FORMAT none, missing:whitespace, missing:whitespace, missing:whitespace, - missing:whitespace, missing:whitespace, missing:whitespace + missing:whitespace, missing:whitespace, missing:whitespace, + missing:whitespace SELECT E.id, LAST_BATCH(E.value), LAST_BATCH(T.value), LAST_BATCH(S.value), LAST_BATCH(P.value), LAST_BATCH(C.value), LAST_BATCH(U.value) @@ -400,6 +401,28 @@ table = "COLUMN 'Method', 'Samples', 'Percent' SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) FROM ExecutionSample GROUP BY T LIMIT 25" +[application.cpu-time-hot-methods] +label = "Java Methods that Execute the Most from CPU Time Sampler" +table = "COLUMN 'Method', 'Samples', 'Percent' + FORMAT none, none, normalized + SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) + FROM CPUTimeSample GROUP BY T LIMIT 25" + +[application.cpu-time-statistics] +label = "CPU Time Sample Statistics" +form = "COLUMN 'Successful Samples', 'Failed Samples', 'Biased Samples', 'Total Samples', 'Lost Samples' + SELECT COUNT(S.startTime), COUNT(F.startTime), COUNT(B.startTime), Count(A.startTime), SUM(L.lostSamples) + FROM + CPUTimeSample AS S, + CPUTimeSample AS F, + CPUTimeSample AS A, + CPUTimeSample AS B, + CPUTimeSamplesLost AS L + WHERE + S.failed = 'false' AND + F.failed = 'true' AND + B.biased = 'true'" + [jvm.jdk-agents] label = "JDK Agents" table = "COLUMN 'Time', 'Initialization', 'Name', 'Options' diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java new file mode 100644 index 00000000000..c18aeef2132 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Datadog, Inc. All rights reserved. + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.internal.settings; + +import static jdk.jfr.internal.util.TimespanUnit.SECONDS; +import static jdk.jfr.internal.util.TimespanUnit.MILLISECONDS; + +import java.util.Objects; +import java.util.Set; + +import jdk.jfr.Description; +import jdk.jfr.SettingControl; +import jdk.jfr.Label; +import jdk.jfr.MetadataDefinition; +import jdk.jfr.Name; +import jdk.jfr.internal.PlatformEventType; +import jdk.jfr.internal.Type; +import jdk.jfr.internal.util.TimespanRate; +import jdk.jfr.internal.util.Utils; + +@MetadataDefinition +@Label("CPUThrottleSetting") +@Description("Upper bounds the emission rate for CPU time samples") +@Name(Type.SETTINGS_PREFIX + "Rate") +public final class CPUThrottleSetting extends SettingControl { + public static final String DEFAULT_VALUE = "0/s"; + private final PlatformEventType eventType; + private String value = DEFAULT_VALUE; + + public CPUThrottleSetting(PlatformEventType eventType) { + this.eventType = Objects.requireNonNull(eventType); + } + + @Override + public String combine(Set values) { + TimespanRate max = null; + for (String value : values) { + TimespanRate rate = TimespanRate.of(value); + if (rate != null) { + if (max == null || rate.isHigher(max)) { + max = rate; + } + max = new TimespanRate(max.rate(), max.autoAdapt() || rate.autoAdapt()); + } + } + // "off" is not supported + return Objects.requireNonNullElse(max.toString(), DEFAULT_VALUE); + } + + @Override + public void setValue(String value) { + TimespanRate rate = TimespanRate.of(value); + if (rate != null) { + eventType.setCPUThrottle(rate); + this.value = value; + } + } + + @Override + public String getValue() { + return value; + } +} + diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java index f32436a5e0f..2632cd63848 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java @@ -55,4 +55,8 @@ public record Rate(long amount, TimespanUnit unit) { private double inNanos() { return (double) amount / unit.nanos; } + + public double perSecond() { + return inNanos() * 1_000_000_000.0; + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java new file mode 100644 index 00000000000..5d671310e3c --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 SAP SE. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.util; + +import jdk.jfr.internal.settings.CPUThrottleSetting; + +/** + * A rate or fixed period, see {@link jdk.jfr.internal.Rate} + */ +public record TimespanRate(double rate, boolean autoAdapt) { + + public static TimespanRate of(String text) { + if (text.equals("off")) { + text = CPUThrottleSetting.DEFAULT_VALUE; + } + boolean isPeriod = !text.contains("/"); + if (isPeriod) { + var period = ValueParser.parseTimespanWithInfinity(text, Long.MAX_VALUE); + if (period == Long.MAX_VALUE) { + return null; + } + if (period == 0) { + return new TimespanRate(0, false); + } + return new TimespanRate(Runtime.getRuntime().availableProcessors() / (period / 1_000_000_000.0), false); + } + Rate r = Rate.of(text); + if (r == null) { + return null; + } + return new TimespanRate(r.perSecond(), true); + } + + public boolean isHigher(TimespanRate that) { + return rate() > that.rate(); + } + + @Override + public String toString() { + if (autoAdapt) { + return String.format("%d/ns", (long)(rate * 1_000_000_000L)); + } + return String.format("%dns", (long)(Runtime.getRuntime().availableProcessors() / rate * 1_000_000_000L)); + } +} diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 293af26746f..541d1d3aa2f 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -226,6 +226,16 @@ off + + false + 500/s + true + + + + true + + true 10 ms diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 89a9022d11e..9cec2d9a70f 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -206,6 +206,16 @@ 20 ms + + false + 10ms + true + + + + true + + true diff --git a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java index 5b8aacfb1d2..d6e126a493f 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java +++ b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java @@ -89,7 +89,10 @@ public class TestLookForUntestedEvents { // Experimental events private static final Set experimentalEvents = Set.of( - "Flush", "SyncOnValueBasedClass"); + "Flush", "SyncOnValueBasedClass", "CPUTimeSample", "CPUTimeSamplesLost"); + + // Subset of the experimental events that should have tests + private static final Set experimentalButTestedEvents = Set.of("CPUTimeSample"); public static void main(String[] args) throws Exception { for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { @@ -110,7 +113,9 @@ public class TestLookForUntestedEvents { .collect(Collectors.toList()); Set eventsNotCoveredByTest = new HashSet<>(jfrEventTypes); - for (String event : jfrEventTypes) { + Set checkedEvents = new HashSet<>(jfrEventTypes); + checkedEvents.addAll(experimentalButTestedEvents); + for (String event : checkedEvents) { for (Path p : paths) { if (findStringInFile(p, event)) { eventsNotCoveredByTest.remove(event); diff --git a/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java new file mode 100644 index 00000000000..de211b8c454 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordedFrame; +import jdk.jfr.consumer.RecordedStackTrace; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.RecurseThread; + +public class BaseTestFullStackTrace { + private final static int MAX_DEPTH = 64; // currently hardcoded in jvm + + private final String eventName; + private final String threadFieldName; + + public BaseTestFullStackTrace(String eventName, String threadFieldName) { + this.eventName = eventName; + this.threadFieldName = threadFieldName; + } + + public void run() throws Throwable { + RecurseThread[] threads = new RecurseThread[3]; + for (int i = 0; i < threads.length; ++i) { + int depth = MAX_DEPTH - 1 + i; + threads[i] = new RecurseThread(depth); + threads[i].setName("recursethread-" + depth); + threads[i].start(); + } + + for (RecurseThread thread : threads) { + while (!thread.isInRunLoop()) { + Thread.sleep(20); + } + } + + assertStackTraces(threads); + + for (RecurseThread thread : threads) { + thread.quit(); + thread.join(); + } + } + + private void assertStackTraces(RecurseThread[] threads) throws Throwable { + while (true) { + try (Recording recording = new Recording()) { + if (eventName.equals(EventNames.CPUTimeSample)) { + recording.enable(eventName).with("throttle", "50ms"); + } else { + recording.enable(eventName).withPeriod(Duration.ofMillis(50)); + } + recording.start(); + Thread.sleep(500); + recording.stop(); + if (hasValidStackTraces(recording, threads)) { + break; + } + } + }; + } + + private boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { + boolean[] isEventFound = new boolean[threads.length]; + + for (RecordedEvent event : Events.fromRecording(recording)) { + System.out.println("Event: " + event); + String threadName = Events.assertField(event, threadFieldName + ".javaName").getValue(); + long threadId = Events.assertField(event, threadFieldName + ".javaThreadId").getValue(); + + for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { + RecurseThread currThread = threads[threadIndex]; + if (threadId == currThread.getId()) { + System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); + Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); + if ("recurseEnd".equals(getTopMethodName(event))) { + isEventFound[threadIndex] = true; + checkEvent(event, currThread.totalDepth); + break; + } + } + } + } + + for (int i = 0; i < threads.length; ++i) { + String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; + System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); + } + for (int i = 0; i < threads.length; ++i) { + if(!isEventFound[i]) { + // no assertion, let's retry. + // Could be race condition, i.e safe point during Thread.sleep + System.out.println("Failed to validate all threads, will retry."); + return false; + } + } + return true; + } + + public String getTopMethodName(RecordedEvent event) { + List frames = event.getStackTrace().getFrames(); + Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); + return frames.getFirst().getMethod().getName(); + } + + private void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { + RecordedStackTrace stacktrace = null; + try { + stacktrace = event.getStackTrace(); + List frames = stacktrace.getFrames(); + Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); + List expectedMethods = getExpectedMethods(expectedDepth); + Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); + + for (int i = 0; i < frames.size(); ++i) { + String name = frames.get(i).getMethod().getName(); + String expectedName = expectedMethods.get(i); + System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); + Asserts.assertEquals(name, expectedName, "Wrong method name"); + } + + boolean isTruncated = stacktrace.isTruncated(); + boolean isTruncateExpected = expectedDepth > MAX_DEPTH; + Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); + + String firstMethod = frames.getLast().getMethod().getName(); + boolean isFullTrace = "run".equals(firstMethod); + String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); + Asserts.assertTrue(isTruncated != isFullTrace, msg); + } catch (Throwable t) { + System.out.println(String.format("stacktrace:%n%s", stacktrace)); + throw t; + } + } + + private List getExpectedMethods(int depth) { + List methods = new ArrayList<>(); + methods.add("recurseEnd"); + for (int i = 0; i < depth - 2; ++i) { + methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); + } + methods.add("run"); + if (depth > MAX_DEPTH) { + methods = methods.subList(0, MAX_DEPTH); + } + return methods; + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java new file mode 100644 index 00000000000..eb8d33832b5 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.RecurseThread; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main/timeout=30 jdk.jfr.event.profiling.TestCPUTimeAndExecutionSample + */ +public class TestCPUTimeAndExecutionSample { + + static String sampleEvent = EventNames.CPUTimeSample; + + // The period is set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). + public static void main(String[] args) throws Exception { + run(EventNames.ExecutionSample); + run(EventNames.CPUTimeSample); + run(EventNames.ExecutionSample); + run(EventNames.CPUTimeSample); + } + + private static void run(String eventType) { + RecurseThread t = new RecurseThread(50); + t.setDaemon(true); + try (RecordingStream rs = new RecordingStream()) { + rs.enable(sampleEvent).with("throttle", "1000/s"); + rs.onEvent(sampleEvent, e -> { + t.quit(); + rs.close(); + }); + t.start(); + rs.start(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java new file mode 100644 index 00000000000..0d1108346ab --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import jdk.test.lib.jfr.EventNames; + +/** + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @build jdk.jfr.event.profiling.BaseTestFullStackTrace + * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleFullStackTrace + */ +public class TestCPUTimeSampleFullStackTrace { + + public static void main(String[] args) throws Throwable { + new BaseTestFullStackTrace(EventNames.CPUTimeSample, "eventThread").run(); + } + +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java new file mode 100644 index 00000000000..133df36684c --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordingStream; +import jdk.jfr.internal.JVM; +import jdk.test.lib.jfr.EventNames; + +/* + * Tests that creating multiple recordings after another is possible. + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSampleMultipleRecordings + */ +public class TestCPUTimeSampleMultipleRecordings { + + static String nativeEvent = EventNames.CPUTimeSample; + + static volatile boolean alive = true; + + public static void main(String[] args) throws Exception { + Thread t = new Thread(TestCPUTimeSampleMultipleRecordings::nativeMethod); + t.setDaemon(true); + t.start(); + for (int i = 0; i < 2; i++) { + try (RecordingStream rs = new RecordingStream()) { + rs.enable(nativeEvent).with("throttle", "1ms"); + rs.onEvent(nativeEvent, e -> { + alive = false; + rs.close(); + }); + + rs.start(); + } + } + alive = false; + } + + public static void nativeMethod() { + while (alive) { + JVM.getPid(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java new file mode 100644 index 00000000000..1617bce4ba3 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordingStream; +import jdk.jfr.internal.JVM; +import jdk.test.lib.jfr.EventNames; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSampleNative + */ +public class TestCPUTimeSampleNative { + + static String nativeEvent = EventNames.CPUTimeSample; + + static volatile boolean alive = true; + + public static void main(String[] args) throws Exception { + try (RecordingStream rs = new RecordingStream()) { + rs.enable(nativeEvent).with("throttle", "1ms"); + rs.onEvent(nativeEvent, e -> { + alive = false; + rs.close(); + }); + Thread t = new Thread(TestCPUTimeSampleNative::nativeMethod); + t.setDaemon(true); + t.start(); + rs.start(); + } + + } + + public static void nativeMethod() { + while (alive) { + JVM.getPid(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java new file mode 100644 index 00000000000..55b350ad096 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; +import java.lang.management.ManagementFactory; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Comparator; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; + +/** + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleThrottling + */ +public class TestCPUTimeSampleThrottling { + + public static void main(String[] args) throws Exception { + testZeroPerSecond(); + testThrottleSettings(); + testThrottleSettingsPeriod(); + } + + private static void testZeroPerSecond() throws Exception { + Asserts.assertTrue(0L == countEvents(1000, "0/s").count()); + } + + private static void testThrottleSettings() throws Exception { + long count = countEvents(1000, + Runtime.getRuntime().availableProcessors() * 2 + "/s").count(); + Asserts.assertTrue(count > 0 && count < 3, + "Expected between 0 and 3 events, got " + count); + } + + private static void testThrottleSettingsPeriod() throws Exception { + float rate = countEvents(1000, "10ms").rate(); + Asserts.assertTrue(rate > 90 && rate < 110, "Expected around 100 events per second, got " + rate); + } + + private record EventCount(long count, float time) { + float rate() { + return count / time; + } + } + + private static EventCount countEvents(int timeMs, String rate) throws Exception { + try(Recording recording = new Recording()) { + recording.enable(EventNames.CPUTimeSample) + .with("throttle", rate); + + var bean = ManagementFactory.getThreadMXBean(); + + recording.start(); + + long startThreadCpuTime = bean.getCurrentThreadCpuTime(); + + wasteCPU(timeMs); + + long spendCPUTime = bean.getCurrentThreadCpuTime() - startThreadCpuTime; + + recording.stop(); + + long eventCount = Events.fromRecording(recording).stream() + .filter(e -> e.getThread().getJavaName() + .equals(Thread.currentThread().getName())) + .count(); + + System.out.println("Event count: " + eventCount + ", CPU time: " + spendCPUTime / 1_000_000_000f + "s"); + + return new EventCount(eventCount, spendCPUTime / 1_000_000_000f); + } + } + + private static void wasteCPU(int durationMs) { + long start = System.currentTimeMillis(); + double i = 0; + while (System.currentTimeMillis() - start < durationMs) { + for (int j = 0; j < 100000; j++) { + i = Math.sqrt(i * Math.pow(Math.sqrt(Math.random()), Math.random())); + } + } + } + +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java new file mode 100644 index 00000000000..69d32d48282 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.RecurseThread; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSamplingLongPeriod + */ +public class TestCPUTimeSamplingLongPeriod { + + static String sampleEvent = EventNames.CPUTimeSample; + + // The period is set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). + public static void main(String[] args) throws Exception { + RecurseThread t = new RecurseThread(50); + t.setDaemon(true); + try (RecordingStream rs = new RecordingStream()) { + rs.enable(sampleEvent).with("throttle", "1100ms"); + rs.onEvent(sampleEvent, e -> { + t.quit(); + rs.close(); + }); + t.start(); + rs.start(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java index b06f9eed03d..c337a8128ab 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java +++ b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java @@ -23,147 +23,20 @@ package jdk.jfr.event.profiling; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; -import jdk.jfr.consumer.RecordedFrame; -import jdk.jfr.consumer.RecordedStackTrace; -import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.Events; -import jdk.test.lib.jfr.RecurseThread; /** * @test * @requires vm.hasJFR * @requires vm.opt.DeoptimizeALot != true * @library /test/lib + * @build jdk.jfr.event.profiling.BaseTestFullStackTrace * @run main/othervm jdk.jfr.event.profiling.TestFullStackTrace */ public class TestFullStackTrace { - private final static String EVENT_NAME = EventNames.ExecutionSample; - private final static int MAX_DEPTH = 64; // currently hardcoded in jvm public static void main(String[] args) throws Throwable { - RecurseThread[] threads = new RecurseThread[3]; - for (int i = 0; i < threads.length; ++i) { - int depth = MAX_DEPTH - 1 + i; - threads[i] = new RecurseThread(depth); - threads[i].setName("recursethread-" + depth); - threads[i].start(); - } - - for (RecurseThread thread : threads) { - while (!thread.isInRunLoop()) { - Thread.sleep(20); - } - } - - assertStackTraces(threads); - - for (RecurseThread thread : threads) { - thread.quit(); - thread.join(); - } + new BaseTestFullStackTrace(EventNames.ExecutionSample, "sampledThread").run(); } - private static void assertStackTraces( RecurseThread[] threads) throws Throwable { - Recording recording= null; - do { - recording = new Recording(); - recording.enable(EVENT_NAME).withPeriod(Duration.ofMillis(50)); - recording.start(); - Thread.sleep(500); - recording.stop(); - } while (!hasValidStackTraces(recording, threads)); - } - - private static boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { - boolean[] isEventFound = new boolean[threads.length]; - - for (RecordedEvent event : Events.fromRecording(recording)) { - //System.out.println("Event: " + event); - String threadName = Events.assertField(event, "sampledThread.javaName").getValue(); - long threadId = Events.assertField(event, "sampledThread.javaThreadId").getValue(); - - for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { - RecurseThread currThread = threads[threadIndex]; - if (threadId == currThread.getId()) { - System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); - Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); - if ("recurseEnd".equals(getTopMethodName(event))) { - isEventFound[threadIndex] = true; - checkEvent(event, currThread.totalDepth); - break; - } - } - } - } - - for (int i = 0; i < threads.length; ++i) { - String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; - System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); - } - for (int i = 0; i < threads.length; ++i) { - if(!isEventFound[i]) { - // no assertion, let's retry. - // Could be race condition, i.e safe point during Thread.sleep - System.out.println("Failed to validate all threads, will retry."); - return false; - } - } - return true; - } - - public static String getTopMethodName(RecordedEvent event) { - List frames = event.getStackTrace().getFrames(); - Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); - return frames.getFirst().getMethod().getName(); - } - - private static void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { - RecordedStackTrace stacktrace = null; - try { - stacktrace = event.getStackTrace(); - List frames = stacktrace.getFrames(); - Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); - List expectedMethods = getExpectedMethods(expectedDepth); - Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); - - for (int i = 0; i < frames.size(); ++i) { - String name = frames.get(i).getMethod().getName(); - String expectedName = expectedMethods.get(i); - System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); - Asserts.assertEquals(name, expectedName, "Wrong method name"); - } - - boolean isTruncated = stacktrace.isTruncated(); - boolean isTruncateExpected = expectedDepth > MAX_DEPTH; - Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); - - String firstMethod = frames.getLast().getMethod().getName(); - boolean isFullTrace = "run".equals(firstMethod); - String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); - Asserts.assertTrue(isTruncated != isFullTrace, msg); - } catch (Throwable t) { - System.out.println(String.format("stacktrace:%n%s", stacktrace)); - throw t; - } - } - - private static List getExpectedMethods(int depth) { - List methods = new ArrayList<>(); - methods.add("recurseEnd"); - for (int i = 0; i < depth - 2; ++i) { - methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); - } - methods.add("run"); - if (depth > MAX_DEPTH) { - methods = methods.subList(0, MAX_DEPTH); - } - return methods; - } } diff --git a/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java b/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java new file mode 100644 index 00000000000..8dc77fd38da --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + package test; + + import java.time.Duration; + + /* + * A class used to create a simple deep call stack for testing purposes + */ + public class RecursiveMethods { + + /** Method that uses recursion to produce a call stack of at least {@code depth} depth */ + public static int entry(int depth) { + return method2(--depth); + } + + private static int method2(int depth) { + return method3(--depth); + } + + private static int method3(int depth) { + return method4(--depth); + } + + private static int method4(int depth) { + return method5(--depth); + } + + private static int method5(int depth) { + return method6(--depth); + } + + private static int method6(int depth) { + return method7(--depth); + } + + private static int method7(int depth) { + return method8(--depth); + } + + private static int method8(int depth) { + return method9(--depth); + } + + private static int method9(int depth) { + return method10(--depth); + } + + private static int method10(int depth) { + if (depth > 0) { + return entry(--depth); + } + return depth; + } +} diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 904abe8e3e2..a00898358a8 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -77,6 +77,8 @@ public class EventNames { public static final String ThreadAllocationStatistics = PREFIX + "ThreadAllocationStatistics"; public static final String ExecutionSample = PREFIX + "ExecutionSample"; public static final String NativeMethodSample = PREFIX + "NativeMethodSample"; + public static final String CPUTimeSample = PREFIX + "CPUTimeSample"; + public static final String CPUTimeSamplesLost = PREFIX + "CPUTimeSamplesLost"; public static final String ThreadDump = PREFIX + "ThreadDump"; public static final String OldObjectSample = PREFIX + "OldObjectSample"; public static final String SymbolTableStatistics = PREFIX + "SymbolTableStatistics"; From b787ff6def08a050b690b60e4a0ceb3aec2b73c8 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 4 Jun 2025 23:19:33 +0000 Subject: [PATCH 155/216] 8358538: Update GHA Windows runner to 2025 Reviewed-by: shade --- .github/workflows/build-windows.yml | 6 +++--- .github/workflows/main.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d02ef91ad86..9bb43a8b83c 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -63,7 +63,7 @@ env: jobs: build-windows: name: build - runs-on: windows-2019 + runs-on: windows-2025 defaults: run: shell: bash @@ -102,7 +102,7 @@ jobs: id: toolchain-check run: | set +e - '/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} + '/c/Program Files/Microsoft Visual Studio/2022/Enterprise/vc/auxiliary/build/vcvars64.bat' -vcvars_ver=${{ inputs.msvc-toolset-version }} if [ $? -eq 0 ]; then echo "Toolchain is already installed" echo "toolchain-installed=true" >> $GITHUB_OUTPUT @@ -115,7 +115,7 @@ jobs: run: | # Run Visual Studio Installer '/c/Program Files (x86)/Microsoft Visual Studio/Installer/vs_installer.exe' \ - modify --quiet --installPath 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise' \ + modify --quiet --installPath 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise' \ --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} if: steps.toolchain-check.outputs.toolchain-installed != 'true' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6ca64bb82d0..0e64ad78625 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -310,7 +310,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-x64 - msvc-toolset-version: '14.29' + msvc-toolset-version: '14.43' 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.29' + msvc-toolset-version: '14.43' msvc-toolset-architecture: 'arm64' make-target: 'hotspot' extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin' @@ -393,5 +393,5 @@ jobs: with: platform: windows-x64 bootjdk-platform: windows-x64 - runs-on: windows-2019 + runs-on: windows-2025 debug-suffix: -debug From 9186cc7310c0cca2fca776031280f08d84e43b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Wed, 4 Jun 2025 23:55:18 +0000 Subject: [PATCH 156/216] 8358628: [BACKOUT] 8342818: Implement JEP 509: JFR CPU-Time Profiling Reviewed-by: pchilanomate, dholmes --- src/hotspot/os/posix/signals_posix.cpp | 8 - src/hotspot/os/posix/signals_posix.hpp | 2 - src/hotspot/share/jfr/jfr.inline.hpp | 3 +- src/hotspot/share/jfr/jni/jfrJniMethod.cpp | 6 - src/hotspot/share/jfr/jni/jfrJniMethod.hpp | 2 - .../jfr/jni/jfrJniMethodRegistration.cpp | 1 - src/hotspot/share/jfr/metadata/metadata.xml | 16 - .../sampling/jfrCPUTimeThreadSampler.cpp | 769 ------------------ .../sampling/jfrCPUTimeThreadSampler.hpp | 152 ---- .../periodic/sampling/jfrSampleRequest.cpp | 33 +- .../periodic/sampling/jfrSampleRequest.hpp | 5 - .../periodic/sampling/jfrThreadSampling.cpp | 92 +-- .../periodic/sampling/jfrThreadSampling.hpp | 2 - .../share/jfr/recorder/jfrRecorder.cpp | 15 - .../share/jfr/recorder/jfrRecorder.hpp | 1 - .../recorder/service/jfrEventThrottler.cpp | 12 +- .../share/jfr/support/jfrThreadLocal.cpp | 98 +-- .../share/jfr/support/jfrThreadLocal.hpp | 53 -- src/hotspot/share/runtime/thread.hpp | 1 - src/hotspot/share/runtime/vmOperation.hpp | 2 - src/hotspot/share/utilities/ticks.hpp | 1 - .../jdk/jfr/internal/EventControl.java | 4 - .../share/classes/jdk/jfr/internal/JVM.java | 10 - .../jdk/jfr/internal/PlatformEventType.java | 19 - .../classes/jdk/jfr/internal/query/view.ini | 25 +- .../internal/settings/CPUThrottleSetting.java | 89 -- .../classes/jdk/jfr/internal/util/Rate.java | 4 - .../jdk/jfr/internal/util/TimespanRate.java | 68 -- src/jdk.jfr/share/conf/jfr/default.jfc | 10 - src/jdk.jfr/share/conf/jfr/profile.jfc | 10 - .../metadata/TestLookForUntestedEvents.java | 9 +- .../profiling/BaseTestFullStackTrace.java | 176 ---- .../TestCPUTimeAndExecutionSample.java | 65 -- .../TestCPUTimeSampleFullStackTrace.java | 41 - .../TestCPUTimeSampleMultipleRecordings.java | 70 -- .../profiling/TestCPUTimeSampleNative.java | 66 -- .../TestCPUTimeSampleThrottling.java | 111 --- .../TestCPUTimeSamplingLongPeriod.java | 58 -- .../event/profiling/TestFullStackTrace.java | 131 ++- .../classes/test/RecursiveMethods.java | 76 -- test/lib/jdk/test/lib/jfr/EventNames.java | 2 - 41 files changed, 140 insertions(+), 2178 deletions(-) delete mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp delete mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java delete mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java delete mode 100644 test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 0157d354f40..e900d5695ae 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -1505,14 +1505,6 @@ bool PosixSignals::is_sig_ignored(int sig) { } } -void* PosixSignals::get_signal_handler_for_signal(int sig) { - struct sigaction oact; - if (sigaction(sig, (struct sigaction*)nullptr, &oact) == -1) { - return nullptr; - } - return get_signal_handler(&oact); -} - static void signal_sets_init() { sigemptyset(&preinstalled_sigs); diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index c1cb70df153..9deade4db18 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -52,8 +52,6 @@ public: static bool is_sig_ignored(int sig); - static void* get_signal_handler_for_signal(int sig); - static void hotspot_sigmask(Thread* thread); static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); diff --git a/src/hotspot/share/jfr/jfr.inline.hpp b/src/hotspot/share/jfr/jfr.inline.hpp index 5b6fc62d0ea..bdb47f600e6 100644 --- a/src/hotspot/share/jfr/jfr.inline.hpp +++ b/src/hotspot/share/jfr/jfr.inline.hpp @@ -32,8 +32,7 @@ inline bool Jfr::has_sample_request(JavaThread* jt) { assert(jt != nullptr, "invariant"); - JfrThreadLocal* tl = jt->jfr_thread_local(); - return tl->has_sample_request() || tl->has_cpu_time_jfr_requests(); + return jt->jfr_thread_local()->has_sample_request(); } inline void Jfr::check_and_process_sample_request(JavaThread* jt) { diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index bc2412a90c1..6f1c1936574 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -24,7 +24,6 @@ #include "jfr/jfr.hpp" #include "jfr/jfrEvents.hpp" -#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrEventSetting.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -170,11 +169,6 @@ NO_TRANSITION(jboolean, jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_ty return JNI_TRUE; NO_TRANSITION_END -JVM_ENTRY_NO_ENV(void, jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt)) - JfrEventSetting::set_enabled(JfrCPUTimeSampleEvent, rate > 0); - JfrCPUTimeThreadSampling::set_rate(rate, auto_adapt == JNI_TRUE); -JVM_END - NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong event_type_id, jlong value)) JfrEventSetting::set_miscellaneous(event_type_id, value); const JfrEventId typed_event_id = (JfrEventId)event_type_id; diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index dbea7f0180d..9c78c6239d4 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -129,8 +129,6 @@ jlong JNICALL jfr_get_unloaded_event_classes_count(JNIEnv* env, jclass jvm); jboolean JNICALL jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms); -void JNICALL jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt); - void JNICALL jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong id, jlong value); void JNICALL jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean, jboolean); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index 82ef93d95b2..33a564dee2f 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -83,7 +83,6 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"getUnloadedEventClassCount", (char*)"()J", (void*)jfr_get_unloaded_event_classes_count, (char*)"setMiscellaneous", (char*)"(JJ)V", (void*)jfr_set_miscellaneous, (char*)"setThrottle", (char*)"(JJJ)Z", (void*)jfr_set_throttle, - (char*)"setCPUThrottle", (char*)"(DZ)V", (void*)jfr_set_cpu_throttle, (char*)"emitOldObjectSamples", (char*)"(JZZ)V", (void*)jfr_emit_old_object_samples, (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk, (char*)"exclude", (char*)"(Ljava/lang/Thread;)V", (void*)jfr_exclude_thread, diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 03daca946f6..9c04ec3dca1 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -962,22 +962,6 @@ - - - - - - - - - - - - - diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp deleted file mode 100644 index ae8877ee3f2..00000000000 --- a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (c) 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 - * 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 "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" -#include "logging/log.hpp" - - -#if defined(LINUX) -#include "jfr/periodic/sampling/jfrThreadSampling.hpp" -#include "jfr/support/jfrThreadLocal.hpp" -#include "jfr/utilities/jfrTime.hpp" -#include "jfr/utilities/jfrThreadIterator.hpp" -#include "jfr/utilities/jfrTypes.hpp" -#include "jfrfiles/jfrEventClasses.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/atomic.hpp" -#include "runtime/javaThread.hpp" -#include "runtime/osThread.hpp" -#include "runtime/safepointMechanism.inline.hpp" -#include "runtime/threadSMR.hpp" -#include "runtime/vmOperation.hpp" -#include "runtime/vmThread.hpp" -#include "utilities/ticks.hpp" - -#include "signals_posix.hpp" - -static const int64_t AUTOADAPT_INTERVAL_MS = 100; - -static bool is_excluded(JavaThread* jt) { - return jt->is_hidden_from_external_view() || - jt->jfr_thread_local()->is_excluded() || - jt->is_JfrRecorder_thread(); -} - -static JavaThread* get_java_thread_if_valid() { - Thread* raw_thread = Thread::current_or_null_safe(); - if (raw_thread == nullptr) { - // probably while shutting down - return nullptr; - } - assert(raw_thread->is_Java_thread(), "invariant"); - JavaThread* jt = JavaThread::cast(raw_thread); - if (is_excluded(jt) || jt->is_exiting()) { - return nullptr; - } - return jt; -} - -JfrCPUTimeTraceQueue::JfrCPUTimeTraceQueue(u4 capacity) : - _capacity(capacity), _head(0), _lost_samples(0) { - _data = JfrCHeapObj::new_array(capacity); -} - -JfrCPUTimeTraceQueue::~JfrCPUTimeTraceQueue() { - JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); -} - -bool JfrCPUTimeTraceQueue::enqueue(JfrCPUTimeSampleRequest& request) { - assert(JavaThread::current()->jfr_thread_local()->is_cpu_time_jfr_enqueue_locked(), "invariant"); - assert(&JavaThread::current()->jfr_thread_local()->cpu_time_jfr_queue() == this, "invariant"); - u4 elementIndex; - do { - elementIndex = Atomic::load_acquire(&_head); - if (elementIndex >= _capacity) { - return false; - } - } while (Atomic::cmpxchg(&_head, elementIndex, elementIndex + 1) != elementIndex); - _data[elementIndex] = request; - return true; -} - -JfrCPUTimeSampleRequest& JfrCPUTimeTraceQueue::at(u4 index) { - assert(index < _head, "invariant"); - return _data[index]; -} - -static volatile u4 _lost_samples_sum = 0; - -u4 JfrCPUTimeTraceQueue::size() const { - return Atomic::load_acquire(&_head); -} - -void JfrCPUTimeTraceQueue::set_size(u4 size) { - Atomic::release_store(&_head, size); -} - -u4 JfrCPUTimeTraceQueue::capacity() const { - return _capacity; -} - -void JfrCPUTimeTraceQueue::set_capacity(u4 capacity) { - _head = 0; - JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); - _data = JfrCHeapObj::new_array(capacity); - _capacity = capacity; -} - -bool JfrCPUTimeTraceQueue::is_empty() const { - return Atomic::load_acquire(&_head) == 0; -} - -u4 JfrCPUTimeTraceQueue::lost_samples() const { - return Atomic::load(&_lost_samples); -} - -void JfrCPUTimeTraceQueue::increment_lost_samples() { - Atomic::inc(&_lost_samples_sum); - Atomic::inc(&_lost_samples); -} - -u4 JfrCPUTimeTraceQueue::get_and_reset_lost_samples() { - return Atomic::xchg(&_lost_samples, (u4)0); -} - -void JfrCPUTimeTraceQueue::resize(u4 capacity) { - if (capacity != _capacity) { - set_capacity(capacity); - } -} - -void JfrCPUTimeTraceQueue::resize_for_period(u4 period_millis) { - u4 capacity = CPU_TIME_QUEUE_CAPACITY; - if (period_millis > 0 && period_millis < 10) { - capacity = (u4) ((double) capacity * 10 / period_millis); - } - resize(capacity); -} - -void JfrCPUTimeTraceQueue::clear() { - Atomic::release_store(&_head, (u4)0); -} - -static int64_t compute_sampling_period(double rate) { - if (rate == 0) { - return 0; - } - return os::active_processor_count() * 1000000000.0 / rate; -} - -class JfrCPUSamplerThread : public NonJavaThread { - friend class JfrCPUTimeThreadSampling; - private: - Semaphore _sample; - NonJavaThread* _sampler_thread; - double _rate; - bool _auto_adapt; - volatile int64_t _current_sampling_period_ns; - volatile bool _disenrolled; - // top bit is used to indicate that no signal handler should proceed - volatile u4 _active_signal_handlers; - volatile bool _is_async_processing_of_cpu_time_jfr_requests_triggered; - volatile bool _warned_about_timer_creation_failure; - volatile bool _signal_handler_installed; - - static const u4 STOP_SIGNAL_BIT = 0x80000000; - - JfrCPUSamplerThread(double rate, bool auto_adapt); - - void start_thread(); - - void enroll(); - void disenroll(); - void update_all_thread_timers(); - - void auto_adapt_period_if_needed(); - - void set_rate(double rate, bool auto_adapt); - int64_t get_sampling_period() const { return Atomic::load(&_current_sampling_period_ns); }; - - void sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now); - - // process the queues for all threads that are in native state (and requested to be processed) - void stackwalk_threads_in_native(); - bool create_timer_for_thread(JavaThread* thread, timer_t &timerid); - - void stop_signal_handlers(); - - // returns false if the stop signal bit was set, true otherwise - bool increment_signal_handler_count(); - - void decrement_signal_handler_count(); - - void initialize_active_signal_handler_counter(); - -protected: - virtual void post_run(); -public: - virtual const char* name() const { return "JFR CPU Sampler Thread"; } - virtual const char* type_name() const { return "JfrCPUTimeSampler"; } - void run(); - void on_javathread_create(JavaThread* thread); - void on_javathread_terminate(JavaThread* thread); - - void handle_timer_signal(siginfo_t* info, void* context); - bool init_timers(); - void stop_timer(); - - void trigger_async_processing_of_cpu_time_jfr_requests(); -}; - -JfrCPUSamplerThread::JfrCPUSamplerThread(double rate, bool auto_adapt) : - _sample(), - _sampler_thread(nullptr), - _rate(rate), - _auto_adapt(auto_adapt), - _current_sampling_period_ns(compute_sampling_period(rate)), - _disenrolled(true), - _active_signal_handlers(STOP_SIGNAL_BIT), - _is_async_processing_of_cpu_time_jfr_requests_triggered(false), - _warned_about_timer_creation_failure(false), - _signal_handler_installed(false) { - assert(rate >= 0, "invariant"); -} - -void JfrCPUSamplerThread::trigger_async_processing_of_cpu_time_jfr_requests() { - Atomic::release_store(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true); -} - -void JfrCPUSamplerThread::on_javathread_create(JavaThread* thread) { - if (thread->is_hidden_from_external_view() || thread->is_JfrRecorder_thread() || - !Atomic::load_acquire(&_signal_handler_installed)) { - return; - } - JfrThreadLocal* tl = thread->jfr_thread_local(); - assert(tl != nullptr, "invariant"); - tl->cpu_time_jfr_queue().resize_for_period(_current_sampling_period_ns / 1000000); - timer_t timerid; - if (create_timer_for_thread(thread, timerid)) { - tl->set_cpu_timer(&timerid); - } else { - if (!Atomic::or_then_fetch(&_warned_about_timer_creation_failure, true)) { - log_warning(jfr)("Failed to create timer for a thread"); - } - tl->deallocate_cpu_time_jfr_queue(); - } -} - -void JfrCPUSamplerThread::on_javathread_terminate(JavaThread* thread) { - JfrThreadLocal* tl = thread->jfr_thread_local(); - assert(tl != nullptr, "invariant"); - timer_t* timer = tl->cpu_timer(); - if (timer == nullptr) { - return; // no timer was created for this thread - } - tl->unset_cpu_timer(); - tl->deallocate_cpu_time_jfr_queue(); - s4 lost_samples = tl->cpu_time_jfr_queue().lost_samples(); - if (lost_samples > 0) { - JfrCPUTimeThreadSampling::send_lost_event(JfrTicks::now(), JfrThreadLocal::thread_id(thread), lost_samples); - } -} - -void JfrCPUSamplerThread::start_thread() { - if (os::create_thread(this, os::os_thread)) { - os::start_thread(this); - } else { - log_error(jfr)("Failed to create thread for thread sampling"); - } -} - -void JfrCPUSamplerThread::enroll() { - if (Atomic::cmpxchg(&_disenrolled, true, false)) { - Atomic::store(&_warned_about_timer_creation_failure, false); - initialize_active_signal_handler_counter(); - log_trace(jfr)("Enrolling CPU thread sampler"); - _sample.signal(); - if (!init_timers()) { - log_error(jfr)("Failed to initialize timers for CPU thread sampler"); - disenroll(); - return; - } - log_trace(jfr)("Enrolled CPU thread sampler"); - } -} - -void JfrCPUSamplerThread::disenroll() { - if (!Atomic::cmpxchg(&_disenrolled, false, true)) { - log_trace(jfr)("Disenrolling CPU thread sampler"); - if (Atomic::load_acquire(&_signal_handler_installed)) { - stop_timer(); - stop_signal_handlers(); - } - _sample.wait(); - log_trace(jfr)("Disenrolled CPU thread sampler"); - } -} - -void JfrCPUSamplerThread::run() { - assert(_sampler_thread == nullptr, "invariant"); - _sampler_thread = this; - int64_t last_auto_adapt_check = os::javaTimeNanos(); - while (true) { - if (!_sample.trywait()) { - // disenrolled - _sample.wait(); - } - _sample.signal(); - - if (os::javaTimeNanos() - last_auto_adapt_check > AUTOADAPT_INTERVAL_MS * 1000000) { - auto_adapt_period_if_needed(); - last_auto_adapt_check = os::javaTimeNanos(); - } - - if (Atomic::cmpxchg(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true, false)) { - stackwalk_threads_in_native(); - } - os::naked_sleep(100); - } -} - -void JfrCPUSamplerThread::stackwalk_threads_in_native() { - ResourceMark rm; - // Required to prevent JFR from sampling through an ongoing safepoint - MutexLocker tlock(Threads_lock); - ThreadsListHandle tlh; - Thread* current = Thread::current(); - for (size_t i = 0; i < tlh.list()->length(); i++) { - JavaThread* jt = tlh.list()->thread_at(i); - JfrThreadLocal* tl = jt->jfr_thread_local(); - if (tl->wants_async_processing_of_cpu_time_jfr_requests()) { - if (jt->thread_state() != _thread_in_native || !tl->try_acquire_cpu_time_jfr_dequeue_lock()) { - tl->set_do_async_processing_of_cpu_time_jfr_requests(false); - continue; - } - if (jt->has_last_Java_frame()) { - JfrThreadSampling::process_cpu_time_request(jt, tl, current, false); - } else { - tl->set_do_async_processing_of_cpu_time_jfr_requests(false); - } - tl->release_cpu_time_jfr_queue_lock(); - } - } -} - -static volatile size_t count = 0; - -void JfrCPUTimeThreadSampling::send_empty_event(const JfrTicks &start_time, traceid tid, Tickspan cpu_time_period) { - EventCPUTimeSample event(UNTIMED); - event.set_failed(true); - event.set_starttime(start_time); - event.set_eventThread(tid); - event.set_stackTrace(0); - event.set_samplingPeriod(cpu_time_period); - event.set_biased(false); - event.commit(); -} - - -static volatile size_t biased_count = 0; - -void JfrCPUTimeThreadSampling::send_event(const JfrTicks &start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased) { - EventCPUTimeSample event(UNTIMED); - event.set_failed(false); - event.set_starttime(start_time); - event.set_eventThread(tid); - event.set_stackTrace(sid); - event.set_samplingPeriod(cpu_time_period); - event.set_biased(biased); - event.commit(); - Atomic::inc(&count); - if (biased) { - Atomic::inc(&biased_count); - } - if (Atomic::load(&count) % 1000 == 0) { - log_debug(jfr)("CPU thread sampler sent %zu events, lost %d, biased %zu\n", Atomic::load(&count), Atomic::load(&_lost_samples_sum), Atomic::load(&biased_count)); - } -} - -void JfrCPUTimeThreadSampling::send_lost_event(const JfrTicks &time, traceid tid, s4 lost_samples) { - if (!EventCPUTimeSamplesLost::is_enabled()) { - return; - } - EventCPUTimeSamplesLost event(UNTIMED); - event.set_starttime(time); - event.set_lostSamples(lost_samples); - event.set_eventThread(tid); - event.commit(); -} - -void JfrCPUSamplerThread::post_run() { - this->NonJavaThread::post_run(); - delete this; -} - -static JfrCPUTimeThreadSampling* _instance = nullptr; - -JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { - return *_instance; -} - -JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { - assert(_instance == nullptr, "invariant"); - _instance = new JfrCPUTimeThreadSampling(); - return _instance; -} - -void JfrCPUTimeThreadSampling::destroy() { - if (_instance != nullptr) { - delete _instance; - _instance = nullptr; - } -} - -JfrCPUTimeThreadSampling::JfrCPUTimeThreadSampling() : _sampler(nullptr) {} - -JfrCPUTimeThreadSampling::~JfrCPUTimeThreadSampling() { - if (_sampler != nullptr) { - _sampler->disenroll(); - } -} - -void JfrCPUTimeThreadSampling::create_sampler(double rate, bool auto_adapt) { - assert(_sampler == nullptr, "invariant"); - _sampler = new JfrCPUSamplerThread(rate, auto_adapt); - _sampler->start_thread(); - _sampler->enroll(); -} - -void JfrCPUTimeThreadSampling::update_run_state(double rate, bool auto_adapt) { - if (rate != 0) { - if (_sampler == nullptr) { - create_sampler(rate, auto_adapt); - } else { - _sampler->set_rate(rate, auto_adapt); - _sampler->enroll(); - } - return; - } - if (_sampler != nullptr) { - _sampler->set_rate(rate /* 0 */, auto_adapt); - _sampler->disenroll(); - } -} - -void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { - assert(rate >= 0, "invariant"); - if (_instance == nullptr) { - return; - } - instance().set_rate_value(rate, auto_adapt); -} - -void JfrCPUTimeThreadSampling::set_rate_value(double rate, bool auto_adapt) { - if (_sampler != nullptr) { - _sampler->set_rate(rate, auto_adapt); - } - update_run_state(rate, auto_adapt); -} - -void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread *thread) { - if (_instance != nullptr && _instance->_sampler != nullptr) { - _instance->_sampler->on_javathread_create(thread); - } -} - -void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread *thread) { - if (_instance != nullptr && _instance->_sampler != nullptr) { - _instance->_sampler->on_javathread_terminate(thread); - } -} - -void JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests() { - if (_instance != nullptr && _instance->_sampler != nullptr) { - _instance->_sampler->trigger_async_processing_of_cpu_time_jfr_requests(); - } -} - -void handle_timer_signal(int signo, siginfo_t* info, void* context) { - assert(_instance != nullptr, "invariant"); - _instance->handle_timer_signal(info, context); -} - - -void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* context) { - if (info->si_code != SI_TIMER) { - // not the signal we are interested in - return; - } - assert(_sampler != nullptr, "invariant"); - - if (!_sampler->increment_signal_handler_count()) { - return; - } - _sampler->handle_timer_signal(info, context); - _sampler->decrement_signal_handler_count(); -} - -void JfrCPUSamplerThread::sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now) { - JfrSampleRequestBuilder::build_cpu_time_sample_request(request, ucontext, jt, jt->jfr_thread_local(), now); -} - -static bool check_state(JavaThread* thread) { - switch (thread->thread_state()) { - case _thread_in_Java: - case _thread_in_native: - return true; - default: - return false; - } -} - -void JfrCPUSamplerThread::handle_timer_signal(siginfo_t* info, void* context) { - JfrTicks now = JfrTicks::now(); - JavaThread* jt = get_java_thread_if_valid(); - if (jt == nullptr) { - return; - } - JfrThreadLocal* tl = jt->jfr_thread_local(); - JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); - if (!check_state(jt)) { - queue.increment_lost_samples(); - return; - } - if (!tl->try_acquire_cpu_time_jfr_enqueue_lock()) { - queue.increment_lost_samples(); - return; - } - - JfrCPUTimeSampleRequest request; - // the sampling period might be too low for the current Linux configuration - // so samples might be skipped and we have to compute the actual period - int64_t period = get_sampling_period() * (info->si_overrun + 1); - request._cpu_time_period = Ticks(period / 1000000000.0 * JfrTime::frequency()) - Ticks(0); - sample_thread(request._request, context, jt, tl, now); - - if (queue.enqueue(request)) { - if (queue.size() == 1) { - tl->set_has_cpu_time_jfr_requests(true); - SafepointMechanism::arm_local_poll_release(jt); - } - } else { - queue.increment_lost_samples(); - } - - if (jt->thread_state() == _thread_in_native) { - if (!tl->wants_async_processing_of_cpu_time_jfr_requests()) { - tl->set_do_async_processing_of_cpu_time_jfr_requests(true); - JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests(); - } - } else { - tl->set_do_async_processing_of_cpu_time_jfr_requests(false); - } - - tl->release_cpu_time_jfr_queue_lock(); -} - -static const int SIG = SIGPROF; - -static void set_timer_time(timer_t timerid, int64_t period_nanos) { - struct itimerspec its; - if (period_nanos == 0) { - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - } else { - its.it_interval.tv_sec = period_nanos / NANOSECS_PER_SEC; - its.it_interval.tv_nsec = period_nanos % NANOSECS_PER_SEC; - } - its.it_value = its.it_interval; - if (timer_settime(timerid, 0, &its, nullptr) == -1) { - warning("Failed to set timer for thread sampling: %s", os::strerror(os::get_last_error())); - } -} - -bool JfrCPUSamplerThread::create_timer_for_thread(JavaThread* thread, timer_t& timerid) { - struct sigevent sev; - sev.sigev_notify = SIGEV_THREAD_ID; - sev.sigev_signo = SIG; - sev.sigev_value.sival_ptr = nullptr; - ((int*)&sev.sigev_notify)[1] = thread->osthread()->thread_id(); - clockid_t clock; - int err = pthread_getcpuclockid(thread->osthread()->pthread_id(), &clock); - if (err != 0) { - log_error(jfr)("Failed to get clock for thread sampling: %s", os::strerror(err)); - return false; - } - if (timer_create(clock, &sev, &timerid) < 0) { - return false; - } - int64_t period = get_sampling_period(); - if (period != 0) { - set_timer_time(timerid, period); - } - return true; -} - - -void JfrCPUSamplerThread::stop_signal_handlers() { - // set the stop signal bit - Atomic::or_then_fetch(&_active_signal_handlers, STOP_SIGNAL_BIT, memory_order_acq_rel); - while (Atomic::load_acquire(&_active_signal_handlers) > STOP_SIGNAL_BIT) { - // wait for all signal handlers to finish - os::naked_short_nanosleep(1000); - } -} - -// returns false if the stop signal bit was set, true otherwise -bool JfrCPUSamplerThread::increment_signal_handler_count() { - // increment the count of active signal handlers - u4 old_value = Atomic::fetch_then_add(&_active_signal_handlers, (u4)1, memory_order_acq_rel); - if ((old_value & STOP_SIGNAL_BIT) != 0) { - // if the stop signal bit was set, we are not allowed to increment - Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); - return false; - } - return true; -} - -void JfrCPUSamplerThread::decrement_signal_handler_count() { - Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); -} - -void JfrCPUSamplerThread::initialize_active_signal_handler_counter() { - Atomic::release_store(&_active_signal_handlers, (u4)0); -} - -class VM_JFRInitializeCPUTimeSampler : public VM_Operation { - private: - JfrCPUSamplerThread* const _sampler; - - public: - VM_JFRInitializeCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} - - VMOp_Type type() const { return VMOp_JFRInitializeCPUTimeSampler; } - void doit() { - JfrJavaThreadIterator iter; - while (iter.has_next()) { - _sampler->on_javathread_create(iter.next()); - } - }; -}; - -bool JfrCPUSamplerThread::init_timers() { - // install sig handler for sig - void* prev_handler = PosixSignals::get_signal_handler_for_signal(SIG); - if ((prev_handler != SIG_DFL && prev_handler != SIG_IGN && prev_handler != (void*)::handle_timer_signal) || - PosixSignals::install_generic_signal_handler(SIG, (void*)::handle_timer_signal) == (void*)-1) { - log_error(jfr)("Conflicting SIGPROF handler found: %p. CPUTimeSample events will not be recorded", prev_handler); - return false; - } - Atomic::release_store(&_signal_handler_installed, true); - VM_JFRInitializeCPUTimeSampler op(this); - VMThread::execute(&op); - return true; -} - -class VM_JFRTerminateCPUTimeSampler : public VM_Operation { - private: - JfrCPUSamplerThread* const _sampler; - - public: - VM_JFRTerminateCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} - - VMOp_Type type() const { return VMOp_JFRTerminateCPUTimeSampler; } - void doit() { - JfrJavaThreadIterator iter; - while (iter.has_next()) { - JavaThread *thread = iter.next(); - JfrThreadLocal* tl = thread->jfr_thread_local(); - timer_t* timer = tl->cpu_timer(); - if (timer == nullptr) { - continue; - } - timer_delete(*timer); - tl->deallocate_cpu_time_jfr_queue(); - tl->unset_cpu_timer(); - } - }; -}; - -void JfrCPUSamplerThread::stop_timer() { - VM_JFRTerminateCPUTimeSampler op(this); - VMThread::execute(&op); -} - -void JfrCPUSamplerThread::auto_adapt_period_if_needed() { - int64_t current_period = get_sampling_period(); - if (_auto_adapt || current_period == -1) { - int64_t period = compute_sampling_period(_rate); - if (period != current_period) { - Atomic::store(&_current_sampling_period_ns, period); - update_all_thread_timers(); - } - } -} - -void JfrCPUSamplerThread::set_rate(double rate, bool auto_adapt) { - _rate = rate; - _auto_adapt = auto_adapt; - if (_rate > 0 && Atomic::load_acquire(&_disenrolled) == false) { - auto_adapt_period_if_needed(); - } else { - Atomic::store(&_current_sampling_period_ns, compute_sampling_period(rate)); - } -} - -void JfrCPUSamplerThread::update_all_thread_timers() { - int64_t period_millis = get_sampling_period(); - ThreadsListHandle tlh; - for (size_t i = 0; i < tlh.length(); i++) { - JavaThread* thread = tlh.thread_at(i); - JfrThreadLocal* tl = thread->jfr_thread_local(); - assert(tl != nullptr, "invariant"); - timer_t* timer = tl->cpu_timer(); - if (timer != nullptr) { - set_timer_time(*timer, period_millis); - } - } -} - -#else - -static void warn() { - static bool displayed_warning = false; - if (!displayed_warning) { - warning("CPU time method sampling not supported in JFR on your platform"); - displayed_warning = true; - } -} - -static JfrCPUTimeThreadSampling* _instance = nullptr; - -JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { - return *_instance; -} - -JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { - _instance = new JfrCPUTimeThreadSampling(); - return _instance; -} - -void JfrCPUTimeThreadSampling::destroy() { - delete _instance; - _instance = nullptr; -} - -void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { - if (rate != 0) { - warn(); - } -} - -void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread* thread) { -} - -void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread* thread) { -} - -#endif // defined(LINUX) && defined(INCLUDE_JFR) diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp deleted file mode 100644 index 7c0545f4772..00000000000 --- a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 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 - * 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. - * - */ - -#ifndef SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP -#define SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP - -#include "jfr/utilities/jfrAllocation.hpp" - -class JavaThread; - -#if defined(LINUX) - -#include "jfr/periodic/sampling/jfrSampleRequest.hpp" -#include "jfr/utilities/jfrTypes.hpp" - -struct JfrCPUTimeSampleRequest { - JfrSampleRequest _request; - Tickspan _cpu_time_period; - - JfrCPUTimeSampleRequest() {} -}; - -// Fixed size async-signal-safe SPSC linear queue backed by an array. -// Designed to be only used under lock and read linearly -class JfrCPUTimeTraceQueue { - - // the default queue capacity, scaled if the sampling period is smaller than 10ms - // when the thread is started - static const u4 CPU_TIME_QUEUE_CAPACITY = 500; - - JfrCPUTimeSampleRequest* _data; - u4 _capacity; - // next unfilled index - volatile u4 _head; - - volatile u4 _lost_samples; - -public: - JfrCPUTimeTraceQueue(u4 capacity); - - ~JfrCPUTimeTraceQueue(); - - // signal safe, but can't be interleaved with dequeue - bool enqueue(JfrCPUTimeSampleRequest& trace); - - JfrCPUTimeSampleRequest& at(u4 index); - - u4 size() const; - - void set_size(u4 size); - - u4 capacity() const; - - // deletes all samples in the queue - void set_capacity(u4 capacity); - - bool is_empty() const; - - u4 lost_samples() const; - - void increment_lost_samples(); - - // returns the previous lost samples count - u4 get_and_reset_lost_samples(); - - void resize(u4 capacity); - - void resize_for_period(u4 period_millis); - - void clear(); - -}; - - -class JfrCPUSamplerThread; - -class JfrCPUTimeThreadSampling : public JfrCHeapObj { - friend class JfrRecorder; - private: - - JfrCPUSamplerThread* _sampler; - - void create_sampler(double rate, bool auto_adapt); - void set_rate_value(double rate, bool auto_adapt); - - JfrCPUTimeThreadSampling(); - ~JfrCPUTimeThreadSampling(); - - static JfrCPUTimeThreadSampling& instance(); - static JfrCPUTimeThreadSampling* create(); - static void destroy(); - - void update_run_state(double rate, bool auto_adapt); - - public: - static void set_rate(double rate, bool auto_adapt); - - static void on_javathread_create(JavaThread* thread); - static void on_javathread_terminate(JavaThread* thread); - void handle_timer_signal(siginfo_t* info, void* context); - - static void send_empty_event(const JfrTicks& start_time, traceid tid, Tickspan cpu_time_period); - static void send_event(const JfrTicks& start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased); - static void send_lost_event(const JfrTicks& time, traceid tid, s4 lost_samples); - - static void trigger_async_processing_of_cpu_time_jfr_requests(); -}; - -#else - -// a basic implementation on other platforms that -// emits warnings - -class JfrCPUTimeThreadSampling : public JfrCHeapObj { - friend class JfrRecorder; -private: - static JfrCPUTimeThreadSampling& instance(); - static JfrCPUTimeThreadSampling* create(); - static void destroy(); - - public: - static void set_rate(double rate, bool auto_adapt); - - static void on_javathread_create(JavaThread* thread); - static void on_javathread_terminate(JavaThread* thread); -}; - -#endif // defined(LINUX) - - -#endif // SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp index 7049df0198b..f8e63e2e344 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp @@ -24,7 +24,6 @@ #include "asm/codeBuffer.hpp" #include "interpreter/interpreter.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" -#include "jfr/utilities/jfrTime.hpp" #include "runtime/continuationEntry.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.inline.hpp" @@ -172,7 +171,7 @@ static bool build(JfrSampleRequest& request, intptr_t* fp, JavaThread* jt) { assert(request._sample_sp != nullptr, "invariant"); assert(request._sample_pc != nullptr, "invariant"); assert(jt != nullptr, "invariant"); - assert(jt->thread_state() == _thread_in_Java || jt->thread_state() == _thread_in_native, "invariant"); + assert(jt->thread_state() == _thread_in_Java, "invariant"); // 1. Interpreter frame? if (is_interpreter(request)) { @@ -304,33 +303,3 @@ JfrSampleResult JfrSampleRequestBuilder::build_java_sample_request(const void* u } return set_biased_java_sample(request, tl, jt); } - - -// A biased sample request is denoted by an empty bcp and an empty pc. -static inline void set_cpu_time_biased_sample(JfrSampleRequest& request, JavaThread* jt) { - if (request._sample_bcp != nullptr) { - request._sample_bcp = nullptr; - } - assert(request._sample_bcp == nullptr, "invariant"); - request._sample_pc = nullptr; -} - -void JfrSampleRequestBuilder::build_cpu_time_sample_request(JfrSampleRequest& request, - void* ucontext, - JavaThread* jt, - JfrThreadLocal* tl, - JfrTicks& now) { - assert(jt != nullptr, "invariant"); - request._sample_ticks = now; - - // Prioritize the ljf, if one exists. - request._sample_sp = jt->last_Java_sp(); - if (request._sample_sp == nullptr || !build_from_ljf(request, tl, jt)) { - intptr_t* fp; - request._sample_pc = os::fetch_frame_from_context(ucontext, reinterpret_cast(&request._sample_sp), &fp); - assert(sp_in_stack(request, jt), "invariant"); - if (!build(request, fp, jt)) { - set_cpu_time_biased_sample(request, jt); - } - } -} diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp index 20e737e0cbf..6567e7f8bff 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp @@ -81,11 +81,6 @@ class JfrSampleRequestBuilder : AllStatic { static JfrSampleResult build_java_sample_request(const void* ucontext, JfrThreadLocal* tl, JavaThread* jt); - static void build_cpu_time_sample_request(JfrSampleRequest &request, - void* ucontext, - JavaThread* jt, - JfrThreadLocal* tl, - JfrTicks& now); }; #endif // SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEREQUEST_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp index ddc9d59b295..aa72c29cf50 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp @@ -28,7 +28,6 @@ #include "code/nmethod.hpp" #include "interpreter/interpreter.hpp" #include "jfr/jfrEvents.hpp" -#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrSampleMonitor.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" #include "jfr/periodic/sampling/jfrThreadSampling.hpp" @@ -162,7 +161,7 @@ static inline bool is_valid(const PcDesc* pc_desc) { return pc_desc != nullptr && pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null; } -static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt, bool& biased) { +static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt) { assert(jt != nullptr, "invariant"); if (!jt->has_last_Java_frame()) { @@ -179,7 +178,6 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, // A biased sample is requested or no code blob. top_frame = jt->last_frame(); in_continuation = is_in_continuation(top_frame, jt); - biased = true; return true; } @@ -229,8 +227,6 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, assert(!stream.current()->is_safepoint_blob_frame(), "invariant"); - biased = true; - // Search the first frame that is above the sampled sp. for (; !stream.is_done(); stream.next()) { frame* const current = stream.current(); @@ -254,7 +250,6 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, const PcDesc* const pc_desc = get_pc_desc(sampled_nm, sampled_pc); if (is_valid(pc_desc)) { current->adjust_pc(pc_desc->real_pc(sampled_nm)); - biased = false; } } } @@ -275,9 +270,8 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick assert(current != nullptr, "invariant"); frame top_frame; - bool biased = false; bool in_continuation; - if (!compute_top_frame(request, top_frame, in_continuation, jt, biased)) { + if (!compute_top_frame(request, top_frame, in_continuation, jt)) { return; } @@ -299,42 +293,6 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick } } -#ifdef LINUX -static void record_cpu_time_thread(const JfrCPUTimeSampleRequest& request, const JfrTicks& now, const JfrThreadLocal* tl, JavaThread* jt, Thread* current) { - assert(jt != nullptr, "invariant"); - assert(tl != nullptr, "invariant"); - assert(current != nullptr, "invariant"); - frame top_frame; - bool biased = false; - bool in_continuation = false; - bool could_compute_top_frame = compute_top_frame(request._request, top_frame, in_continuation, jt, biased); - const traceid tid = in_continuation ? tl->vthread_id_with_epoch_update(jt) : JfrThreadLocal::jvm_thread_id(jt); - - if (!could_compute_top_frame) { - JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); - return; - } - traceid sid; - { - ResourceMark rm(current); - JfrStackTrace stacktrace; - if (!stacktrace.record(jt, top_frame, in_continuation, request._request)) { - // Unable to record stacktrace. Fail. - JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); - return; - } - sid = JfrStackTraceRepository::add(stacktrace); - } - assert(sid != 0, "invariant"); - - - JfrCPUTimeThreadSampling::send_event(request._request._sample_ticks, sid, tid, request._cpu_time_period, biased); - if (current == jt) { - send_safepoint_latency_event(request._request, now, sid, jt); - } -} -#endif - static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { assert(tl != nullptr, "invariant"); assert(jt != nullptr, "invariant"); @@ -350,49 +308,6 @@ static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, Jav assert(!tl->has_enqueued_requests(), "invariant"); } -static void drain_enqueued_cpu_time_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current, bool lock) { - assert(tl != nullptr, "invariant"); - assert(jt != nullptr, "invariant"); - assert(current != nullptr, "invariant"); -#ifdef LINUX - tl->set_do_async_processing_of_cpu_time_jfr_requests(false); - if (lock) { - tl->acquire_cpu_time_jfr_dequeue_lock(); - } - JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); - for (u4 i = 0; i < queue.size(); i++) { - record_cpu_time_thread(queue.at(i), now, tl, jt, current); - } - queue.clear(); - assert(queue.is_empty(), "invariant"); - tl->set_has_cpu_time_jfr_requests(false); - if (queue.lost_samples() > 0) { - JfrCPUTimeThreadSampling::send_lost_event( now, JfrThreadLocal::thread_id(jt), queue.get_and_reset_lost_samples()); - } - if (lock) { - tl->release_cpu_time_jfr_queue_lock(); - } -#endif -} - -// Entry point for a thread that has been sampled in native code and has a pending JFR CPU time request. -void JfrThreadSampling::process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock) { - assert(jt != nullptr, "invariant"); - - const JfrTicks now = JfrTicks::now(); - drain_enqueued_cpu_time_requests(now, tl, jt, current, lock); -} - -static void drain_all_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { - assert(tl != nullptr, "invariant"); - assert(jt != nullptr, "invariant"); - assert(current != nullptr, "invariant"); - drain_enqueued_requests(now, tl, jt, current); - if (tl->has_cpu_time_jfr_requests()) { - drain_enqueued_cpu_time_requests(now, tl, jt, current, true); - } -} - // Only entered by the JfrSampler thread. bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread) { assert(tl != nullptr, "invairant"); @@ -467,6 +382,5 @@ void JfrThreadSampling::process_sample_request(JavaThread* jt) { break; } } - drain_all_enqueued_requests(now, tl, jt, jt); + drain_enqueued_requests(now, tl, jt, jt); } - diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp index 3c4d1a126b0..d4c4bc0d873 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp @@ -33,10 +33,8 @@ class Thread; class JfrThreadSampling : AllStatic { friend class JfrSamplerThread; - friend class JfrCPUSamplerThread; private: static bool process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread); - static void process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock); public: static void process_sample_request(JavaThread* jt); }; diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp index dd75cb2929f..384305862ca 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp @@ -29,7 +29,6 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/periodic/jfrOSInterface.hpp" -#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" @@ -305,9 +304,6 @@ bool JfrRecorder::create_components() { if (!create_thread_sampler()) { return false; } - if (!create_cpu_time_thread_sampling()) { - return false; - } if (!create_event_throttler()) { return false; } @@ -322,7 +318,6 @@ static JfrStackTraceRepository* _stack_trace_repository; static JfrStringPool* _stringpool = nullptr; static JfrOSInterface* _os_interface = nullptr; static JfrThreadSampler* _thread_sampler = nullptr; -static JfrCPUTimeThreadSampling* _cpu_time_thread_sampling = nullptr; static JfrCheckpointManager* _checkpoint_manager = nullptr; bool JfrRecorder::create_java_event_writer() { @@ -395,12 +390,6 @@ bool JfrRecorder::create_thread_sampler() { return _thread_sampler != nullptr; } -bool JfrRecorder::create_cpu_time_thread_sampling() { - assert(_cpu_time_thread_sampling == nullptr, "invariant"); - _cpu_time_thread_sampling = JfrCPUTimeThreadSampling::create(); - return _cpu_time_thread_sampling != nullptr; -} - bool JfrRecorder::create_event_throttler() { return JfrEventThrottler::create(); } @@ -439,10 +428,6 @@ void JfrRecorder::destroy_components() { JfrThreadSampler::destroy(); _thread_sampler = nullptr; } - if (_cpu_time_thread_sampling != nullptr) { - JfrCPUTimeThreadSampling::destroy(); - _cpu_time_thread_sampling = nullptr; - } JfrEventThrottler::destroy(); } diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp index 3099c8ad344..b917904c5fb 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp @@ -54,7 +54,6 @@ class JfrRecorder : public JfrCHeapObj { static bool create_storage(); static bool create_stringpool(); static bool create_thread_sampler(); - static bool create_cpu_time_thread_sampling(); static bool create_event_throttler(); static bool create_components(); static void destroy_components(); diff --git a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp index f660a01c04c..0befaae7751 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp @@ -34,7 +34,6 @@ constexpr static const JfrSamplerParams _disabled_params = { false // reconfigure }; -static JfrEventThrottler* _disabled_cpu_time_sample_throttler = nullptr; static JfrEventThrottler* _object_allocation_throttler = nullptr; static JfrEventThrottler* _safepoint_latency_throttler = nullptr; @@ -49,9 +48,6 @@ JfrEventThrottler::JfrEventThrottler(JfrEventId event_id) : _update(false) {} bool JfrEventThrottler::create() { - assert(_disabled_cpu_time_sample_throttler == nullptr, "invariant"); - _disabled_cpu_time_sample_throttler = new JfrEventThrottler(JfrCPUTimeSampleEvent); - _disabled_cpu_time_sample_throttler->_disabled = true; assert(_object_allocation_throttler == nullptr, "invariant"); _object_allocation_throttler = new JfrEventThrottler(JfrObjectAllocationSampleEvent); if (_object_allocation_throttler == nullptr || !_object_allocation_throttler->initialize()) { @@ -63,8 +59,6 @@ bool JfrEventThrottler::create() { } void JfrEventThrottler::destroy() { - delete _disabled_cpu_time_sample_throttler; - _disabled_cpu_time_sample_throttler = nullptr; delete _object_allocation_throttler; _object_allocation_throttler = nullptr; delete _safepoint_latency_throttler; @@ -75,19 +69,15 @@ void JfrEventThrottler::destroy() { // and another for the SamplingLatency event. // When introducing many more throttlers, consider adding a lookup map keyed by event id. JfrEventThrottler* JfrEventThrottler::for_event(JfrEventId event_id) { - assert(_disabled_cpu_time_sample_throttler != nullptr, "Disabled CPU time throttler has not been properly initialized"); assert(_object_allocation_throttler != nullptr, "ObjectAllocation throttler has not been properly initialized"); assert(_safepoint_latency_throttler != nullptr, "SafepointLatency throttler has not been properly initialized"); - assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent || event_id == JfrCPUTimeSampleEvent, "Event type has an unconfigured throttler"); + assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent, "Event type has an unconfigured throttler"); if (event_id == JfrObjectAllocationSampleEvent) { return _object_allocation_throttler; } if (event_id == JfrSafepointLatencyEvent) { return _safepoint_latency_throttler; } - if (event_id == JfrCPUTimeSampleEvent) { - return _disabled_cpu_time_sample_throttler; - } return nullptr; } diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp index 4b805a98a32..503aa85e02f 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp @@ -26,7 +26,6 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" #include "jfr/periodic/jfrThreadCPULoadEvent.hpp" -#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrOopTraceId.inline.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -79,15 +78,7 @@ JfrThreadLocal::JfrThreadLocal() : _enqueued_requests(false), _vthread(false), _notified(false), - _dead(false) -#ifdef LINUX - ,_cpu_timer(nullptr), - _cpu_time_jfr_locked(UNLOCKED), - _has_cpu_time_jfr_requests(false), - _cpu_time_jfr_queue(0), - _do_async_processing_of_cpu_time_jfr_requests(false) -#endif - { + _dead(false) { Thread* thread = Thread::current_or_null(); _parent_trace_id = thread != nullptr ? jvm_thread_id(thread) : (traceid)0; } @@ -138,9 +129,7 @@ void JfrThreadLocal::on_start(Thread* t) { if (JfrRecorder::is_recording()) { JfrCheckpointManager::write_checkpoint(t); if (t->is_Java_thread()) { - JavaThread *const jt = JavaThread::cast(t); - JfrCPUTimeThreadSampling::on_javathread_create(jt); - send_java_thread_start_event(jt); + send_java_thread_start_event(JavaThread::cast(t)); } } if (t->jfr_thread_local()->has_cached_stack_trace()) { @@ -232,7 +221,6 @@ void JfrThreadLocal::on_exit(Thread* t) { if (t->is_Java_thread()) { JavaThread* const jt = JavaThread::cast(t); send_java_thread_end_event(jt, JfrThreadLocal::jvm_thread_id(jt)); - JfrCPUTimeThreadSampling::on_javathread_terminate(jt); JfrThreadCPULoadEvent::send_event_for_thread(jt); } release(tl, Thread::current()); // because it could be that Thread::current() != t @@ -549,85 +537,3 @@ Arena* JfrThreadLocal::dcmd_arena(JavaThread* jt) { tl->_dcmd_arena = arena; return arena; } - - -#ifdef LINUX - -void JfrThreadLocal::set_cpu_timer(timer_t* timer) { - if (_cpu_timer == nullptr) { - _cpu_timer = JfrCHeapObj::new_array(1); - } - *_cpu_timer = *timer; -} - -void JfrThreadLocal::unset_cpu_timer() { - if (_cpu_timer != nullptr) { - timer_delete(*_cpu_timer); - JfrCHeapObj::free(_cpu_timer, sizeof(timer_t)); - _cpu_timer = nullptr; - } -} - -timer_t* JfrThreadLocal::cpu_timer() const { - return _cpu_timer; -} - -bool JfrThreadLocal::is_cpu_time_jfr_enqueue_locked() { - return Atomic::load_acquire(&_cpu_time_jfr_locked) == ENQUEUE; -} - -bool JfrThreadLocal::is_cpu_time_jfr_dequeue_locked() { - return Atomic::load_acquire(&_cpu_time_jfr_locked) == DEQUEUE; -} - -bool JfrThreadLocal::try_acquire_cpu_time_jfr_enqueue_lock() { - return Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, ENQUEUE) == UNLOCKED; -} - -bool JfrThreadLocal::try_acquire_cpu_time_jfr_dequeue_lock() { - CPUTimeLockState got; - while (true) { - CPUTimeLockState got = Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE); - if (got == UNLOCKED) { - return true; // successfully locked for dequeue - } - if (got == DEQUEUE) { - return false; // already locked for dequeue - } - // else wait for the lock to be released from a signal handler - } -} - -void JfrThreadLocal::acquire_cpu_time_jfr_dequeue_lock() { - while (Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE) != UNLOCKED); -} - -void JfrThreadLocal::release_cpu_time_jfr_queue_lock() { - Atomic::release_store(&_cpu_time_jfr_locked, UNLOCKED); -} - -void JfrThreadLocal::set_has_cpu_time_jfr_requests(bool has_requests) { - Atomic::release_store(&_has_cpu_time_jfr_requests, has_requests); -} - -bool JfrThreadLocal::has_cpu_time_jfr_requests() { - return Atomic::load_acquire(&_has_cpu_time_jfr_requests); -} - -JfrCPUTimeTraceQueue& JfrThreadLocal::cpu_time_jfr_queue() { - return _cpu_time_jfr_queue; -} - -void JfrThreadLocal::deallocate_cpu_time_jfr_queue() { - cpu_time_jfr_queue().resize(0); -} - -void JfrThreadLocal::set_do_async_processing_of_cpu_time_jfr_requests(bool wants) { - Atomic::release_store(&_do_async_processing_of_cpu_time_jfr_requests, wants); -} - -bool JfrThreadLocal::wants_async_processing_of_cpu_time_jfr_requests() { - return Atomic::load_acquire(&_do_async_processing_of_cpu_time_jfr_requests); -} - -#endif diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp index 715a2c44f93..8e545d9c429 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp @@ -33,10 +33,6 @@ #include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" -#ifdef LINUX -#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" -#endif - class Arena; class JavaThread; class JfrBuffer; @@ -83,22 +79,6 @@ class JfrThreadLocal { bool _dead; bool _sampling_critical_section; -#ifdef LINUX - timer_t* _cpu_timer; - - enum CPUTimeLockState { - UNLOCKED, - // locked for enqueuing - ENQUEUE, - // locked for dequeuing - DEQUEUE - }; - volatile CPUTimeLockState _cpu_time_jfr_locked; - volatile bool _has_cpu_time_jfr_requests; - JfrCPUTimeTraceQueue _cpu_time_jfr_queue; - volatile bool _do_async_processing_of_cpu_time_jfr_requests; -#endif - JfrBuffer* install_native_buffer() const; JfrBuffer* install_java_buffer() const; void release(Thread* t); @@ -362,39 +342,6 @@ class JfrThreadLocal { void set_thread_blob(const JfrBlobHandle& handle); const JfrBlobHandle& thread_blob() const; - // CPU time sampling -#ifdef LINUX - void set_cpu_timer(timer_t* timer); - void unset_cpu_timer(); - timer_t* cpu_timer() const; - - // The CPU time JFR lock has three different states: - // - ENQUEUE: lock for enqueuing CPU time requests - // - DEQUEUE: lock for dequeuing CPU time requests - // - UNLOCKED: no lock held - // This ensures that we can safely enqueue and dequeue CPU time requests, - // without interleaving - - bool is_cpu_time_jfr_enqueue_locked(); - bool is_cpu_time_jfr_dequeue_locked(); - - bool try_acquire_cpu_time_jfr_enqueue_lock(); - bool try_acquire_cpu_time_jfr_dequeue_lock(); - void acquire_cpu_time_jfr_dequeue_lock(); - void release_cpu_time_jfr_queue_lock(); - - void set_has_cpu_time_jfr_requests(bool has_events); - bool has_cpu_time_jfr_requests(); - - JfrCPUTimeTraceQueue& cpu_time_jfr_queue(); - void deallocate_cpu_time_jfr_queue(); - - void set_do_async_processing_of_cpu_time_jfr_requests(bool wants); - bool wants_async_processing_of_cpu_time_jfr_requests(); -#else - bool has_cpu_time_jfr_requests() { return false; } -#endif - // Hooks static void on_start(Thread* t); static void on_exit(Thread* t); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 772ef7bbe82..f3a06d5efd2 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -78,7 +78,6 @@ class JavaThread; // - WorkerThread // - WatcherThread // - JfrThreadSampler -// - JfrCPUSamplerThread // - LogAsyncWriter // // All Thread subclasses must be either JavaThread or NonJavaThread. diff --git a/src/hotspot/share/runtime/vmOperation.hpp b/src/hotspot/share/runtime/vmOperation.hpp index ac5d37381f9..50d85944485 100644 --- a/src/hotspot/share/runtime/vmOperation.hpp +++ b/src/hotspot/share/runtime/vmOperation.hpp @@ -115,8 +115,6 @@ template(JFROldObject) \ template(JvmtiPostObjectFree) \ template(RendezvousGCThreads) \ - template(JFRInitializeCPUTimeSampler) \ - template(JFRTerminateCPUTimeSampler) \ template(ReinitializeMDO) class Thread; diff --git a/src/hotspot/share/utilities/ticks.hpp b/src/hotspot/share/utilities/ticks.hpp index 88dc9a787f9..8d2bbc7ce1f 100644 --- a/src/hotspot/share/utilities/ticks.hpp +++ b/src/hotspot/share/utilities/ticks.hpp @@ -236,7 +236,6 @@ class TimeInstant : public Rep { friend class TimePartitionsTest; friend class GCTimerTest; friend class CompilerEvent; - friend class JfrCPUSamplerThread; }; #if INCLUDE_JFR diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 2ea4725abc8..f43e45b724e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -51,7 +51,6 @@ import jdk.jfr.internal.settings.EnabledSetting; import jdk.jfr.internal.settings.LevelSetting; import jdk.jfr.internal.settings.MethodSetting; import jdk.jfr.internal.settings.PeriodSetting; -import jdk.jfr.internal.settings.CPUThrottleSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; import jdk.jfr.internal.settings.ThrottleSetting; @@ -327,9 +326,6 @@ public final class EventControl { private static Control defineThrottle(PlatformEventType type) { String def = type.getAnnotationValue(Throttle.class, ThrottleSetting.DEFAULT_VALUE); type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THROTTLE, Throttle.NAME, def, Collections.emptyList())); - if (type.getName().equals("jdk.CPUTimeSample")) { - return new Control(new CPUThrottleSetting(type), def); - } return new Control(new ThrottleSetting(type, def), def); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index b91f0c337b2..e0eaef74b4c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -270,16 +270,6 @@ public final class JVM { */ public static native void setMethodSamplingPeriod(long type, long periodMillis); - /** - * Set the maximum event emission rate for the CPU time sampler - * - * Setting rate to 0 turns off the CPU time sampler. - * - * @param rate the new rate in events per second - * @param autoAdapt true if the rate should be adapted automatically - */ - public static native void setCPUThrottle(double rate, boolean autoAdapt); - /** * Sets the file where data should be written. * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java index 769e7055305..32b59bca4c0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java @@ -30,10 +30,8 @@ import java.util.List; import java.util.Objects; import jdk.jfr.SettingDescriptor; -import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.ImplicitFields; -import jdk.jfr.internal.util.TimespanRate; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.tracing.Modification; @@ -47,7 +45,6 @@ public final class PlatformEventType extends Type { private final boolean isJVM; private final boolean isJDK; private final boolean isMethodSampling; - private final boolean isCPUTimeMethodSampling; private final List settings = new ArrayList<>(5); private final boolean dynamicSettings; private final int stackTraceOffset; @@ -59,7 +56,6 @@ public final class PlatformEventType extends Type { private boolean stackTraceEnabled = true; private long thresholdTicks = 0; private long period = 0; - private TimespanRate cpuRate; private boolean hasHook; private boolean beginChunk; @@ -79,7 +75,6 @@ public final class PlatformEventType extends Type { this.dynamicSettings = dynamicSettings; this.isJVM = Type.isDefinedByJVM(id); this.isMethodSampling = determineMethodSampling(); - this.isCPUTimeMethodSampling = isJVM && name.equals(Type.EVENT_NAME_PREFIX + "CPUTimeSample"); this.isJDK = isJDK; this.stackTraceOffset = determineStackTraceOffset(); } @@ -196,13 +191,6 @@ public final class PlatformEventType extends Type { } } - public void setCPUThrottle(TimespanRate rate) { - if (isCPUTimeMethodSampling) { - this.cpuRate = rate; - JVM.setCPUThrottle(rate.rate(), rate.autoAdapt()); - } - } - public void setHasPeriod(boolean hasPeriod) { this.hasPeriod = hasPeriod; } @@ -263,9 +251,6 @@ public final class PlatformEventType extends Type { if (isMethodSampling) { long p = enabled ? period : 0; JVM.setMethodSamplingPeriod(getId(), p); - } else if (isCPUTimeMethodSampling) { - TimespanRate r = enabled ? cpuRate : new TimespanRate(0, false); - JVM.setCPUThrottle(r.rate(), r.autoAdapt()); } else { JVM.setEnabled(getId(), enabled); } @@ -403,10 +388,6 @@ public final class PlatformEventType extends Type { return isMethodSampling; } - public boolean isCPUTimeMethodSampling() { - return isCPUTimeMethodSampling; - } - public void setStackFilterId(long id) { startFilterId = id; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini index a2ac74142f4..a6192db1ab0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini @@ -39,8 +39,7 @@ label = "Active Settings" table = "COLUMN 'Event Type', 'Enabled', 'Threshold', 'Stack Trace','Period','Cutoff', 'Throttle' FORMAT none, missing:whitespace, missing:whitespace, missing:whitespace, - missing:whitespace, missing:whitespace, missing:whitespace, - missing:whitespace + missing:whitespace, missing:whitespace, missing:whitespace SELECT E.id, LAST_BATCH(E.value), LAST_BATCH(T.value), LAST_BATCH(S.value), LAST_BATCH(P.value), LAST_BATCH(C.value), LAST_BATCH(U.value) @@ -401,28 +400,6 @@ table = "COLUMN 'Method', 'Samples', 'Percent' SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) FROM ExecutionSample GROUP BY T LIMIT 25" -[application.cpu-time-hot-methods] -label = "Java Methods that Execute the Most from CPU Time Sampler" -table = "COLUMN 'Method', 'Samples', 'Percent' - FORMAT none, none, normalized - SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) - FROM CPUTimeSample GROUP BY T LIMIT 25" - -[application.cpu-time-statistics] -label = "CPU Time Sample Statistics" -form = "COLUMN 'Successful Samples', 'Failed Samples', 'Biased Samples', 'Total Samples', 'Lost Samples' - SELECT COUNT(S.startTime), COUNT(F.startTime), COUNT(B.startTime), Count(A.startTime), SUM(L.lostSamples) - FROM - CPUTimeSample AS S, - CPUTimeSample AS F, - CPUTimeSample AS A, - CPUTimeSample AS B, - CPUTimeSamplesLost AS L - WHERE - S.failed = 'false' AND - F.failed = 'true' AND - B.biased = 'true'" - [jvm.jdk-agents] label = "JDK Agents" table = "COLUMN 'Time', 'Initialization', 'Name', 'Options' diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java deleted file mode 100644 index c18aeef2132..00000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, Datadog, Inc. All rights reserved. - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.internal.settings; - -import static jdk.jfr.internal.util.TimespanUnit.SECONDS; -import static jdk.jfr.internal.util.TimespanUnit.MILLISECONDS; - -import java.util.Objects; -import java.util.Set; - -import jdk.jfr.Description; -import jdk.jfr.SettingControl; -import jdk.jfr.Label; -import jdk.jfr.MetadataDefinition; -import jdk.jfr.Name; -import jdk.jfr.internal.PlatformEventType; -import jdk.jfr.internal.Type; -import jdk.jfr.internal.util.TimespanRate; -import jdk.jfr.internal.util.Utils; - -@MetadataDefinition -@Label("CPUThrottleSetting") -@Description("Upper bounds the emission rate for CPU time samples") -@Name(Type.SETTINGS_PREFIX + "Rate") -public final class CPUThrottleSetting extends SettingControl { - public static final String DEFAULT_VALUE = "0/s"; - private final PlatformEventType eventType; - private String value = DEFAULT_VALUE; - - public CPUThrottleSetting(PlatformEventType eventType) { - this.eventType = Objects.requireNonNull(eventType); - } - - @Override - public String combine(Set values) { - TimespanRate max = null; - for (String value : values) { - TimespanRate rate = TimespanRate.of(value); - if (rate != null) { - if (max == null || rate.isHigher(max)) { - max = rate; - } - max = new TimespanRate(max.rate(), max.autoAdapt() || rate.autoAdapt()); - } - } - // "off" is not supported - return Objects.requireNonNullElse(max.toString(), DEFAULT_VALUE); - } - - @Override - public void setValue(String value) { - TimespanRate rate = TimespanRate.of(value); - if (rate != null) { - eventType.setCPUThrottle(rate); - this.value = value; - } - } - - @Override - public String getValue() { - return value; - } -} - diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java index 2632cd63848..f32436a5e0f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java @@ -55,8 +55,4 @@ public record Rate(long amount, TimespanUnit unit) { private double inNanos() { return (double) amount / unit.nanos; } - - public double perSecond() { - return inNanos() * 1_000_000_000.0; - } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java deleted file mode 100644 index 5d671310e3c..00000000000 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2025 SAP SE. All rights reserved. - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jfr.internal.util; - -import jdk.jfr.internal.settings.CPUThrottleSetting; - -/** - * A rate or fixed period, see {@link jdk.jfr.internal.Rate} - */ -public record TimespanRate(double rate, boolean autoAdapt) { - - public static TimespanRate of(String text) { - if (text.equals("off")) { - text = CPUThrottleSetting.DEFAULT_VALUE; - } - boolean isPeriod = !text.contains("/"); - if (isPeriod) { - var period = ValueParser.parseTimespanWithInfinity(text, Long.MAX_VALUE); - if (period == Long.MAX_VALUE) { - return null; - } - if (period == 0) { - return new TimespanRate(0, false); - } - return new TimespanRate(Runtime.getRuntime().availableProcessors() / (period / 1_000_000_000.0), false); - } - Rate r = Rate.of(text); - if (r == null) { - return null; - } - return new TimespanRate(r.perSecond(), true); - } - - public boolean isHigher(TimespanRate that) { - return rate() > that.rate(); - } - - @Override - public String toString() { - if (autoAdapt) { - return String.format("%d/ns", (long)(rate * 1_000_000_000L)); - } - return String.format("%dns", (long)(Runtime.getRuntime().availableProcessors() / rate * 1_000_000_000L)); - } -} diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 541d1d3aa2f..293af26746f 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -226,16 +226,6 @@ off - - false - 500/s - true - - - - true - - true 10 ms diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 9cec2d9a70f..89a9022d11e 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -206,16 +206,6 @@ 20 ms - - false - 10ms - true - - - - true - - true diff --git a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java index d6e126a493f..5b8aacfb1d2 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java +++ b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java @@ -89,10 +89,7 @@ public class TestLookForUntestedEvents { // Experimental events private static final Set experimentalEvents = Set.of( - "Flush", "SyncOnValueBasedClass", "CPUTimeSample", "CPUTimeSamplesLost"); - - // Subset of the experimental events that should have tests - private static final Set experimentalButTestedEvents = Set.of("CPUTimeSample"); + "Flush", "SyncOnValueBasedClass"); public static void main(String[] args) throws Exception { for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { @@ -113,9 +110,7 @@ public class TestLookForUntestedEvents { .collect(Collectors.toList()); Set eventsNotCoveredByTest = new HashSet<>(jfrEventTypes); - Set checkedEvents = new HashSet<>(jfrEventTypes); - checkedEvents.addAll(experimentalButTestedEvents); - for (String event : checkedEvents) { + for (String event : jfrEventTypes) { for (Path p : paths) { if (findStringInFile(p, event)) { eventsNotCoveredByTest.remove(event); diff --git a/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java deleted file mode 100644 index de211b8c454..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; -import jdk.jfr.consumer.RecordedFrame; -import jdk.jfr.consumer.RecordedStackTrace; -import jdk.test.lib.Asserts; -import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.Events; -import jdk.test.lib.jfr.RecurseThread; - -public class BaseTestFullStackTrace { - private final static int MAX_DEPTH = 64; // currently hardcoded in jvm - - private final String eventName; - private final String threadFieldName; - - public BaseTestFullStackTrace(String eventName, String threadFieldName) { - this.eventName = eventName; - this.threadFieldName = threadFieldName; - } - - public void run() throws Throwable { - RecurseThread[] threads = new RecurseThread[3]; - for (int i = 0; i < threads.length; ++i) { - int depth = MAX_DEPTH - 1 + i; - threads[i] = new RecurseThread(depth); - threads[i].setName("recursethread-" + depth); - threads[i].start(); - } - - for (RecurseThread thread : threads) { - while (!thread.isInRunLoop()) { - Thread.sleep(20); - } - } - - assertStackTraces(threads); - - for (RecurseThread thread : threads) { - thread.quit(); - thread.join(); - } - } - - private void assertStackTraces(RecurseThread[] threads) throws Throwable { - while (true) { - try (Recording recording = new Recording()) { - if (eventName.equals(EventNames.CPUTimeSample)) { - recording.enable(eventName).with("throttle", "50ms"); - } else { - recording.enable(eventName).withPeriod(Duration.ofMillis(50)); - } - recording.start(); - Thread.sleep(500); - recording.stop(); - if (hasValidStackTraces(recording, threads)) { - break; - } - } - }; - } - - private boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { - boolean[] isEventFound = new boolean[threads.length]; - - for (RecordedEvent event : Events.fromRecording(recording)) { - System.out.println("Event: " + event); - String threadName = Events.assertField(event, threadFieldName + ".javaName").getValue(); - long threadId = Events.assertField(event, threadFieldName + ".javaThreadId").getValue(); - - for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { - RecurseThread currThread = threads[threadIndex]; - if (threadId == currThread.getId()) { - System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); - Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); - if ("recurseEnd".equals(getTopMethodName(event))) { - isEventFound[threadIndex] = true; - checkEvent(event, currThread.totalDepth); - break; - } - } - } - } - - for (int i = 0; i < threads.length; ++i) { - String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; - System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); - } - for (int i = 0; i < threads.length; ++i) { - if(!isEventFound[i]) { - // no assertion, let's retry. - // Could be race condition, i.e safe point during Thread.sleep - System.out.println("Failed to validate all threads, will retry."); - return false; - } - } - return true; - } - - public String getTopMethodName(RecordedEvent event) { - List frames = event.getStackTrace().getFrames(); - Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); - return frames.getFirst().getMethod().getName(); - } - - private void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { - RecordedStackTrace stacktrace = null; - try { - stacktrace = event.getStackTrace(); - List frames = stacktrace.getFrames(); - Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); - List expectedMethods = getExpectedMethods(expectedDepth); - Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); - - for (int i = 0; i < frames.size(); ++i) { - String name = frames.get(i).getMethod().getName(); - String expectedName = expectedMethods.get(i); - System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); - Asserts.assertEquals(name, expectedName, "Wrong method name"); - } - - boolean isTruncated = stacktrace.isTruncated(); - boolean isTruncateExpected = expectedDepth > MAX_DEPTH; - Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); - - String firstMethod = frames.getLast().getMethod().getName(); - boolean isFullTrace = "run".equals(firstMethod); - String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); - Asserts.assertTrue(isTruncated != isFullTrace, msg); - } catch (Throwable t) { - System.out.println(String.format("stacktrace:%n%s", stacktrace)); - throw t; - } - } - - private List getExpectedMethods(int depth) { - List methods = new ArrayList<>(); - methods.add("recurseEnd"); - for (int i = 0; i < depth - 2; ++i) { - methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); - } - methods.add("run"); - if (depth > MAX_DEPTH) { - methods = methods.subList(0, MAX_DEPTH); - } - return methods; - } -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java deleted file mode 100644 index eb8d33832b5..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import java.time.Duration; - -import jdk.jfr.consumer.RecordingStream; -import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.RecurseThread; - -/* - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @modules jdk.jfr/jdk.jfr.internal - * @run main/timeout=30 jdk.jfr.event.profiling.TestCPUTimeAndExecutionSample - */ -public class TestCPUTimeAndExecutionSample { - - static String sampleEvent = EventNames.CPUTimeSample; - - // The period is set to 1100 ms to provoke the 1000 ms - // threshold in the JVM for os::naked_short_sleep(). - public static void main(String[] args) throws Exception { - run(EventNames.ExecutionSample); - run(EventNames.CPUTimeSample); - run(EventNames.ExecutionSample); - run(EventNames.CPUTimeSample); - } - - private static void run(String eventType) { - RecurseThread t = new RecurseThread(50); - t.setDaemon(true); - try (RecordingStream rs = new RecordingStream()) { - rs.enable(sampleEvent).with("throttle", "1000/s"); - rs.onEvent(sampleEvent, e -> { - t.quit(); - rs.close(); - }); - t.start(); - rs.start(); - } - } -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java deleted file mode 100644 index 0d1108346ab..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import jdk.test.lib.jfr.EventNames; - -/** - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @build jdk.jfr.event.profiling.BaseTestFullStackTrace - * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleFullStackTrace - */ -public class TestCPUTimeSampleFullStackTrace { - - public static void main(String[] args) throws Throwable { - new BaseTestFullStackTrace(EventNames.CPUTimeSample, "eventThread").run(); - } - -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java deleted file mode 100644 index 133df36684c..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import java.time.Duration; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordingStream; -import jdk.jfr.internal.JVM; -import jdk.test.lib.jfr.EventNames; - -/* - * Tests that creating multiple recordings after another is possible. - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @modules jdk.jfr/jdk.jfr.internal - * @run main jdk.jfr.event.profiling.TestCPUTimeSampleMultipleRecordings - */ -public class TestCPUTimeSampleMultipleRecordings { - - static String nativeEvent = EventNames.CPUTimeSample; - - static volatile boolean alive = true; - - public static void main(String[] args) throws Exception { - Thread t = new Thread(TestCPUTimeSampleMultipleRecordings::nativeMethod); - t.setDaemon(true); - t.start(); - for (int i = 0; i < 2; i++) { - try (RecordingStream rs = new RecordingStream()) { - rs.enable(nativeEvent).with("throttle", "1ms"); - rs.onEvent(nativeEvent, e -> { - alive = false; - rs.close(); - }); - - rs.start(); - } - } - alive = false; - } - - public static void nativeMethod() { - while (alive) { - JVM.getPid(); - } - } -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java deleted file mode 100644 index 1617bce4ba3..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import java.time.Duration; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordingStream; -import jdk.jfr.internal.JVM; -import jdk.test.lib.jfr.EventNames; - -/* - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @modules jdk.jfr/jdk.jfr.internal - * @run main jdk.jfr.event.profiling.TestCPUTimeSampleNative - */ -public class TestCPUTimeSampleNative { - - static String nativeEvent = EventNames.CPUTimeSample; - - static volatile boolean alive = true; - - public static void main(String[] args) throws Exception { - try (RecordingStream rs = new RecordingStream()) { - rs.enable(nativeEvent).with("throttle", "1ms"); - rs.onEvent(nativeEvent, e -> { - alive = false; - rs.close(); - }); - Thread t = new Thread(TestCPUTimeSampleNative::nativeMethod); - t.setDaemon(true); - t.start(); - rs.start(); - } - - } - - public static void nativeMethod() { - while (alive) { - JVM.getPid(); - } - } -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java deleted file mode 100644 index 55b350ad096..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; -import java.lang.management.ManagementFactory; -import java.time.Duration; -import java.time.Instant; -import java.util.List; -import java.util.Comparator; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; -import jdk.test.lib.Asserts; -import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.Events; - -/** - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleThrottling - */ -public class TestCPUTimeSampleThrottling { - - public static void main(String[] args) throws Exception { - testZeroPerSecond(); - testThrottleSettings(); - testThrottleSettingsPeriod(); - } - - private static void testZeroPerSecond() throws Exception { - Asserts.assertTrue(0L == countEvents(1000, "0/s").count()); - } - - private static void testThrottleSettings() throws Exception { - long count = countEvents(1000, - Runtime.getRuntime().availableProcessors() * 2 + "/s").count(); - Asserts.assertTrue(count > 0 && count < 3, - "Expected between 0 and 3 events, got " + count); - } - - private static void testThrottleSettingsPeriod() throws Exception { - float rate = countEvents(1000, "10ms").rate(); - Asserts.assertTrue(rate > 90 && rate < 110, "Expected around 100 events per second, got " + rate); - } - - private record EventCount(long count, float time) { - float rate() { - return count / time; - } - } - - private static EventCount countEvents(int timeMs, String rate) throws Exception { - try(Recording recording = new Recording()) { - recording.enable(EventNames.CPUTimeSample) - .with("throttle", rate); - - var bean = ManagementFactory.getThreadMXBean(); - - recording.start(); - - long startThreadCpuTime = bean.getCurrentThreadCpuTime(); - - wasteCPU(timeMs); - - long spendCPUTime = bean.getCurrentThreadCpuTime() - startThreadCpuTime; - - recording.stop(); - - long eventCount = Events.fromRecording(recording).stream() - .filter(e -> e.getThread().getJavaName() - .equals(Thread.currentThread().getName())) - .count(); - - System.out.println("Event count: " + eventCount + ", CPU time: " + spendCPUTime / 1_000_000_000f + "s"); - - return new EventCount(eventCount, spendCPUTime / 1_000_000_000f); - } - } - - private static void wasteCPU(int durationMs) { - long start = System.currentTimeMillis(); - double i = 0; - while (System.currentTimeMillis() - start < durationMs) { - for (int j = 0; j < 100000; j++) { - i = Math.sqrt(i * Math.pow(Math.sqrt(Math.random()), Math.random())); - } - } - } - -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java deleted file mode 100644 index 69d32d48282..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jfr.event.profiling; - -import java.time.Duration; - -import jdk.jfr.consumer.RecordingStream; -import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.RecurseThread; - -/* - * @test - * @requires vm.hasJFR & os.family == "linux" - * @library /test/lib - * @modules jdk.jfr/jdk.jfr.internal - * @run main jdk.jfr.event.profiling.TestCPUTimeSamplingLongPeriod - */ -public class TestCPUTimeSamplingLongPeriod { - - static String sampleEvent = EventNames.CPUTimeSample; - - // The period is set to 1100 ms to provoke the 1000 ms - // threshold in the JVM for os::naked_short_sleep(). - public static void main(String[] args) throws Exception { - RecurseThread t = new RecurseThread(50); - t.setDaemon(true); - try (RecordingStream rs = new RecordingStream()) { - rs.enable(sampleEvent).with("throttle", "1100ms"); - rs.onEvent(sampleEvent, e -> { - t.quit(); - rs.close(); - }); - t.start(); - rs.start(); - } - } -} diff --git a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java index c337a8128ab..b06f9eed03d 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java +++ b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java @@ -23,20 +23,147 @@ package jdk.jfr.event.profiling; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordedFrame; +import jdk.jfr.consumer.RecordedStackTrace; +import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.RecurseThread; /** * @test * @requires vm.hasJFR * @requires vm.opt.DeoptimizeALot != true * @library /test/lib - * @build jdk.jfr.event.profiling.BaseTestFullStackTrace * @run main/othervm jdk.jfr.event.profiling.TestFullStackTrace */ public class TestFullStackTrace { + private final static String EVENT_NAME = EventNames.ExecutionSample; + private final static int MAX_DEPTH = 64; // currently hardcoded in jvm public static void main(String[] args) throws Throwable { - new BaseTestFullStackTrace(EventNames.ExecutionSample, "sampledThread").run(); + RecurseThread[] threads = new RecurseThread[3]; + for (int i = 0; i < threads.length; ++i) { + int depth = MAX_DEPTH - 1 + i; + threads[i] = new RecurseThread(depth); + threads[i].setName("recursethread-" + depth); + threads[i].start(); + } + + for (RecurseThread thread : threads) { + while (!thread.isInRunLoop()) { + Thread.sleep(20); + } + } + + assertStackTraces(threads); + + for (RecurseThread thread : threads) { + thread.quit(); + thread.join(); + } } + private static void assertStackTraces( RecurseThread[] threads) throws Throwable { + Recording recording= null; + do { + recording = new Recording(); + recording.enable(EVENT_NAME).withPeriod(Duration.ofMillis(50)); + recording.start(); + Thread.sleep(500); + recording.stop(); + } while (!hasValidStackTraces(recording, threads)); + } + + private static boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { + boolean[] isEventFound = new boolean[threads.length]; + + for (RecordedEvent event : Events.fromRecording(recording)) { + //System.out.println("Event: " + event); + String threadName = Events.assertField(event, "sampledThread.javaName").getValue(); + long threadId = Events.assertField(event, "sampledThread.javaThreadId").getValue(); + + for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { + RecurseThread currThread = threads[threadIndex]; + if (threadId == currThread.getId()) { + System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); + Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); + if ("recurseEnd".equals(getTopMethodName(event))) { + isEventFound[threadIndex] = true; + checkEvent(event, currThread.totalDepth); + break; + } + } + } + } + + for (int i = 0; i < threads.length; ++i) { + String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; + System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); + } + for (int i = 0; i < threads.length; ++i) { + if(!isEventFound[i]) { + // no assertion, let's retry. + // Could be race condition, i.e safe point during Thread.sleep + System.out.println("Failed to validate all threads, will retry."); + return false; + } + } + return true; + } + + public static String getTopMethodName(RecordedEvent event) { + List frames = event.getStackTrace().getFrames(); + Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); + return frames.getFirst().getMethod().getName(); + } + + private static void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { + RecordedStackTrace stacktrace = null; + try { + stacktrace = event.getStackTrace(); + List frames = stacktrace.getFrames(); + Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); + List expectedMethods = getExpectedMethods(expectedDepth); + Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); + + for (int i = 0; i < frames.size(); ++i) { + String name = frames.get(i).getMethod().getName(); + String expectedName = expectedMethods.get(i); + System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); + Asserts.assertEquals(name, expectedName, "Wrong method name"); + } + + boolean isTruncated = stacktrace.isTruncated(); + boolean isTruncateExpected = expectedDepth > MAX_DEPTH; + Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); + + String firstMethod = frames.getLast().getMethod().getName(); + boolean isFullTrace = "run".equals(firstMethod); + String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); + Asserts.assertTrue(isTruncated != isFullTrace, msg); + } catch (Throwable t) { + System.out.println(String.format("stacktrace:%n%s", stacktrace)); + throw t; + } + } + + private static List getExpectedMethods(int depth) { + List methods = new ArrayList<>(); + methods.add("recurseEnd"); + for (int i = 0; i < depth - 2; ++i) { + methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); + } + methods.add("run"); + if (depth > MAX_DEPTH) { + methods = methods.subList(0, MAX_DEPTH); + } + return methods; + } } diff --git a/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java b/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java deleted file mode 100644 index 8dc77fd38da..00000000000 --- a/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - package test; - - import java.time.Duration; - - /* - * A class used to create a simple deep call stack for testing purposes - */ - public class RecursiveMethods { - - /** Method that uses recursion to produce a call stack of at least {@code depth} depth */ - public static int entry(int depth) { - return method2(--depth); - } - - private static int method2(int depth) { - return method3(--depth); - } - - private static int method3(int depth) { - return method4(--depth); - } - - private static int method4(int depth) { - return method5(--depth); - } - - private static int method5(int depth) { - return method6(--depth); - } - - private static int method6(int depth) { - return method7(--depth); - } - - private static int method7(int depth) { - return method8(--depth); - } - - private static int method8(int depth) { - return method9(--depth); - } - - private static int method9(int depth) { - return method10(--depth); - } - - private static int method10(int depth) { - if (depth > 0) { - return entry(--depth); - } - return depth; - } -} diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index a00898358a8..904abe8e3e2 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -77,8 +77,6 @@ public class EventNames { public static final String ThreadAllocationStatistics = PREFIX + "ThreadAllocationStatistics"; public static final String ExecutionSample = PREFIX + "ExecutionSample"; public static final String NativeMethodSample = PREFIX + "NativeMethodSample"; - public static final String CPUTimeSample = PREFIX + "CPUTimeSample"; - public static final String CPUTimeSamplesLost = PREFIX + "CPUTimeSamplesLost"; public static final String ThreadDump = PREFIX + "ThreadDump"; public static final String OldObjectSample = PREFIX + "OldObjectSample"; public static final String SymbolTableStatistics = PREFIX + "SymbolTableStatistics"; From 8f8b367ae3c9afca3581f6aced7f9855ef0d541d Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 5 Jun 2025 00:35:26 +0000 Subject: [PATCH 157/216] 8350029: Illegal invokespecial interface not caught by verification Reviewed-by: coleenp, matsaave --- .../share/classfile/verificationType.cpp | 56 ++++++----- .../share/classfile/verificationType.hpp | 25 +++-- src/hotspot/share/classfile/verifier.cpp | 55 +++++++---- .../share/interpreter/linkResolver.cpp | 4 +- .../runtime/verifier/invokespecial/Run.java | 29 ++++++ .../TestInvokeSpecialInterface.java | 99 +++++++++++++++++++ .../invokespecial/UseInterfaceMethodRef.jasm | 37 +++++++ .../verifier/invokespecial/UseMethodRef.jasm | 37 +++++++ 8 files changed, 289 insertions(+), 53 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/verifier/invokespecial/Run.java create mode 100644 test/hotspot/jtreg/runtime/verifier/invokespecial/TestInvokeSpecialInterface.java create mode 100644 test/hotspot/jtreg/runtime/verifier/invokespecial/UseInterfaceMethodRef.jasm create mode 100644 test/hotspot/jtreg/runtime/verifier/invokespecial/UseMethodRef.jasm diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index e6115dfce9b..aedb620aabe 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -48,41 +48,50 @@ VerificationType VerificationType::from_tag(u1 tag) { } } -bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name, - Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) { +// Potentially resolve the target class and from class, and check whether the from class is assignable +// to the target class. The current_klass is the class being verified - it could also be the target in some +// cases, and otherwise is needed to obtain the correct classloader for resolving the other classes. +bool VerificationType::resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, Symbol* from_name, + bool from_field_is_protected, bool from_is_array, + bool from_is_object, bool* target_is_interface, TRAPS) { HandleMark hm(THREAD); - Klass* this_class; - if (klass->is_hidden() && klass->name() == name) { - this_class = klass; + Klass* target_klass; + if (current_klass->is_hidden() && current_klass->name() == target_name) { + target_klass = current_klass; } else { - this_class = SystemDictionary::resolve_or_fail( - name, Handle(THREAD, klass->class_loader()), true, CHECK_false); + target_klass = SystemDictionary::resolve_or_fail( + target_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { - Verifier::trace_class_resolution(this_class, klass); + Verifier::trace_class_resolution(target_klass, current_klass); } } - if (this_class->is_interface() && (!from_field_is_protected || + bool is_intf = target_klass->is_interface(); + if (target_is_interface != nullptr) { + *target_is_interface = is_intf; + } + + if (is_intf && (!from_field_is_protected || from_name != vmSymbols::java_lang_Object())) { // If we are not trying to access a protected field or method in // java.lang.Object then, for arrays, we only allow assignability // to interfaces java.lang.Cloneable and java.io.Serializable. // Otherwise, we treat interfaces as java.lang.Object. return !from_is_array || - this_class == vmClasses::Cloneable_klass() || - this_class == vmClasses::Serializable_klass(); + target_klass == vmClasses::Cloneable_klass() || + target_klass == vmClasses::Serializable_klass(); } else if (from_is_object) { - Klass* from_class; - if (klass->is_hidden() && klass->name() == from_name) { - from_class = klass; + Klass* from_klass; + if (current_klass->is_hidden() && current_klass->name() == from_name) { + from_klass = current_klass; } else { - from_class = SystemDictionary::resolve_or_fail( - from_name, Handle(THREAD, klass->class_loader()), true, CHECK_false); + from_klass = SystemDictionary::resolve_or_fail( + from_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { - Verifier::trace_class_resolution(from_class, klass); + Verifier::trace_class_resolution(from_klass, current_klass); } } - return from_class->is_subclass_of(this_class); + return from_klass->is_subclass_of(target_klass); } return false; @@ -90,8 +99,8 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym bool VerificationType::is_reference_assignable_from( const VerificationType& from, ClassVerifier* context, - bool from_field_is_protected, TRAPS) const { - InstanceKlass* klass = context->current_class(); + bool from_field_is_protected, bool* this_is_interface, TRAPS) const { + if (from.is_null()) { // null is assignable to any reference return true; @@ -109,7 +118,7 @@ bool VerificationType::is_reference_assignable_from( #if INCLUDE_CDS if (CDSConfig::is_dumping_archive()) { bool skip_assignability_check = false; - SystemDictionaryShared::add_verification_constraint(klass, + SystemDictionaryShared::add_verification_constraint(context->current_class(), name(), from.name(), from_field_is_protected, from.is_array(), from.is_object(), &skip_assignability_check); if (skip_assignability_check) { @@ -119,8 +128,9 @@ bool VerificationType::is_reference_assignable_from( } } #endif - return resolve_and_check_assignability(klass, name(), from.name(), - from_field_is_protected, from.is_array(), from.is_object(), THREAD); + return resolve_and_check_assignability(context->current_class(), name(), from.name(), + from_field_is_protected, from.is_array(), + from.is_object(), this_is_interface, THREAD); } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(context); VerificationType comp_from = from.get_component(context); diff --git a/src/hotspot/share/classfile/verificationType.hpp b/src/hotspot/share/classfile/verificationType.hpp index 4f0609f0cce..788e0029fad 100644 --- a/src/hotspot/share/classfile/verificationType.hpp +++ b/src/hotspot/share/classfile/verificationType.hpp @@ -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 @@ -288,7 +288,7 @@ class VerificationType { if (is_reference() && from.is_reference()) { return is_reference_assignable_from(from, context, from_field_is_protected, - THREAD); + nullptr, THREAD); } else { return false; } @@ -327,17 +327,24 @@ class VerificationType { void print_on(outputStream* st) const; - private: + bool is_reference_assignable_from(const VerificationType& from, ClassVerifier* context, + bool from_field_is_protected, bool* this_is_interface, TRAPS) const; - bool is_reference_assignable_from( - const VerificationType&, ClassVerifier*, bool from_field_is_protected, - TRAPS) const; - - public: - static bool resolve_and_check_assignability(InstanceKlass* klass, Symbol* name, + static bool resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, + TRAPS) { + return resolve_and_check_assignability(current_klass, target_name, from_name, from_field_is_protected, + from_is_array, from_is_object, nullptr, THREAD); + } + + private: + static bool resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, + Symbol* from_name, bool from_field_is_protected, + bool from_is_array, bool from_is_object, + bool* target_is_interface, TRAPS); + }; #endif // SHARE_CLASSFILE_VERIFICATIONTYPE_HPP diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index 98c05909b82..0f1468f0309 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -2891,26 +2891,43 @@ void ClassVerifier::verify_invoke_instructions( "Illegal call to internal method"); return; } - } else if (opcode == Bytecodes::_invokespecial - && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) - && !ref_class_type.equals(VerificationType::reference_type( - current_class()->super()->name()))) { - bool subtype = false; - bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; - subtype = ref_class_type.is_assignable_from( - current_type(), this, false, CHECK_VERIFY(this)); - if (!subtype) { - verify_error(ErrorContext::bad_code(bci), - "Bad invokespecial instruction: " - "current class isn't assignable to reference class."); - return; - } else if (have_imr_indirect) { - verify_error(ErrorContext::bad_code(bci), - "Bad invokespecial instruction: " - "interface method reference is in an indirect superinterface."); - return; - } + } + // invokespecial, when not , must be to a method in the current class, a direct superinterface, + // or any superclass (including Object). + else if (opcode == Bytecodes::_invokespecial + && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) + && !ref_class_type.equals(VerificationType::reference_type(current_class()->super()->name()))) { + // We know it is not current class, direct superinterface or immediate superclass. That means it + // could be: + // - a totally unrelated class or interface + // - an indirect superinterface + // - an indirect superclass (including Object) + // We use the assignability test to see if it is a superclass, or else an interface, and keep track + // of the latter. Note that subtype can be true if we are dealing with an interface that is not actually + // implemented as assignability treats all interfaces as Object. + + bool is_interface = false; // This can only be set true if the assignability check will return true + // and we loaded the class. For any other "true" returns (e.g. same class + // or Object) we either can't get here (same class already excluded above) + // or we know it is not an interface (i.e. Object). + bool subtype = ref_class_type.is_reference_assignable_from(current_type(), this, false, + &is_interface, CHECK_VERIFY(this)); + if (!subtype) { // Totally unrelated class + verify_error(ErrorContext::bad_code(bci), + "Bad invokespecial instruction: " + "current class isn't assignable to reference class."); + return; + } else { + // Indirect superclass (including Object), indirect interface, or unrelated interface. + // Any interface use is an error. + if (is_interface) { + verify_error(ErrorContext::bad_code(bci), + "Bad invokespecial instruction: " + "interface method to invoke is not in a direct superinterface."); + return; + } + } } // Get the verification types for the method's arguments. diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index b26c643d15f..22199baef8e 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -1200,7 +1200,7 @@ Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, } // ensure that invokespecial's interface method reference is in - // a direct superinterface, not an indirect superinterface + // a direct superinterface, not an indirect superinterface or unrelated interface Klass* current_klass = link_info.current_klass(); if (current_klass != nullptr && resolved_klass->is_interface()) { InstanceKlass* klass_to_check = InstanceKlass::cast(current_klass); @@ -1209,7 +1209,7 @@ Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, stringStream ss; ss.print("Interface method reference: '"); resolved_method->print_external_name(&ss); - ss.print("', is in an indirect superinterface of %s", + ss.print("', is not in a direct superinterface of %s", current_klass->external_name()); THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string()); } diff --git a/test/hotspot/jtreg/runtime/verifier/invokespecial/Run.java b/test/hotspot/jtreg/runtime/verifier/invokespecial/Run.java new file mode 100644 index 00000000000..df9a1d157b0 --- /dev/null +++ b/test/hotspot/jtreg/runtime/verifier/invokespecial/Run.java @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * A class with a run()V method that doesn't implement Runnable. + */ +public class Run { + public void run() { } +} diff --git a/test/hotspot/jtreg/runtime/verifier/invokespecial/TestInvokeSpecialInterface.java b/test/hotspot/jtreg/runtime/verifier/invokespecial/TestInvokeSpecialInterface.java new file mode 100644 index 00000000000..caced8b3b51 --- /dev/null +++ b/test/hotspot/jtreg/runtime/verifier/invokespecial/TestInvokeSpecialInterface.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id=verified + * @compile Run.java UseMethodRef.jasm UseInterfaceMethodRef.jasm TestInvokeSpecialInterface.java + * @run main/othervm TestInvokeSpecialInterface true + */ + +/* + * @test id=unverified + * @compile Run.java UseMethodRef.jasm UseInterfaceMethodRef.jasm TestInvokeSpecialInterface.java + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-BytecodeVerificationRemote TestInvokeSpecialInterface false + */ + +public class TestInvokeSpecialInterface { + public static void main(String[] args) throws Throwable { + if (args[0].equals("true")) { + check_verified(); + } else { + check_unverified(); + } + } + + static void check_verified() { + String veMsg = "interface method to invoke is not in a direct superinterface"; + try { + UseMethodRef t = new UseMethodRef(); + UseMethodRef.test(t); + } + catch(VerifyError ve) { + if (ve.getMessage().contains(veMsg)) { + System.out.println("Got expected: " + ve); + } else { + throw new RuntimeException("Unexpected VerifyError thrown", ve); + } + } + + try { + UseInterfaceMethodRef t = new UseInterfaceMethodRef(); + UseInterfaceMethodRef.test(t); + } + catch(VerifyError ve) { + if (ve.getMessage().contains(veMsg)) { + System.out.println("Got expected: " + ve); + } else { + throw new RuntimeException("Unexpected VerifyError thrown", ve); + } + } + } + + static void check_unverified() { + try { + UseMethodRef t = new UseMethodRef(); + UseMethodRef.test(t); + } + catch(IncompatibleClassChangeError icce) { + String icceMsg = "Method 'void java.lang.Runnable.run()' must be InterfaceMethodref constant"; + if (icce.getMessage().contains(icceMsg)) { + System.out.println("Got expected: " + icce); + } else { + throw new RuntimeException("Unexpected IncompatibleClassChangeError", icce); + } + } + + try { + UseInterfaceMethodRef t = new UseInterfaceMethodRef(); + UseInterfaceMethodRef.test(t); + } + catch(IncompatibleClassChangeError icce) { + String icceMsg = "Interface method reference: 'void java.lang.Runnable.run()', is not in a direct superinterface of UseInterfaceMethodRef"; + if (icce.getMessage().contains(icceMsg)) { + System.out.println("Got expected: " + icce); + } else { + throw new RuntimeException("Unexpected IncompatibleClassChangeError", icce); + } + } + } +} diff --git a/test/hotspot/jtreg/runtime/verifier/invokespecial/UseInterfaceMethodRef.jasm b/test/hotspot/jtreg/runtime/verifier/invokespecial/UseInterfaceMethodRef.jasm new file mode 100644 index 00000000000..49290b3c1bc --- /dev/null +++ b/test/hotspot/jtreg/runtime/verifier/invokespecial/UseInterfaceMethodRef.jasm @@ -0,0 +1,37 @@ +/* + * 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. + */ + +class UseInterfaceMethodRef extends Run version 52:0 { + + public Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method Run."":"()V"; + return; + } + + public static Method test:"(LUseInterfaceMethodRef;)V" stack 2 { + aload_0; + invokespecial InterfaceMethod java/lang/Runnable.run:()V; // VerifyError + return; + } +} diff --git a/test/hotspot/jtreg/runtime/verifier/invokespecial/UseMethodRef.jasm b/test/hotspot/jtreg/runtime/verifier/invokespecial/UseMethodRef.jasm new file mode 100644 index 00000000000..cf1ebec115b --- /dev/null +++ b/test/hotspot/jtreg/runtime/verifier/invokespecial/UseMethodRef.jasm @@ -0,0 +1,37 @@ +/* + * 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. + */ + +class UseMethodRef extends Run version 52:0 { + + public Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method Run."":"()V"; + return; + } + + public static Method test:"(LUseMethodRef;)V" stack 2 { + aload_0; + invokespecial Method java/lang/Runnable.run:()V; // VerifyError + return; + } +} From 575806c0e5584ea24cda80158070579b88c477f7 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Thu, 5 Jun 2025 01:41:21 +0000 Subject: [PATCH 158/216] 8358078: javap crashes with NPE on preview class file Reviewed-by: liach --- .../com/sun/tools/javap/ClassWriter.java | 6 +- .../tools/javap/ClassFileVersionTest.java | 98 +++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 test/langtools/tools/javap/ClassFileVersionTest.java diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java index 4036a185ab1..c5c75d8848c 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java @@ -118,9 +118,11 @@ public class ClassWriter extends BasicWriter { protected ClassFileFormatVersion cffv() { var major = classModel.majorVersion(); if (major < JAVA_1_VERSION || major > ClassFile.latestMajorVersion()) - return null; + // something not representable by CFFV, let's fall back + return ClassFileFormatVersion.latest(); if (major >= JAVA_12_VERSION && classModel.minorVersion() != 0) { - return null; + // preview versions aren't explicitly supported, but latest is good enough for now + return ClassFileFormatVersion.latest(); } return ClassFileFormatVersion.fromMajor(major); } diff --git a/test/langtools/tools/javap/ClassFileVersionTest.java b/test/langtools/tools/javap/ClassFileVersionTest.java new file mode 100644 index 00000000000..c5968dfd84e --- /dev/null +++ b/test/langtools/tools/javap/ClassFileVersionTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8358078 + * @summary javap should not crash due to class file versions + * @library /tools/lib + * @modules jdk.jdeps/com.sun.tools.javap + * @run junit ClassFileVersionTest + */ + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import toolbox.JavapTask; +import toolbox.Task; +import toolbox.ToolBox; + +import java.lang.classfile.ClassFile; +import java.lang.constant.ClassDesc; +import java.lang.reflect.AccessFlag; +import java.lang.reflect.ClassFileFormatVersion; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.of; + +public class ClassFileVersionTest { + + final ToolBox toolBox = new ToolBox(); + + public static Stream classFiles() { + int major17 = ClassFileFormatVersion.RELEASE_17.major(); + int preview = Character.MAX_VALUE; + int majorLatest = ClassFileFormatVersion.latest().major(); + AccessFlag[] noFlags = {}; + return Stream.of( + of(false, major17, 0, noFlags), + of(false, major17, preview, noFlags), + of(false, 0, 0, noFlags), + of(false, major17, 0, new AccessFlag[]{AccessFlag.PUBLIC}), + of(false, major17, preview, new AccessFlag[]{AccessFlag.PUBLIC}), + of(false, majorLatest, preview, new AccessFlag[]{AccessFlag.PUBLIC}), + of(true, majorLatest, 0, new AccessFlag[]{AccessFlag.BRIDGE}), // misplaced access flag + of(true, majorLatest, preview, new AccessFlag[]{AccessFlag.BRIDGE}) // misplaced access flag + ); + } + + private static byte[] createClassFile(int major, int minor, AccessFlag[] classFlags) { + return ClassFile.of().build(ClassDesc.of("Test"), (builder) -> { + // manually assemble flag bits to avoid exception in ClassFile api + int flags = 0; + for (AccessFlag classFlag : classFlags) { + flags |= classFlag.mask(); + } + builder.withVersion(major, minor).withFlags(flags); + }); + } + + @ParameterizedTest + @MethodSource("classFiles") + void test(boolean shouldError, int major, int minor, AccessFlag[] classFlags) throws Throwable { + + Files.write(Path.of("cf.class"), createClassFile(major, minor, classFlags)); + + var lines = new JavapTask(toolBox) + .classes("cf.class") + .options("-c", "-p", "-v") + .run(shouldError ? Task.Expect.FAIL : Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + assertEquals(shouldError, lines.stream().anyMatch(l -> l.startsWith("Error: Access Flags:")), "printed error"); + } +} From 849655a145a40b056a751528cebc78a11481514c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 5 Jun 2025 03:25:46 +0000 Subject: [PATCH 159/216] 8358632: [asan] reports heap-buffer-overflow in AOTCodeCache::copy_bytes Reviewed-by: vlivanov, iveresov --- src/hotspot/share/code/aotCodeCache.cpp | 15 +++------------ .../appcds/aotCode/AOTCodeCompressedOopsTest.java | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index 6d8faa10a38..d0692ee678b 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -460,18 +460,9 @@ AOTCodeCache* AOTCodeCache::open_for_dump() { } void copy_bytes(const char* from, address to, uint size) { - assert(size > 0, "sanity"); - bool by_words = true; - if ((size > 2 * HeapWordSize) && (((intptr_t)from | (intptr_t)to) & (HeapWordSize - 1)) == 0) { - // Use wordwise copies if possible: - Copy::disjoint_words((HeapWord*)from, - (HeapWord*)to, - ((size_t)size + HeapWordSize-1) / HeapWordSize); - } else { - by_words = false; - Copy::conjoint_jbytes(from, to, (size_t)size); - } - log_trace(aot, codecache)("Copied %d bytes as %s from " INTPTR_FORMAT " to " INTPTR_FORMAT, size, (by_words ? "HeapWord" : "bytes"), p2i(from), p2i(to)); + assert((int)size > 0, "sanity"); + memcpy(to, from, size); + log_trace(aot, codecache)("Copied %d bytes from " INTPTR_FORMAT " to " INTPTR_FORMAT, size, p2i(from), p2i(to)); } AOTCodeReader::AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java index 267b9a267b2..4587eeae5e5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java @@ -173,7 +173,7 @@ public class AOTCodeCompressedOopsTest { * [0.022s][info][cds] narrow_oop_mode = 3, narrow_oop_base = 0x0000000300000000, narrow_oop_shift = 3 * [0.022s][info][cds] heap range = [0x0000000301000000 - 0x0000000ac1000000] */ - Pattern p = Pattern.compile("narrow_oop_base = 0x(\\d+), narrow_oop_shift = (\\d)"); + Pattern p = Pattern.compile("narrow_oop_base = 0x([0-9a-fA-F]+), narrow_oop_shift = (\\d)"); for (int i = 0; i < list.size(); i++) { String line = list.get(i); if (line.indexOf("CDS archive was created with max heap size") != -1) { From 08023481edec4c0cacc79a608c573856f0718e58 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 5 Jun 2025 04:24:05 +0000 Subject: [PATCH 160/216] 8358558: (zipfs) Reorder the listing of "accessMode" property in the ZIP file system's documentation Reviewed-by: dfuchs, vyazici, alanb, lancea --- src/jdk.zipfs/share/classes/module-info.java | 83 ++++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/jdk.zipfs/share/classes/module-info.java b/src/jdk.zipfs/share/classes/module-info.java index db7ae3eec81..0716fdf8266 100644 --- a/src/jdk.zipfs/share/classes/module-info.java +++ b/src/jdk.zipfs/share/classes/module-info.java @@ -149,12 +149,52 @@ import java.util.Set; * *
        * + * + * + * + * + * + * * * * * * * @@ -266,47 +306,6 @@ import java.util.Set; * * * - * - * - * - * - * - * * *
        accessMode{@link java.lang.String}null/unset + * A value defining the desired access mode of the file system. + * ZIP file systems can be created to allow for read-write or + * read-only access. + *
          + *
        • + * If no value is set, the file system is created as read-write + * if possible. Use {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} to determine the actual access mode. + *
        • + *
        • + * If the value is {@code "readOnly"}, the file system is created + * read-only, and {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} will always return {@code true}. Creating a + * read-only file system requires the underlying ZIP file to + * already exist. + *
        • + *
        • + * If the value is {@code "readWrite"}, the file system is created + * read-write, and {@link java.nio.file.FileSystem#isReadOnly() + * isReadOnly()} will always return {@code false}. If a writable file + * system cannot be created, an {@code IOException} will be thrown + * when creating the ZIP file system. + *
        • + *
        • + * Any other values will cause an {@code IllegalArgumentException} + * to be thrown when creating the ZIP file system. + *
        • + *
        + * The {@code accessMode} property has no effect on reported POSIX file + * permissions (in cases where POSIX support is enabled). + *
        create{@link java.lang.String} or {@link java.lang.Boolean}false * If the value is {@code true}, the ZIP file system provider creates a - * new ZIP or JAR file if it does not exist. + * new ZIP or JAR file if it does not exist. Specifying the {@code create} + * property as {@code true} with the {@code accessMode} as {@code "readOnly"} + * will cause an {@code IllegalArgumentException} to be thrown when creating + * the ZIP file system. *
        accessMode{@link java.lang.String}null/unset - * A value defining the desired access mode of the file system. - * ZIP file systems can be created to allow for read-write or - * read-only access. - *
          - *
        • - * If no value is set, the file system is created as read-write - * if possible. Use {@link java.nio.file.FileSystem#isReadOnly() - * isReadOnly()} to determine the actual access mode. - *
        • - *
        • - * If the value is {@code "readOnly"}, the file system is created - * read-only, and {@link java.nio.file.FileSystem#isReadOnly() - * isReadOnly()} will always return {@code true}. Creating a - * read-only file system requires the underlying ZIP file to - * already exist. - * Specifying the {@code create} property as {@code true} with the - * {@code accessMode} as {@code readOnly} will cause an {@code - * IllegalArgumentException} to be thrown when creating the ZIP file - * system. - *
        • - *
        • - * If the value is {@code "readWrite"}, the file system is created - * read-write, and {@link java.nio.file.FileSystem#isReadOnly() - * isReadOnly()} will always return {@code false}. If a writable file - * system cannot be created, an {@code IOException} will be thrown - * when creating the ZIP file system. - *
        • - *
        • - * Any other values will cause an {@code IllegalArgumentException} - * to be thrown when creating the ZIP file system. - *
        • - *
        - * The {@code accessMode} property has no effect on reported POSIX file - * permissions (in cases where POSIX support is enabled). - *
        * From 48b97ac0e006362528423ffd657b2ea3afa46a6e Mon Sep 17 00:00:00 2001 From: Dingli Zhang Date: Thu, 5 Jun 2025 07:34:48 +0000 Subject: [PATCH 161/216] 8358634: RISC-V: Fix several broken documentation web-links Reviewed-by: fyang --- src/hotspot/cpu/riscv/macroAssembler_riscv.hpp | 2 +- src/hotspot/cpu/riscv/vm_version_riscv.hpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index f302b3602ad..7fa7f931044 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -666,7 +666,7 @@ class MacroAssembler: public Assembler { // We try to follow risc-v asm menomics. // But as we don't layout a reachable GOT, // we often need to resort to movptr, li <48imm>. - // https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md + // https://github.com/riscv-non-isa/riscv-asm-manual/blob/main/src/asm-manual.adoc // Hotspot only use the standard calling convention using x1/ra. // The alternative calling convection using x5/t0 is not used. diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 4214d6c53dc..a0a42fb5463 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -221,13 +221,13 @@ class VM_Version : public Abstract_VM_Version { FLAG_SET_DEFAULT(UseExtension, true); \ } \ - // https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva20-profiles + // https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc#rva20-profiles #define RV_USE_RVA20U64 \ RV_ENABLE_EXTENSION(UseRVC) \ static void useRVA20U64Profile(); - // https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles + // https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc#rva22-profiles #define RV_USE_RVA22U64 \ RV_ENABLE_EXTENSION(UseRVC) \ RV_ENABLE_EXTENSION(UseZba) \ @@ -241,7 +241,7 @@ class VM_Version : public Abstract_VM_Version { static void useRVA22U64Profile(); - // https://github.com/riscv/riscv-profiles/blob/main/rva23-profile.adoc#rva23u64-profile + // https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc#rva23u64-profile #define RV_USE_RVA23U64 \ RV_ENABLE_EXTENSION(UseRVC) \ RV_ENABLE_EXTENSION(UseRVV) \ From ace70a6d6aca619da34b2f9cac2586cc88cefb5a Mon Sep 17 00:00:00 2001 From: Johannes Bechberger Date: Thu, 5 Jun 2025 08:18:18 +0000 Subject: [PATCH 162/216] 8358666: [REDO] Implement JEP 509: JFR CPU-Time Profiling Reviewed-by: mgronlun --- src/hotspot/os/posix/signals_posix.cpp | 8 + src/hotspot/os/posix/signals_posix.hpp | 2 + src/hotspot/share/jfr/jfr.inline.hpp | 3 +- src/hotspot/share/jfr/jni/jfrJniMethod.cpp | 6 + src/hotspot/share/jfr/jni/jfrJniMethod.hpp | 2 + .../jfr/jni/jfrJniMethodRegistration.cpp | 1 + src/hotspot/share/jfr/metadata/metadata.xml | 16 + .../sampling/jfrCPUTimeThreadSampler.cpp | 780 ++++++++++++++++++ .../sampling/jfrCPUTimeThreadSampler.hpp | 152 ++++ .../periodic/sampling/jfrSampleRequest.cpp | 33 +- .../periodic/sampling/jfrSampleRequest.hpp | 5 + .../periodic/sampling/jfrThreadSampling.cpp | 92 ++- .../periodic/sampling/jfrThreadSampling.hpp | 2 + .../share/jfr/recorder/jfrRecorder.cpp | 15 + .../share/jfr/recorder/jfrRecorder.hpp | 1 + .../recorder/service/jfrEventThrottler.cpp | 12 +- .../share/jfr/support/jfrThreadLocal.cpp | 98 ++- .../share/jfr/support/jfrThreadLocal.hpp | 53 ++ src/hotspot/share/runtime/thread.hpp | 1 + src/hotspot/share/runtime/vmOperation.hpp | 2 + src/hotspot/share/utilities/ticks.hpp | 1 + .../jdk/jfr/internal/EventControl.java | 4 + .../share/classes/jdk/jfr/internal/JVM.java | 10 + .../jdk/jfr/internal/PlatformEventType.java | 21 + .../classes/jdk/jfr/internal/query/view.ini | 25 +- .../internal/settings/CPUThrottleSetting.java | 89 ++ .../classes/jdk/jfr/internal/util/Rate.java | 4 + .../jdk/jfr/internal/util/TimespanRate.java | 68 ++ src/jdk.jfr/share/conf/jfr/default.jfc | 10 + src/jdk.jfr/share/conf/jfr/profile.jfc | 10 + .../metadata/TestLookForUntestedEvents.java | 9 +- .../profiling/BaseTestFullStackTrace.java | 176 ++++ .../TestCPUTimeAndExecutionSample.java | 65 ++ .../TestCPUTimeSampleFullStackTrace.java | 41 + .../TestCPUTimeSampleMultipleRecordings.java | 70 ++ .../profiling/TestCPUTimeSampleNative.java | 66 ++ .../TestCPUTimeSampleThrottling.java | 111 +++ .../TestCPUTimeSamplingLongPeriod.java | 58 ++ .../event/profiling/TestFullStackTrace.java | 131 +-- .../classes/test/RecursiveMethods.java | 76 ++ test/lib/jdk/test/lib/jfr/EventNames.java | 2 + 41 files changed, 2191 insertions(+), 140 deletions(-) create mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp create mode 100644 src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java create mode 100644 test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java create mode 100644 test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java create mode 100644 test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index e900d5695ae..0157d354f40 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -1505,6 +1505,14 @@ bool PosixSignals::is_sig_ignored(int sig) { } } +void* PosixSignals::get_signal_handler_for_signal(int sig) { + struct sigaction oact; + if (sigaction(sig, (struct sigaction*)nullptr, &oact) == -1) { + return nullptr; + } + return get_signal_handler(&oact); +} + static void signal_sets_init() { sigemptyset(&preinstalled_sigs); diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index 9deade4db18..c1cb70df153 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -52,6 +52,8 @@ public: static bool is_sig_ignored(int sig); + static void* get_signal_handler_for_signal(int sig); + static void hotspot_sigmask(Thread* thread); static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); diff --git a/src/hotspot/share/jfr/jfr.inline.hpp b/src/hotspot/share/jfr/jfr.inline.hpp index bdb47f600e6..5b6fc62d0ea 100644 --- a/src/hotspot/share/jfr/jfr.inline.hpp +++ b/src/hotspot/share/jfr/jfr.inline.hpp @@ -32,7 +32,8 @@ inline bool Jfr::has_sample_request(JavaThread* jt) { assert(jt != nullptr, "invariant"); - return jt->jfr_thread_local()->has_sample_request(); + JfrThreadLocal* tl = jt->jfr_thread_local(); + return tl->has_sample_request() || tl->has_cpu_time_jfr_requests(); } inline void Jfr::check_and_process_sample_request(JavaThread* jt) { diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index 6f1c1936574..bc2412a90c1 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -24,6 +24,7 @@ #include "jfr/jfr.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrEventSetting.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -169,6 +170,11 @@ NO_TRANSITION(jboolean, jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_ty return JNI_TRUE; NO_TRANSITION_END +JVM_ENTRY_NO_ENV(void, jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt)) + JfrEventSetting::set_enabled(JfrCPUTimeSampleEvent, rate > 0); + JfrCPUTimeThreadSampling::set_rate(rate, auto_adapt == JNI_TRUE); +JVM_END + NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong event_type_id, jlong value)) JfrEventSetting::set_miscellaneous(event_type_id, value); const JfrEventId typed_event_id = (JfrEventId)event_type_id; diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index 9c78c6239d4..dbea7f0180d 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -129,6 +129,8 @@ jlong JNICALL jfr_get_unloaded_event_classes_count(JNIEnv* env, jclass jvm); jboolean JNICALL jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms); +void JNICALL jfr_set_cpu_throttle(JNIEnv* env, jclass jvm, jdouble rate, jboolean auto_adapt); + void JNICALL jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong id, jlong value); void JNICALL jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean, jboolean); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index 33a564dee2f..82ef93d95b2 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -83,6 +83,7 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"getUnloadedEventClassCount", (char*)"()J", (void*)jfr_get_unloaded_event_classes_count, (char*)"setMiscellaneous", (char*)"(JJ)V", (void*)jfr_set_miscellaneous, (char*)"setThrottle", (char*)"(JJJ)Z", (void*)jfr_set_throttle, + (char*)"setCPUThrottle", (char*)"(DZ)V", (void*)jfr_set_cpu_throttle, (char*)"emitOldObjectSamples", (char*)"(JZZ)V", (void*)jfr_emit_old_object_samples, (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk, (char*)"exclude", (char*)"(Ljava/lang/Thread;)V", (void*)jfr_exclude_thread, diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 9c04ec3dca1..03daca946f6 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -962,6 +962,22 @@ + + + + + + + + + + + + + diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp new file mode 100644 index 00000000000..2f063123a3d --- /dev/null +++ b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (c) 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 + * 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 "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" +#include "logging/log.hpp" + + +#if defined(LINUX) +#include "jfr/periodic/sampling/jfrThreadSampling.hpp" +#include "jfr/support/jfrThreadLocal.hpp" +#include "jfr/utilities/jfrTime.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" +#include "jfr/utilities/jfrTypes.hpp" +#include "jfrfiles/jfrEventClasses.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/atomic.hpp" +#include "runtime/javaThread.hpp" +#include "runtime/osThread.hpp" +#include "runtime/safepointMechanism.inline.hpp" +#include "runtime/threadSMR.hpp" +#include "runtime/vmOperation.hpp" +#include "runtime/vmThread.hpp" +#include "utilities/ticks.hpp" + +#include "signals_posix.hpp" + +static const int64_t AUTOADAPT_INTERVAL_MS = 100; + +static bool is_excluded(JavaThread* jt) { + return jt->is_hidden_from_external_view() || + jt->jfr_thread_local()->is_excluded() || + jt->is_JfrRecorder_thread(); +} + +static JavaThread* get_java_thread_if_valid() { + Thread* raw_thread = Thread::current_or_null_safe(); + if (raw_thread == nullptr) { + // probably while shutting down + return nullptr; + } + assert(raw_thread->is_Java_thread(), "invariant"); + JavaThread* jt = JavaThread::cast(raw_thread); + if (is_excluded(jt) || jt->is_exiting()) { + return nullptr; + } + return jt; +} + +JfrCPUTimeTraceQueue::JfrCPUTimeTraceQueue(u4 capacity) : + _data(nullptr), _capacity(capacity), _head(0), _lost_samples(0) { + if (capacity != 0) { + _data = JfrCHeapObj::new_array(capacity); + } +} + +JfrCPUTimeTraceQueue::~JfrCPUTimeTraceQueue() { + if (_data != nullptr) { + assert(_capacity != 0, "invariant"); + JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); + } +} + +bool JfrCPUTimeTraceQueue::enqueue(JfrCPUTimeSampleRequest& request) { + assert(JavaThread::current()->jfr_thread_local()->is_cpu_time_jfr_enqueue_locked(), "invariant"); + assert(&JavaThread::current()->jfr_thread_local()->cpu_time_jfr_queue() == this, "invariant"); + u4 elementIndex; + do { + elementIndex = Atomic::load_acquire(&_head); + if (elementIndex >= _capacity) { + return false; + } + } while (Atomic::cmpxchg(&_head, elementIndex, elementIndex + 1) != elementIndex); + _data[elementIndex] = request; + return true; +} + +JfrCPUTimeSampleRequest& JfrCPUTimeTraceQueue::at(u4 index) { + assert(index < _head, "invariant"); + return _data[index]; +} + +static volatile u4 _lost_samples_sum = 0; + +u4 JfrCPUTimeTraceQueue::size() const { + return Atomic::load_acquire(&_head); +} + +void JfrCPUTimeTraceQueue::set_size(u4 size) { + Atomic::release_store(&_head, size); +} + +u4 JfrCPUTimeTraceQueue::capacity() const { + return _capacity; +} + +void JfrCPUTimeTraceQueue::set_capacity(u4 capacity) { + _head = 0; + if (_data != nullptr) { + assert(_capacity != 0, "invariant"); + JfrCHeapObj::free(_data, _capacity * sizeof(JfrCPUTimeSampleRequest)); + } + if (capacity != 0) { + _data = JfrCHeapObj::new_array(capacity); + } else { + _data = nullptr; + } + _capacity = capacity; +} + +bool JfrCPUTimeTraceQueue::is_empty() const { + return Atomic::load_acquire(&_head) == 0; +} + +u4 JfrCPUTimeTraceQueue::lost_samples() const { + return Atomic::load(&_lost_samples); +} + +void JfrCPUTimeTraceQueue::increment_lost_samples() { + Atomic::inc(&_lost_samples_sum); + Atomic::inc(&_lost_samples); +} + +u4 JfrCPUTimeTraceQueue::get_and_reset_lost_samples() { + return Atomic::xchg(&_lost_samples, (u4)0); +} + +void JfrCPUTimeTraceQueue::resize(u4 capacity) { + if (capacity != _capacity) { + set_capacity(capacity); + } +} + +void JfrCPUTimeTraceQueue::resize_for_period(u4 period_millis) { + u4 capacity = CPU_TIME_QUEUE_CAPACITY; + if (period_millis > 0 && period_millis < 10) { + capacity = (u4) ((double) capacity * 10 / period_millis); + } + resize(capacity); +} + +void JfrCPUTimeTraceQueue::clear() { + Atomic::release_store(&_head, (u4)0); +} + +static int64_t compute_sampling_period(double rate) { + if (rate == 0) { + return 0; + } + return os::active_processor_count() * 1000000000.0 / rate; +} + +class JfrCPUSamplerThread : public NonJavaThread { + friend class JfrCPUTimeThreadSampling; + private: + Semaphore _sample; + NonJavaThread* _sampler_thread; + double _rate; + bool _auto_adapt; + volatile int64_t _current_sampling_period_ns; + volatile bool _disenrolled; + // top bit is used to indicate that no signal handler should proceed + volatile u4 _active_signal_handlers; + volatile bool _is_async_processing_of_cpu_time_jfr_requests_triggered; + volatile bool _warned_about_timer_creation_failure; + volatile bool _signal_handler_installed; + + static const u4 STOP_SIGNAL_BIT = 0x80000000; + + JfrCPUSamplerThread(double rate, bool auto_adapt); + + void start_thread(); + + void enroll(); + void disenroll(); + void update_all_thread_timers(); + + void auto_adapt_period_if_needed(); + + void set_rate(double rate, bool auto_adapt); + int64_t get_sampling_period() const { return Atomic::load(&_current_sampling_period_ns); }; + + void sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now); + + // process the queues for all threads that are in native state (and requested to be processed) + void stackwalk_threads_in_native(); + bool create_timer_for_thread(JavaThread* thread, timer_t &timerid); + + void stop_signal_handlers(); + + // returns false if the stop signal bit was set, true otherwise + bool increment_signal_handler_count(); + + void decrement_signal_handler_count(); + + void initialize_active_signal_handler_counter(); + +protected: + virtual void post_run(); +public: + virtual const char* name() const { return "JFR CPU Sampler Thread"; } + virtual const char* type_name() const { return "JfrCPUTimeSampler"; } + void run(); + void on_javathread_create(JavaThread* thread); + void on_javathread_terminate(JavaThread* thread); + + void handle_timer_signal(siginfo_t* info, void* context); + bool init_timers(); + void stop_timer(); + + void trigger_async_processing_of_cpu_time_jfr_requests(); +}; + +JfrCPUSamplerThread::JfrCPUSamplerThread(double rate, bool auto_adapt) : + _sample(), + _sampler_thread(nullptr), + _rate(rate), + _auto_adapt(auto_adapt), + _current_sampling_period_ns(compute_sampling_period(rate)), + _disenrolled(true), + _active_signal_handlers(STOP_SIGNAL_BIT), + _is_async_processing_of_cpu_time_jfr_requests_triggered(false), + _warned_about_timer_creation_failure(false), + _signal_handler_installed(false) { + assert(rate >= 0, "invariant"); +} + +void JfrCPUSamplerThread::trigger_async_processing_of_cpu_time_jfr_requests() { + Atomic::release_store(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true); +} + +void JfrCPUSamplerThread::on_javathread_create(JavaThread* thread) { + if (thread->is_hidden_from_external_view() || thread->is_JfrRecorder_thread() || + !Atomic::load_acquire(&_signal_handler_installed)) { + return; + } + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + tl->cpu_time_jfr_queue().resize_for_period(_current_sampling_period_ns / 1000000); + timer_t timerid; + if (create_timer_for_thread(thread, timerid)) { + tl->set_cpu_timer(&timerid); + } else { + if (!Atomic::or_then_fetch(&_warned_about_timer_creation_failure, true)) { + log_warning(jfr)("Failed to create timer for a thread"); + } + tl->deallocate_cpu_time_jfr_queue(); + } +} + +void JfrCPUSamplerThread::on_javathread_terminate(JavaThread* thread) { + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + timer_t* timer = tl->cpu_timer(); + if (timer == nullptr) { + return; // no timer was created for this thread + } + tl->unset_cpu_timer(); + tl->deallocate_cpu_time_jfr_queue(); + s4 lost_samples = tl->cpu_time_jfr_queue().lost_samples(); + if (lost_samples > 0) { + JfrCPUTimeThreadSampling::send_lost_event(JfrTicks::now(), JfrThreadLocal::thread_id(thread), lost_samples); + } +} + +void JfrCPUSamplerThread::start_thread() { + if (os::create_thread(this, os::os_thread)) { + os::start_thread(this); + } else { + log_error(jfr)("Failed to create thread for thread sampling"); + } +} + +void JfrCPUSamplerThread::enroll() { + if (Atomic::cmpxchg(&_disenrolled, true, false)) { + Atomic::store(&_warned_about_timer_creation_failure, false); + initialize_active_signal_handler_counter(); + log_trace(jfr)("Enrolling CPU thread sampler"); + _sample.signal(); + if (!init_timers()) { + log_error(jfr)("Failed to initialize timers for CPU thread sampler"); + disenroll(); + return; + } + log_trace(jfr)("Enrolled CPU thread sampler"); + } +} + +void JfrCPUSamplerThread::disenroll() { + if (!Atomic::cmpxchg(&_disenrolled, false, true)) { + log_trace(jfr)("Disenrolling CPU thread sampler"); + if (Atomic::load_acquire(&_signal_handler_installed)) { + stop_timer(); + stop_signal_handlers(); + } + _sample.wait(); + log_trace(jfr)("Disenrolled CPU thread sampler"); + } +} + +void JfrCPUSamplerThread::run() { + assert(_sampler_thread == nullptr, "invariant"); + _sampler_thread = this; + int64_t last_auto_adapt_check = os::javaTimeNanos(); + while (true) { + if (!_sample.trywait()) { + // disenrolled + _sample.wait(); + } + _sample.signal(); + + if (os::javaTimeNanos() - last_auto_adapt_check > AUTOADAPT_INTERVAL_MS * 1000000) { + auto_adapt_period_if_needed(); + last_auto_adapt_check = os::javaTimeNanos(); + } + + if (Atomic::cmpxchg(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true, false)) { + stackwalk_threads_in_native(); + } + os::naked_sleep(100); + } +} + +void JfrCPUSamplerThread::stackwalk_threads_in_native() { + ResourceMark rm; + // Required to prevent JFR from sampling through an ongoing safepoint + MutexLocker tlock(Threads_lock); + ThreadsListHandle tlh; + Thread* current = Thread::current(); + for (size_t i = 0; i < tlh.list()->length(); i++) { + JavaThread* jt = tlh.list()->thread_at(i); + JfrThreadLocal* tl = jt->jfr_thread_local(); + if (tl->wants_async_processing_of_cpu_time_jfr_requests()) { + if (jt->thread_state() != _thread_in_native || !tl->try_acquire_cpu_time_jfr_dequeue_lock()) { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + continue; + } + if (jt->has_last_Java_frame()) { + JfrThreadSampling::process_cpu_time_request(jt, tl, current, false); + } else { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + } + tl->release_cpu_time_jfr_queue_lock(); + } + } +} + +static volatile size_t count = 0; + +void JfrCPUTimeThreadSampling::send_empty_event(const JfrTicks &start_time, traceid tid, Tickspan cpu_time_period) { + EventCPUTimeSample event(UNTIMED); + event.set_failed(true); + event.set_starttime(start_time); + event.set_eventThread(tid); + event.set_stackTrace(0); + event.set_samplingPeriod(cpu_time_period); + event.set_biased(false); + event.commit(); +} + + +static volatile size_t biased_count = 0; + +void JfrCPUTimeThreadSampling::send_event(const JfrTicks &start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased) { + EventCPUTimeSample event(UNTIMED); + event.set_failed(false); + event.set_starttime(start_time); + event.set_eventThread(tid); + event.set_stackTrace(sid); + event.set_samplingPeriod(cpu_time_period); + event.set_biased(biased); + event.commit(); + Atomic::inc(&count); + if (biased) { + Atomic::inc(&biased_count); + } + if (Atomic::load(&count) % 1000 == 0) { + log_debug(jfr)("CPU thread sampler sent %zu events, lost %d, biased %zu\n", Atomic::load(&count), Atomic::load(&_lost_samples_sum), Atomic::load(&biased_count)); + } +} + +void JfrCPUTimeThreadSampling::send_lost_event(const JfrTicks &time, traceid tid, s4 lost_samples) { + if (!EventCPUTimeSamplesLost::is_enabled()) { + return; + } + EventCPUTimeSamplesLost event(UNTIMED); + event.set_starttime(time); + event.set_lostSamples(lost_samples); + event.set_eventThread(tid); + event.commit(); +} + +void JfrCPUSamplerThread::post_run() { + this->NonJavaThread::post_run(); + delete this; +} + +static JfrCPUTimeThreadSampling* _instance = nullptr; + +JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { + return *_instance; +} + +JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { + assert(_instance == nullptr, "invariant"); + _instance = new JfrCPUTimeThreadSampling(); + return _instance; +} + +void JfrCPUTimeThreadSampling::destroy() { + if (_instance != nullptr) { + delete _instance; + _instance = nullptr; + } +} + +JfrCPUTimeThreadSampling::JfrCPUTimeThreadSampling() : _sampler(nullptr) {} + +JfrCPUTimeThreadSampling::~JfrCPUTimeThreadSampling() { + if (_sampler != nullptr) { + _sampler->disenroll(); + } +} + +void JfrCPUTimeThreadSampling::create_sampler(double rate, bool auto_adapt) { + assert(_sampler == nullptr, "invariant"); + _sampler = new JfrCPUSamplerThread(rate, auto_adapt); + _sampler->start_thread(); + _sampler->enroll(); +} + +void JfrCPUTimeThreadSampling::update_run_state(double rate, bool auto_adapt) { + if (rate != 0) { + if (_sampler == nullptr) { + create_sampler(rate, auto_adapt); + } else { + _sampler->set_rate(rate, auto_adapt); + _sampler->enroll(); + } + return; + } + if (_sampler != nullptr) { + _sampler->set_rate(rate /* 0 */, auto_adapt); + _sampler->disenroll(); + } +} + +void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { + assert(rate >= 0, "invariant"); + if (_instance == nullptr) { + return; + } + instance().set_rate_value(rate, auto_adapt); +} + +void JfrCPUTimeThreadSampling::set_rate_value(double rate, bool auto_adapt) { + if (_sampler != nullptr) { + _sampler->set_rate(rate, auto_adapt); + } + update_run_state(rate, auto_adapt); +} + +void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread *thread) { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->on_javathread_create(thread); + } +} + +void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread *thread) { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->on_javathread_terminate(thread); + } +} + +void JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests() { + if (_instance != nullptr && _instance->_sampler != nullptr) { + _instance->_sampler->trigger_async_processing_of_cpu_time_jfr_requests(); + } +} + +void handle_timer_signal(int signo, siginfo_t* info, void* context) { + assert(_instance != nullptr, "invariant"); + _instance->handle_timer_signal(info, context); +} + + +void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* context) { + if (info->si_code != SI_TIMER) { + // not the signal we are interested in + return; + } + assert(_sampler != nullptr, "invariant"); + + if (!_sampler->increment_signal_handler_count()) { + return; + } + _sampler->handle_timer_signal(info, context); + _sampler->decrement_signal_handler_count(); +} + +void JfrCPUSamplerThread::sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now) { + JfrSampleRequestBuilder::build_cpu_time_sample_request(request, ucontext, jt, jt->jfr_thread_local(), now); +} + +static bool check_state(JavaThread* thread) { + switch (thread->thread_state()) { + case _thread_in_Java: + case _thread_in_native: + return true; + default: + return false; + } +} + +void JfrCPUSamplerThread::handle_timer_signal(siginfo_t* info, void* context) { + JfrTicks now = JfrTicks::now(); + JavaThread* jt = get_java_thread_if_valid(); + if (jt == nullptr) { + return; + } + JfrThreadLocal* tl = jt->jfr_thread_local(); + JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); + if (!check_state(jt)) { + queue.increment_lost_samples(); + return; + } + if (!tl->try_acquire_cpu_time_jfr_enqueue_lock()) { + queue.increment_lost_samples(); + return; + } + + JfrCPUTimeSampleRequest request; + // the sampling period might be too low for the current Linux configuration + // so samples might be skipped and we have to compute the actual period + int64_t period = get_sampling_period() * (info->si_overrun + 1); + request._cpu_time_period = Ticks(period / 1000000000.0 * JfrTime::frequency()) - Ticks(0); + sample_thread(request._request, context, jt, tl, now); + + if (queue.enqueue(request)) { + if (queue.size() == 1) { + tl->set_has_cpu_time_jfr_requests(true); + SafepointMechanism::arm_local_poll_release(jt); + } + } else { + queue.increment_lost_samples(); + } + + if (jt->thread_state() == _thread_in_native) { + if (!tl->wants_async_processing_of_cpu_time_jfr_requests()) { + tl->set_do_async_processing_of_cpu_time_jfr_requests(true); + JfrCPUTimeThreadSampling::trigger_async_processing_of_cpu_time_jfr_requests(); + } + } else { + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + } + + tl->release_cpu_time_jfr_queue_lock(); +} + +static const int SIG = SIGPROF; + +static void set_timer_time(timer_t timerid, int64_t period_nanos) { + struct itimerspec its; + if (period_nanos == 0) { + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + } else { + its.it_interval.tv_sec = period_nanos / NANOSECS_PER_SEC; + its.it_interval.tv_nsec = period_nanos % NANOSECS_PER_SEC; + } + its.it_value = its.it_interval; + if (timer_settime(timerid, 0, &its, nullptr) == -1) { + warning("Failed to set timer for thread sampling: %s", os::strerror(os::get_last_error())); + } +} + +bool JfrCPUSamplerThread::create_timer_for_thread(JavaThread* thread, timer_t& timerid) { + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_signo = SIG; + sev.sigev_value.sival_ptr = nullptr; + ((int*)&sev.sigev_notify)[1] = thread->osthread()->thread_id(); + clockid_t clock; + int err = pthread_getcpuclockid(thread->osthread()->pthread_id(), &clock); + if (err != 0) { + log_error(jfr)("Failed to get clock for thread sampling: %s", os::strerror(err)); + return false; + } + if (timer_create(clock, &sev, &timerid) < 0) { + return false; + } + int64_t period = get_sampling_period(); + if (period != 0) { + set_timer_time(timerid, period); + } + return true; +} + + +void JfrCPUSamplerThread::stop_signal_handlers() { + // set the stop signal bit + Atomic::or_then_fetch(&_active_signal_handlers, STOP_SIGNAL_BIT, memory_order_acq_rel); + while (Atomic::load_acquire(&_active_signal_handlers) > STOP_SIGNAL_BIT) { + // wait for all signal handlers to finish + os::naked_short_nanosleep(1000); + } +} + +// returns false if the stop signal bit was set, true otherwise +bool JfrCPUSamplerThread::increment_signal_handler_count() { + // increment the count of active signal handlers + u4 old_value = Atomic::fetch_then_add(&_active_signal_handlers, (u4)1, memory_order_acq_rel); + if ((old_value & STOP_SIGNAL_BIT) != 0) { + // if the stop signal bit was set, we are not allowed to increment + Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); + return false; + } + return true; +} + +void JfrCPUSamplerThread::decrement_signal_handler_count() { + Atomic::dec(&_active_signal_handlers, memory_order_acq_rel); +} + +void JfrCPUSamplerThread::initialize_active_signal_handler_counter() { + Atomic::release_store(&_active_signal_handlers, (u4)0); +} + +class VM_JFRInitializeCPUTimeSampler : public VM_Operation { + private: + JfrCPUSamplerThread* const _sampler; + + public: + VM_JFRInitializeCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} + + VMOp_Type type() const { return VMOp_JFRInitializeCPUTimeSampler; } + void doit() { + JfrJavaThreadIterator iter; + while (iter.has_next()) { + _sampler->on_javathread_create(iter.next()); + } + }; +}; + +bool JfrCPUSamplerThread::init_timers() { + // install sig handler for sig + void* prev_handler = PosixSignals::get_signal_handler_for_signal(SIG); + if ((prev_handler != SIG_DFL && prev_handler != SIG_IGN && prev_handler != (void*)::handle_timer_signal) || + PosixSignals::install_generic_signal_handler(SIG, (void*)::handle_timer_signal) == (void*)-1) { + log_error(jfr)("Conflicting SIGPROF handler found: %p. CPUTimeSample events will not be recorded", prev_handler); + return false; + } + Atomic::release_store(&_signal_handler_installed, true); + VM_JFRInitializeCPUTimeSampler op(this); + VMThread::execute(&op); + return true; +} + +class VM_JFRTerminateCPUTimeSampler : public VM_Operation { + private: + JfrCPUSamplerThread* const _sampler; + + public: + VM_JFRTerminateCPUTimeSampler(JfrCPUSamplerThread* sampler) : _sampler(sampler) {} + + VMOp_Type type() const { return VMOp_JFRTerminateCPUTimeSampler; } + void doit() { + JfrJavaThreadIterator iter; + while (iter.has_next()) { + JavaThread *thread = iter.next(); + JfrThreadLocal* tl = thread->jfr_thread_local(); + timer_t* timer = tl->cpu_timer(); + if (timer == nullptr) { + continue; + } + tl->deallocate_cpu_time_jfr_queue(); + tl->unset_cpu_timer(); + } + }; +}; + +void JfrCPUSamplerThread::stop_timer() { + VM_JFRTerminateCPUTimeSampler op(this); + VMThread::execute(&op); +} + +void JfrCPUSamplerThread::auto_adapt_period_if_needed() { + int64_t current_period = get_sampling_period(); + if (_auto_adapt || current_period == -1) { + int64_t period = compute_sampling_period(_rate); + if (period != current_period) { + Atomic::store(&_current_sampling_period_ns, period); + update_all_thread_timers(); + } + } +} + +void JfrCPUSamplerThread::set_rate(double rate, bool auto_adapt) { + _rate = rate; + _auto_adapt = auto_adapt; + if (_rate > 0 && Atomic::load_acquire(&_disenrolled) == false) { + auto_adapt_period_if_needed(); + } else { + Atomic::store(&_current_sampling_period_ns, compute_sampling_period(rate)); + } +} + +void JfrCPUSamplerThread::update_all_thread_timers() { + int64_t period_millis = get_sampling_period(); + ThreadsListHandle tlh; + for (size_t i = 0; i < tlh.length(); i++) { + JavaThread* thread = tlh.thread_at(i); + JfrThreadLocal* tl = thread->jfr_thread_local(); + assert(tl != nullptr, "invariant"); + timer_t* timer = tl->cpu_timer(); + if (timer != nullptr) { + set_timer_time(*timer, period_millis); + } + } +} + +#else + +static void warn() { + static bool displayed_warning = false; + if (!displayed_warning) { + warning("CPU time method sampling not supported in JFR on your platform"); + displayed_warning = true; + } +} + +static JfrCPUTimeThreadSampling* _instance = nullptr; + +JfrCPUTimeThreadSampling& JfrCPUTimeThreadSampling::instance() { + return *_instance; +} + +JfrCPUTimeThreadSampling* JfrCPUTimeThreadSampling::create() { + _instance = new JfrCPUTimeThreadSampling(); + return _instance; +} + +void JfrCPUTimeThreadSampling::destroy() { + delete _instance; + _instance = nullptr; +} + +void JfrCPUTimeThreadSampling::set_rate(double rate, bool auto_adapt) { + if (rate != 0) { + warn(); + } +} + +void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread* thread) { +} + +void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread* thread) { +} + +#endif // defined(LINUX) && defined(INCLUDE_JFR) diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp new file mode 100644 index 00000000000..7c0545f4772 --- /dev/null +++ b/src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 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 + * 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. + * + */ + +#ifndef SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP +#define SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP + +#include "jfr/utilities/jfrAllocation.hpp" + +class JavaThread; + +#if defined(LINUX) + +#include "jfr/periodic/sampling/jfrSampleRequest.hpp" +#include "jfr/utilities/jfrTypes.hpp" + +struct JfrCPUTimeSampleRequest { + JfrSampleRequest _request; + Tickspan _cpu_time_period; + + JfrCPUTimeSampleRequest() {} +}; + +// Fixed size async-signal-safe SPSC linear queue backed by an array. +// Designed to be only used under lock and read linearly +class JfrCPUTimeTraceQueue { + + // the default queue capacity, scaled if the sampling period is smaller than 10ms + // when the thread is started + static const u4 CPU_TIME_QUEUE_CAPACITY = 500; + + JfrCPUTimeSampleRequest* _data; + u4 _capacity; + // next unfilled index + volatile u4 _head; + + volatile u4 _lost_samples; + +public: + JfrCPUTimeTraceQueue(u4 capacity); + + ~JfrCPUTimeTraceQueue(); + + // signal safe, but can't be interleaved with dequeue + bool enqueue(JfrCPUTimeSampleRequest& trace); + + JfrCPUTimeSampleRequest& at(u4 index); + + u4 size() const; + + void set_size(u4 size); + + u4 capacity() const; + + // deletes all samples in the queue + void set_capacity(u4 capacity); + + bool is_empty() const; + + u4 lost_samples() const; + + void increment_lost_samples(); + + // returns the previous lost samples count + u4 get_and_reset_lost_samples(); + + void resize(u4 capacity); + + void resize_for_period(u4 period_millis); + + void clear(); + +}; + + +class JfrCPUSamplerThread; + +class JfrCPUTimeThreadSampling : public JfrCHeapObj { + friend class JfrRecorder; + private: + + JfrCPUSamplerThread* _sampler; + + void create_sampler(double rate, bool auto_adapt); + void set_rate_value(double rate, bool auto_adapt); + + JfrCPUTimeThreadSampling(); + ~JfrCPUTimeThreadSampling(); + + static JfrCPUTimeThreadSampling& instance(); + static JfrCPUTimeThreadSampling* create(); + static void destroy(); + + void update_run_state(double rate, bool auto_adapt); + + public: + static void set_rate(double rate, bool auto_adapt); + + static void on_javathread_create(JavaThread* thread); + static void on_javathread_terminate(JavaThread* thread); + void handle_timer_signal(siginfo_t* info, void* context); + + static void send_empty_event(const JfrTicks& start_time, traceid tid, Tickspan cpu_time_period); + static void send_event(const JfrTicks& start_time, traceid sid, traceid tid, Tickspan cpu_time_period, bool biased); + static void send_lost_event(const JfrTicks& time, traceid tid, s4 lost_samples); + + static void trigger_async_processing_of_cpu_time_jfr_requests(); +}; + +#else + +// a basic implementation on other platforms that +// emits warnings + +class JfrCPUTimeThreadSampling : public JfrCHeapObj { + friend class JfrRecorder; +private: + static JfrCPUTimeThreadSampling& instance(); + static JfrCPUTimeThreadSampling* create(); + static void destroy(); + + public: + static void set_rate(double rate, bool auto_adapt); + + static void on_javathread_create(JavaThread* thread); + static void on_javathread_terminate(JavaThread* thread); +}; + +#endif // defined(LINUX) + + +#endif // SHARE_JFR_PERIODIC_SAMPLING_JFRCPUTIMETHREADSAMPLER_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp index f8e63e2e344..7049df0198b 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.cpp @@ -24,6 +24,7 @@ #include "asm/codeBuffer.hpp" #include "interpreter/interpreter.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" +#include "jfr/utilities/jfrTime.hpp" #include "runtime/continuationEntry.hpp" #include "runtime/frame.inline.hpp" #include "runtime/javaThread.inline.hpp" @@ -171,7 +172,7 @@ static bool build(JfrSampleRequest& request, intptr_t* fp, JavaThread* jt) { assert(request._sample_sp != nullptr, "invariant"); assert(request._sample_pc != nullptr, "invariant"); assert(jt != nullptr, "invariant"); - assert(jt->thread_state() == _thread_in_Java, "invariant"); + assert(jt->thread_state() == _thread_in_Java || jt->thread_state() == _thread_in_native, "invariant"); // 1. Interpreter frame? if (is_interpreter(request)) { @@ -303,3 +304,33 @@ JfrSampleResult JfrSampleRequestBuilder::build_java_sample_request(const void* u } return set_biased_java_sample(request, tl, jt); } + + +// A biased sample request is denoted by an empty bcp and an empty pc. +static inline void set_cpu_time_biased_sample(JfrSampleRequest& request, JavaThread* jt) { + if (request._sample_bcp != nullptr) { + request._sample_bcp = nullptr; + } + assert(request._sample_bcp == nullptr, "invariant"); + request._sample_pc = nullptr; +} + +void JfrSampleRequestBuilder::build_cpu_time_sample_request(JfrSampleRequest& request, + void* ucontext, + JavaThread* jt, + JfrThreadLocal* tl, + JfrTicks& now) { + assert(jt != nullptr, "invariant"); + request._sample_ticks = now; + + // Prioritize the ljf, if one exists. + request._sample_sp = jt->last_Java_sp(); + if (request._sample_sp == nullptr || !build_from_ljf(request, tl, jt)) { + intptr_t* fp; + request._sample_pc = os::fetch_frame_from_context(ucontext, reinterpret_cast(&request._sample_sp), &fp); + assert(sp_in_stack(request, jt), "invariant"); + if (!build(request, fp, jt)) { + set_cpu_time_biased_sample(request, jt); + } + } +} diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp index 6567e7f8bff..20e737e0cbf 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrSampleRequest.hpp @@ -81,6 +81,11 @@ class JfrSampleRequestBuilder : AllStatic { static JfrSampleResult build_java_sample_request(const void* ucontext, JfrThreadLocal* tl, JavaThread* jt); + static void build_cpu_time_sample_request(JfrSampleRequest &request, + void* ucontext, + JavaThread* jt, + JfrThreadLocal* tl, + JfrTicks& now); }; #endif // SHARE_JFR_PERIODIC_SAMPLING_JFRSAMPLEREQUEST_HPP diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp index aa72c29cf50..ddc9d59b295 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp @@ -28,6 +28,7 @@ #include "code/nmethod.hpp" #include "interpreter/interpreter.hpp" #include "jfr/jfrEvents.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrSampleMonitor.hpp" #include "jfr/periodic/sampling/jfrSampleRequest.hpp" #include "jfr/periodic/sampling/jfrThreadSampling.hpp" @@ -161,7 +162,7 @@ static inline bool is_valid(const PcDesc* pc_desc) { return pc_desc != nullptr && pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null; } -static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt) { +static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, bool& in_continuation, JavaThread* jt, bool& biased) { assert(jt != nullptr, "invariant"); if (!jt->has_last_Java_frame()) { @@ -178,6 +179,7 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, // A biased sample is requested or no code blob. top_frame = jt->last_frame(); in_continuation = is_in_continuation(top_frame, jt); + biased = true; return true; } @@ -227,6 +229,8 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, assert(!stream.current()->is_safepoint_blob_frame(), "invariant"); + biased = true; + // Search the first frame that is above the sampled sp. for (; !stream.is_done(); stream.next()) { frame* const current = stream.current(); @@ -250,6 +254,7 @@ static bool compute_top_frame(const JfrSampleRequest& request, frame& top_frame, const PcDesc* const pc_desc = get_pc_desc(sampled_nm, sampled_pc); if (is_valid(pc_desc)) { current->adjust_pc(pc_desc->real_pc(sampled_nm)); + biased = false; } } } @@ -270,8 +275,9 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick assert(current != nullptr, "invariant"); frame top_frame; + bool biased = false; bool in_continuation; - if (!compute_top_frame(request, top_frame, in_continuation, jt)) { + if (!compute_top_frame(request, top_frame, in_continuation, jt, biased)) { return; } @@ -293,6 +299,42 @@ static void record_thread_in_java(const JfrSampleRequest& request, const JfrTick } } +#ifdef LINUX +static void record_cpu_time_thread(const JfrCPUTimeSampleRequest& request, const JfrTicks& now, const JfrThreadLocal* tl, JavaThread* jt, Thread* current) { + assert(jt != nullptr, "invariant"); + assert(tl != nullptr, "invariant"); + assert(current != nullptr, "invariant"); + frame top_frame; + bool biased = false; + bool in_continuation = false; + bool could_compute_top_frame = compute_top_frame(request._request, top_frame, in_continuation, jt, biased); + const traceid tid = in_continuation ? tl->vthread_id_with_epoch_update(jt) : JfrThreadLocal::jvm_thread_id(jt); + + if (!could_compute_top_frame) { + JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); + return; + } + traceid sid; + { + ResourceMark rm(current); + JfrStackTrace stacktrace; + if (!stacktrace.record(jt, top_frame, in_continuation, request._request)) { + // Unable to record stacktrace. Fail. + JfrCPUTimeThreadSampling::send_empty_event(request._request._sample_ticks, tid, request._cpu_time_period); + return; + } + sid = JfrStackTraceRepository::add(stacktrace); + } + assert(sid != 0, "invariant"); + + + JfrCPUTimeThreadSampling::send_event(request._request._sample_ticks, sid, tid, request._cpu_time_period, biased); + if (current == jt) { + send_safepoint_latency_event(request._request, now, sid, jt); + } +} +#endif + static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { assert(tl != nullptr, "invariant"); assert(jt != nullptr, "invariant"); @@ -308,6 +350,49 @@ static void drain_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, Jav assert(!tl->has_enqueued_requests(), "invariant"); } +static void drain_enqueued_cpu_time_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current, bool lock) { + assert(tl != nullptr, "invariant"); + assert(jt != nullptr, "invariant"); + assert(current != nullptr, "invariant"); +#ifdef LINUX + tl->set_do_async_processing_of_cpu_time_jfr_requests(false); + if (lock) { + tl->acquire_cpu_time_jfr_dequeue_lock(); + } + JfrCPUTimeTraceQueue& queue = tl->cpu_time_jfr_queue(); + for (u4 i = 0; i < queue.size(); i++) { + record_cpu_time_thread(queue.at(i), now, tl, jt, current); + } + queue.clear(); + assert(queue.is_empty(), "invariant"); + tl->set_has_cpu_time_jfr_requests(false); + if (queue.lost_samples() > 0) { + JfrCPUTimeThreadSampling::send_lost_event( now, JfrThreadLocal::thread_id(jt), queue.get_and_reset_lost_samples()); + } + if (lock) { + tl->release_cpu_time_jfr_queue_lock(); + } +#endif +} + +// Entry point for a thread that has been sampled in native code and has a pending JFR CPU time request. +void JfrThreadSampling::process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock) { + assert(jt != nullptr, "invariant"); + + const JfrTicks now = JfrTicks::now(); + drain_enqueued_cpu_time_requests(now, tl, jt, current, lock); +} + +static void drain_all_enqueued_requests(const JfrTicks& now, JfrThreadLocal* tl, JavaThread* jt, Thread* current) { + assert(tl != nullptr, "invariant"); + assert(jt != nullptr, "invariant"); + assert(current != nullptr, "invariant"); + drain_enqueued_requests(now, tl, jt, current); + if (tl->has_cpu_time_jfr_requests()) { + drain_enqueued_cpu_time_requests(now, tl, jt, current, true); + } +} + // Only entered by the JfrSampler thread. bool JfrThreadSampling::process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread) { assert(tl != nullptr, "invairant"); @@ -382,5 +467,6 @@ void JfrThreadSampling::process_sample_request(JavaThread* jt) { break; } } - drain_enqueued_requests(now, tl, jt, jt); + drain_all_enqueued_requests(now, tl, jt, jt); } + diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp index d4c4bc0d873..3c4d1a126b0 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.hpp @@ -33,8 +33,10 @@ class Thread; class JfrThreadSampling : AllStatic { friend class JfrSamplerThread; + friend class JfrCPUSamplerThread; private: static bool process_native_sample_request(JfrThreadLocal* tl, JavaThread* jt, Thread* sampler_thread); + static void process_cpu_time_request(JavaThread* jt, JfrThreadLocal* tl, Thread* current, bool lock); public: static void process_sample_request(JavaThread* jt); }; diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp index 384305862ca..dd75cb2929f 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp @@ -29,6 +29,7 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/sampling/objectSampler.hpp" #include "jfr/periodic/jfrOSInterface.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/periodic/sampling/jfrThreadSampler.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" @@ -304,6 +305,9 @@ bool JfrRecorder::create_components() { if (!create_thread_sampler()) { return false; } + if (!create_cpu_time_thread_sampling()) { + return false; + } if (!create_event_throttler()) { return false; } @@ -318,6 +322,7 @@ static JfrStackTraceRepository* _stack_trace_repository; static JfrStringPool* _stringpool = nullptr; static JfrOSInterface* _os_interface = nullptr; static JfrThreadSampler* _thread_sampler = nullptr; +static JfrCPUTimeThreadSampling* _cpu_time_thread_sampling = nullptr; static JfrCheckpointManager* _checkpoint_manager = nullptr; bool JfrRecorder::create_java_event_writer() { @@ -390,6 +395,12 @@ bool JfrRecorder::create_thread_sampler() { return _thread_sampler != nullptr; } +bool JfrRecorder::create_cpu_time_thread_sampling() { + assert(_cpu_time_thread_sampling == nullptr, "invariant"); + _cpu_time_thread_sampling = JfrCPUTimeThreadSampling::create(); + return _cpu_time_thread_sampling != nullptr; +} + bool JfrRecorder::create_event_throttler() { return JfrEventThrottler::create(); } @@ -428,6 +439,10 @@ void JfrRecorder::destroy_components() { JfrThreadSampler::destroy(); _thread_sampler = nullptr; } + if (_cpu_time_thread_sampling != nullptr) { + JfrCPUTimeThreadSampling::destroy(); + _cpu_time_thread_sampling = nullptr; + } JfrEventThrottler::destroy(); } diff --git a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp index b917904c5fb..3099c8ad344 100644 --- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp +++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp @@ -54,6 +54,7 @@ class JfrRecorder : public JfrCHeapObj { static bool create_storage(); static bool create_stringpool(); static bool create_thread_sampler(); + static bool create_cpu_time_thread_sampling(); static bool create_event_throttler(); static bool create_components(); static void destroy_components(); diff --git a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp index 0befaae7751..f660a01c04c 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp +++ b/src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp @@ -34,6 +34,7 @@ constexpr static const JfrSamplerParams _disabled_params = { false // reconfigure }; +static JfrEventThrottler* _disabled_cpu_time_sample_throttler = nullptr; static JfrEventThrottler* _object_allocation_throttler = nullptr; static JfrEventThrottler* _safepoint_latency_throttler = nullptr; @@ -48,6 +49,9 @@ JfrEventThrottler::JfrEventThrottler(JfrEventId event_id) : _update(false) {} bool JfrEventThrottler::create() { + assert(_disabled_cpu_time_sample_throttler == nullptr, "invariant"); + _disabled_cpu_time_sample_throttler = new JfrEventThrottler(JfrCPUTimeSampleEvent); + _disabled_cpu_time_sample_throttler->_disabled = true; assert(_object_allocation_throttler == nullptr, "invariant"); _object_allocation_throttler = new JfrEventThrottler(JfrObjectAllocationSampleEvent); if (_object_allocation_throttler == nullptr || !_object_allocation_throttler->initialize()) { @@ -59,6 +63,8 @@ bool JfrEventThrottler::create() { } void JfrEventThrottler::destroy() { + delete _disabled_cpu_time_sample_throttler; + _disabled_cpu_time_sample_throttler = nullptr; delete _object_allocation_throttler; _object_allocation_throttler = nullptr; delete _safepoint_latency_throttler; @@ -69,15 +75,19 @@ void JfrEventThrottler::destroy() { // and another for the SamplingLatency event. // When introducing many more throttlers, consider adding a lookup map keyed by event id. JfrEventThrottler* JfrEventThrottler::for_event(JfrEventId event_id) { + assert(_disabled_cpu_time_sample_throttler != nullptr, "Disabled CPU time throttler has not been properly initialized"); assert(_object_allocation_throttler != nullptr, "ObjectAllocation throttler has not been properly initialized"); assert(_safepoint_latency_throttler != nullptr, "SafepointLatency throttler has not been properly initialized"); - assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent, "Event type has an unconfigured throttler"); + assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent || event_id == JfrCPUTimeSampleEvent, "Event type has an unconfigured throttler"); if (event_id == JfrObjectAllocationSampleEvent) { return _object_allocation_throttler; } if (event_id == JfrSafepointLatencyEvent) { return _safepoint_latency_throttler; } + if (event_id == JfrCPUTimeSampleEvent) { + return _disabled_cpu_time_sample_throttler; + } return nullptr; } diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp index 503aa85e02f..4b805a98a32 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp @@ -26,6 +26,7 @@ #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" #include "jfr/periodic/jfrThreadCPULoadEvent.hpp" +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" #include "jfr/recorder/checkpoint/types/traceid/jfrOopTraceId.inline.hpp" #include "jfr/recorder/jfrRecorder.hpp" @@ -78,7 +79,15 @@ JfrThreadLocal::JfrThreadLocal() : _enqueued_requests(false), _vthread(false), _notified(false), - _dead(false) { + _dead(false) +#ifdef LINUX + ,_cpu_timer(nullptr), + _cpu_time_jfr_locked(UNLOCKED), + _has_cpu_time_jfr_requests(false), + _cpu_time_jfr_queue(0), + _do_async_processing_of_cpu_time_jfr_requests(false) +#endif + { Thread* thread = Thread::current_or_null(); _parent_trace_id = thread != nullptr ? jvm_thread_id(thread) : (traceid)0; } @@ -129,7 +138,9 @@ void JfrThreadLocal::on_start(Thread* t) { if (JfrRecorder::is_recording()) { JfrCheckpointManager::write_checkpoint(t); if (t->is_Java_thread()) { - send_java_thread_start_event(JavaThread::cast(t)); + JavaThread *const jt = JavaThread::cast(t); + JfrCPUTimeThreadSampling::on_javathread_create(jt); + send_java_thread_start_event(jt); } } if (t->jfr_thread_local()->has_cached_stack_trace()) { @@ -221,6 +232,7 @@ void JfrThreadLocal::on_exit(Thread* t) { if (t->is_Java_thread()) { JavaThread* const jt = JavaThread::cast(t); send_java_thread_end_event(jt, JfrThreadLocal::jvm_thread_id(jt)); + JfrCPUTimeThreadSampling::on_javathread_terminate(jt); JfrThreadCPULoadEvent::send_event_for_thread(jt); } release(tl, Thread::current()); // because it could be that Thread::current() != t @@ -537,3 +549,85 @@ Arena* JfrThreadLocal::dcmd_arena(JavaThread* jt) { tl->_dcmd_arena = arena; return arena; } + + +#ifdef LINUX + +void JfrThreadLocal::set_cpu_timer(timer_t* timer) { + if (_cpu_timer == nullptr) { + _cpu_timer = JfrCHeapObj::new_array(1); + } + *_cpu_timer = *timer; +} + +void JfrThreadLocal::unset_cpu_timer() { + if (_cpu_timer != nullptr) { + timer_delete(*_cpu_timer); + JfrCHeapObj::free(_cpu_timer, sizeof(timer_t)); + _cpu_timer = nullptr; + } +} + +timer_t* JfrThreadLocal::cpu_timer() const { + return _cpu_timer; +} + +bool JfrThreadLocal::is_cpu_time_jfr_enqueue_locked() { + return Atomic::load_acquire(&_cpu_time_jfr_locked) == ENQUEUE; +} + +bool JfrThreadLocal::is_cpu_time_jfr_dequeue_locked() { + return Atomic::load_acquire(&_cpu_time_jfr_locked) == DEQUEUE; +} + +bool JfrThreadLocal::try_acquire_cpu_time_jfr_enqueue_lock() { + return Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, ENQUEUE) == UNLOCKED; +} + +bool JfrThreadLocal::try_acquire_cpu_time_jfr_dequeue_lock() { + CPUTimeLockState got; + while (true) { + CPUTimeLockState got = Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE); + if (got == UNLOCKED) { + return true; // successfully locked for dequeue + } + if (got == DEQUEUE) { + return false; // already locked for dequeue + } + // else wait for the lock to be released from a signal handler + } +} + +void JfrThreadLocal::acquire_cpu_time_jfr_dequeue_lock() { + while (Atomic::cmpxchg(&_cpu_time_jfr_locked, UNLOCKED, DEQUEUE) != UNLOCKED); +} + +void JfrThreadLocal::release_cpu_time_jfr_queue_lock() { + Atomic::release_store(&_cpu_time_jfr_locked, UNLOCKED); +} + +void JfrThreadLocal::set_has_cpu_time_jfr_requests(bool has_requests) { + Atomic::release_store(&_has_cpu_time_jfr_requests, has_requests); +} + +bool JfrThreadLocal::has_cpu_time_jfr_requests() { + return Atomic::load_acquire(&_has_cpu_time_jfr_requests); +} + +JfrCPUTimeTraceQueue& JfrThreadLocal::cpu_time_jfr_queue() { + return _cpu_time_jfr_queue; +} + +void JfrThreadLocal::deallocate_cpu_time_jfr_queue() { + cpu_time_jfr_queue().resize(0); +} + +void JfrThreadLocal::set_do_async_processing_of_cpu_time_jfr_requests(bool wants) { + Atomic::release_store(&_do_async_processing_of_cpu_time_jfr_requests, wants); +} + +bool JfrThreadLocal::wants_async_processing_of_cpu_time_jfr_requests() { + return Atomic::load_acquire(&_do_async_processing_of_cpu_time_jfr_requests); +} + +#endif diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp index 8e545d9c429..715a2c44f93 100644 --- a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp +++ b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp @@ -33,6 +33,10 @@ #include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" +#ifdef LINUX +#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp" +#endif + class Arena; class JavaThread; class JfrBuffer; @@ -79,6 +83,22 @@ class JfrThreadLocal { bool _dead; bool _sampling_critical_section; +#ifdef LINUX + timer_t* _cpu_timer; + + enum CPUTimeLockState { + UNLOCKED, + // locked for enqueuing + ENQUEUE, + // locked for dequeuing + DEQUEUE + }; + volatile CPUTimeLockState _cpu_time_jfr_locked; + volatile bool _has_cpu_time_jfr_requests; + JfrCPUTimeTraceQueue _cpu_time_jfr_queue; + volatile bool _do_async_processing_of_cpu_time_jfr_requests; +#endif + JfrBuffer* install_native_buffer() const; JfrBuffer* install_java_buffer() const; void release(Thread* t); @@ -342,6 +362,39 @@ class JfrThreadLocal { void set_thread_blob(const JfrBlobHandle& handle); const JfrBlobHandle& thread_blob() const; + // CPU time sampling +#ifdef LINUX + void set_cpu_timer(timer_t* timer); + void unset_cpu_timer(); + timer_t* cpu_timer() const; + + // The CPU time JFR lock has three different states: + // - ENQUEUE: lock for enqueuing CPU time requests + // - DEQUEUE: lock for dequeuing CPU time requests + // - UNLOCKED: no lock held + // This ensures that we can safely enqueue and dequeue CPU time requests, + // without interleaving + + bool is_cpu_time_jfr_enqueue_locked(); + bool is_cpu_time_jfr_dequeue_locked(); + + bool try_acquire_cpu_time_jfr_enqueue_lock(); + bool try_acquire_cpu_time_jfr_dequeue_lock(); + void acquire_cpu_time_jfr_dequeue_lock(); + void release_cpu_time_jfr_queue_lock(); + + void set_has_cpu_time_jfr_requests(bool has_events); + bool has_cpu_time_jfr_requests(); + + JfrCPUTimeTraceQueue& cpu_time_jfr_queue(); + void deallocate_cpu_time_jfr_queue(); + + void set_do_async_processing_of_cpu_time_jfr_requests(bool wants); + bool wants_async_processing_of_cpu_time_jfr_requests(); +#else + bool has_cpu_time_jfr_requests() { return false; } +#endif + // Hooks static void on_start(Thread* t); static void on_exit(Thread* t); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index f3a06d5efd2..772ef7bbe82 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -78,6 +78,7 @@ class JavaThread; // - WorkerThread // - WatcherThread // - JfrThreadSampler +// - JfrCPUSamplerThread // - LogAsyncWriter // // All Thread subclasses must be either JavaThread or NonJavaThread. diff --git a/src/hotspot/share/runtime/vmOperation.hpp b/src/hotspot/share/runtime/vmOperation.hpp index 50d85944485..ac5d37381f9 100644 --- a/src/hotspot/share/runtime/vmOperation.hpp +++ b/src/hotspot/share/runtime/vmOperation.hpp @@ -115,6 +115,8 @@ template(JFROldObject) \ template(JvmtiPostObjectFree) \ template(RendezvousGCThreads) \ + template(JFRInitializeCPUTimeSampler) \ + template(JFRTerminateCPUTimeSampler) \ template(ReinitializeMDO) class Thread; diff --git a/src/hotspot/share/utilities/ticks.hpp b/src/hotspot/share/utilities/ticks.hpp index 8d2bbc7ce1f..88dc9a787f9 100644 --- a/src/hotspot/share/utilities/ticks.hpp +++ b/src/hotspot/share/utilities/ticks.hpp @@ -236,6 +236,7 @@ class TimeInstant : public Rep { friend class TimePartitionsTest; friend class GCTimerTest; friend class CompilerEvent; + friend class JfrCPUSamplerThread; }; #if INCLUDE_JFR diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index f43e45b724e..2ea4725abc8 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -51,6 +51,7 @@ import jdk.jfr.internal.settings.EnabledSetting; import jdk.jfr.internal.settings.LevelSetting; import jdk.jfr.internal.settings.MethodSetting; import jdk.jfr.internal.settings.PeriodSetting; +import jdk.jfr.internal.settings.CPUThrottleSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; import jdk.jfr.internal.settings.ThrottleSetting; @@ -326,6 +327,9 @@ public final class EventControl { private static Control defineThrottle(PlatformEventType type) { String def = type.getAnnotationValue(Throttle.class, ThrottleSetting.DEFAULT_VALUE); type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THROTTLE, Throttle.NAME, def, Collections.emptyList())); + if (type.getName().equals("jdk.CPUTimeSample")) { + return new Control(new CPUThrottleSetting(type), def); + } return new Control(new ThrottleSetting(type, def), def); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index e0eaef74b4c..b91f0c337b2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -270,6 +270,16 @@ public final class JVM { */ public static native void setMethodSamplingPeriod(long type, long periodMillis); + /** + * Set the maximum event emission rate for the CPU time sampler + * + * Setting rate to 0 turns off the CPU time sampler. + * + * @param rate the new rate in events per second + * @param autoAdapt true if the rate should be adapted automatically + */ + public static native void setCPUThrottle(double rate, boolean autoAdapt); + /** * Sets the file where data should be written. * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java index 32b59bca4c0..b65a26f3aad 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java @@ -30,8 +30,10 @@ import java.util.List; import java.util.Objects; import jdk.jfr.SettingDescriptor; +import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.ImplicitFields; +import jdk.jfr.internal.util.TimespanRate; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.tracing.Modification; @@ -45,6 +47,7 @@ public final class PlatformEventType extends Type { private final boolean isJVM; private final boolean isJDK; private final boolean isMethodSampling; + private final boolean isCPUTimeMethodSampling; private final List settings = new ArrayList<>(5); private final boolean dynamicSettings; private final int stackTraceOffset; @@ -56,6 +59,7 @@ public final class PlatformEventType extends Type { private boolean stackTraceEnabled = true; private long thresholdTicks = 0; private long period = 0; + private TimespanRate cpuRate; private boolean hasHook; private boolean beginChunk; @@ -75,6 +79,7 @@ public final class PlatformEventType extends Type { this.dynamicSettings = dynamicSettings; this.isJVM = Type.isDefinedByJVM(id); this.isMethodSampling = determineMethodSampling(); + this.isCPUTimeMethodSampling = isJVM && name.equals(Type.EVENT_NAME_PREFIX + "CPUTimeSample"); this.isJDK = isJDK; this.stackTraceOffset = determineStackTraceOffset(); } @@ -191,6 +196,15 @@ public final class PlatformEventType extends Type { } } + public void setCPUThrottle(TimespanRate rate) { + if (isCPUTimeMethodSampling) { + this.cpuRate = rate; + if (isEnabled()) { + JVM.setCPUThrottle(rate.rate(), rate.autoAdapt()); + } + } + } + public void setHasPeriod(boolean hasPeriod) { this.hasPeriod = hasPeriod; } @@ -251,6 +265,9 @@ public final class PlatformEventType extends Type { if (isMethodSampling) { long p = enabled ? period : 0; JVM.setMethodSamplingPeriod(getId(), p); + } else if (isCPUTimeMethodSampling) { + TimespanRate r = enabled ? cpuRate : new TimespanRate(0, false); + JVM.setCPUThrottle(r.rate(), r.autoAdapt()); } else { JVM.setEnabled(getId(), enabled); } @@ -388,6 +405,10 @@ public final class PlatformEventType extends Type { return isMethodSampling; } + public boolean isCPUTimeMethodSampling() { + return isCPUTimeMethodSampling; + } + public void setStackFilterId(long id) { startFilterId = id; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini index a6192db1ab0..a2ac74142f4 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini @@ -39,7 +39,8 @@ label = "Active Settings" table = "COLUMN 'Event Type', 'Enabled', 'Threshold', 'Stack Trace','Period','Cutoff', 'Throttle' FORMAT none, missing:whitespace, missing:whitespace, missing:whitespace, - missing:whitespace, missing:whitespace, missing:whitespace + missing:whitespace, missing:whitespace, missing:whitespace, + missing:whitespace SELECT E.id, LAST_BATCH(E.value), LAST_BATCH(T.value), LAST_BATCH(S.value), LAST_BATCH(P.value), LAST_BATCH(C.value), LAST_BATCH(U.value) @@ -400,6 +401,28 @@ table = "COLUMN 'Method', 'Samples', 'Percent' SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) FROM ExecutionSample GROUP BY T LIMIT 25" +[application.cpu-time-hot-methods] +label = "Java Methods that Execute the Most from CPU Time Sampler" +table = "COLUMN 'Method', 'Samples', 'Percent' + FORMAT none, none, normalized + SELECT stackTrace.topFrame AS T, COUNT(*), COUNT(*) + FROM CPUTimeSample GROUP BY T LIMIT 25" + +[application.cpu-time-statistics] +label = "CPU Time Sample Statistics" +form = "COLUMN 'Successful Samples', 'Failed Samples', 'Biased Samples', 'Total Samples', 'Lost Samples' + SELECT COUNT(S.startTime), COUNT(F.startTime), COUNT(B.startTime), Count(A.startTime), SUM(L.lostSamples) + FROM + CPUTimeSample AS S, + CPUTimeSample AS F, + CPUTimeSample AS A, + CPUTimeSample AS B, + CPUTimeSamplesLost AS L + WHERE + S.failed = 'false' AND + F.failed = 'true' AND + B.biased = 'true'" + [jvm.jdk-agents] label = "JDK Agents" table = "COLUMN 'Time', 'Initialization', 'Name', 'Options' diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java new file mode 100644 index 00000000000..c18aeef2132 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/CPUThrottleSetting.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Datadog, Inc. All rights reserved. + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.internal.settings; + +import static jdk.jfr.internal.util.TimespanUnit.SECONDS; +import static jdk.jfr.internal.util.TimespanUnit.MILLISECONDS; + +import java.util.Objects; +import java.util.Set; + +import jdk.jfr.Description; +import jdk.jfr.SettingControl; +import jdk.jfr.Label; +import jdk.jfr.MetadataDefinition; +import jdk.jfr.Name; +import jdk.jfr.internal.PlatformEventType; +import jdk.jfr.internal.Type; +import jdk.jfr.internal.util.TimespanRate; +import jdk.jfr.internal.util.Utils; + +@MetadataDefinition +@Label("CPUThrottleSetting") +@Description("Upper bounds the emission rate for CPU time samples") +@Name(Type.SETTINGS_PREFIX + "Rate") +public final class CPUThrottleSetting extends SettingControl { + public static final String DEFAULT_VALUE = "0/s"; + private final PlatformEventType eventType; + private String value = DEFAULT_VALUE; + + public CPUThrottleSetting(PlatformEventType eventType) { + this.eventType = Objects.requireNonNull(eventType); + } + + @Override + public String combine(Set values) { + TimespanRate max = null; + for (String value : values) { + TimespanRate rate = TimespanRate.of(value); + if (rate != null) { + if (max == null || rate.isHigher(max)) { + max = rate; + } + max = new TimespanRate(max.rate(), max.autoAdapt() || rate.autoAdapt()); + } + } + // "off" is not supported + return Objects.requireNonNullElse(max.toString(), DEFAULT_VALUE); + } + + @Override + public void setValue(String value) { + TimespanRate rate = TimespanRate.of(value); + if (rate != null) { + eventType.setCPUThrottle(rate); + this.value = value; + } + } + + @Override + public String getValue() { + return value; + } +} + diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java index f32436a5e0f..2632cd63848 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Rate.java @@ -55,4 +55,8 @@ public record Rate(long amount, TimespanUnit unit) { private double inNanos() { return (double) amount / unit.nanos; } + + public double perSecond() { + return inNanos() * 1_000_000_000.0; + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java new file mode 100644 index 00000000000..5d671310e3c --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanRate.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 SAP SE. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.util; + +import jdk.jfr.internal.settings.CPUThrottleSetting; + +/** + * A rate or fixed period, see {@link jdk.jfr.internal.Rate} + */ +public record TimespanRate(double rate, boolean autoAdapt) { + + public static TimespanRate of(String text) { + if (text.equals("off")) { + text = CPUThrottleSetting.DEFAULT_VALUE; + } + boolean isPeriod = !text.contains("/"); + if (isPeriod) { + var period = ValueParser.parseTimespanWithInfinity(text, Long.MAX_VALUE); + if (period == Long.MAX_VALUE) { + return null; + } + if (period == 0) { + return new TimespanRate(0, false); + } + return new TimespanRate(Runtime.getRuntime().availableProcessors() / (period / 1_000_000_000.0), false); + } + Rate r = Rate.of(text); + if (r == null) { + return null; + } + return new TimespanRate(r.perSecond(), true); + } + + public boolean isHigher(TimespanRate that) { + return rate() > that.rate(); + } + + @Override + public String toString() { + if (autoAdapt) { + return String.format("%d/ns", (long)(rate * 1_000_000_000L)); + } + return String.format("%dns", (long)(Runtime.getRuntime().availableProcessors() / rate * 1_000_000_000L)); + } +} diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 293af26746f..541d1d3aa2f 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -226,6 +226,16 @@ off + + false + 500/s + true + + + + true + + true 10 ms diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 89a9022d11e..9cec2d9a70f 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -206,6 +206,16 @@ 20 ms + + false + 10ms + true + + + + true + + true diff --git a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java index 5b8aacfb1d2..d6e126a493f 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java +++ b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java @@ -89,7 +89,10 @@ public class TestLookForUntestedEvents { // Experimental events private static final Set experimentalEvents = Set.of( - "Flush", "SyncOnValueBasedClass"); + "Flush", "SyncOnValueBasedClass", "CPUTimeSample", "CPUTimeSamplesLost"); + + // Subset of the experimental events that should have tests + private static final Set experimentalButTestedEvents = Set.of("CPUTimeSample"); public static void main(String[] args) throws Exception { for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { @@ -110,7 +113,9 @@ public class TestLookForUntestedEvents { .collect(Collectors.toList()); Set eventsNotCoveredByTest = new HashSet<>(jfrEventTypes); - for (String event : jfrEventTypes) { + Set checkedEvents = new HashSet<>(jfrEventTypes); + checkedEvents.addAll(experimentalButTestedEvents); + for (String event : checkedEvents) { for (Path p : paths) { if (findStringInFile(p, event)) { eventsNotCoveredByTest.remove(event); diff --git a/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java new file mode 100644 index 00000000000..de211b8c454 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/BaseTestFullStackTrace.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordedFrame; +import jdk.jfr.consumer.RecordedStackTrace; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.RecurseThread; + +public class BaseTestFullStackTrace { + private final static int MAX_DEPTH = 64; // currently hardcoded in jvm + + private final String eventName; + private final String threadFieldName; + + public BaseTestFullStackTrace(String eventName, String threadFieldName) { + this.eventName = eventName; + this.threadFieldName = threadFieldName; + } + + public void run() throws Throwable { + RecurseThread[] threads = new RecurseThread[3]; + for (int i = 0; i < threads.length; ++i) { + int depth = MAX_DEPTH - 1 + i; + threads[i] = new RecurseThread(depth); + threads[i].setName("recursethread-" + depth); + threads[i].start(); + } + + for (RecurseThread thread : threads) { + while (!thread.isInRunLoop()) { + Thread.sleep(20); + } + } + + assertStackTraces(threads); + + for (RecurseThread thread : threads) { + thread.quit(); + thread.join(); + } + } + + private void assertStackTraces(RecurseThread[] threads) throws Throwable { + while (true) { + try (Recording recording = new Recording()) { + if (eventName.equals(EventNames.CPUTimeSample)) { + recording.enable(eventName).with("throttle", "50ms"); + } else { + recording.enable(eventName).withPeriod(Duration.ofMillis(50)); + } + recording.start(); + Thread.sleep(500); + recording.stop(); + if (hasValidStackTraces(recording, threads)) { + break; + } + } + }; + } + + private boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { + boolean[] isEventFound = new boolean[threads.length]; + + for (RecordedEvent event : Events.fromRecording(recording)) { + System.out.println("Event: " + event); + String threadName = Events.assertField(event, threadFieldName + ".javaName").getValue(); + long threadId = Events.assertField(event, threadFieldName + ".javaThreadId").getValue(); + + for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { + RecurseThread currThread = threads[threadIndex]; + if (threadId == currThread.getId()) { + System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); + Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); + if ("recurseEnd".equals(getTopMethodName(event))) { + isEventFound[threadIndex] = true; + checkEvent(event, currThread.totalDepth); + break; + } + } + } + } + + for (int i = 0; i < threads.length; ++i) { + String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; + System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); + } + for (int i = 0; i < threads.length; ++i) { + if(!isEventFound[i]) { + // no assertion, let's retry. + // Could be race condition, i.e safe point during Thread.sleep + System.out.println("Failed to validate all threads, will retry."); + return false; + } + } + return true; + } + + public String getTopMethodName(RecordedEvent event) { + List frames = event.getStackTrace().getFrames(); + Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); + return frames.getFirst().getMethod().getName(); + } + + private void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { + RecordedStackTrace stacktrace = null; + try { + stacktrace = event.getStackTrace(); + List frames = stacktrace.getFrames(); + Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); + List expectedMethods = getExpectedMethods(expectedDepth); + Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); + + for (int i = 0; i < frames.size(); ++i) { + String name = frames.get(i).getMethod().getName(); + String expectedName = expectedMethods.get(i); + System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); + Asserts.assertEquals(name, expectedName, "Wrong method name"); + } + + boolean isTruncated = stacktrace.isTruncated(); + boolean isTruncateExpected = expectedDepth > MAX_DEPTH; + Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); + + String firstMethod = frames.getLast().getMethod().getName(); + boolean isFullTrace = "run".equals(firstMethod); + String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); + Asserts.assertTrue(isTruncated != isFullTrace, msg); + } catch (Throwable t) { + System.out.println(String.format("stacktrace:%n%s", stacktrace)); + throw t; + } + } + + private List getExpectedMethods(int depth) { + List methods = new ArrayList<>(); + methods.add("recurseEnd"); + for (int i = 0; i < depth - 2; ++i) { + methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); + } + methods.add("run"); + if (depth > MAX_DEPTH) { + methods = methods.subList(0, MAX_DEPTH); + } + return methods; + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java new file mode 100644 index 00000000000..eb8d33832b5 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeAndExecutionSample.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.RecurseThread; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main/timeout=30 jdk.jfr.event.profiling.TestCPUTimeAndExecutionSample + */ +public class TestCPUTimeAndExecutionSample { + + static String sampleEvent = EventNames.CPUTimeSample; + + // The period is set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). + public static void main(String[] args) throws Exception { + run(EventNames.ExecutionSample); + run(EventNames.CPUTimeSample); + run(EventNames.ExecutionSample); + run(EventNames.CPUTimeSample); + } + + private static void run(String eventType) { + RecurseThread t = new RecurseThread(50); + t.setDaemon(true); + try (RecordingStream rs = new RecordingStream()) { + rs.enable(sampleEvent).with("throttle", "1000/s"); + rs.onEvent(sampleEvent, e -> { + t.quit(); + rs.close(); + }); + t.start(); + rs.start(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java new file mode 100644 index 00000000000..0d1108346ab --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleFullStackTrace.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import jdk.test.lib.jfr.EventNames; + +/** + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @build jdk.jfr.event.profiling.BaseTestFullStackTrace + * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleFullStackTrace + */ +public class TestCPUTimeSampleFullStackTrace { + + public static void main(String[] args) throws Throwable { + new BaseTestFullStackTrace(EventNames.CPUTimeSample, "eventThread").run(); + } + +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java new file mode 100644 index 00000000000..133df36684c --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleMultipleRecordings.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordingStream; +import jdk.jfr.internal.JVM; +import jdk.test.lib.jfr.EventNames; + +/* + * Tests that creating multiple recordings after another is possible. + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSampleMultipleRecordings + */ +public class TestCPUTimeSampleMultipleRecordings { + + static String nativeEvent = EventNames.CPUTimeSample; + + static volatile boolean alive = true; + + public static void main(String[] args) throws Exception { + Thread t = new Thread(TestCPUTimeSampleMultipleRecordings::nativeMethod); + t.setDaemon(true); + t.start(); + for (int i = 0; i < 2; i++) { + try (RecordingStream rs = new RecordingStream()) { + rs.enable(nativeEvent).with("throttle", "1ms"); + rs.onEvent(nativeEvent, e -> { + alive = false; + rs.close(); + }); + + rs.start(); + } + } + alive = false; + } + + public static void nativeMethod() { + while (alive) { + JVM.getPid(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java new file mode 100644 index 00000000000..1617bce4ba3 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleNative.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordingStream; +import jdk.jfr.internal.JVM; +import jdk.test.lib.jfr.EventNames; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSampleNative + */ +public class TestCPUTimeSampleNative { + + static String nativeEvent = EventNames.CPUTimeSample; + + static volatile boolean alive = true; + + public static void main(String[] args) throws Exception { + try (RecordingStream rs = new RecordingStream()) { + rs.enable(nativeEvent).with("throttle", "1ms"); + rs.onEvent(nativeEvent, e -> { + alive = false; + rs.close(); + }); + Thread t = new Thread(TestCPUTimeSampleNative::nativeMethod); + t.setDaemon(true); + t.start(); + rs.start(); + } + + } + + public static void nativeMethod() { + while (alive) { + JVM.getPid(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java new file mode 100644 index 00000000000..55b350ad096 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSampleThrottling.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; +import java.lang.management.ManagementFactory; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Comparator; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; + +/** + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @run main/othervm jdk.jfr.event.profiling.TestCPUTimeSampleThrottling + */ +public class TestCPUTimeSampleThrottling { + + public static void main(String[] args) throws Exception { + testZeroPerSecond(); + testThrottleSettings(); + testThrottleSettingsPeriod(); + } + + private static void testZeroPerSecond() throws Exception { + Asserts.assertTrue(0L == countEvents(1000, "0/s").count()); + } + + private static void testThrottleSettings() throws Exception { + long count = countEvents(1000, + Runtime.getRuntime().availableProcessors() * 2 + "/s").count(); + Asserts.assertTrue(count > 0 && count < 3, + "Expected between 0 and 3 events, got " + count); + } + + private static void testThrottleSettingsPeriod() throws Exception { + float rate = countEvents(1000, "10ms").rate(); + Asserts.assertTrue(rate > 90 && rate < 110, "Expected around 100 events per second, got " + rate); + } + + private record EventCount(long count, float time) { + float rate() { + return count / time; + } + } + + private static EventCount countEvents(int timeMs, String rate) throws Exception { + try(Recording recording = new Recording()) { + recording.enable(EventNames.CPUTimeSample) + .with("throttle", rate); + + var bean = ManagementFactory.getThreadMXBean(); + + recording.start(); + + long startThreadCpuTime = bean.getCurrentThreadCpuTime(); + + wasteCPU(timeMs); + + long spendCPUTime = bean.getCurrentThreadCpuTime() - startThreadCpuTime; + + recording.stop(); + + long eventCount = Events.fromRecording(recording).stream() + .filter(e -> e.getThread().getJavaName() + .equals(Thread.currentThread().getName())) + .count(); + + System.out.println("Event count: " + eventCount + ", CPU time: " + spendCPUTime / 1_000_000_000f + "s"); + + return new EventCount(eventCount, spendCPUTime / 1_000_000_000f); + } + } + + private static void wasteCPU(int durationMs) { + long start = System.currentTimeMillis(); + double i = 0; + while (System.currentTimeMillis() - start < durationMs) { + for (int j = 0; j < 100000; j++) { + i = Math.sqrt(i * Math.pow(Math.sqrt(Math.random()), Math.random())); + } + } + } + +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java new file mode 100644 index 00000000000..69d32d48282 --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/TestCPUTimeSamplingLongPeriod.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.profiling; + +import java.time.Duration; + +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.RecurseThread; + +/* + * @test + * @requires vm.hasJFR & os.family == "linux" + * @library /test/lib + * @modules jdk.jfr/jdk.jfr.internal + * @run main jdk.jfr.event.profiling.TestCPUTimeSamplingLongPeriod + */ +public class TestCPUTimeSamplingLongPeriod { + + static String sampleEvent = EventNames.CPUTimeSample; + + // The period is set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). + public static void main(String[] args) throws Exception { + RecurseThread t = new RecurseThread(50); + t.setDaemon(true); + try (RecordingStream rs = new RecordingStream()) { + rs.enable(sampleEvent).with("throttle", "1100ms"); + rs.onEvent(sampleEvent, e -> { + t.quit(); + rs.close(); + }); + t.start(); + rs.start(); + } + } +} diff --git a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java index b06f9eed03d..c337a8128ab 100644 --- a/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java +++ b/test/jdk/jdk/jfr/event/profiling/TestFullStackTrace.java @@ -23,147 +23,20 @@ package jdk.jfr.event.profiling; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; -import jdk.jfr.consumer.RecordedFrame; -import jdk.jfr.consumer.RecordedStackTrace; -import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; -import jdk.test.lib.jfr.Events; -import jdk.test.lib.jfr.RecurseThread; /** * @test * @requires vm.hasJFR * @requires vm.opt.DeoptimizeALot != true * @library /test/lib + * @build jdk.jfr.event.profiling.BaseTestFullStackTrace * @run main/othervm jdk.jfr.event.profiling.TestFullStackTrace */ public class TestFullStackTrace { - private final static String EVENT_NAME = EventNames.ExecutionSample; - private final static int MAX_DEPTH = 64; // currently hardcoded in jvm public static void main(String[] args) throws Throwable { - RecurseThread[] threads = new RecurseThread[3]; - for (int i = 0; i < threads.length; ++i) { - int depth = MAX_DEPTH - 1 + i; - threads[i] = new RecurseThread(depth); - threads[i].setName("recursethread-" + depth); - threads[i].start(); - } - - for (RecurseThread thread : threads) { - while (!thread.isInRunLoop()) { - Thread.sleep(20); - } - } - - assertStackTraces(threads); - - for (RecurseThread thread : threads) { - thread.quit(); - thread.join(); - } + new BaseTestFullStackTrace(EventNames.ExecutionSample, "sampledThread").run(); } - private static void assertStackTraces( RecurseThread[] threads) throws Throwable { - Recording recording= null; - do { - recording = new Recording(); - recording.enable(EVENT_NAME).withPeriod(Duration.ofMillis(50)); - recording.start(); - Thread.sleep(500); - recording.stop(); - } while (!hasValidStackTraces(recording, threads)); - } - - private static boolean hasValidStackTraces(Recording recording, RecurseThread[] threads) throws Throwable { - boolean[] isEventFound = new boolean[threads.length]; - - for (RecordedEvent event : Events.fromRecording(recording)) { - //System.out.println("Event: " + event); - String threadName = Events.assertField(event, "sampledThread.javaName").getValue(); - long threadId = Events.assertField(event, "sampledThread.javaThreadId").getValue(); - - for (int threadIndex = 0; threadIndex < threads.length; ++threadIndex) { - RecurseThread currThread = threads[threadIndex]; - if (threadId == currThread.getId()) { - System.out.println("ThreadName=" + currThread.getName() + ", depth=" + currThread.totalDepth); - Asserts.assertEquals(threadName, currThread.getName(), "Wrong thread name"); - if ("recurseEnd".equals(getTopMethodName(event))) { - isEventFound[threadIndex] = true; - checkEvent(event, currThread.totalDepth); - break; - } - } - } - } - - for (int i = 0; i < threads.length; ++i) { - String msg = "threadIndex=%d, recurseDepth=%d, isEventFound=%b%n"; - System.out.printf(msg, i, threads[i].totalDepth, isEventFound[i]); - } - for (int i = 0; i < threads.length; ++i) { - if(!isEventFound[i]) { - // no assertion, let's retry. - // Could be race condition, i.e safe point during Thread.sleep - System.out.println("Failed to validate all threads, will retry."); - return false; - } - } - return true; - } - - public static String getTopMethodName(RecordedEvent event) { - List frames = event.getStackTrace().getFrames(); - Asserts.assertFalse(frames.isEmpty(), "JavaFrames was empty"); - return frames.getFirst().getMethod().getName(); - } - - private static void checkEvent(RecordedEvent event, int expectedDepth) throws Throwable { - RecordedStackTrace stacktrace = null; - try { - stacktrace = event.getStackTrace(); - List frames = stacktrace.getFrames(); - Asserts.assertEquals(Math.min(MAX_DEPTH, expectedDepth), frames.size(), "Wrong stacktrace depth. Expected:" + expectedDepth); - List expectedMethods = getExpectedMethods(expectedDepth); - Asserts.assertEquals(expectedMethods.size(), frames.size(), "Wrong expectedMethods depth. Test error."); - - for (int i = 0; i < frames.size(); ++i) { - String name = frames.get(i).getMethod().getName(); - String expectedName = expectedMethods.get(i); - System.out.printf("method[%d]=%s, expected=%s%n", i, name, expectedName); - Asserts.assertEquals(name, expectedName, "Wrong method name"); - } - - boolean isTruncated = stacktrace.isTruncated(); - boolean isTruncateExpected = expectedDepth > MAX_DEPTH; - Asserts.assertEquals(isTruncated, isTruncateExpected, "Wrong value for isTruncated. Expected:" + isTruncateExpected); - - String firstMethod = frames.getLast().getMethod().getName(); - boolean isFullTrace = "run".equals(firstMethod); - String msg = String.format("Wrong values for isTruncated=%b, isFullTrace=%b", isTruncated, isFullTrace); - Asserts.assertTrue(isTruncated != isFullTrace, msg); - } catch (Throwable t) { - System.out.println(String.format("stacktrace:%n%s", stacktrace)); - throw t; - } - } - - private static List getExpectedMethods(int depth) { - List methods = new ArrayList<>(); - methods.add("recurseEnd"); - for (int i = 0; i < depth - 2; ++i) { - methods.add((i % 2) == 0 ? "recurseA" : "recurseB"); - } - methods.add("run"); - if (depth > MAX_DEPTH) { - methods = methods.subList(0, MAX_DEPTH); - } - return methods; - } } diff --git a/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java b/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java new file mode 100644 index 00000000000..8dc77fd38da --- /dev/null +++ b/test/jdk/jdk/jfr/event/profiling/classes/test/RecursiveMethods.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + package test; + + import java.time.Duration; + + /* + * A class used to create a simple deep call stack for testing purposes + */ + public class RecursiveMethods { + + /** Method that uses recursion to produce a call stack of at least {@code depth} depth */ + public static int entry(int depth) { + return method2(--depth); + } + + private static int method2(int depth) { + return method3(--depth); + } + + private static int method3(int depth) { + return method4(--depth); + } + + private static int method4(int depth) { + return method5(--depth); + } + + private static int method5(int depth) { + return method6(--depth); + } + + private static int method6(int depth) { + return method7(--depth); + } + + private static int method7(int depth) { + return method8(--depth); + } + + private static int method8(int depth) { + return method9(--depth); + } + + private static int method9(int depth) { + return method10(--depth); + } + + private static int method10(int depth) { + if (depth > 0) { + return entry(--depth); + } + return depth; + } +} diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 904abe8e3e2..a00898358a8 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -77,6 +77,8 @@ public class EventNames { public static final String ThreadAllocationStatistics = PREFIX + "ThreadAllocationStatistics"; public static final String ExecutionSample = PREFIX + "ExecutionSample"; public static final String NativeMethodSample = PREFIX + "NativeMethodSample"; + public static final String CPUTimeSample = PREFIX + "CPUTimeSample"; + public static final String CPUTimeSamplesLost = PREFIX + "CPUTimeSamplesLost"; public static final String ThreadDump = PREFIX + "ThreadDump"; public static final String OldObjectSample = PREFIX + "OldObjectSample"; public static final String SymbolTableStatistics = PREFIX + "SymbolTableStatistics"; From dc949003ded278805d10c7b630e82348a7d998fe Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 5 Jun 2025 09:02:23 +0000 Subject: [PATCH 163/216] 8358588: ThreadSnapshot.ThreadLock should be static nested class Reviewed-by: alanb, sspitsyn, amenkov --- src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java index b5607059abc..e0dd4bbc508 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java @@ -175,7 +175,7 @@ class ThreadSnapshot { /** * Represents a locking operation of a thread at a specific stack depth. */ - private class ThreadLock { + private static class ThreadLock { private static final OwnedLockType[] lockTypeValues = OwnedLockType.values(); // cache // set by the VM From 66feb490bdf670c9b101f36b2fa1d0a923c0c3df Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 5 Jun 2025 09:30:44 +0000 Subject: [PATCH 164/216] 8358543: Remove CommentChecker.java and DirDiff.java Reviewed-by: erikj --- .../tools/commentchecker/CommentChecker.java | 217 -------------- .../src/build/tools/dirdiff/DirDiff.java | 275 ------------------ 2 files changed, 492 deletions(-) delete mode 100644 src/utils/src/build/tools/commentchecker/CommentChecker.java delete mode 100644 src/utils/src/build/tools/dirdiff/DirDiff.java diff --git a/src/utils/src/build/tools/commentchecker/CommentChecker.java b/src/utils/src/build/tools/commentchecker/CommentChecker.java deleted file mode 100644 index 5de89e00646..00000000000 --- a/src/utils/src/build/tools/commentchecker/CommentChecker.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package build.tools.commentchecker; - -import java.io.*; -import java.util.StringTokenizer; - -/** - * CommentChecker is a utility which verifies that there aren't - * "/*" or "/**" tokens inside any comment blocks in one or more - * Java source files. Although it is legal to have beginning - * comment delimiters inside of a comment block (JLS 3.7), there - * have been errors where a dropped end-comment delimiter in a - * method'd doc-comment effectively "erased" that method. We're - * therefore restricting beginning comment delimiters inside of - * JDK source (at least the Swing team is for their portion). - * - * To scan a few files, run CommentChecker as follows: - * - * java CommentChecker file1.java file2.java ... - * - * There are too many Java files in the JDK base for most shells - * to support listing in a single command, so CommentChecker also - * supports cpio and tar-style filename passing, where "-" - * indicates that the list of files is read from stdin: - * - * find . -name SCCS -prune -o -name '*.java' -print | \ - * java CommentChecker - - * - * @author Thomas Ball - */ -public class CommentChecker { - - static int errors = 0; - - // Turn on this flag and recompile to dump this tool's state changes. - static final boolean verbose = false; - - static void check(String fileName) { - BufferedReader in = null; - boolean inComment = false; - boolean inLineComment = false; - boolean inQuote = false; - boolean inEscape = false; - int lastChar = -1; - int lineNumber = 1; - - try { - in = new BufferedReader(new FileReader(fileName)); - while (true) { - int ch = in.read(); - if (ch == -1) { - if (inQuote || inComment) { - error(fileName + ": premature EOF."); - } - return; - } - - if (verbose) { - System.out.print((char)ch); - } - - switch (ch) { - case '\n': - if (inQuote && !inComment) { - error(fileName + ":" + lineNumber + - " dangling quote."); - inQuote = false; - } - if (inLineComment) { - inLineComment = false; - if (verbose) { - System.out.println("\ninLineComment=false"); - } - } - lineNumber++; - break; - - case '\"': - if (!inComment && !inLineComment && !inEscape && - !(!inQuote && lastChar == '\'')) { - inQuote = !inQuote; - if (verbose) { - System.out.println("\ninQuote=" + inQuote); - } - } - break; - - case '/': - if (!inQuote && lastChar == '*') { - inComment = false; - if (verbose) { - System.out.println("\ninComment=false"); - } - } - if (!inQuote && lastChar == '/') { - inLineComment = true; - if (verbose) { - System.out.println("\ninLineComment=true"); - } - } - break; - - case '*': - if (!inQuote && lastChar == '/') { - if (inComment) { - error(fileName + ":" + lineNumber + - " nested comment."); - } - inComment = true; - if (verbose) { - System.out.println("\ninComment=true"); - } - } - break; - } - - lastChar = ch; - - // Watch for escaped characters, such as '\"'. - if (ch == '\\' && !inEscape) { - inEscape = true; - if (verbose) { - System.out.println("\ninEscape set"); - } - } else { - inEscape = false; - } - } - } catch (FileNotFoundException fnfe) { - error(fileName + " not found."); - } catch (IOException ioe) { - error(fileName + ": " + ioe); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - error(fileName + ": " + e); - } - } - } - } - - static void error(String description) { - System.err.println(description); - errors++; - } - - static void exit() { - if (errors != 1) { - System.out.println("There were " + errors + " errors."); - } else { - System.out.println("There was 1 error."); - } - System.exit(errors); - } - - public static void main(String[] args) { - if (args.length == 0) { - System.err.println("usage: java CommentChecker [-] file.java ..."); - System.exit(1); - } - - if (args.length == 1 && args[0].equals("-")) { - /* read filenames in one per line from stdin, ala cpio. - * This is good for checking the whole JDK in one pass: - * - * cpio . -name SCCS -prune -o -name '*.java' -print | \ - * java CommentChecker - - */ - try { - BufferedReader br = - new BufferedReader(new InputStreamReader(System.in)); - while (true) { - String fileName = br.readLine(); - if (fileName == null) { - break; - } - check(fileName); - } - br.close(); - } catch (Exception e) { - error("error reading System.in: " + e); - } - } else { - for (int i = 0; i < args.length; i++) { - check(args[i]); - } - } - - exit(); - } -} diff --git a/src/utils/src/build/tools/dirdiff/DirDiff.java b/src/utils/src/build/tools/dirdiff/DirDiff.java deleted file mode 100644 index 149f4eba3af..00000000000 --- a/src/utils/src/build/tools/dirdiff/DirDiff.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package build.tools.dirdiff; - -import java.io.File; -import java.util.TreeSet; - -public class DirDiff implements Runnable { - private static final String FILE_SEPARATOR = System.getProperty("file.separator"); - private static final boolean traversSccsDirs; - private static final boolean recurseExtraDirs; - private static final boolean verboseMode; - private static final boolean checkSizes; - private static long SizeTolerance = 0; - private File goldenDir = null; - private File testDir = null; - - // static initializer: - static { - String traversePropertyValue = System.getProperty("sccs"); - traversSccsDirs = (traversePropertyValue != null && - traversePropertyValue.toLowerCase().equals("true"))? true : false; - if (traversSccsDirs) { - System.err.println("traversing SCCS directories..."); - } - - String verbosePropertyValue = System.getProperty("verbose"); - verboseMode = (verbosePropertyValue != null && - verbosePropertyValue.toLowerCase().equals("true"))? true : false; - if (verboseMode) { - System.err.println("verbose mode truned on..."); - } - - String noRecurseExtraDirsPropertyValue = System.getProperty("recurse"); - recurseExtraDirs = (noRecurseExtraDirsPropertyValue != null && - noRecurseExtraDirsPropertyValue.toLowerCase().equals("true"))? true : false; - if (recurseExtraDirs) { - System.err.println("recursing extra directories..."); - } - - String sizeToleranceValue = System.getProperty("sizeTolerance"); - checkSizes = (sizeToleranceValue != null); - if (checkSizes) { - try { - SizeTolerance = Long.parseLong(sizeToleranceValue); - } - catch (NumberFormatException e) { - System.err.println("Invlalid sizeTolerance value: " + sizeToleranceValue); - System.err.println("Expecting a long value. Exiting."); - System.exit(1); - } - System.err.println("checking matching files for size differences of at least " + SizeTolerance); - } - } - - public DirDiff(File inGoldenDir, File inTestDir) { - goldenDir = inGoldenDir; - testDir = inTestDir; - } - - private void whatToDoWithMatchingFiles(File goldenChild, File testChild) { - if (verboseMode) { - System.out.println("Files Match:\t" + goldenChild.getAbsolutePath() + - " and " + testChild.getAbsolutePath()); - } - if (checkSizes) { - // compare file sizes... - long goldenLength = 0; - long testLength = 0; - try { - goldenLength = goldenChild.length(); - testLength = testChild.length(); - } - catch (Exception e) { - System.err.println("Error: exception thrown and caught:"); - e.printStackTrace(); - } - if (java.lang.Math.abs(goldenLength - testLength) > SizeTolerance) { - if (goldenLength > testLength) { - System.out.println("File short [" + (testLength - goldenLength) + "]:\t" + testChild.getAbsolutePath()); - } else { - System.out.println("File long [" + (testLength - goldenLength) + "]:\t" + testChild.getAbsolutePath()); - } - } - } - } - - - private void whatToDoWithMatchingDirs(File goldenChild, File testChild) { - if (verboseMode) { - System.out.println("Dirs Match:\t" + goldenChild.getAbsolutePath() + - " and " + testChild.getAbsolutePath()); - } - } - - private void whatToDoWithMissingFiles(File missingFile) { - long length = 0; - try { - length = missingFile.length(); - } - catch (Exception e) { - System.err.println("Error: exception thrown and caught:"); - e.printStackTrace(); - } - - System.out.println("Missing File [" + length + "]:\t" + missingFile.getAbsolutePath()); - } - - private void whatToDoWithExtraFiles(File extraFile) { - long length = 0; - try { - length = extraFile.length(); - } - catch (Exception e) { - System.err.println("Error: exception thrown and caught:"); - e.printStackTrace(); - } - - System.out.println("Extra File [" + length + "]:\t" + extraFile.getAbsolutePath()); - } - - private void whatToDoWithMissingDirs(File missingDir) { - System.out.println("Missing Dir:\t" + missingDir.getAbsolutePath()); - } - - private void whatToDoWithExtraDirs(File extraDir) { - System.out.println("Extra Dir:\t" + extraDir.getAbsolutePath()); - } - - private void whatToDoWithNonMatchingChildren(File goldenChild, File testChild) { - System.out.println("Type Mismatch:\t" + goldenChild.getAbsolutePath() + " is a " + - (goldenChild.isDirectory()? "directory" : "file") + - " and " + testChild.getAbsolutePath() + " is a " + - (testChild.isDirectory()? "directory" : "file")); - } - - public void run() { - File[] currentTestDirs = null; - if (testDir != null) { - currentTestDirs = testDir.listFiles(); - } - - File[] currentGoldenDirs = null; - TreeSet goldDirSet = new TreeSet<>(); - if (goldenDir != null) { - currentGoldenDirs = goldenDir.listFiles(); - for (int i=0; i Date: Thu, 5 Jun 2025 10:14:41 +0000 Subject: [PATCH 165/216] 8357962: JFR Cooperative Sampling reveals inconsistent interpreter frames as part of JVMTI PopFrame Reviewed-by: dholmes, eosterlund --- src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp | 1 + src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp | 1 + src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 0ed064f48ba..710970d1ea2 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1893,6 +1893,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_remove_activation_preserving_args_entry = __ pc(); __ empty_expression_stack(); + __ restore_bcp(); // We could have returned from deoptimizing this frame, so restore rbcp. // Set the popframe_processing bit in pending_popframe_condition // indicating that we are currently handling popframe, so that // call_VMs that may happen later do not trigger new popframe diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index 75469ea40e9..b8de3547c83 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -1646,6 +1646,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_remove_activation_preserving_args_entry = __ pc(); __ empty_expression_stack(); + __ restore_bcp(); // We could have returned from deoptimizing this frame, so restore rbcp. // Set the popframe_processing bit in pending_popframe_condition // indicating that we are currently handling popframe, so that // call_VMs that may happen later do not trigger new popframe diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index d4691c9874c..bd061d45fbd 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1441,6 +1441,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { Interpreter::_remove_activation_preserving_args_entry = __ pc(); __ empty_expression_stack(); + __ restore_bcp(); // We could have returned from deoptimizing this frame, so restore rbcp. // Set the popframe_processing bit in pending_popframe_condition // indicating that we are currently handling popframe, so that // call_VMs that may happen later do not trigger new popframe From bd08932d5b9d1a363d8229ea72df4c6dbfd4571d Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Thu, 5 Jun 2025 10:31:23 +0000 Subject: [PATCH 166/216] 8356633: Incorrect use of {@link} in jdk.jshell Reviewed-by: rgiulietti, vyazici --- src/jdk.jshell/share/classes/jdk/jshell/Snippet.java | 4 ++-- .../share/classes/jdk/jshell/SourceCodeAnalysis.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java b/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java index 8e5971bedf8..cfbd4fe4ef5 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -524,7 +524,7 @@ public abstract class Snippet { /** * The snippet is inactive because it does not yet exist. - * Used only in {@link SnippetEvent#previousStatus} for new + * Used only in {@link SnippetEvent#previousStatus()} for new * snippets. * {@link jdk.jshell.JShell#status(jdk.jshell.Snippet) JShell.status(Snippet)} * will never return this {@code Status}. diff --git a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java index 0375a2ead65..10da664cd03 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,7 +150,7 @@ public abstract class SourceCodeAnalysis { * They will not appear in queries for snippets -- * for example, {@link JShell#snippets() }. *

        - * Restrictions on the input are as in {@link JShell#eval}. + * Restrictions on the input are as in {@link JShell#eval(String)}. *

        * Only preliminary compilation is performed, sufficient to build the * {@code Snippet}. Snippets known to be erroneous, are returned as From c5daf890534dfdbe5f66189ef6b08af8ffd4de47 Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Thu, 5 Jun 2025 11:05:52 +0000 Subject: [PATCH 167/216] 8349369: test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java did not report on missing man page files Reviewed-by: hannesw --- .../doccheck/checks/jdkCheckLinks.java | 4 +-- .../doccheck/doccheckutils/FileProcessor.java | 8 ++--- .../doccheckutils/checkers/LinkChecker.java | 30 ++++++++++--------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java index bd818923d9f..3db1cdf6cb9 100644 --- a/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java +++ b/test/docs/jdk/javadoc/doccheck/checks/jdkCheckLinks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8337109 + * @bug 8337109 8349369 * @summary Check Links in the generated documentation * @library /test/langtools/tools/lib ../../doccheck /test/lib ../../../../tools/tester * @build DocTester toolbox.TestRunner diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java index 6ae3a473bdb..2291d649c3a 100644 --- a/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/FileProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,16 +44,16 @@ public class FileProcessor { public void processFiles(Path directory) { try { - Files.walkFileTree(directory, new SimpleFileVisitor() { + Files.walkFileTree(directory, new SimpleFileVisitor<>() { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { if (file.toString().endsWith(".html")) files.add(file); return FileVisitResult.CONTINUE; } @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { return FileVisitResult.CONTINUE; } }); diff --git a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java index 62ead5a25d3..ed0098d2714 100644 --- a/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java +++ b/test/docs/jdk/javadoc/doccheck/doccheckutils/checkers/LinkChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -220,20 +220,14 @@ public class LinkChecker implements HtmlChecker { @Override public boolean isOK() { - return duplicateIds == 0 - && missingIds == 0 - && missingFiles == 0 - && badSchemes == 0; + return log.noErrors() && (missingFiles == 0); } @Override public void close() { - report(); - if (!isOK()) { - throw new RuntimeException( - "LinkChecker encountered errors. Duplicate IDs: " - + duplicateIds + ", Missing IDs: " + missingIds - + ", Missing Files: " + missingFiles + ", Bad Schemes: " + badSchemes); + if (!log.noErrors()) { + report(); + throw new RuntimeException("LinkChecker encountered errors; see log above."); } } @@ -276,6 +270,11 @@ public class LinkChecker implements HtmlChecker { p = currFile.getParent().resolve(resolvedUriPath).normalize(); } + if (!Files.exists(p)) { + log.log(currFile, line, "missing file reference: " + log.relativize(p)); + return; + } + if (fragment != null && !fragment.isEmpty()) { foundReference(line, p, fragment); } @@ -392,7 +391,7 @@ public class LinkChecker implements HtmlChecker { void addID(int line, String name) { if (checked) { - throw new IllegalStateException("Adding ID after file has been"); + throw new IllegalStateException("Adding ID after file has been checked"); } Objects.requireNonNull(name); IDInfo info = map.computeIfAbsent(name, _ -> new IDInfo()); @@ -413,7 +412,9 @@ public class LinkChecker implements HtmlChecker { if (name != null) { IDInfo id = map.get(name); if (id == null || !id.declared) { - log.log(log.relativize(from), line, "id not found: " + this.pathOrURI + "#" + name); + log.log(log.relativize(from), line, + "id not found: " + this.pathOrURI + "#" + name); + LinkChecker.this.missingIds++; } } } else { @@ -429,7 +430,8 @@ public class LinkChecker implements HtmlChecker { map.forEach((name, id) -> { if (name != null && !id.declared) { for (Position ref : id.references) { - log.log(log.relativize(ref.path), ref.line, "id not found: " + this.pathOrURI + "#" + name); + log.log(log.relativize(ref.path), ref.line, + "id not found: " + this.pathOrURI + "#" + name); } missingIds++; } From eb770a060ad86d69b38df7d11622e9e25a528e1d Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 5 Jun 2025 11:36:08 +0000 Subject: [PATCH 168/216] 8351594: JFR: Rate-limited sampling of Java events Reviewed-by: mgronlun, alanb --- .../classes/java/io/FileInputStream.java | 25 +- .../classes/java/io/FileOutputStream.java | 18 +- .../classes/java/io/RandomAccessFile.java | 41 +-- .../share/classes/java/lang/Throwable.java | 4 +- .../share/classes/java/net/Socket.java | 10 +- .../internal/event/ExceptionThrownEvent.java | 7 +- .../jdk/internal/event/FileReadEvent.java | 26 +- .../jdk/internal/event/FileWriteEvent.java | 25 +- .../jdk/internal/event/SocketReadEvent.java | 10 +- .../jdk/internal/event/SocketWriteEvent.java | 14 +- .../jdk/internal/event/ThrowableTracer.java | 22 +- .../classes/sun/nio/ch/FileChannelImpl.java | 65 +--- .../jdk/jfr/{internal => }/Throttle.java | 52 ++-- .../jdk/jfr/events/ExceptionThrownEvent.java | 4 +- .../classes/jdk/jfr/events/FileReadEvent.java | 4 +- .../jdk/jfr/events/FileWriteEvent.java | 4 +- .../jdk/jfr/events/SocketReadEvent.java | 4 +- .../jdk/jfr/events/SocketWriteEvent.java | 4 +- .../jdk/jfr/internal/ClassInspector.java | 16 + .../jdk/jfr/internal/EventControl.java | 3 + .../jfr/internal/EventInstrumentation.java | 107 ++++++- .../classes/jdk/jfr/internal/JVMSupport.java | 2 +- .../jdk/jfr/internal/MetadataLoader.java | 5 +- .../jdk/jfr/internal/MetadataRepository.java | 6 +- .../jdk/jfr/internal/PlatformEventType.java | 16 +- .../internal/event/EventConfiguration.java | 29 ++ .../internal/settings/ThrottleSetting.java | 3 +- .../jdk/jfr/internal/settings/Throttler.java | 233 ++++++++++++++ .../settings/ThrottlerParameters.java | 94 ++++++ .../internal/settings/ThrottlerWindow.java | 99 ++++++ .../share/classes/jdk/jfr/package-info.java | 24 +- src/jdk.jfr/share/conf/jfr/default.jfc | 36 ++- src/jdk.jfr/share/conf/jfr/profile.jfc | 38 ++- .../metadata/annotations/TestThrottle.java | 290 ++++++++++++++++++ .../settings/TestSettingsAvailability.java | 14 +- .../jfr/startupargs/TestEventSettings.java | 4 +- 36 files changed, 1120 insertions(+), 238 deletions(-) rename src/jdk.jfr/share/classes/jdk/jfr/{internal => }/Throttle.java (58%) create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/Throttler.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerParameters.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerWindow.java create mode 100644 test/jdk/jdk/jfr/api/metadata/annotations/TestThrottle.java diff --git a/src/java.base/share/classes/java/io/FileInputStream.java b/src/java.base/share/classes/java/io/FileInputStream.java index ab312fc8c5b..b5b4813cbb5 100644 --- a/src/java.base/share/classes/java/io/FileInputStream.java +++ b/src/java.base/share/classes/java/io/FileInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -205,22 +205,17 @@ public class FileInputStream extends InputStream private int traceRead0() throws IOException { int result = 0; - boolean endOfFile = false; long bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); result = read0(); if (result < 0) { - endOfFile = true; + bytesRead = -1; } else { bytesRead = 1; } } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - FileReadEvent.commit(start, duration, path, bytesRead, endOfFile); - } + FileReadEvent.offer(start, path, bytesRead); } return result; } @@ -236,19 +231,11 @@ public class FileInputStream extends InputStream private int traceReadBytes(byte b[], int off, int len) throws IOException { int bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); bytesRead = readBytes(b, off, len); } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - if (bytesRead < 0) { - FileReadEvent.commit(start, duration, path, 0L, true); - } else { - FileReadEvent.commit(start, duration, path, bytesRead, false); - } - } + FileReadEvent.offer(start, path, bytesRead); } return bytesRead; } diff --git a/src/java.base/share/classes/java/io/FileOutputStream.java b/src/java.base/share/classes/java/io/FileOutputStream.java index 6c5a30ea432..022aa44397a 100644 --- a/src/java.base/share/classes/java/io/FileOutputStream.java +++ b/src/java.base/share/classes/java/io/FileOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -266,16 +266,12 @@ public class FileOutputStream extends OutputStream private void traceWrite(int b, boolean append) throws IOException { long bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); write(b, append); bytesWritten = 1; } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - FileWriteEvent.commit(start, duration, path, bytesWritten); - } + FileWriteEvent.offer(start, path, bytesWritten); } } @@ -310,16 +306,12 @@ public class FileOutputStream extends OutputStream private void traceWriteBytes(byte b[], int off, int len, boolean append) throws IOException { long bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); writeBytes(b, off, len, append); bytesWritten = len; } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - FileWriteEvent.commit(start, duration, path, bytesWritten); - } + FileWriteEvent.offer(start, path, bytesWritten); } } diff --git a/src/java.base/share/classes/java/io/RandomAccessFile.java b/src/java.base/share/classes/java/io/RandomAccessFile.java index c09f87afcdc..339030e022c 100644 --- a/src/java.base/share/classes/java/io/RandomAccessFile.java +++ b/src/java.base/share/classes/java/io/RandomAccessFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -367,21 +367,16 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private int traceRead0() throws IOException { int result = 0; long bytesRead = 0; - boolean endOfFile = false; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); result = read0(); if (result < 0) { - endOfFile = true; + bytesRead = -1; } else { bytesRead = 1; } } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - FileReadEvent.commit(start, duration, path, bytesRead, endOfFile); - } + FileReadEvent.offer(start, path, bytesRead); } return result; } @@ -404,19 +399,11 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private int traceReadBytes0(byte b[], int off, int len) throws IOException { int bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); bytesRead = readBytes0(b, off, len); } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - if (bytesRead < 0) { - FileReadEvent.commit(start, duration, path, 0L, true); - } else { - FileReadEvent.commit(start, duration, path, bytesRead, false); - } - } + FileReadEvent.offer(start, path, bytesRead); } return bytesRead; } @@ -582,16 +569,12 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private void traceImplWrite(int b) throws IOException { long bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); implWrite(b); bytesWritten = 1; } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - FileWriteEvent.commit(start, duration, path, bytesWritten); - } + FileWriteEvent.offer(start, path, bytesWritten); } } @@ -624,16 +607,12 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private void traceImplWriteBytes(byte b[], int off, int len) throws IOException { long bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); implWriteBytes(b, off, len); bytesWritten = len; } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - FileWriteEvent.commit(start, duration, path, bytesWritten); - } + FileWriteEvent.offer(start, path, bytesWritten); } } diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 8c0ce29dbee..ac3325fc514 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -121,7 +121,7 @@ public class Throwable implements Serializable { * Flag set by jdk.internal.event.JFRTracing to indicate if * exceptions should be traced by JFR. */ - static volatile boolean jfrTracing; + static boolean jfrTracing; /** * The JVM saves some indication of the stack backtrace in this slot. diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java index d2afa166a88..2905a51b402 100644 --- a/src/java.base/share/classes/java/net/Socket.java +++ b/src/java.base/share/classes/java/net/Socket.java @@ -965,10 +965,7 @@ public class Socket implements java.io.Closeable { } long start = SocketReadEvent.timestamp(); int nbytes = implRead(b, off, len); - long duration = SocketReadEvent.timestamp() - start; - if (SocketReadEvent.shouldCommit(duration)) { - SocketReadEvent.emit(start, duration, nbytes, parent.getRemoteSocketAddress(), getSoTimeout()); - } + SocketReadEvent.offer(start, nbytes, parent.getRemoteSocketAddress(), getSoTimeout()); return nbytes; } @@ -1081,10 +1078,7 @@ public class Socket implements java.io.Closeable { } long start = SocketWriteEvent.timestamp(); implWrite(b, off, len); - long duration = SocketWriteEvent.timestamp() - start; - if (SocketWriteEvent.shouldCommit(duration)) { - SocketWriteEvent.emit(start, duration, len, parent.getRemoteSocketAddress()); - } + SocketWriteEvent.offer(start, len, parent.getRemoteSocketAddress()); } private void implWrite(byte[] b, int off, int len) throws IOException { diff --git a/src/java.base/share/classes/jdk/internal/event/ExceptionThrownEvent.java b/src/java.base/share/classes/jdk/internal/event/ExceptionThrownEvent.java index 45c13e3010d..355ee81c0fc 100644 --- a/src/java.base/share/classes/jdk/internal/event/ExceptionThrownEvent.java +++ b/src/java.base/share/classes/jdk/internal/event/ExceptionThrownEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -31,6 +31,11 @@ public final class ExceptionThrownEvent extends Event { public String message; public Class thrownClass; + public static boolean shouldThrottleCommit(long timestamp) { + // Generated by JFR + return false; + } + public static void commit(long start, String message, Class thrownClass) { // Generated by JFR } diff --git a/src/java.base/share/classes/jdk/internal/event/FileReadEvent.java b/src/java.base/share/classes/jdk/internal/event/FileReadEvent.java index 34ff4e9d4ed..77b2568802e 100644 --- a/src/java.base/share/classes/jdk/internal/event/FileReadEvent.java +++ b/src/java.base/share/classes/jdk/internal/event/FileReadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,11 +45,33 @@ public final class FileReadEvent extends Event { return 0L; } - public static boolean shouldCommit(long duration) { + public static boolean shouldThrottleCommit(long duration, long end) { // Generated by JFR return false; } + /** + * Helper method to offer the data needed to potentially commit an event. + * The duration of the operation is computed using the current + * timestamp and the given start time. If the duration meets + * or exceeds the configured value and is not throttled (determined by calling the + * generated method {@link #shouldThrottleCommit(long, long)}), an event will be + * emitted by calling {@link #commit(long, long, String, long, boolean)} + * + * @param start the start time + * @param path the path + * @param bytesRead the number of bytes that were read, or -1 if the end of the file was reached + */ + public static void offer(long start, String path, long bytesRead) { + long end = timestamp(); + long duration = end - start; + if (shouldThrottleCommit(duration, end)) { + boolean endOfFile = bytesRead < 0; + long bytes = endOfFile ? 0 : bytesRead; + commit(start, duration, path, bytes, endOfFile); + } + } + public static void commit(long start, long duration, String path, long bytesRead, boolean endOfFile) { // Generated by JFR } diff --git a/src/java.base/share/classes/jdk/internal/event/FileWriteEvent.java b/src/java.base/share/classes/jdk/internal/event/FileWriteEvent.java index f6c27960430..3fa7dbe9822 100644 --- a/src/java.base/share/classes/jdk/internal/event/FileWriteEvent.java +++ b/src/java.base/share/classes/jdk/internal/event/FileWriteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -44,11 +44,32 @@ public final class FileWriteEvent extends Event { return 0L; } - public static boolean shouldCommit(long duration) { + public static boolean shouldThrottleCommit(long duration, long end) { // Generated by JFR return false; } + /** + * Helper method to offer the data needed to potentially commit an event. + * The duration of the operation is computed using the current + * timestamp and the given start time. If the duration meets + * or exceeds the configured value and is not throttled (determined by calling the + * generated method {@link #shouldThrottleCommit(long, long)}), an event will be + * emitted by calling {@link #commit(long, long, String, long)} + * + * @param start the start time + * @param path the path + * @param bytesRead the number of bytes that were written, or -1 if the end of the file was reached + */ + public static void offer(long start, String path, long bytesWritten) { + long end = timestamp(); + long duration = end - start; + if (shouldThrottleCommit(duration, end)) { + long bytes = bytesWritten > 0 ? bytesWritten : 0; + commit(start, duration, path, bytes); + } + } + public static void commit(long start, long duration, String path, long bytesWritten) { // Generated by JFR } diff --git a/src/java.base/share/classes/jdk/internal/event/SocketReadEvent.java b/src/java.base/share/classes/jdk/internal/event/SocketReadEvent.java index d5f6c3241d9..09b3f23b07f 100644 --- a/src/java.base/share/classes/jdk/internal/event/SocketReadEvent.java +++ b/src/java.base/share/classes/jdk/internal/event/SocketReadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -74,9 +74,10 @@ public class SocketReadEvent extends Event { * of this method is generated automatically if jfr is enabled. * * @param duration time in nanoseconds to complete the operation + * @param end timestamp at the end of the operation * @return true if the event should be commited */ - public static boolean shouldCommit(long duration) { + public static boolean shouldThrottleCommit(long duration, long end) { // Generated by JFR return false; } @@ -118,8 +119,9 @@ public class SocketReadEvent extends Event { * @param timeout maximum time to wait */ public static void offer(long start, long nbytes, SocketAddress remote, long timeout) { - long duration = timestamp() - start; - if (shouldCommit(duration)) { + long end = timestamp(); + long duration = end - start; + if (shouldThrottleCommit(duration, end)) { emit(start, duration, nbytes, remote, timeout); } } diff --git a/src/java.base/share/classes/jdk/internal/event/SocketWriteEvent.java b/src/java.base/share/classes/jdk/internal/event/SocketWriteEvent.java index 7c56ef826a5..12d8ffbf65b 100644 --- a/src/java.base/share/classes/jdk/internal/event/SocketWriteEvent.java +++ b/src/java.base/share/classes/jdk/internal/event/SocketWriteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -68,10 +68,11 @@ public class SocketWriteEvent extends Event { * must exceed some threshold in order to commit the event. The implementation * of this method is generated automatically if jfr is enabled. * - * @param duration time in nanoseconds to complete the operation + * @param duration time to complete the operation + * @param end timestamp at the end of the operation * @return true if the event should be commited */ - public static boolean shouldCommit(long duration) { + public static boolean shouldThrottleCommit(long duration, long end) { // Generated by JFR return false; } @@ -104,7 +105,7 @@ public class SocketWriteEvent extends Event { * The duration of the operation is computed using the current * timestamp and the given start time. If the duration is meets * or exceeds the configured value (determined by calling the generated method - * {@link #shouldCommit(long)}), an event will be emitted by calling + * {@link #shouldThrottleCommit(long)}), an event will be emitted by calling * {@link #emit(long, long, long, SocketAddress)}. * * @param start the start time @@ -112,8 +113,9 @@ public class SocketWriteEvent extends Event { * @param remote the address of the remote socket being written to */ public static void offer(long start, long bytesWritten, SocketAddress remote) { - long duration = timestamp() - start; - if (shouldCommit(duration)) { + long end = timestamp(); + long duration = end - start; + if (shouldThrottleCommit(duration, end)) { emit(start, duration, bytesWritten, remote); } } diff --git a/src/java.base/share/classes/jdk/internal/event/ThrowableTracer.java b/src/java.base/share/classes/jdk/internal/event/ThrowableTracer.java index f7076b44e90..6502cbc8002 100644 --- a/src/java.base/share/classes/jdk/internal/event/ThrowableTracer.java +++ b/src/java.base/share/classes/jdk/internal/event/ThrowableTracer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -37,22 +37,24 @@ public final class ThrowableTracer { if (OutOfMemoryError.class.isAssignableFrom(clazz)) { return; } - - if (ErrorThrownEvent.enabled()) { + if (ErrorThrownEvent.enabled() || ExceptionThrownEvent.enabled()) { long timestamp = ErrorThrownEvent.timestamp(); - ErrorThrownEvent.commit(timestamp, message, clazz); - } - if (ExceptionThrownEvent.enabled()) { - long timestamp = ExceptionThrownEvent.timestamp(); - ExceptionThrownEvent.commit(timestamp, message, clazz); + if (ErrorThrownEvent.enabled()) { + ErrorThrownEvent.commit(timestamp, message, clazz); + } + if (ExceptionThrownEvent.shouldThrottleCommit(timestamp)) { + ExceptionThrownEvent.commit(timestamp, message, clazz); + } } numThrowables.incrementAndGet(); } public static void traceThrowable(Class clazz, String message) { if (ExceptionThrownEvent.enabled()) { - long timestamp = ExceptionThrownEvent.timestamp(); - ExceptionThrownEvent.commit(timestamp, message, clazz); + long timestamp = ErrorThrownEvent.timestamp(); + if (ExceptionThrownEvent.shouldThrottleCommit(timestamp)) { + ExceptionThrownEvent.commit(timestamp, message, clazz); + } } numThrowables.incrementAndGet(); } diff --git a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java index 72de217a83c..240405c2f7c 100644 --- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -264,19 +264,11 @@ public class FileChannelImpl private int traceImplRead(ByteBuffer dst) throws IOException { int bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); bytesRead = implRead(dst); } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - if (bytesRead < 0) { - FileReadEvent.commit(start, duration, path, 0L, true); - } else { - FileReadEvent.commit(start, duration, path, bytesRead, false); - } - } + FileReadEvent.offer(start, path, bytesRead); } return bytesRead; } @@ -326,19 +318,11 @@ public class FileChannelImpl private long traceImplRead(ByteBuffer[] dsts, int offset, int length) throws IOException { long bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); bytesRead = implRead(dsts, offset, length); } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - if (bytesRead < 0) { - FileReadEvent.commit(start, duration, path, 0L, true); - } else { - FileReadEvent.commit(start, duration, path, bytesRead, false); - } - } + FileReadEvent.offer(start, path, bytesRead); } return bytesRead; } @@ -385,16 +369,11 @@ public class FileChannelImpl private int traceImplWrite(ByteBuffer src) throws IOException { int bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); bytesWritten = implWrite(src); } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - long bytes = bytesWritten > 0 ? bytesWritten : 0; - FileWriteEvent.commit(start, duration, path, bytes); - } + FileWriteEvent.offer(start, path, bytesWritten); } return bytesWritten; } @@ -441,16 +420,11 @@ public class FileChannelImpl private long traceImplWrite(ByteBuffer[] srcs, int offset, int length) throws IOException { long bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); bytesWritten = implWrite(srcs, offset, length); } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - long bytes = bytesWritten > 0 ? bytesWritten : 0; - FileWriteEvent.commit(start, duration, path, bytes); - } + FileWriteEvent.offer(start, path, bytesWritten); } return bytesWritten; } @@ -1199,19 +1173,11 @@ public class FileChannelImpl private int traceImplRead(ByteBuffer dst, long position) throws IOException { int bytesRead = 0; - long start = 0; + long start = FileReadEvent.timestamp(); try { - start = FileReadEvent.timestamp(); bytesRead = implRead(dst, position); } finally { - long duration = FileReadEvent.timestamp() - start; - if (FileReadEvent.shouldCommit(duration)) { - if (bytesRead < 0) { - FileReadEvent.commit(start, duration, path, 0L, true); - } else { - FileReadEvent.commit(start, duration, path, bytesRead, false); - } - } + FileReadEvent.offer(start, path, bytesRead); } return bytesRead; } @@ -1271,16 +1237,11 @@ public class FileChannelImpl private int traceImplWrite(ByteBuffer src, long position) throws IOException { int bytesWritten = 0; - long start = 0; + long start = FileWriteEvent.timestamp(); try { - start = FileWriteEvent.timestamp(); bytesWritten = implWrite(src, position); } finally { - long duration = FileWriteEvent.timestamp() - start; - if (FileWriteEvent.shouldCommit(duration)) { - long bytes = bytesWritten > 0 ? bytesWritten : 0; - FileWriteEvent.commit(start, duration, path, bytes); - } + FileWriteEvent.offer(start, path, bytesWritten); } return bytesWritten; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Throttle.java b/src/jdk.jfr/share/classes/jdk/jfr/Throttle.java similarity index 58% rename from src/jdk.jfr/share/classes/jdk/jfr/internal/Throttle.java rename to src/jdk.jfr/share/classes/jdk/jfr/Throttle.java index 39409d008ab..7b9771eba2b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Throttle.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Throttle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Datadog, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,7 @@ * questions. */ -package jdk.jfr.internal; +package jdk.jfr; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -32,14 +32,15 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import jdk.jfr.MetadataDefinition; - /** - * Event annotation, determines the event emission rate in events per time unit. + * Event annotation, specifies the maximum rate of events per time unit, (for + * example, {@code "100/s"}). + *

        + * If the event class annotated with {@code Throttle} is filtered by other + * settings, such as a {@link jdk.jfr.Threshold} or a user-defined setting, the + * throttling will happen after those settings have been applied. * - * This setting is only supported for JVM events. - * - * @since 16 + * @since 25 */ @MetadataDefinition @Target({ ElementType.TYPE }) @@ -47,30 +48,33 @@ import jdk.jfr.MetadataDefinition; @Retention(RetentionPolicy.RUNTIME) public @interface Throttle { /** - * Settings name {@code "throttle"} for configuring an event emission rate in events per time unit. + * Setting name {@code "throttle"} for configuring throttled events. */ public static final String NAME = "throttle"; - public static final String DEFAULT = "off"; /** - * Throttle, for example {@code "100/s"}. + * The throttle rate, for example {@code "100/s"}. *

        - * String representation of a non-negative {@code Long} value followed by a slash ("/") - * and one of the following units
        - * {@code "ns"} (nanoseconds)
        - * {@code "us"} (microseconds)
        - * {@code "ms"} (milliseconds)
        - * {@code "s"} (seconds)
        - * {@code "m"} (minutes)
        - * {@code "h"} (hours)
        - * {@code "d"} (days)
        + * String representation of a non-negative {@code long} value followed by a + * forward slash ("/") and one of the following units:
        + *

          + *
        • {@code "ns"} (nanoseconds)
        • + *
        • {@code "us"} (microseconds)
        • + *
        • {@code "ms"} (milliseconds)
        • + *
        • {@code "s"} (seconds)
        • + *
        • {@code "m"} (minutes)
        • + *
        • {@code "h"} (hours)
        • + *
        • {@code "d"} (days)
        • + *
        *

        * Example values, {@code "6000/m"}, {@code "10/ms"} and {@code "200/s"}. - * When zero is specified, for example {@code "0/s"}, no events are emitted. - * When {@code "off"} is specified, all events are emitted. + *

        + * Specifying zero, for example {@code "0/s"}, results in no events being + * emitted. + *

        + * Specifying {@code "off"} (case-sensitive) results in all events being emitted. * * @return the throttle value, default {@code "off"} not {@code null} - * */ - String value() default DEFAULT; + String value() default "off"; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java index 22c87f3132d..41945aaf66c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -29,6 +29,7 @@ import jdk.jfr.Category; import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.Name; +import jdk.jfr.Throttle; import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; @@ -38,6 +39,7 @@ import jdk.jfr.internal.Type; @Category("Java Application") @Description("An object derived from java.lang.Exception has been created") @RemoveFields("duration") +@Throttle public final class ExceptionThrownEvent extends MirrorEvent { @Label("Message") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java index 84886d2493a..bd9926c08d3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileReadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -30,6 +30,7 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.DataAmount; import jdk.jfr.Name; +import jdk.jfr.Throttle; import jdk.jfr.internal.Type; import jdk.jfr.internal.MirrorEvent; @@ -38,6 +39,7 @@ import jdk.jfr.internal.MirrorEvent; @Category("Java Application") @Description("Reading data from a file") @StackFilter({"java.io.FileInputStream", "java.io.RandomAccessFile", "sun.nio.ch.FileChannelImpl"}) +@Throttle public final class FileReadEvent extends MirrorEvent { @Label("Path") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java index 990f1845168..e7861eef1b6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/FileWriteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -30,6 +30,7 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.DataAmount; import jdk.jfr.Name; +import jdk.jfr.Throttle; import jdk.jfr.internal.Type; import jdk.jfr.internal.MirrorEvent; @@ -38,6 +39,7 @@ import jdk.jfr.internal.MirrorEvent; @Category("Java Application") @Description("Writing data to a file") @StackFilter({"java.io.FileOutputStream", "java.io.RandomAccessFile", "sun.nio.ch.FileChannelImpl"}) +@Throttle public final class FileWriteEvent extends MirrorEvent { @Label("Path") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java index 917eabd9206..b2cdee4f8dc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketReadEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -31,6 +31,7 @@ import jdk.jfr.Label; import jdk.jfr.DataAmount; import jdk.jfr.Name; import jdk.jfr.Timespan; +import jdk.jfr.Throttle; import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.Type; @@ -38,6 +39,7 @@ import jdk.jfr.internal.Type; @Label("Socket Read") @Category("Java Application") @Description("Reading data from a socket") +@Throttle public final class SocketReadEvent extends MirrorEvent { @Label("Remote Host") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java index 92c85c132d4..661a4d1a68e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SocketWriteEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -30,6 +30,7 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.DataAmount; import jdk.jfr.Name; +import jdk.jfr.Throttle; import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.Type; @@ -37,6 +38,7 @@ import jdk.jfr.internal.Type; @Label("Socket Write") @Category("Java Application") @Description("Writing data to a socket") +@Throttle public final class SocketWriteEvent extends MirrorEvent { @Label("Remote Host") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ClassInspector.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ClassInspector.java index d310c505da6..3646162e8f7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ClassInspector.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ClassInspector.java @@ -51,6 +51,7 @@ import jdk.jfr.Name; import jdk.jfr.Registered; import jdk.jfr.SettingControl; import jdk.jfr.SettingDefinition; +import jdk.jfr.Throttle; import jdk.jfr.internal.util.Bytecode; import jdk.jfr.internal.util.ImplicitFields; import jdk.jfr.internal.util.Bytecode.FieldDesc; @@ -64,6 +65,7 @@ final class ClassInspector { private static final ClassDesc ANNOTATION_NAME = classDesc(Name.class); private static final ClassDesc ANNOTATION_ENABLED = classDesc(Enabled.class); private static final ClassDesc ANNOTATION_REMOVE_FIELDS = classDesc(RemoveFields.class); + private static final ClassDesc ANNOTATION_THROTTLE = classDesc(Throttle.class); private static final String[] EMPTY_STRING_ARRAY = {}; private final ClassModel classModel; @@ -138,6 +140,20 @@ final class ClassInspector { return true; } + boolean isThrottled() { + String result = annotationValue(ANNOTATION_THROTTLE, String.class, "off"); + if (result != null) { + return true; + } + if (superClass != null) { + Throttle t = superClass.getAnnotation(Throttle.class); + if (t != null) { + return true; + } + } + return false; + } + boolean hasStaticMethod(MethodDesc method) { for (MethodModel m : classModel.methods()) { if (Modifier.isStatic(m.flags().flagsMask())) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 2ea4725abc8..02775b7707a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -44,6 +44,7 @@ import jdk.jfr.SettingControl; import jdk.jfr.SettingDefinition; import jdk.jfr.StackTrace; import jdk.jfr.Threshold; +import jdk.jfr.Throttle; import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.events.StackFilter; import jdk.jfr.internal.settings.CutoffSetting; @@ -55,6 +56,7 @@ import jdk.jfr.internal.settings.CPUThrottleSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; import jdk.jfr.internal.settings.ThrottleSetting; +import jdk.jfr.internal.settings.Throttler; import jdk.jfr.internal.tracing.Modification; import jdk.jfr.internal.util.Utils; @@ -95,6 +97,7 @@ public final class EventControl { } if (eventType.hasThrottle()) { addControl(Throttle.NAME, defineThrottle(eventType)); + eventType.setThrottler(new Throttler(eventType)); } if (eventType.hasLevel()) { addControl(Level.NAME, defineLevel(eventType)); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java index 96e6f36e5c8..7f0ed76586a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java @@ -60,7 +60,14 @@ import jdk.jfr.internal.util.ImplicitFields; * Class responsible for adding instrumentation to a subclass of {@link Event}. * */ -final class EventInstrumentation { +public final class EventInstrumentation { + public static final long MASK_THROTTLE = 1 << 62; + public static final long MASK_THROTTLE_CHECK = 1 << 63; + public static final long MASK_THROTTLE_BITS = MASK_THROTTLE | MASK_THROTTLE_CHECK; + public static final long MASK_THROTTLE_CHECK_SUCCESS = MASK_THROTTLE_CHECK | MASK_THROTTLE; + public static final long MASK_THROTTLE_CHECK_FAIL = MASK_THROTTLE_CHECK | 0; + public static final long MASK_NON_THROTTLE_BITS = ~MASK_THROTTLE_BITS; + private static final FieldDesc FIELD_EVENT_CONFIGURATION = FieldDesc.of(Object.class, "eventConfiguration"); private static final ClassDesc TYPE_EVENT_CONFIGURATION = classDesc(EventConfiguration.class); @@ -71,11 +78,17 @@ final class EventInstrumentation { private static final MethodDesc METHOD_BEGIN = MethodDesc.of("begin", "()V"); private static final MethodDesc METHOD_COMMIT = MethodDesc.of("commit", "()V"); private static final MethodDesc METHOD_DURATION = MethodDesc.of("duration", "(J)J"); + private static final MethodDesc METHOD_THROTTLE = MethodDesc.of("throttle", "(JJ)J"); private static final MethodDesc METHOD_ENABLED = MethodDesc.of("enabled", "()Z"); private static final MethodDesc METHOD_END = MethodDesc.of("end", "()V"); - private static final MethodDesc METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT = MethodDesc.of("shouldCommit", "(J)Z"); + private static final MethodDesc METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT_LONG = MethodDesc.of("shouldCommit", "(J)Z"); + private static final MethodDesc METHOD_EVENT_CONFIGURATION_SHOULD_THROTTLE_COMMIT_LONG_LONG = MethodDesc.of("shouldThrottleCommit", "(JJ)Z"); + private static final MethodDesc METHOD_EVENT_CONFIGURATION_SHOULD_THROTTLE_COMMIT_LONG = MethodDesc.of("shouldThrottleCommit", "(J)Z"); + private static final MethodDesc METHOD_EVENT_CONFIGURATION_GET_SETTING = MethodDesc.of("getSetting", SettingControl.class, int.class); private static final MethodDesc METHOD_EVENT_SHOULD_COMMIT = MethodDesc.of("shouldCommit", "()Z"); + private static final MethodDesc METHOD_EVENT_SHOULD_THROTTLE_COMMIT_LONG_LONG = MethodDesc.of("shouldThrottleCommit", "(JJ)Z"); + private static final MethodDesc METHOD_EVENT_SHOULD_THROTTLE_COMMIT_LONG = MethodDesc.of("shouldThrottleCommit", "(J)Z"); private static final MethodDesc METHOD_GET_EVENT_WRITER = MethodDesc.of("getEventWriter", "()" + TYPE_EVENT_WRITER.descriptorString()); private static final MethodDesc METHOD_IS_ENABLED = MethodDesc.of("isEnabled", "()Z"); private static final MethodDesc METHOD_RESET = MethodDesc.of("reset", "()V"); @@ -88,6 +101,7 @@ final class EventInstrumentation { private final MethodDesc staticCommitMethod; private final boolean untypedEventConfiguration; private final boolean guardEventConfiguration; + private final boolean throttled; /** * Creates an EventInstrumentation object. @@ -110,6 +124,11 @@ final class EventInstrumentation { this.eventClassDesc = inspector.getClassDesc(); this.staticCommitMethod = inspector.findStaticCommitMethod(); this.untypedEventConfiguration = hasUntypedConfiguration(); + if (inspector.isJDK()) { + this.throttled = inspector.hasStaticMethod(METHOD_EVENT_SHOULD_THROTTLE_COMMIT_LONG_LONG); + } else { + this.throttled = inspector.isThrottled(); + } } byte[] buildInstrumented() { @@ -147,6 +166,12 @@ final class EventInstrumentation { if (isMethod(method, METHOD_SHOULD_COMMIT_LONG)) { return this::methodShouldCommitStatic; } + if (isMethod(method, METHOD_EVENT_SHOULD_THROTTLE_COMMIT_LONG_LONG)) { + return this::methodShouldCommitThrottleStaticLongLong; + } + if (isMethod(method, METHOD_EVENT_SHOULD_THROTTLE_COMMIT_LONG)) { + return this::methodShouldCommitThrottleStaticLong; + } if (isMethod(method, METHOD_TIME_STAMP)) { return this::methodTimestamp; } @@ -188,11 +213,11 @@ final class EventInstrumentation { if (!inspector.hasDuration()) { throwMissingDuration(codeBuilder, "end"); } else { - codeBuilder.aload(0); - codeBuilder.aload(0); - getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_START_TIME); - invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_DURATION); - putfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + setDuration(codeBuilder, cb -> { + codeBuilder.aload(0); + getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_START_TIME); + invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_DURATION); + }); codeBuilder.return_(); } } @@ -205,9 +230,8 @@ final class EventInstrumentation { } // if (!eventConfiguration.shouldCommit(duration) goto fail; getEventConfiguration(codeBuilder); - codeBuilder.aload(0); - getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); - invokevirtual(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT); + getDuration(codeBuilder); + invokevirtual(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT_LONG); codeBuilder.ifeq(fail); List settingDescs = inspector.getSettings(); for (int index = 0; index < settingDescs.size(); index++) { @@ -222,6 +246,30 @@ final class EventInstrumentation { codeBuilder.invokevirtual(eventClassDesc, sd.methodName(), mdesc); codeBuilder.ifeq(fail); } + if (throttled) { + // long d = eventConfiguration.throttle(this.duration); + // this.duration = d; + // if (d & MASK_THROTTLE_BIT == 0) { + // goto fail; + // } + getEventConfiguration(codeBuilder); + codeBuilder.aload(0); + getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_START_TIME); + codeBuilder.aload(0); + getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + Bytecode.invokevirtual(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_THROTTLE); + int result = codeBuilder.allocateLocal(TypeKind.LONG); + codeBuilder.lstore(result); + codeBuilder.aload(0); + codeBuilder.lload(result); + putfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + codeBuilder.lload(result); + codeBuilder.ldc(MASK_THROTTLE); + codeBuilder.land(); + codeBuilder.lconst_0(); + codeBuilder.lcmp(); + codeBuilder.ifeq(fail); + } // return true codeBuilder.iconst_1(); codeBuilder.ireturn(); @@ -294,6 +342,17 @@ final class EventInstrumentation { } private void methodShouldCommitStatic(CodeBuilder codeBuilder) { + methodShouldCommitStatic(codeBuilder, METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT_LONG); + } + + private void methodShouldCommitThrottleStaticLongLong(CodeBuilder codeBuilder) { + methodShouldCommitStatic(codeBuilder, METHOD_EVENT_CONFIGURATION_SHOULD_THROTTLE_COMMIT_LONG_LONG); + } + private void methodShouldCommitThrottleStaticLong(CodeBuilder codeBuilder) { + methodShouldCommitStatic(codeBuilder, METHOD_EVENT_CONFIGURATION_SHOULD_THROTTLE_COMMIT_LONG); + } + + private void methodShouldCommitStatic(CodeBuilder codeBuilder, MethodDesc method) { Label fail = codeBuilder.newLabel(); if (guardEventConfiguration) { // if (eventConfiguration == null) goto fail; @@ -302,8 +361,10 @@ final class EventInstrumentation { } // return eventConfiguration.shouldCommit(duration); getEventConfiguration(codeBuilder); - codeBuilder.lload(0); - codeBuilder.invokevirtual(TYPE_EVENT_CONFIGURATION, METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT.name(), METHOD_EVENT_CONFIGURATION_SHOULD_COMMIT.descriptor()); + for (int i = 0 ; i < method.descriptor().parameterCount(); i++) { + codeBuilder.lload(2 * i); + } + codeBuilder.invokevirtual(TYPE_EVENT_CONFIGURATION, method.name(), method.descriptor()); codeBuilder.ireturn(); // fail: codeBuilder.labelBinding(fail); @@ -515,6 +576,28 @@ final class EventInstrumentation { return desc.matches(m); } + private void getDuration(CodeBuilder codeBuilder) { + codeBuilder.aload(0); + getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + if (throttled) { + codeBuilder.loadConstant(MASK_NON_THROTTLE_BITS); + codeBuilder.land(); + } + } + + private void setDuration(CodeBuilder codeBuilder, Consumer expression) { + codeBuilder.aload(0); + expression.accept(codeBuilder); + if (throttled) { + codeBuilder.aload(0); + getfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + codeBuilder.loadConstant(MASK_THROTTLE_BITS); + codeBuilder.land(); + codeBuilder.lor(); + } + putfield(codeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION); + } + private static void getEventWriter(CodeBuilder codeBuilder) { invokestatic(codeBuilder, TYPE_EVENT_WRITER, METHOD_GET_EVENT_WRITER); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java index ded1f78b76e..8314437ce72 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java @@ -98,7 +98,7 @@ public final class JVMSupport { public static void tryToInitializeJVM() { } - static long nanosToTicks(long nanos) { + public static long nanosToTicks(long nanos) { return (long) (nanos * JVM.getTimeConversionFactor()); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java index 60db375c876..2d1332aed06 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataLoader.java @@ -45,11 +45,12 @@ import jdk.jfr.Period; import jdk.jfr.Relational; import jdk.jfr.StackTrace; import jdk.jfr.Threshold; +import jdk.jfr.Throttle; import jdk.jfr.TransitionFrom; import jdk.jfr.TransitionTo; import jdk.jfr.Unsigned; import jdk.jfr.internal.util.Utils; - +import jdk.jfr.internal.settings.ThrottleSetting; public final class MetadataLoader { // Caching to reduce allocation pressure and heap usage @@ -320,7 +321,7 @@ public final class MetadataLoader { aes.add(new AnnotationElement(Cutoff.class, Cutoff.INFINITY)); } if (t.throttle) { - aes.add(new AnnotationElement(Throttle.class, Throttle.DEFAULT)); + aes.add(new AnnotationElement(Throttle.class, ThrottleSetting.DEFAULT_VALUE)); } } if (t.experimental) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 5dcf07f719d..e574ab47992 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -45,11 +45,13 @@ import jdk.jfr.EventType; import jdk.jfr.Name; import jdk.jfr.Period; import jdk.jfr.SettingControl; +import jdk.jfr.Throttle; import jdk.jfr.ValueDescriptor; import jdk.jfr.internal.consumer.RepositoryFiles; import jdk.jfr.internal.event.EventConfiguration; import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.periodic.PeriodicEvents; +import jdk.jfr.internal.settings.Throttler; import jdk.jfr.internal.util.Utils; public final class MetadataRepository { @@ -214,9 +216,11 @@ public final class MetadataRepository { } } EventType eventType = PrivateAccess.getInstance().newEventType(pEventType); + pEventType.setHasThrottle(pEventType.getAnnotation(Throttle.class) != null); EventControl ec = new EventControl(pEventType, eventClass); SettingControl[] settings = ec.getSettingControls().toArray(new SettingControl[0]); - EventConfiguration configuration = new EventConfiguration(pEventType, eventType, ec, settings, eventType.getId()); + Throttler throttler = pEventType.getThrottler(); + EventConfiguration configuration = new EventConfiguration(pEventType, eventType, ec, settings, throttler, eventType.getId()); pEventType.setRegistered(true); // If class is instrumented or should not be instrumented, mark as instrumented. if (JVM.isInstrumented(eventClass) || !JVMSupport.shouldInstrument(pEventType.isJDK(), pEventType.getName())) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java index b65a26f3aad..ff3e0238cf0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java @@ -35,6 +35,7 @@ import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.ImplicitFields; import jdk.jfr.internal.util.TimespanRate; import jdk.jfr.internal.util.Utils; +import jdk.jfr.internal.settings.Throttler; import jdk.jfr.internal.tracing.Modification; /** @@ -72,6 +73,7 @@ public final class PlatformEventType extends Type { private boolean registered = true; private boolean committable = enabled && registered; private boolean hasLevel = false; + private Throttler throttler; // package private PlatformEventType(String name, long id, boolean isJDK, boolean dynamicSettings) { @@ -190,9 +192,11 @@ public final class PlatformEventType extends Type { } } - public void setThrottle(long eventSampleSize, long period_ms) { + public void setThrottle(long eventSampleSize, long periodInMillis) { if (isJVM) { - JVM.setThrottle(getId(), eventSampleSize, period_ms); + JVM.setThrottle(getId(), eventSampleSize, periodInMillis); + } else { + throttler.configure(eventSampleSize, periodInMillis); } } @@ -420,4 +424,12 @@ public final class PlatformEventType extends Type { public long getStackFilterId() { return startFilterId; } + + public Throttler getThrottler() { + return throttler; + } + + public void setThrottler(Throttler throttler) { + this.throttler = throttler; + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventConfiguration.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventConfiguration.java index 4b0f2fba3da..f16e153fe43 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventConfiguration.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventConfiguration.java @@ -28,14 +28,17 @@ package jdk.jfr.internal.event; import jdk.jfr.EventType; import jdk.jfr.SettingControl; import jdk.jfr.internal.EventControl; +import jdk.jfr.internal.EventInstrumentation; import jdk.jfr.internal.JVM; import jdk.jfr.internal.PlatformEventType; +import jdk.jfr.internal.settings.Throttler; public record EventConfiguration( PlatformEventType platformEventType, EventType eventType, EventControl eventControl, SettingControl[] settings, + Throttler throttler, long id) { // Accessed by generated code in event class @@ -43,6 +46,19 @@ public record EventConfiguration( return isEnabled() && duration >= platformEventType.getThresholdTicks(); } + // Accessed by generated code in event class. Used by: + // static boolean shouldThrottleCommit(long duration, long timestamp) + public boolean shouldThrottleCommit(long duration, long timestamp) { + return isEnabled() && duration >= platformEventType.getThresholdTicks() && throttler.sample(timestamp); + } + + // Caller must of Event::shouldThrottleCommit must check enablement. + // Accessed by generated code in event class. Used by: + // static boolean shouldThrottleCommit(long timestamp) + public boolean shouldThrottleCommit(long timestamp) { + return throttler.sample(timestamp); + } + // Accessed by generated code in event class public SettingControl getSetting(int index) { return settings[index]; @@ -53,6 +69,19 @@ public record EventConfiguration( return platformEventType.isCommittable(); } + public long throttle(long startTime, long rawDuration) { + // We have already tried to throttle, return as is + if ((rawDuration & EventInstrumentation.MASK_THROTTLE_BITS) != 0) { + return rawDuration; + } + long endTime = startTime + rawDuration; + if (throttler.sample(endTime)) { + return rawDuration | EventInstrumentation.MASK_THROTTLE_CHECK_SUCCESS; + } else { + return rawDuration | EventInstrumentation.MASK_THROTTLE_CHECK_FAIL; + } + } + // Not really part of the configuration, but the method // needs to be somewhere the event class can access, // but not part of the public API. diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java index 800443cfaed..ab26b5fcd31 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottleSetting.java @@ -38,7 +38,6 @@ import jdk.jfr.MetadataDefinition; import jdk.jfr.Name; import jdk.jfr.SettingControl; import jdk.jfr.internal.PlatformEventType; -import jdk.jfr.internal.Throttle; import jdk.jfr.internal.Type; import jdk.jfr.internal.util.Rate; import jdk.jfr.internal.util.TimespanUnit; @@ -49,7 +48,7 @@ import jdk.jfr.internal.util.Utils; @Description("Throttles the emission rate for an event") @Name(Type.SETTINGS_PREFIX + "Throttle") public final class ThrottleSetting extends SettingControl { - public static final String DEFAULT_VALUE = Throttle.DEFAULT; + public static final String DEFAULT_VALUE = "off"; private final PlatformEventType eventType; private final String defaultValue; private String value; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/Throttler.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/Throttler.java new file mode 100644 index 00000000000..df8f5a58700 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/Throttler.java @@ -0,0 +1,233 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.settings; + +import java.util.Random; +import java.util.concurrent.locks.ReentrantLock; +import jdk.jfr.internal.PlatformEventType; +public final class Throttler { + private static final ThrottlerParameters DISABLED_PARAMETERS = new ThrottlerParameters(0, 0, 0); + private static final long MILLIUNITS = 1000; + private static final long MINUTE = 60 * MILLIUNITS; + private static final long TEN_PER_1000_MS_IN_MINUTES = 600; + private static final long HOUR = 60 * MINUTE; + private static final long TEN_PER_1000_MS_IN_HOURS = 36000; + private static final long TEN_PER_1000_MS_IN_DAYS = 864000; + private static final long EVENT_THROTTLER_OFF = -2; + + private final ReentrantLock lock = new ReentrantLock(); + private final Random randomGenerator = new Random(); + private final ThrottlerWindow window0 = new ThrottlerWindow(); + private final ThrottlerWindow window1 = new ThrottlerWindow(); + + private volatile ThrottlerWindow activeWindow = window0; + + // Guarded by lock + private double averagePopulationSize; + private double ewmaPopulationSize; + private long accumulatedDebtCarryLimit; + private long accumulatedDebtCarryCount; + private ThrottlerParameters lastParameters = new ThrottlerParameters(0, 0, 0); + private long sampleSize; + private long periodMillis; + private boolean disabled; + private boolean update = true; + + public Throttler(PlatformEventType t) { + } + // Not synchronized in fast path, but uses volatile reads. + public boolean sample(long ticks) { + if (disabled) { + return true; + } + ThrottlerWindow current = activeWindow; + if (current.isExpired(ticks)) { + if (lock.tryLock()) { + try { + rotateWindow(ticks); + } finally { + lock.unlock(); + } + } + return activeWindow.sample(); + } + return current.sample(); + } + + public void configure(long sampleSize, long periodMillis) { + lock.lock(); + try { + this.sampleSize = sampleSize; + this.periodMillis = periodMillis; + this.update = true; + this.activeWindow = configure(nextWindowParameters(), activeWindow); + } finally { + lock.unlock(); + } + } + + private ThrottlerWindow configure(ThrottlerParameters parameters, ThrottlerWindow expired) { + if (parameters.reconfigure) { + // Store updated params once to both windows + expired.parameters = parameters; + nextWindow(expired).parameters = parameters; + configure(parameters); + } + ThrottlerWindow next = setRate(parameters, expired); + next.initialize(parameters); + return next; + } + + private void configure(ThrottlerParameters parameters) { + averagePopulationSize = 0; + ewmaPopulationSize = computeEwmaAlphaCoefficient(parameters.windowLookBackCount); + accumulatedDebtCarryLimit = computeAccumulatedDebtCarryLimit(parameters); + accumulatedDebtCarryCount = accumulatedDebtCarryLimit; + parameters.reconfigure = false; + } + + private void rotateWindow(long ticks) { + ThrottlerWindow current = activeWindow; + if (current.isExpired(ticks)) { + activeWindow = configure(current.parameters.copy(), current); + } + } + + private ThrottlerWindow setRate(ThrottlerParameters parameters, ThrottlerWindow expired) { + ThrottlerWindow next = nextWindow(expired); + long projectedSampleSize = parameters.samplePointsPerWindow + amortizeDebt(expired); + if (projectedSampleSize == 0) { + next.projectedPopulationSize = 0; + return next; + } + next.samplingInterval = deriveSamplingInterval(projectedSampleSize, expired); + next.projectedPopulationSize = projectedSampleSize * next.samplingInterval; + return next; + } + + private long amortizeDebt(ThrottlerWindow expired) { + long accumulatedDebt = expired.accumulatedDebt(); + if (accumulatedDebtCarryCount == accumulatedDebtCarryLimit) { + accumulatedDebtCarryCount = 1; + return 0; + } + accumulatedDebtCarryCount++; + return -accumulatedDebt; + } + + private long deriveSamplingInterval(double sampleSize, ThrottlerWindow expired) { + double populationSize = projectPopulationSize(expired); + if (populationSize <= sampleSize) { + return 1; + } + double projectProbability = sampleSize / populationSize; + return nextGeometric(projectProbability, randomGenerator.nextDouble()); + } + + private double projectPopulationSize(ThrottlerWindow expired) { + averagePopulationSize = exponentiallyWeightedMovingAverage(expired.populationSize(), ewmaPopulationSize, averagePopulationSize); + return averagePopulationSize; + } + + private static long nextGeometric(double p, double u) { + return (long) Math.ceil(Math.log(1.0 - adjustBoundary(u)) / Math.log(1.0 - p)); + } + + private static double adjustBoundary(double u) { + if (u == 0.0) { + return 0.01; + } + if (u == 1.0) { + return 0.99; + } + return u; + } + + private void normalize() { + if (periodMillis == MILLIUNITS) { + return; + } + if (periodMillis == MINUTE) { + if (sampleSize >= TEN_PER_1000_MS_IN_MINUTES) { + sampleSize /= 60; + periodMillis /= 60; + } + return; + } + if (periodMillis == HOUR) { + if (sampleSize >= TEN_PER_1000_MS_IN_HOURS) { + sampleSize /= 3600; + periodMillis /= 3600; + } + return; + } + if (sampleSize >= TEN_PER_1000_MS_IN_DAYS) { + sampleSize /= 86400; + periodMillis /= 86400; + } + } + + private ThrottlerParameters nextWindowParameters() { + if (update) { + return updateParameters(); + } + return disabled ? DISABLED_PARAMETERS : lastParameters; + } + + private ThrottlerParameters updateParameters() { + disabled = is_disabled(sampleSize); + if (disabled) { + return DISABLED_PARAMETERS; + } + normalize(); + lastParameters.setSamplePointsAndWindowDuration(sampleSize, periodMillis); + lastParameters.reconfigure = true; + update = false; + return lastParameters; + } + + private boolean is_disabled(long eventSampleSize) { + return eventSampleSize == EVENT_THROTTLER_OFF; + } + + private double exponentiallyWeightedMovingAverage(double y, double alpha, double s) { + return alpha * y + (1 - alpha) * s; + } + + private double computeEwmaAlphaCoefficient(long lookBackCount) { + return lookBackCount <= 1 ? 1.0 : 1.0 / lookBackCount; + } + + private long computeAccumulatedDebtCarryLimit(ThrottlerParameters parameters) { + if (parameters.windowDurationMillis == 0 || parameters.windowDurationMillis >= 1000) { + return 1; + } + return 1000 / parameters.windowDurationMillis; + } + + private ThrottlerWindow nextWindow(ThrottlerWindow expired) { + return expired == window0 ? window1 : window0; + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerParameters.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerParameters.java new file mode 100644 index 00000000000..68908fda2a6 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerParameters.java @@ -0,0 +1,94 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.settings; + +final class ThrottlerParameters { + private static final long LOW_RATE_UPPER_BOUND = 9; + private static final long WINDOW_DIVISOR = 5; + private static final long MILLIUNITS = 1000; + private static final long MINUTE = 60 * MILLIUNITS; + private static final long TEN_PER_1000_MS_IN_MINUTES = 600; + private static final long HOUR = 60 * MINUTE; + private static final long TEN_PER_1000_MS_IN_HOURS = 36000; + private static final long DAY = 24 * HOUR; + private static final long TEN_PER_1000_MS_IN_DAYS = 864000; + private static final long DEFAULT_WINDOWS_LOOKBACK_COUNT = 25; // 25 windows == 5 seconds (for default window duration of 200 ms) + + long samplePointsPerWindow; + long windowDurationMillis; + long windowLookBackCount; + boolean reconfigure; + + ThrottlerParameters(long samplePointsPerWindow, long windowDuration, long windowLockBackCount) { + this.samplePointsPerWindow = samplePointsPerWindow; + this.windowDurationMillis = windowDuration; + this.windowLookBackCount = windowLockBackCount; + } + + public ThrottlerParameters copy() { + return new ThrottlerParameters(samplePointsPerWindow, windowDurationMillis, windowLookBackCount); + } + + void setSamplePointsAndWindowDuration(long sampleSize, long periodMillis) { + try { + if (sampleSize <= LOW_RATE_UPPER_BOUND) { + samplePointsPerWindow = sampleSize; + windowDurationMillis = periodMillis; + return; + } + if (periodMillis == MINUTE && sampleSize < TEN_PER_1000_MS_IN_MINUTES) { + samplePointsPerWindow = sampleSize; + windowDurationMillis = periodMillis; + return; + } + if (periodMillis == HOUR && sampleSize < TEN_PER_1000_MS_IN_HOURS) { + samplePointsPerWindow = sampleSize; + windowDurationMillis = periodMillis; + return; + } + if (periodMillis == DAY && sampleSize < TEN_PER_1000_MS_IN_DAYS) { + samplePointsPerWindow = sampleSize; + windowDurationMillis = periodMillis; + return; + } + samplePointsPerWindow = sampleSize / WINDOW_DIVISOR; + windowDurationMillis = periodMillis / WINDOW_DIVISOR; + } finally { + updateWindowLookback(); + } + } + + private void updateWindowLookback() { + if (windowDurationMillis <= MILLIUNITS) { + windowLookBackCount = DEFAULT_WINDOWS_LOOKBACK_COUNT; // 5 seconds + return; + } + if (windowDurationMillis == MINUTE) { + windowLookBackCount = 5; // 5 windows == 5 minutes + return; + } + windowLookBackCount = 1; // 1 window == 1 hour or 1 day + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerWindow.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerWindow.java new file mode 100644 index 00000000000..31fb6cab63c --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/ThrottlerWindow.java @@ -0,0 +1,99 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.settings; + +import jdk.jfr.internal.JVMSupport; + +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicLong; +import jdk.jfr.internal.JVM; + +final class ThrottlerWindow { + private final AtomicLong measuredPopulationSize = new AtomicLong(); + // Guarded by Throttler.lock. + ThrottlerParameters parameters = new ThrottlerParameters(0, 0, 0); + long samplingInterval = 1; + long projectedPopulationSize; + + private volatile long endTicks; + + void initialize(ThrottlerParameters parameters) { + if (parameters.windowDurationMillis == 0) { + endTicks = 0; + return; + } + measuredPopulationSize.set(0); + endTicks = JVM.counterTime() + JVMSupport.nanosToTicks(1_000_000L * parameters.windowDurationMillis); + } + + boolean isExpired(long timestamp) { + long endTicks = this.endTicks; + if (timestamp == 0) { + return JVM.counterTime() >= endTicks; + } else { + return timestamp >= endTicks; + } + } + + boolean sample() { + long ordinal = measuredPopulationSize.incrementAndGet(); + return ordinal <= projectedPopulationSize && ordinal % samplingInterval == 0; + } + + long maxSampleSize() { + return samplingInterval == 0 ? 0 : projectedPopulationSize / samplingInterval; + } + + long sampleSize() { + long size = populationSize(); + return size > projectedPopulationSize ? maxSampleSize() : size / samplingInterval; + } + + long populationSize() { + return measuredPopulationSize.get(); + } + + long accumulatedDebt() { + if (projectedPopulationSize == 0) { + return 0; + } + return parameters.samplePointsPerWindow - maxSampleSize() + debt(); + } + + long debt() { + if (projectedPopulationSize == 0) { + return 0; + } + return sampleSize() - parameters.samplePointsPerWindow; + } + + public String toString() { + StringJoiner sb = new StringJoiner(", "); + sb.add("measuredPopulationSize=" + measuredPopulationSize); + sb.add("samplingInterval=" + samplingInterval); + sb.add("projectedPopulationSize=" + projectedPopulationSize); + return sb.toString(); + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/package-info.java b/src/jdk.jfr/share/classes/jdk/jfr/package-info.java index bd5b197d7fc..54866ec508f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/package-info.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -177,6 +177,28 @@ * {@code "false"} * * + * {@code throttle} + * Specifies the maximum rate of events per time unit. + * {@code "off"} (no throttling) + * + * "off", if events should not be throttled, otherwise a string representation of a positive {@code Long} value followed by forward slash ("/") and one of the following units: + *

          + *
        • {@code "ns"} (nanoseconds) + *
        • {@code "us"} (microseconds) + *
        • {@code "ms"} (milliseconds)
        • + *
        • {@code "s"} (seconds)
        • + *
        • {@code "m"} (minutes)
        • + *
        • {@code "h"} (hours)
        • + *
        • {@code "d"} (days)
        • + *
        + * + * + * {@code "off"}
        + * {@code "100/s"}
        + * {@code "1000/m"} + * + * + * * {@code filter} * Specifies the filter for the event * {@code ""} (empty string) diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 541d1d3aa2f..565dfbdee05 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -769,31 +769,35 @@ true true - 20 ms + 20 ms true true - 20 ms + 1 ms + 100/s true true - 20 ms + 1 ms + 100/s true true - 20 ms + 1 ms + 100/s true true - 20 ms + 1 ms + 100/s @@ -836,8 +840,9 @@ - false + true true + 100/s @@ -1136,20 +1141,27 @@ - + - - + + - + + + + + + + + @@ -1177,10 +1189,6 @@ 20 ms - 20 ms - - 20 ms - diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 9cec2d9a70f..2c0812e75fe 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -769,31 +769,35 @@ true true - 10 ms + 10 ms true true - 10 ms + 1 ms + 300/s true true - 10 ms + 1 ms + 300/s true true - 10 ms + 1 ms + 300/s true true - 10 ms + 1 ms + 300/s @@ -836,8 +840,9 @@ - false + true true + 300/s @@ -1135,21 +1140,28 @@ - + - - + + - + - + + + + + + + + @@ -1176,10 +1188,6 @@ 10 ms - 10 ms - - 10 ms - diff --git a/test/jdk/jdk/jfr/api/metadata/annotations/TestThrottle.java b/test/jdk/jdk/jfr/api/metadata/annotations/TestThrottle.java new file mode 100644 index 00000000000..da3bd311abb --- /dev/null +++ b/test/jdk/jdk/jfr/api/metadata/annotations/TestThrottle.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.api.metadata.annotations; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Constructor; +import java.time.Duration; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +import jdk.jfr.AnnotationElement; +import jdk.jfr.Event; +import jdk.jfr.EventType; +import jdk.jfr.MetadataDefinition; +import jdk.jfr.Name; +import jdk.jfr.Threshold; +import jdk.jfr.Enabled; +import jdk.jfr.Recording; +import jdk.jfr.SettingDefinition; +import jdk.jfr.SettingDescriptor; +import jdk.jfr.Throttle; +import jdk.jfr.ValueDescriptor; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.Events; +import jdk.jfr.SettingControl; + +/** + * @test + * @requires vm.flagless + * @requires vm.hasJFR + * @library /test/lib + * @run main/othervm jdk.jfr.api.metadata.annotations.TestThrottle + */ +public class TestThrottle { + + @Throttle("off") + @Enabled(false) + public static class ThrottledDisabledEvent extends Event { + } + + @Throttle("off") + public static class ThrottledOffEvent extends Event { + } + + @Throttle("0/s") + public static class ThrottledZeroRateEvent extends Event { + } + + @Throttle("10000000/s") + public static class ThrottledHighRateEvent extends Event { + } + + @Throttle("off") + @Threshold("5 h") + public static class ThrottledThresholdedEvent extends Event { + } + + @Throttle("50/s") + public static class ThrottledNormalRateEvent extends Event { + public int index; + } + + static class TestSetting extends SettingControl { + private boolean value; + + @Override + public String combine(Set values) { + if (values.contains("true")) { + return "true"; + } + if (values.contains("false")) { + return "false"; + } + return "true"; + } + + @Override + public void setValue(String text) { + value = Boolean.parseBoolean(text); + } + + @Override + public String getValue() { + return "" + value; + } + } + + @Throttle("10000000/s") + public static class ThrottledUserdefinedEvent extends Event { + @SettingDefinition + public boolean test(TestSetting control) { + return control.value; + } + } + + @Throttle("50/s") + public static class ThrottledReuseEvent extends Event { + public int index; + } + + public static void main(String[] args) throws Exception { + testThrottleDisabled(); + testThrottledOff(); + testThottleZeroRate(); + testThrottleHighRate(); + testThrottleThresholded(); + testThrottleNormalRate(); + testThrottleUserdefined(); + } + + private static void testThrottleDisabled() throws Exception { + testEvent(ThrottledDisabledEvent.class, false); + } + + private static void testThrottledOff() throws Exception { + testEvent(ThrottledOffEvent.class, true); + } + + private static void testThottleZeroRate() throws Exception { + testEvent(ThrottledZeroRateEvent.class, false); + } + + private static void testThrottleHighRate() throws Exception { + testEvent(ThrottledHighRateEvent.class, true); + } + + private static void testThrottleThresholded() throws Exception { + testEvent(ThrottledThresholdedEvent.class, false); + } + + private static void testThrottleNormalRate() throws Exception { + try (RecordingStream rs = new RecordingStream()) { + AtomicInteger lastIndex = new AtomicInteger(); + AtomicInteger throttled = new AtomicInteger(); + rs.onEvent(ThrottledNormalRateEvent.class.getName(), e -> { + int index = e.getInt("index"); + if (lastIndex.get() + 1 != index) { + throttled.incrementAndGet(); + } + lastIndex.set(index); + }); + rs.startAsync(); + int index = 1; + while (throttled.get() < 30) { + ThrottledNormalRateEvent e = new ThrottledNormalRateEvent(); + e.index = index; + e.commit(); + index++; + Thread.sleep(3); + } + } + } + + private static void testThrottleUserdefined() throws Exception { + testThrottleUserdefined("false", "1000000/s", false); + testThrottleUserdefined("true", "10000000/s", true); + testThrottleUserdefined("true", "0/s", false); + testThrottleUserdefined("true", "off", true); + testThrottleUserdefined("false", "off", false); + } + + private static void testThrottleUserdefined(String test, String throttle, boolean emit) throws Exception { + String eventName = ThrottledUserdefinedEvent.class.getName(); + try (Recording r = new Recording()) { + r.enable(eventName).with("test", test).with("throttle", throttle); + r.start(); + + ThrottledUserdefinedEvent e1 = new ThrottledUserdefinedEvent(); + e1.commit(); + + ThrottledUserdefinedEvent e2 = new ThrottledUserdefinedEvent(); + e2.begin(); + e2.commit(); + + ThrottledUserdefinedEvent e3 = new ThrottledUserdefinedEvent(); + e3.begin(); + e3.end(); + e3.commit(); + + ThrottledUserdefinedEvent e4 = new ThrottledUserdefinedEvent(); + if (e4.shouldCommit()) { + e4.commit(); + } + assertShouldCommit(e4, emit); + + ThrottledUserdefinedEvent e5 = new ThrottledUserdefinedEvent(); + assertShouldCommit(e5, emit); + if (e5.shouldCommit()) { + e5.commit(); + } + + r.stop(); + assertEvents(r, eventName, emit ? 5 : 0); + } + } + + @SuppressWarnings("unchecked") + private static void testEvent(Class eventClass, boolean shouldCommit) throws Exception { + try (Recording r = new Recording()) { + r.start(); + Constructor c = (Constructor) eventClass.getConstructor(); + for (int i = 0; i < 17; i++) { + Event e = c.newInstance(); + if (i % 5 == 0) { + assertShouldCommit(e, shouldCommit); + } + e.commit(); + if (i % 3 == 0) { + assertShouldCommit(e, shouldCommit); + } + } + for (int i = 0; i < 50; i++) { + Event e = c.newInstance(); + e.begin(); + if (i % 5 == 0) { + assertShouldCommit(e, shouldCommit); + } + e.end(); + if (i % 3 == 0) { + assertShouldCommit(e, shouldCommit); + } + e.commit(); + if (i % 7 == 0) { + assertShouldCommit(e, shouldCommit); + } + } + for (int i = 0; i < 11; i++) { + Event e = c.newInstance(); + e.begin(); + e.commit(); + if (i % 7 == 0) { + assertShouldCommit(e, shouldCommit); + } + } + if (shouldCommit) { + assertEvents(r, eventClass.getName(), 17 + 50 + 11); + } + } + } + + private static void assertEvents(Recording r, String name, int expected) throws Exception { + int count = 0; + for (RecordedEvent event : Events.fromRecording(r)) { + if (event.getEventType().getName().equals(name)) { + count++; + } + } + if (count != expected) { + throw new Exception("Expected " + expected + " " + name + " events, but found " + count); + } + } + + private static void assertShouldCommit(Event e, boolean expected) throws Exception { + if (e.shouldCommit() != expected) { + throw new Exception("Expected " + e.getClass() + "::shouldCommit() to return " + expected); + } + } +} diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java index dc22644b4d0..7c6e6fa276b 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java @@ -66,7 +66,7 @@ public class TestSettingsAvailability { for (EventType parsedType : rf.readEventTypes()) { EventType inMem = inMemoryTypes.get(parsedType.getName()); if (inMem == null) { - throw new Exception("Superflous event type " + parsedType.getName() + " in recording"); + throw new Exception("Superfluous event type " + parsedType.getName() + " in recording"); } Set inMemsettings = new HashSet<>(); for (SettingDescriptor sd : inMem.getSettingDescriptors()) { @@ -75,7 +75,7 @@ public class TestSettingsAvailability { for (SettingDescriptor parsedSetting : parsedType.getSettingDescriptors()) { if (!inMemsettings.contains(parsedSetting.getName())) { - throw new Exception("Superflous setting " + parsedSetting.getName() + " in " + parsedType.getName()); + throw new Exception("Superfluous setting " + parsedSetting.getName() + " in " + parsedType.getName()); } inMemsettings.remove(parsedSetting.getName()); } @@ -89,14 +89,14 @@ public class TestSettingsAvailability { private static void testKnownSettings() throws Exception { testSetting(EventNames.JVMInformation, "enabled", "period"); - testSetting(EventNames.FileRead, "enabled", "threshold", "stackTrace"); - testSetting(EventNames.FileWrite, "enabled", "threshold","stackTrace"); + testSetting(EventNames.FileRead, "enabled", "threshold", "stackTrace", "throttle"); + testSetting(EventNames.FileWrite, "enabled", "threshold", "stackTrace", "throttle"); testSetting(EventNames.ExceptionStatistics, "enabled", "period"); - testSetting(EventNames.SocketRead, "enabled", "threshold", "stackTrace"); - testSetting(EventNames.SocketWrite, "enabled", "threshold", "stackTrace"); + testSetting(EventNames.SocketRead, "enabled", "threshold", "stackTrace", "throttle"); + testSetting(EventNames.SocketWrite, "enabled", "threshold", "stackTrace", "throttle"); testSetting(EventNames.ActiveRecording, "enabled"); testSetting(EventNames.ActiveSetting, "enabled"); - testSetting(EventNames.JavaExceptionThrow, "enabled", "stackTrace"); + testSetting(EventNames.JavaExceptionThrow, "enabled", "stackTrace", "throttle"); } private static void testSetting(String eventName, String... settingNames) throws Exception { diff --git a/test/jdk/jdk/jfr/startupargs/TestEventSettings.java b/test/jdk/jdk/jfr/startupargs/TestEventSettings.java index 37af394affd..c86a6331c52 100644 --- a/test/jdk/jdk/jfr/startupargs/TestEventSettings.java +++ b/test/jdk/jdk/jfr/startupargs/TestEventSettings.java @@ -51,7 +51,7 @@ import jdk.jfr.Recording; * jdk.jfr.startupargs.TestEventSettings multipleSettings * * @run main/othervm - * -XX:StartFlightRecording:class-loading=true,socket-threshold=100ms + * -XX:StartFlightRecording:class-loading=true,locking-threshold=100ms * jdk.jfr.startupargs.TestEventSettings jfcOptions */ public class TestEventSettings { @@ -70,7 +70,7 @@ public class TestEventSettings { } case "jfcOptions" -> { assertSetting("jdk.ClassDefine#enabled","true"); - assertSetting("jdk.SocketRead#threshold", "100 ms"); + assertSetting("jdk.JavaMonitorEnter#threshold", "100 ms"); } default -> throw new Exception("Uknown tes " + subTest); } From 6cdfd36ac80ad889ddbcfc702115b750a32d9645 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 5 Jun 2025 11:42:31 +0000 Subject: [PATCH 169/216] 8358590: JFR: Include min and max in MethodTiming event Reviewed-by: mgronlun --- src/hotspot/share/jfr/metadata/metadata.xml | 4 ++- .../jdk/jfr/events/MethodTimingEvent.java | 10 ++++++- .../classes/jdk/jfr/internal/query/view.ini | 4 +-- .../jfr/internal/tracing/PlatformTracer.java | 2 ++ .../jdk/jfr/internal/tracing/TimedClass.java | 7 ++++- .../jdk/jfr/internal/tracing/TimedMethod.java | 29 +++++++++++++++++-- 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 03daca946f6..d7287adb1a6 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -1315,7 +1315,9 @@ - + + + diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java index cc1d8f681c7..4998966939b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/MethodTimingEvent.java @@ -42,11 +42,19 @@ public final class MethodTimingEvent extends AbstractJDKEvent { @Label("Invocations") public long invocations; + @Label("Minimum Time") + @Timespan(Timespan.TICKS) + public long minimum; + @Label("Average Time") @Timespan(Timespan.TICKS) public long average; - public static void commit(long start, long method, long invocations, long average) { + @Label("Maximum Time") + @Timespan(Timespan.TICKS) + public long maximum; + + public static void commit(long start, long method, long invocations, long minimum, long average, long maximum) { // Generated by JFR } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini index a2ac74142f4..018f41bbf22 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/view.ini @@ -471,9 +471,9 @@ table = "COLUMN 'Alloc. Time', 'Application Method', 'Object Age', 'Heap Usage' [application.method-timing] label = "Method Timing" -table = "COLUMN 'Timed Method', 'Invocations', 'Average Time' +table = "COLUMN 'Timed Method', 'Invocations', 'Min. Tim', 'Max. Time', 'Average Time' FORMAT none, none, ms-precision:6 - SELECT LAST_BATCH(method) AS M, LAST_BATCH(invocations), LAST_BATCH(average) + SELECT LAST_BATCH(method) AS M, LAST_BATCH(invocations), LAST_BATCH(minimum), LAST_BATCH(maximum), LAST_BATCH(average) FROM jdk.MethodTiming GROUP BY method ORDER BY average" [application.method-calls] diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java index 608fe865147..abc3b0f8cd0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/PlatformTracer.java @@ -146,6 +146,7 @@ public final class PlatformTracer { public static void addObjectTiming(long duration) { OBJECT.invocations().getAndIncrement(); OBJECT.time().addAndGet(duration); + OBJECT.updateMinMax(duration); } public static void addTiming(long id, long duration) { @@ -153,6 +154,7 @@ public final class PlatformTracer { if (entry != null) { entry.invocations().getAndIncrement(); entry.time().addAndGet(duration); + entry.updateMinMax(duration); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedClass.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedClass.java index 936a8cf835d..ed592fec645 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedClass.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedClass.java @@ -61,7 +61,12 @@ public final class TimedClass { long invocations = tm.invocations().get(); long time = tm.time().get(); long average = invocations == 0 ? Long.MIN_VALUE : time / invocations; - MethodTimingEvent.commit(timestamp, methodId, invocations, average); + long min = tm.minimum().get(); + if (min == Long.MAX_VALUE) { + min = Long.MIN_VALUE; // Signals that the value is missing + } + long max = tm.maximum().get(); + MethodTimingEvent.commit(timestamp, methodId, invocations, min, average, max); tm.method().log("Emitted event"); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedMethod.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedMethod.java index 185fab62421..be7f0c8f084 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedMethod.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tracing/TimedMethod.java @@ -33,8 +33,33 @@ import java.util.concurrent.atomic.AtomicLong; *

        * Fields in record classes are truly final so might help to have a record here. */ -record TimedMethod(AtomicLong invocations, AtomicLong time, Method method, AtomicBoolean published) { +record TimedMethod(AtomicLong invocations, AtomicLong time, AtomicLong minimum, AtomicLong maximum, Method method, AtomicBoolean published) { TimedMethod(Method method) { - this(new AtomicLong(), new AtomicLong(), method, new AtomicBoolean()); + this(new AtomicLong(), new AtomicLong(), new AtomicLong(Long.MAX_VALUE), new AtomicLong(Long.MIN_VALUE), method, new AtomicBoolean()); + } + + public void updateMinMax(long duration) { + if (duration > maximum.getPlain()) { + while (true) { + long max = maximum.get(); + if (duration <= max) { + return; + } + if (maximum.weakCompareAndSetVolatile(max, duration)) { + return; + } + } + } + if (duration < minimum.getPlain()) { + while (true) { + long min = minimum.get(); + if (duration >= min) { + return; + } + if (minimum.weakCompareAndSetVolatile(min, duration)) { + return; + } + } + } } } From 782bbca439cd0d6db9366b4bd8d4861b8f780203 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Thu, 5 Jun 2025 12:04:57 +0000 Subject: [PATCH 170/216] 8358633: Test ThreadPoolExecutorTest::testTimedInvokeAnyNullTimeUnit is broken by JDK-8347491 Reviewed-by: alanb --- test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java index d9ce643a26d..2bc66b1e9e3 100644 --- a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java +++ b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java @@ -1727,7 +1727,7 @@ public class ThreadPoolExecutorTest extends JSR166TestCase { e.invokeAny(l, randomTimeout(), null); shouldThrow(); } catch (NullPointerException success) { - assertEquals("Cannot invoke \"java.util.concurrent.TimeUnit.toNanos(long)\" because \"unit\" is null", success.getMessage()); + // Do not check the message, as ThreadPoolExecutor does not override invokeAny } } } From 33ed7c1842e61664c1ad0ea4d29f20728c89e06c Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 5 Jun 2025 13:08:48 +0000 Subject: [PATCH 171/216] 8358689: test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java does not build after JDK-8351594 Reviewed-by: alanb --- .../bench/java/net/SocketEventOverhead.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java b/test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java index c405de0af3c..0ba577f49d7 100644 --- a/test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java +++ b/test/micro/org/openjdk/bench/java/net/SocketEventOverhead.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -65,7 +65,7 @@ public class SocketEventOverhead { @Fork(value = 1, jvmArgs = { "--add-exports", "java.base/jdk.internal.event=ALL-UNNAMED", - "-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=1s"}) + "-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=1s,jdk.SocketWrite#throttle=off"}) @Benchmark public int socketWriteJFREnabledEventNotEmitted(SkeletonFixture fixture) { return fixture.write(); @@ -73,7 +73,7 @@ public class SocketEventOverhead { @Fork(value = 1, jvmArgs = { "--add-exports","java.base/jdk.internal.event=ALL-UNNAMED", - "-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=0ms,disk=false,jdk.SocketWrite#stackTrace=false"}) + "-XX:StartFlightRecording:jdk.SocketWrite#enabled=true,jdk.SocketWrite#threshold=0ms,disk=false,jdk.SocketWrite#stackTrace=false,jdk.SocketWrite#throttle=off"}) @Benchmark public int socketWriteJFREnabledEventEmitted(SkeletonFixture fixture) { return fixture.write(); @@ -99,7 +99,7 @@ public class SocketEventOverhead { @Fork(value = 1, jvmArgs = { "--add-exports", "java.base/jdk.internal.event=ALL-UNNAMED", - "-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=1s"}) + "-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=1s,jdk.SocketRead#throttle=off"}) @Benchmark public int socketReadJFREnabledEventNotEmitted(SkeletonFixture fixture) { return fixture.read(); @@ -107,7 +107,7 @@ public class SocketEventOverhead { @Fork(value = 1, jvmArgs = { "--add-exports","java.base/jdk.internal.event=ALL-UNNAMED", - "-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=0ms,disk=false,jdk.SocketRead#stackTrace=false"}) + "-XX:StartFlightRecording:jdk.SocketRead#enabled=true,jdk.SocketRead#threshold=0ms,disk=false,jdk.SocketRead#stackTrace=false,jdk.SocketRead#throttle=off"}) @Benchmark public int socketReadJFREnabledEventEmitted(SkeletonFixture fixture) { return fixture.read(); @@ -137,10 +137,7 @@ public class SocketEventOverhead { try { nbytes = write0(); } finally { - long duration = start - SocketWriteEvent.timestamp(); - if (SocketWriteEvent.shouldCommit(duration)) { - SocketWriteEvent.emit(start, duration, nbytes, getRemoteAddress()); - } + SocketWriteEvent.offer(start, nbytes, getRemoteAddress()); } return nbytes; } @@ -158,10 +155,7 @@ public class SocketEventOverhead { try { nbytes = read0(); } finally { - long duration = start - SocketReadEvent.timestamp(); - if (SocketReadEvent.shouldCommit(duration)) { - SocketReadEvent.emit(start, duration, nbytes, getRemoteAddress(), 0); - } + SocketReadEvent.offer(start, nbytes, getRemoteAddress(), 0); } return nbytes; } From 23f1d4f9a993033596ff17751c877f2bb3f792ed Mon Sep 17 00:00:00 2001 From: Dmitry Chuyko Date: Thu, 5 Jun 2025 14:28:27 +0000 Subject: [PATCH 172/216] 8337666: AArch64: SHA3 GPR intrinsic Reviewed-by: aph --- src/hotspot/cpu/aarch64/globals_aarch64.hpp | 4 +- .../cpu/aarch64/macroAssembler_aarch64.hpp | 21 + .../cpu/aarch64/stubGenerator_aarch64.cpp | 370 +++++++++++++++++- .../cpu/aarch64/vm_version_aarch64.cpp | 2 +- .../sha/sanity/TestSHA3Intrinsics.java | 128 +++++- .../sanity/TestSHA3MultiBlockIntrinsics.java | 230 ++++++++++- 6 files changed, 749 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp index 632bba728a1..b316103d656 100644 --- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -95,6 +95,8 @@ define_pd_global(intx, InlineSmallCode, 1000); "Use simplest and shortest implementation for array equals") \ product(bool, UseSIMDForBigIntegerShiftIntrinsics, true, \ "Use SIMD instructions for left/right shift of BigInteger") \ + product(bool, UseSIMDForSHA3Intrinsic, true, \ + "Use SIMD SHA3 instructions for SHA3 intrinsic") \ product(bool, AvoidUnalignedAccesses, false, \ "Avoid generating unaligned memory accesses") \ product(bool, UseLSE, false, \ diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 32506c49cfa..d77bc92875f 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -323,6 +323,27 @@ class MacroAssembler: public Assembler { extr(Rd, Rn, Rn, imm); } + inline void rolw(Register Rd, Register Rn, unsigned imm) { + extrw(Rd, Rn, Rn, (32 - imm)); + } + + inline void rol(Register Rd, Register Rn, unsigned imm) { + extr(Rd, Rn, Rn, (64 - imm)); + } + + using Assembler::rax1; + using Assembler::eor3; + + inline void rax1(Register Rd, Register Rn, Register Rm) { + eor(Rd, Rn, Rm, ROR, 63); // Rd = Rn ^ rol(Rm, 1) + } + + inline void eor3(Register Rd, Register Rn, Register Rm, Register Rk) { + assert(Rd != Rn, "Use tmp register"); + eor(Rd, Rm, Rk); + eor(Rd, Rd, Rn); + } + inline void sxtbw(Register Rd, Register Rn) { sbfmw(Rd, Rn, 0, 7); } diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 1b6f6d489f3..a0d1e22ff96 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -7081,6 +7081,366 @@ class StubGenerator: public StubCodeGenerator { return start; } + void bcax5(Register a0, Register a1, Register a2, Register a3, Register a4, + Register tmp0, Register tmp1, Register tmp2) { + __ bic(tmp0, a2, a1); // for a0 + __ bic(tmp1, a3, a2); // for a1 + __ bic(tmp2, a4, a3); // for a2 + __ eor(a2, a2, tmp2); + __ bic(tmp2, a0, a4); // for a3 + __ eor(a3, a3, tmp2); + __ bic(tmp2, a1, a0); // for a4 + __ eor(a0, a0, tmp0); + __ eor(a1, a1, tmp1); + __ eor(a4, a4, tmp2); + } + + void keccak_round_gpr(bool can_use_fp, bool can_use_r18, Register rc, + Register a0, Register a1, Register a2, Register a3, Register a4, + Register a5, Register a6, Register a7, Register a8, Register a9, + Register a10, Register a11, Register a12, Register a13, Register a14, + Register a15, Register a16, Register a17, Register a18, Register a19, + Register a20, Register a21, Register a22, Register a23, Register a24, + Register tmp0, Register tmp1, Register tmp2) { + __ eor3(tmp1, a4, a9, a14); + __ eor3(tmp0, tmp1, a19, a24); // tmp0 = a4^a9^a14^a19^a24 = c4 + __ eor3(tmp2, a1, a6, a11); + __ eor3(tmp1, tmp2, a16, a21); // tmp1 = a1^a6^a11^a16^a21 = c1 + __ rax1(tmp2, tmp0, tmp1); // d0 + { + + Register tmp3, tmp4; + if (can_use_fp && can_use_r18) { + tmp3 = rfp; + tmp4 = r18_tls; + } else { + tmp3 = a4; + tmp4 = a9; + __ stp(tmp3, tmp4, __ pre(sp, -16)); + } + + __ eor3(tmp3, a0, a5, a10); + __ eor3(tmp4, tmp3, a15, a20); // tmp4 = a0^a5^a10^a15^a20 = c0 + __ eor(a0, a0, tmp2); + __ eor(a5, a5, tmp2); + __ eor(a10, a10, tmp2); + __ eor(a15, a15, tmp2); + __ eor(a20, a20, tmp2); // d0(tmp2) + __ eor3(tmp3, a2, a7, a12); + __ eor3(tmp2, tmp3, a17, a22); // tmp2 = a2^a7^a12^a17^a22 = c2 + __ rax1(tmp3, tmp4, tmp2); // d1 + __ eor(a1, a1, tmp3); + __ eor(a6, a6, tmp3); + __ eor(a11, a11, tmp3); + __ eor(a16, a16, tmp3); + __ eor(a21, a21, tmp3); // d1(tmp3) + __ rax1(tmp3, tmp2, tmp0); // d3 + __ eor3(tmp2, a3, a8, a13); + __ eor3(tmp0, tmp2, a18, a23); // tmp0 = a3^a8^a13^a18^a23 = c3 + __ eor(a3, a3, tmp3); + __ eor(a8, a8, tmp3); + __ eor(a13, a13, tmp3); + __ eor(a18, a18, tmp3); + __ eor(a23, a23, tmp3); + __ rax1(tmp2, tmp1, tmp0); // d2 + __ eor(a2, a2, tmp2); + __ eor(a7, a7, tmp2); + __ eor(a12, a12, tmp2); + __ rax1(tmp0, tmp0, tmp4); // d4 + if (!can_use_fp || !can_use_r18) { + __ ldp(tmp3, tmp4, __ post(sp, 16)); + } + __ eor(a17, a17, tmp2); + __ eor(a22, a22, tmp2); + __ eor(a4, a4, tmp0); + __ eor(a9, a9, tmp0); + __ eor(a14, a14, tmp0); + __ eor(a19, a19, tmp0); + __ eor(a24, a24, tmp0); + } + + __ rol(tmp0, a10, 3); + __ rol(a10, a1, 1); + __ rol(a1, a6, 44); + __ rol(a6, a9, 20); + __ rol(a9, a22, 61); + __ rol(a22, a14, 39); + __ rol(a14, a20, 18); + __ rol(a20, a2, 62); + __ rol(a2, a12, 43); + __ rol(a12, a13, 25); + __ rol(a13, a19, 8) ; + __ rol(a19, a23, 56); + __ rol(a23, a15, 41); + __ rol(a15, a4, 27); + __ rol(a4, a24, 14); + __ rol(a24, a21, 2); + __ rol(a21, a8, 55); + __ rol(a8, a16, 45); + __ rol(a16, a5, 36); + __ rol(a5, a3, 28); + __ rol(a3, a18, 21); + __ rol(a18, a17, 15); + __ rol(a17, a11, 10); + __ rol(a11, a7, 6); + __ mov(a7, tmp0); + + bcax5(a0, a1, a2, a3, a4, tmp0, tmp1, tmp2); + bcax5(a5, a6, a7, a8, a9, tmp0, tmp1, tmp2); + bcax5(a10, a11, a12, a13, a14, tmp0, tmp1, tmp2); + bcax5(a15, a16, a17, a18, a19, tmp0, tmp1, tmp2); + bcax5(a20, a21, a22, a23, a24, tmp0, tmp1, tmp2); + + __ ldr(tmp1, __ post(rc, 8)); + __ eor(a0, a0, tmp1); + + } + + // Arguments: + // + // Inputs: + // c_rarg0 - byte[] source+offset + // c_rarg1 - byte[] SHA.state + // c_rarg2 - int block_size + // c_rarg3 - int offset + // c_rarg4 - int limit + // + address generate_sha3_implCompress_gpr(StubGenStubId stub_id) { + bool multi_block; + switch (stub_id) { + case sha3_implCompress_id: + multi_block = false; + break; + case sha3_implCompressMB_id: + multi_block = true; + break; + default: + ShouldNotReachHere(); + } + + static const uint64_t round_consts[24] = { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, + 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, + 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, + 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L + }; + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); + address start = __ pc(); + + Register buf = c_rarg0; + Register state = c_rarg1; + Register block_size = c_rarg2; + Register ofs = c_rarg3; + Register limit = c_rarg4; + + // use r3.r17,r19..r28 to keep a0..a24. + // a0..a24 are respective locals from SHA3.java + Register a0 = r25, + a1 = r26, + a2 = r27, + a3 = r3, + a4 = r4, + a5 = r5, + a6 = r6, + a7 = r7, + a8 = rscratch1, // r8 + a9 = rscratch2, // r9 + a10 = r10, + a11 = r11, + a12 = r12, + a13 = r13, + a14 = r14, + a15 = r15, + a16 = r16, + a17 = r17, + a18 = r28, + a19 = r19, + a20 = r20, + a21 = r21, + a22 = r22, + a23 = r23, + a24 = r24; + + Register tmp0 = block_size, tmp1 = buf, tmp2 = state, tmp3 = r30; + + Label sha3_loop, rounds24_preloop, loop_body; + Label sha3_512_or_sha3_384, shake128; + + bool can_use_r18 = false; +#ifndef R18_RESERVED + can_use_r18 = true; +#endif + bool can_use_fp = !PreserveFramePointer; + + __ enter(); + + // save almost all yet unsaved gpr registers on stack + __ str(block_size, __ pre(sp, -128)); + if (multi_block) { + __ stpw(ofs, limit, Address(sp, 8)); + } + // 8 bytes at sp+16 will be used to keep buf + __ stp(r19, r20, Address(sp, 32)); + __ stp(r21, r22, Address(sp, 48)); + __ stp(r23, r24, Address(sp, 64)); + __ stp(r25, r26, Address(sp, 80)); + __ stp(r27, r28, Address(sp, 96)); + if (can_use_r18 && can_use_fp) { + __ stp(r18_tls, state, Address(sp, 112)); + } else { + __ str(state, Address(sp, 112)); + } + + // begin sha3 calculations: loading a0..a24 from state arrary + __ ldp(a0, a1, state); + __ ldp(a2, a3, Address(state, 16)); + __ ldp(a4, a5, Address(state, 32)); + __ ldp(a6, a7, Address(state, 48)); + __ ldp(a8, a9, Address(state, 64)); + __ ldp(a10, a11, Address(state, 80)); + __ ldp(a12, a13, Address(state, 96)); + __ ldp(a14, a15, Address(state, 112)); + __ ldp(a16, a17, Address(state, 128)); + __ ldp(a18, a19, Address(state, 144)); + __ ldp(a20, a21, Address(state, 160)); + __ ldp(a22, a23, Address(state, 176)); + __ ldr(a24, Address(state, 192)); + + __ BIND(sha3_loop); + + // load input + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a0, a0, tmp3); + __ eor(a1, a1, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a2, a2, tmp3); + __ eor(a3, a3, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a4, a4, tmp3); + __ eor(a5, a5, tmp2); + __ ldr(tmp3, __ post(buf, 8)); + __ eor(a6, a6, tmp3); + + // block_size == 72, SHA3-512; block_size == 104, SHA3-384 + __ tbz(block_size, 7, sha3_512_or_sha3_384); + + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a7, a7, tmp3); + __ eor(a8, a8, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a9, a9, tmp3); + __ eor(a10, a10, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a11, a11, tmp3); + __ eor(a12, a12, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a13, a13, tmp3); + __ eor(a14, a14, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a15, a15, tmp3); + __ eor(a16, a16, tmp2); + + // block_size == 136, bit4 == 0 and bit5 == 0, SHA3-256 or SHAKE256 + __ andw(tmp2, block_size, 48); + __ cbzw(tmp2, rounds24_preloop); + __ tbnz(block_size, 5, shake128); + // block_size == 144, bit5 == 0, SHA3-244 + __ ldr(tmp3, __ post(buf, 8)); + __ eor(a17, a17, tmp3); + __ b(rounds24_preloop); + + __ BIND(shake128); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a17, a17, tmp3); + __ eor(a18, a18, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a19, a19, tmp3); + __ eor(a20, a20, tmp2); + __ b(rounds24_preloop); // block_size == 168, SHAKE128 + + __ BIND(sha3_512_or_sha3_384); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a7, a7, tmp3); + __ eor(a8, a8, tmp2); + __ tbz(block_size, 5, rounds24_preloop); // SHA3-512 + + // SHA3-384 + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a9, a9, tmp3); + __ eor(a10, a10, tmp2); + __ ldp(tmp3, tmp2, __ post(buf, 16)); + __ eor(a11, a11, tmp3); + __ eor(a12, a12, tmp2); + + __ BIND(rounds24_preloop); + __ fmovs(v0, 24.0); // float loop counter, + __ fmovs(v1, 1.0); // exact representation + + __ str(buf, Address(sp, 16)); + __ lea(tmp3, ExternalAddress((address) round_consts)); + + __ BIND(loop_body); + keccak_round_gpr(can_use_fp, can_use_r18, tmp3, + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, + tmp0, tmp1, tmp2); + __ fsubs(v0, v0, v1); + __ fcmps(v0, 0.0); + __ br(__ NE, loop_body); + + if (multi_block) { + __ ldrw(block_size, sp); // block_size + __ ldpw(tmp2, tmp1, Address(sp, 8)); // offset, limit + __ addw(tmp2, tmp2, block_size); + __ cmpw(tmp2, tmp1); + __ strw(tmp2, Address(sp, 8)); // store offset in case we're jumping + __ ldr(buf, Address(sp, 16)); // restore buf in case we're jumping + __ br(Assembler::LE, sha3_loop); + __ movw(c_rarg0, tmp2); // return offset + } + if (can_use_fp && can_use_r18) { + __ ldp(r18_tls, state, Address(sp, 112)); + } else { + __ ldr(state, Address(sp, 112)); + } + // save calculated sha3 state + __ stp(a0, a1, Address(state)); + __ stp(a2, a3, Address(state, 16)); + __ stp(a4, a5, Address(state, 32)); + __ stp(a6, a7, Address(state, 48)); + __ stp(a8, a9, Address(state, 64)); + __ stp(a10, a11, Address(state, 80)); + __ stp(a12, a13, Address(state, 96)); + __ stp(a14, a15, Address(state, 112)); + __ stp(a16, a17, Address(state, 128)); + __ stp(a18, a19, Address(state, 144)); + __ stp(a20, a21, Address(state, 160)); + __ stp(a22, a23, Address(state, 176)); + __ str(a24, Address(state, 192)); + + // restore required registers from stack + __ ldp(r19, r20, Address(sp, 32)); + __ ldp(r21, r22, Address(sp, 48)); + __ ldp(r23, r24, Address(sp, 64)); + __ ldp(r25, r26, Address(sp, 80)); + __ ldp(r27, r28, Address(sp, 96)); + if (can_use_fp && can_use_r18) { + __ add(rfp, sp, 128); // leave() will copy rfp to sp below + } // else no need to recalculate rfp, since it wasn't changed + + __ leave(); + + __ ret(lr); + + return start; + } + /** * Arguments: * @@ -11512,9 +11872,15 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubGenStubId::sha512_implCompressMB_id); } if (UseSHA3Intrinsics) { - StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_double_keccak = generate_double_keccak(); - StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); + if (UseSIMDForSHA3Intrinsic) { + StubRoutines::_sha3_implCompress = generate_sha3_implCompress(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress(StubGenStubId::sha3_implCompressMB_id); + } else { + StubRoutines::_sha3_implCompress = generate_sha3_implCompress_gpr(StubGenStubId::sha3_implCompress_id); + StubRoutines::_sha3_implCompressMB = generate_sha3_implCompress_gpr(StubGenStubId::sha3_implCompressMB_id); + } } if (UsePoly1305Intrinsics) { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 6ed7a6be585..941cb254532 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -379,7 +379,7 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseSHA3Intrinsics, true); } } - } else if (UseSHA3Intrinsics) { + } else if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic) { warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); } diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java index f4d16af854e..44bfa10e36d 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3Intrinsics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -40,6 +40,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -Dalgorithm=SHA3-224 * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions @@ -58,6 +59,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -Dalgorithm=SHA3-256 * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions @@ -76,6 +78,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -Dalgorithm=SHA3-384 * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions @@ -94,6 +97,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -Dalgorithm=SHA3-512 * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions @@ -110,6 +114,128 @@ * negative_224.log negative_256.log negative_384.log negative_512.log */ +/** + * @test + * @bug 8337666 + * @requires os.arch == "aarch64" + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 intrinsic is actually used. + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log positive_384.log positive_512.log + */ + +/** + * @test + * @bug 8337666 + * @requires os.arch == "aarch64" + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 intrinsic is actually used. + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3Intrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log positive_384.log positive_512.log + */ + package compiler.intrinsics.sha.sanity; import compiler.testlibrary.sha.predicate.IntrinsicPredicates; diff --git a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java index d350a5f0b13..b6b3fb22dd5 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java +++ b/test/hotspot/jtreg/compiler/intrinsics/sha/sanity/TestSHA3MultiBlockIntrinsics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -40,6 +40,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-224 * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics @@ -50,6 +51,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-224 + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 @@ -67,6 +69,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-256 * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics @@ -77,6 +80,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-256 + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 @@ -94,6 +98,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-384 * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics @@ -104,6 +109,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-384 + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 @@ -121,6 +127,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-512 * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics @@ -131,6 +138,7 @@ * -XX:CompileOnly=sun.security.provider.DigestBase::* * -XX:CompileOnly=sun.security.provider.SHA3::* * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-512 + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseSIMDForSHA3Intrinsic * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 @@ -147,6 +155,226 @@ * negative_384.log negative_512.log */ +/** + * @test + * @bug 8337666 + * @requires os.arch == "aarch64" + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 multi block intrinsic is actually used. + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-224 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-256 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-384 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-512 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:-PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log + * positive_384.log positive_512.log positive_224_def.log positive_256_def.log + * positive_384_def.log positive_512_def.log + */ + +/** + * @test + * @bug 8337666 + * @requires os.arch == "aarch64" + * @summary Verify that SHA3-224, SHA3-256, SHA3-384, SHA3-512 multi block intrinsic is actually used. + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-224 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_224_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-224 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-256 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_256_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-256 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-384 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_384_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-384 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -XX:-UseMD5Intrinsics + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * -XX:-UseSHA1Intrinsics -XX:-UseSHA256Intrinsics + * -XX:-UseSHA512Intrinsics -Dalgorithm=SHA3-512 + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:CompileThreshold=500 + * -XX:Tier4InvocationThreshold=500 + * -XX:+LogCompilation -XX:LogFile=positive_512_def.log + * -XX:CompileOnly=sun.security.provider.DigestBase::* + * -XX:CompileOnly=sun.security.provider.SHA3::* + * -XX:+UseSHA3Intrinsics -Dalgorithm=SHA3-512 + * -XX:+IgnoreUnrecognizedVMOptions + * -XX:-UseSIMDForSHA3Intrinsic -XX:+PreserveFramePointer + * compiler.intrinsics.sha.sanity.TestSHA3MultiBlockIntrinsics + * @run main/othervm -DverificationStrategy=VERIFY_INTRINSIC_USAGE + * compiler.testlibrary.intrinsics.Verifier positive_224.log positive_256.log + * positive_384.log positive_512.log positive_224_def.log positive_256_def.log + * positive_384_def.log positive_512_def.log + */ + package compiler.intrinsics.sha.sanity; import compiler.testlibrary.sha.predicate.IntrinsicPredicates; From c59e44a7aa2aeff0823830b698d524523b996650 Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo Date: Thu, 5 Jun 2025 15:02:02 +0000 Subject: [PATCH 173/216] 8357914: TestEmptyBootstrapMethodsAttr.java fails when run with TEST_THREAD_FACTORY=Virtual Reviewed-by: lmesnik, dholmes, sspitsyn, syan --- test/hotspot/jtreg/ProblemList-Virtual.txt | 1 - .../TestEmptyBootstrapMethodsAttr.java | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index dbd555c1cdd..4216eddb885 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -90,7 +90,6 @@ vmTestbase/nsk/jdi/ThreadReference/isSuspended/issuspended002/TestDescription.ja gc/arguments/TestNewSizeThreadIncrease.java 0000000 generic-all gc/g1/TestSkipRebuildRemsetPhase.java 0000000 generic-all -runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java 8346442 generic-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 0000000 generic-all runtime/Thread/AsyncExceptionOnMonitorEnter.java 0000000 generic-all runtime/Thread/StopAtExit.java 0000000 generic-all diff --git a/test/hotspot/jtreg/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java b/test/hotspot/jtreg/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java index 53c85d53c44..33d42a31a04 100644 --- a/test/hotspot/jtreg/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java +++ b/test/hotspot/jtreg/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,8 +54,13 @@ public class TestEmptyBootstrapMethodsAttr { "-Duser.language=en", "-Duser.country=US", className); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotContain("java.lang.ClassFormatError"); - output.shouldContain("Main method not found in class " + className); output.shouldHaveExitValue(1); + boolean vthreadMode = pb.command().toString().contains("test.thread.factory=Virtual"); + if (vthreadMode) { + output.shouldContain("java.lang.NoSuchMethodException: " + className + ".main"); + } else { + output.shouldContain("Main method not found in class " + className); + } // Test case #2: // Try loading class with empty bootstrap_methods table where an @@ -69,7 +74,12 @@ public class TestEmptyBootstrapMethodsAttr { "-Duser.language=en", "-Duser.country=US", className); output = new OutputAnalyzer(pb.start()); output.shouldNotContain("java.lang.ClassFormatError"); - output.shouldContain("Main method not found in class " + className); output.shouldHaveExitValue(1); + vthreadMode = pb.command().toString().contains("test.thread.factory=Virtual"); + if (vthreadMode) { + output.shouldContain("java.lang.NoSuchMethodException: " + className + ".main"); + } else { + output.shouldContain("Main method not found in class " + className); + } } } From af87035b713f8bfe05a007a4d4670cefc6a6aaf2 Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Thu, 5 Jun 2025 16:01:32 +0000 Subject: [PATCH 174/216] 8355746: Start of release updates for JDK 26 8355748: Add SourceVersion.RELEASE_26 8355751: Add source 26 and target 26 to javac Co-authored-by: Joe Darcy Reviewed-by: iris, coleenp, darcy --- .jcheck/conf | 2 +- make/conf/version-numbers.conf | 10 +- .../share/classfile/classFileParser.cpp | 2 + .../java/lang/classfile/ClassFile.java | 10 +- .../lang/reflect/ClassFileFormatVersion.java | 14 +- .../javax/lang/model/SourceVersion.java | 16 +- .../AbstractAnnotationValueVisitor14.java | 4 +- ...AbstractAnnotationValueVisitorPreview.java | 4 +- .../model/util/AbstractElementVisitor14.java | 4 +- .../util/AbstractElementVisitorPreview.java | 4 +- .../model/util/AbstractTypeVisitor14.java | 4 +- .../util/AbstractTypeVisitorPreview.java | 4 +- .../lang/model/util/ElementKindVisitor14.java | 4 +- .../model/util/ElementKindVisitorPreview.java | 4 +- .../lang/model/util/ElementScanner14.java | 4 +- .../model/util/ElementScannerPreview.java | 4 +- .../util/SimpleAnnotationValueVisitor14.java | 4 +- .../SimpleAnnotationValueVisitorPreview.java | 4 +- .../model/util/SimpleElementVisitor14.java | 4 +- .../util/SimpleElementVisitorPreview.java | 4 +- .../lang/model/util/SimpleTypeVisitor14.java | 4 +- .../model/util/SimpleTypeVisitorPreview.java | 4 +- .../lang/model/util/TypeKindVisitor14.java | 4 +- .../model/util/TypeKindVisitorPreview.java | 4 +- .../com/sun/tools/javac/code/Source.java | 7 + .../com/sun/tools/javac/jvm/ClassFile.java | 3 +- .../com/sun/tools/javac/jvm/Target.java | 3 + .../javac/processing/PrintingProcessor.java | 2 +- .../share/data/symbols/java.base-P.sym.txt | 829 ++++++++++++++++++ .../data/symbols/java.compiler-P.sym.txt | 85 ++ .../share/data/symbols/java.desktop-P.sym.txt | 43 + .../share/data/symbols/java.logging-P.sym.txt | 44 + .../data/symbols/java.management-P.sym.txt | 57 ++ .../data/symbols/java.net.http-P.sym.txt | 37 + .../data/symbols/java.security.jgss-P.sym.txt | 36 + .../data/symbols/java.xml.crypto-P.sym.txt | 34 + .../share/data/symbols/jdk.attach-P.sym.txt | 32 + .../share/data/symbols/jdk.compiler-P.sym.txt | 32 + .../symbols/jdk.crypto.cryptoki-P.sym.txt | 31 + .../symbols/jdk.incubator.foreign-P.sym.txt | 105 +++ .../symbols/jdk.incubator.vector-P.sym.txt | 113 +++ .../share/data/symbols/jdk.jdi-P.sym.txt | 32 + .../share/data/symbols/jdk.jfr-P.sym.txt | 31 + .../share/data/symbols/jdk.jpackage-P.sym.txt | 31 + .../share/data/symbols/jdk.jshell-P.sym.txt | 46 + .../share/data/symbols/jdk.net-P.sym.txt | 31 + .../data/symbols/jdk.security.jgss-P.sym.txt | 31 + src/jdk.compiler/share/data/symbols/symbols | 5 +- test/hotspot/jtreg/ProblemList.txt | 5 + .../CommandLine/VMDeprecatedOptions.java | 17 +- .../asm/org/objectweb/asm/ClassReader.java | 2 +- .../asm/org/objectweb/asm/Opcodes.java | 1 + test/jdk/ProblemList.txt | 6 + .../javac/api/TestGetSourceVersions.java | 6 +- .../javac/classfiles/ClassVersionChecker.java | 5 +- .../lib/JavacTestingAbstractProcessor.java | 20 +- .../options/HelpOutputColumnWidthTest.java | 4 +- .../classReaderTest/Client.nopreview.out | 2 +- .../classReaderTest/Client.preview.out | 2 +- .../tools/javac/versions/Versions.java | 8 +- 60 files changed, 1814 insertions(+), 90 deletions(-) create mode 100644 src/jdk.compiler/share/data/symbols/java.base-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.compiler-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.desktop-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.logging-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.management-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.net.http-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.security.jgss-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/java.xml.crypto-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.attach-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.compiler-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.crypto.cryptoki-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.incubator.foreign-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.incubator.vector-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.jdi-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.jfr-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.jpackage-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.jshell-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.net-P.sym.txt create mode 100644 src/jdk.compiler/share/data/symbols/jdk.security.jgss-P.sym.txt diff --git a/.jcheck/conf b/.jcheck/conf index 6ab5c2d64c2..60881e74d2a 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk jbs=JDK -version=25 +version=26 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists,copyright diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index ce9e32315a9..38d6e42dff9 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -26,17 +26,17 @@ # Default version, product, and vendor information to use, # unless overridden by configure -DEFAULT_VERSION_FEATURE=25 +DEFAULT_VERSION_FEATURE=26 DEFAULT_VERSION_INTERIM=0 DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2025-09-16 -DEFAULT_VERSION_CLASSFILE_MAJOR=69 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" +DEFAULT_VERSION_DATE=2026-03-17 +DEFAULT_VERSION_CLASSFILE_MAJOR=70 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="24 25" -DEFAULT_JDK_SOURCE_TARGET_VERSION=25 +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="24 25 26" +DEFAULT_JDK_SOURCE_TARGET_VERSION=26 DEFAULT_PROMOTED_VERSION_PRE=ea diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 0f021c0ef4d..bfb41f8384a 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -154,6 +154,8 @@ #define JAVA_25_VERSION 69 +#define JAVA_26_VERSION 70 + void ClassFileParser::set_class_bad_constant_seen(short bad_constant) { assert((bad_constant == JVM_CONSTANT_Module || bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION, diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFile.java b/src/java.base/share/classes/java/lang/classfile/ClassFile.java index 4b529c39099..216facbdddf 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFile.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFile.java @@ -1030,6 +1030,14 @@ public sealed interface ClassFile */ int JAVA_25_VERSION = 69; + /** + * The class major version introduced by Java SE 26, {@value}. + * + * @see ClassFileFormatVersion#RELEASE_26 + * @since 26 + */ + int JAVA_26_VERSION = 70; + /** * A minor version number {@value} indicating a class uses preview features * of a Java SE release since 12, for major versions {@value @@ -1041,7 +1049,7 @@ public sealed interface ClassFile * {@return the latest class major version supported by the current runtime} */ static int latestMajorVersion() { - return JAVA_25_VERSION; + return JAVA_26_VERSION; } /** diff --git a/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java b/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java index 70eb921a124..4a63dd157f8 100644 --- a/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java +++ b/src/java.base/share/classes/java/lang/reflect/ClassFileFormatVersion.java @@ -371,6 +371,18 @@ public enum ClassFileFormatVersion { * The Java Virtual Machine Specification, Java SE 25 Edition */ RELEASE_25(69), + + /** + * The version introduced by the Java Platform, Standard Edition + * 26. + * + * @since 26 + * + * @see + * The Java Virtual Machine Specification, Java SE 26 Edition + */ + RELEASE_26(70), ; // Reduce code churn when appending new constants // Note to maintainers: when adding constants for newer releases, @@ -386,7 +398,7 @@ public enum ClassFileFormatVersion { * {@return the latest class file format version} */ public static ClassFileFormatVersion latest() { - return RELEASE_25; + return RELEASE_26; } /** diff --git a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java index 46d1a2cf9c9..6b4ae119504 100644 --- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java +++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java @@ -468,6 +468,18 @@ public enum SourceVersion { * JEP 513: Flexible Constructor Bodies */ RELEASE_25, + + /** + * The version introduced by the Java Platform, Standard Edition + * 26. + * + * @since 26 + * + * @see + * The Java Language Specification, Java SE 26 Edition + */ + RELEASE_26, ; // Reduce code churn when appending new constants // Note that when adding constants for newer releases, the @@ -477,7 +489,7 @@ public enum SourceVersion { * {@return the latest source version that can be modeled} */ public static SourceVersion latest() { - return RELEASE_25; + return RELEASE_26; } private static final SourceVersion latestSupported = getLatestSupported(); @@ -492,7 +504,7 @@ public enum SourceVersion { private static SourceVersion getLatestSupported() { int intVersion = Runtime.version().feature(); return (intVersion >= 11) ? - valueOf("RELEASE_" + Math.min(25, intVersion)): + valueOf("RELEASE_" + Math.min(26, intVersion)): RELEASE_10; } diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java index 4d36781c584..2b2f80358b0 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -44,7 +44,7 @@ import javax.annotation.processing.SupportedSourceVersion; * @see AbstractAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public abstract class AbstractAnnotationValueVisitor14 extends AbstractAnnotationValueVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitorPreview.java index 4afcc7fbf1d..59d1eb28282 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -50,7 +50,7 @@ import javax.annotation.processing.ProcessingEnvironment; * @see AbstractAnnotationValueVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public abstract class AbstractAnnotationValueVisitorPreview extends AbstractAnnotationValueVisitor14 { diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java index 3a57ef18c5b..b624bb9f999 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -50,7 +50,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractElementVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public abstract class AbstractElementVisitor14 extends AbstractElementVisitor9 { /** * Constructor for concrete subclasses to call. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitorPreview.java index b9642b203fe..761916a1434 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -53,7 +53,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractElementVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public abstract class AbstractElementVisitorPreview extends AbstractElementVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java index eb96f4abb99..1860cd09ac5 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -47,7 +47,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public abstract class AbstractTypeVisitor14 extends AbstractTypeVisitor9 { /** * Constructor for concrete subclasses to call. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitorPreview.java index 74b007356d4..6b701262a4f 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -53,7 +53,7 @@ import static javax.lang.model.SourceVersion.*; * @see AbstractTypeVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public abstract class AbstractTypeVisitorPreview extends AbstractTypeVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java index d7941d6e153..cb0e1cfbc9f 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -61,7 +61,7 @@ import javax.lang.model.SourceVersion; * @see ElementKindVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class ElementKindVisitor14 extends ElementKindVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitorPreview.java index 868e89c23eb..0f436e6d1e5 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -67,7 +67,7 @@ import static javax.lang.model.SourceVersion.*; * @see ElementKindVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class ElementKindVisitorPreview extends ElementKindVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java index e0c05ab228e..946cf97b092 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -77,7 +77,7 @@ import static javax.lang.model.SourceVersion.*; * @see ElementScanner9 * @since 16 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class ElementScanner14 extends ElementScanner9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementScannerPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementScannerPreview.java index 6d80aa8c661..a9d8e7c1f3f 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScannerPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScannerPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -81,7 +81,7 @@ import static javax.lang.model.SourceVersion.*; * @see ElementScanner14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class ElementScannerPreview extends ElementScanner14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java index 4682e2a7ee8..9320e18d5dd 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -52,7 +52,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class SimpleAnnotationValueVisitor14 extends SimpleAnnotationValueVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitorPreview.java index a477f33017c..01509c0c4a5 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -58,7 +58,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleAnnotationValueVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class SimpleAnnotationValueVisitorPreview extends SimpleAnnotationValueVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java index db97e59152f..dff1731d3c9 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -58,7 +58,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleElementVisitor9 * @since 16 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class SimpleElementVisitor14 extends SimpleElementVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitorPreview.java index 0d9914f3852..c3896a794c0 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -61,7 +61,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleElementVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class SimpleElementVisitorPreview extends SimpleElementVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java index 3f962137987..d06f5d673d3 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -56,7 +56,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class SimpleTypeVisitor14 extends SimpleTypeVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitorPreview.java index 13a0ad41d7e..11e2e8a50d5 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -62,7 +62,7 @@ import static javax.lang.model.SourceVersion.*; * @see SimpleTypeVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class SimpleTypeVisitorPreview extends SimpleTypeVisitor14 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java index 57d43e77500..295ceb200b8 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -61,7 +61,7 @@ import static javax.lang.model.SourceVersion.*; * @see TypeKindVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) public class TypeKindVisitor14 extends TypeKindVisitor9 { /** * Constructor for concrete subclasses to call; uses {@code null} diff --git a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitorPreview.java b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitorPreview.java index 3ae19353a0b..c0ca3a0450a 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitorPreview.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitorPreview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -66,7 +66,7 @@ import static javax.lang.model.SourceVersion.*; * @see TypeKindVisitor14 * @since 23 */ -@SupportedSourceVersion(RELEASE_25) +@SupportedSourceVersion(RELEASE_26) @PreviewFeature(feature=PreviewFeature.Feature.LANGUAGE_MODEL, reflective=true) public class TypeKindVisitorPreview extends TypeKindVisitor14 { /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java index b0b82fa5734..063d37be4e2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java @@ -153,6 +153,11 @@ public enum Source { * 25, tbd */ JDK25("25"), + + /** + * 26, tbd + */ + JDK26("26"), ; // Reduce code churn when appending new constants private static final Context.Key sourceKey = new Context.Key<>(); @@ -205,6 +210,7 @@ public enum Source { public Target requiredTarget() { return switch(this) { + case JDK26 -> Target.JDK1_26; case JDK25 -> Target.JDK1_25; case JDK24 -> Target.JDK1_24; case JDK23 -> Target.JDK1_23; @@ -358,6 +364,7 @@ public enum Source { case JDK23 -> RELEASE_23; case JDK24 -> RELEASE_24; case JDK25 -> RELEASE_25; + case JDK26 -> RELEASE_26; default -> null; }; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java index 202d92f63bc..e5adecdb107 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,6 +129,7 @@ public class ClassFile { V67(67, 0), // JDK 23 V68(68, 0), // JDK 24 V69(69, 0), // JDK 25 + V70(70, 0), // JDK 26 ; // Reduce code churn when appending new constants Version(int major, int minor) { this.major = major; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java index eeca1dadc1b..f60adcb3b80 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java @@ -110,6 +110,9 @@ public enum Target { /** JDK 25. */ JDK1_25("25", 69, 0), + + /** JDK 26. */ + JDK1_26("26", 70, 0), ; // Reduce code churn when appending new constants private static final Context.Key targetKey = new Context.Key<>(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java index 72a2b564ec5..7aaf035fd36 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java @@ -55,7 +55,7 @@ import com.sun.tools.javac.util.StringUtils; * deletion without notice. */ @SupportedAnnotationTypes("*") -@SupportedSourceVersion(SourceVersion.RELEASE_25) +@SupportedSourceVersion(SourceVersion.RELEASE_26) public class PrintingProcessor extends AbstractProcessor { PrintWriter writer; diff --git a/src/jdk.compiler/share/data/symbols/java.base-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.base-P.sym.txt new file mode 100644 index 00000000000..95544fc3cac --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.base-P.sym.txt @@ -0,0 +1,829 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name java.base +header exports java/io,java/lang,java/lang/annotation,java/lang/classfile,java/lang/classfile/attribute,java/lang/classfile/constantpool,java/lang/classfile/instruction,java/lang/constant,java/lang/foreign,java/lang/invoke,java/lang/module,java/lang/ref,java/lang/reflect,java/lang/runtime,java/math,java/net,java/net/spi,java/nio,java/nio/channels,java/nio/channels/spi,java/nio/charset,java/nio/charset/spi,java/nio/file,java/nio/file/attribute,java/nio/file/spi,java/security,java/security/cert,java/security/interfaces,java/security/spec,java/text,java/text/spi,java/time,java/time/chrono,java/time/format,java/time/temporal,java/time/zone,java/util,java/util/concurrent,java/util/concurrent/atomic,java/util/concurrent/locks,java/util/function,java/util/jar,java/util/random,java/util/regex,java/util/spi,java/util/stream,java/util/zip,javax/crypto,javax/crypto/interfaces,javax/crypto/spec,javax/net,javax/net/ssl,javax/security/auth,javax/security/auth/callback,javax/security/auth/login,javax/security/auth/spi,javax/security/auth/x500,javax/security/cert,jdk/internal/event[jdk.jfr],jdk/internal/javac[java.compiler\u005C;u002C;java.desktop\u005C;u002C;jdk.compiler\u005C;u002C;jdk.incubator.vector\u005C;u002C;jdk.jartool\u005C;u002C;jdk.jdeps\u005C;u002C;jdk.jfr\u005C;u002C;jdk.jlink\u005C;u002C;jdk.jshell],jdk/internal/vm/vector[jdk.incubator.vector] extraModulePackages jdk/internal/access/foreign,jdk/internal/classfile/impl,jdk/internal/constant,jdk/internal/foreign/abi,jdk/internal/foreign/abi/aarch64/linux,jdk/internal/foreign/abi/aarch64/macos,jdk/internal/foreign/abi/aarch64/windows,jdk/internal/foreign/abi/fallback,jdk/internal/foreign/abi/ppc64/aix,jdk/internal/foreign/abi/ppc64/linux,jdk/internal/foreign/abi/riscv64/linux,jdk/internal/foreign/abi/s390/linux,jdk/internal/foreign/abi/x64/sysv,jdk/internal/foreign/abi/x64/windows,jdk/internal/foreign/layout,jdk/internal/lang/stable,sun/nio/ch,sun/net,jdk/internal/foreign,jdk/internal/foreign,sun/net,sun/nio/ch uses java/lang/System$LoggerFinder,java/net/ContentHandlerFactory,java/net/spi/InetAddressResolverProvider,java/net/spi/URLStreamHandlerProvider,java/nio/channels/spi/AsynchronousChannelProvider,java/nio/channels/spi/SelectorProvider,java/nio/charset/spi/CharsetProvider,java/nio/file/spi/FileSystemProvider,java/nio/file/spi/FileTypeDetector,java/security/Provider,java/text/spi/BreakIteratorProvider,java/text/spi/CollatorProvider,java/text/spi/DateFormatProvider,java/text/spi/DateFormatSymbolsProvider,java/text/spi/DecimalFormatSymbolsProvider,java/text/spi/NumberFormatProvider,java/time/chrono/AbstractChronology,java/time/chrono/Chronology,java/time/zone/ZoneRulesProvider,java/util/spi/CalendarDataProvider,java/util/spi/CalendarNameProvider,java/util/spi/CurrencyNameProvider,java/util/spi/LocaleNameProvider,java/util/spi/ResourceBundleControlProvider,java/util/spi/ResourceBundleProvider,java/util/spi/TimeZoneNameProvider,java/util/spi/ToolProvider,javax/security/auth/spi/LoginModule,jdk/internal/io/JdkConsoleProvider,jdk/internal/logger/DefaultLoggerFinder,sun/text/spi/JavaTimeDateTimePatternProvider,sun/util/locale/provider/LocaleDataMetaInfo,sun/util/resources/LocaleData$CommonResourceBundleProvider,sun/util/resources/LocaleData$SupplementaryResourceBundleProvider,sun/util/spi/CalendarProvider provides interface\u0020;java/nio/file/spi/FileSystemProvider\u0020;impls\u0020;jdk/internal/jrtfs/JrtFileSystemProvider target macos-aarch64 flags 8000 + +class name java/io/Console +-method name println descriptor (Ljava/lang/Object;)Ljava/io/Console; +-method name print descriptor (Ljava/lang/Object;)Ljava/io/Console; +-method name readln descriptor (Ljava/lang/String;)Ljava/lang/String; +-method name println descriptor ()Ljava/io/Console; +-method name readln descriptor ()Ljava/lang/String; + +class name java/io/FilePermission +header extends java/security/Permission implements java/io/Serializable flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +-class name java/io/IO + +class name java/io/OptionalDataException +header extends java/io/ObjectStreamException flags 31 + +class name java/io/ProxyingConsole +-method name println descriptor (Ljava/lang/Object;)Ljava/io/Console; +-method name print descriptor (Ljava/lang/Object;)Ljava/io/Console; +-method name readln descriptor (Ljava/lang/String;)Ljava/lang/String; +-method name readln descriptor ()Ljava/lang/String; + +class name java/io/SerializablePermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/lang/Boolean +-method name descriptor (Z)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (Z)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/Byte +-method name descriptor (B)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (B)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/CharSequence +method name getChars descriptor (II[CI)V flags 1 + +class name java/lang/Character +-method name descriptor (C)V +method name descriptor (C)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/Class +-method name isInterface descriptor ()Z +-method name isArray descriptor ()Z +-method name isPrimitive descriptor ()Z +-method name getModifiers descriptor ()I +method name isInterface descriptor ()Z flags 1 +method name isArray descriptor ()Z flags 1 +method name isPrimitive descriptor ()Z flags 1 +method name getModifiers descriptor ()I flags 1 + +class name java/lang/Double +-method name descriptor (D)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (D)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/Float +-method name descriptor (F)V +-method name descriptor (D)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (F)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (D)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/IO +header extends java/lang/Object flags 31 +method name println descriptor (Ljava/lang/Object;)V flags 9 +method name println descriptor ()V flags 9 +method name print descriptor (Ljava/lang/Object;)V flags 9 +method name readln descriptor ()Ljava/lang/String; flags 9 +method name readln descriptor (Ljava/lang/String;)Ljava/lang/String; flags 9 + +class name java/lang/Integer +-method name descriptor (I)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (I)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/Long +-method name descriptor (J)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (J)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/Math +-method name max descriptor (JJ)J +-method name min descriptor (JJ)J +method name max descriptor (JJ)J flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name min descriptor (JJ)J flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name unsignedMultiplyExact descriptor (II)I flags 9 +method name unsignedMultiplyExact descriptor (JI)J flags 9 +method name unsignedMultiplyExact descriptor (JJ)J flags 9 +method name powExact descriptor (II)I flags 9 +method name unsignedPowExact descriptor (II)I flags 9 +method name powExact descriptor (JI)J flags 9 +method name unsignedPowExact descriptor (JI)J flags 9 + +class name java/lang/Package +header extends java/lang/NamedPackage implements java/lang/reflect/AnnotatedElement flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/ProcessHandle +header extends java/lang/Object implements java/lang/Comparable nestMembers java/lang/ProcessHandle$Info flags 601 signature Ljava/lang/Object;Ljava/lang/Comparable; +innerclass innerClass java/lang/ProcessHandle$Info outerClass java/lang/ProcessHandle innerClassName Info flags 609 + +class name java/lang/Runtime +header extends java/lang/Object nestMembers java/lang/Runtime$Version flags 31 +innerclass innerClass java/lang/Runtime$Version outerClass java/lang/Runtime innerClassName Version flags 19 + +class name java/lang/RuntimePermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/lang/Short +-method name descriptor (S)V +-method name descriptor (Ljava/lang/String;)V +method name descriptor (S)V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") +method name descriptor (Ljava/lang/String;)V thrownTypes java/lang/NumberFormatException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(since="9") + +class name java/lang/StableValue +header extends java/lang/Object sealed true permittedSubclasses jdk/internal/lang/stable/StableValueImpl flags 601 signature Ljava/lang/Object; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STABLE_VALUES;) +method name trySet descriptor (Ljava/lang/Object;)Z flags 401 signature (TT;)Z +method name orElse descriptor (Ljava/lang/Object;)Ljava/lang/Object; flags 401 signature (TT;)TT; +method name orElseThrow descriptor ()Ljava/lang/Object; flags 401 signature ()TT; +method name isSet descriptor ()Z flags 401 +method name orElseSet descriptor (Ljava/util/function/Supplier;)Ljava/lang/Object; flags 401 signature (Ljava/util/function/Supplier<+TT;>;)TT; +method name setOrThrow descriptor (Ljava/lang/Object;)V flags 401 signature (TT;)V +method name equals descriptor (Ljava/lang/Object;)Z flags 401 +method name hashCode descriptor ()I flags 401 +method name of descriptor ()Ljava/lang/StableValue; flags 9 signature ()Ljava/lang/StableValue; +method name of descriptor (Ljava/lang/Object;)Ljava/lang/StableValue; flags 9 signature (TT;)Ljava/lang/StableValue; +method name supplier descriptor (Ljava/util/function/Supplier;)Ljava/util/function/Supplier; flags 9 signature (Ljava/util/function/Supplier<+TT;>;)Ljava/util/function/Supplier; +method name intFunction descriptor (ILjava/util/function/IntFunction;)Ljava/util/function/IntFunction; flags 9 signature (ILjava/util/function/IntFunction<+TR;>;)Ljava/util/function/IntFunction; +method name function descriptor (Ljava/util/Set;Ljava/util/function/Function;)Ljava/util/function/Function; flags 9 signature (Ljava/util/Set<+TT;>;Ljava/util/function/Function<-TT;+TR;>;)Ljava/util/function/Function; +method name list descriptor (ILjava/util/function/IntFunction;)Ljava/util/List; flags 9 signature (ILjava/util/function/IntFunction<+TE;>;)Ljava/util/List; +method name map descriptor (Ljava/util/Set;Ljava/util/function/Function;)Ljava/util/Map; flags 9 signature (Ljava/util/Set;Ljava/util/function/Function<-TK;+TV;>;)Ljava/util/Map; + +class name java/lang/StrictMath +method name unsignedMultiplyExact descriptor (II)I flags 9 +method name unsignedMultiplyExact descriptor (JI)J flags 9 +method name unsignedMultiplyExact descriptor (JJ)J flags 9 +method name powExact descriptor (II)I flags 9 +method name unsignedPowExact descriptor (II)I flags 9 +method name powExact descriptor (JI)J flags 9 +method name unsignedPowExact descriptor (JI)J flags 9 + +class name java/lang/classfile/ClassFile +field name JAVA_25_VERSION descriptor I constantValue 69 flags 19 + +class name java/lang/classfile/CodeElement +header extends java/lang/Object implements java/lang/classfile/ClassFileElement sealed true permittedSubclasses java/lang/classfile/Instruction,java/lang/classfile/PseudoInstruction,java/lang/classfile/CustomAttribute,java/lang/classfile/attribute/RuntimeVisibleTypeAnnotationsAttribute,java/lang/classfile/attribute/RuntimeInvisibleTypeAnnotationsAttribute,java/lang/classfile/attribute/StackMapTableAttribute,java/lang/classfile/attribute/UnknownAttribute flags 601 + +class name java/lang/classfile/attribute/UnknownAttribute +header extends java/lang/Object implements java/lang/classfile/Attribute,java/lang/classfile/ClassElement,java/lang/classfile/MethodElement,java/lang/classfile/FieldElement,java/lang/classfile/CodeElement sealed true permittedSubclasses jdk/internal/classfile/impl/BoundAttribute$BoundUnknownAttribute flags 601 signature Ljava/lang/Object;Ljava/lang/classfile/Attribute;Ljava/lang/classfile/ClassElement;Ljava/lang/classfile/MethodElement;Ljava/lang/classfile/FieldElement;Ljava/lang/classfile/CodeElement; +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundUnknownAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundUnknownAttribute flags 19 + +class name java/lang/classfile/constantpool/ClassEntry +method name matches descriptor (Ljava/lang/constant/ClassDesc;)Z flags 401 + +class name java/lang/classfile/constantpool/ConstantPoolBuilder +header extends java/lang/Object implements java/lang/classfile/constantpool/ConstantPool sealed true permittedSubclasses jdk/internal/classfile/impl/SplitConstantPool,jdk/internal/classfile/impl/TemporaryConstantPool flags 601 +innerclass innerClass jdk/internal/classfile/impl/AbstractPoolEntry$ClassEntryImpl outerClass jdk/internal/classfile/impl/AbstractPoolEntry innerClassName ClassEntryImpl flags 19 +innerclass innerClass java/lang/constant/DirectMethodHandleDesc$Kind outerClass java/lang/constant/DirectMethodHandleDesc innerClassName Kind flags 4019 +innerclass innerClass jdk/internal/classfile/impl/AbstractPoolEntry$MethodHandleEntryImpl outerClass jdk/internal/classfile/impl/AbstractPoolEntry innerClassName MethodHandleEntryImpl flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractPoolEntry$InvokeDynamicEntryImpl outerClass jdk/internal/classfile/impl/AbstractPoolEntry innerClassName InvokeDynamicEntryImpl flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractPoolEntry$ConstantDynamicEntryImpl outerClass jdk/internal/classfile/impl/AbstractPoolEntry innerClassName ConstantDynamicEntryImpl flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/classfile/constantpool/MethodTypeEntry +method name matches descriptor (Ljava/lang/constant/MethodTypeDesc;)Z flags 401 + +class name java/lang/classfile/constantpool/ModuleEntry +method name matches descriptor (Ljava/lang/constant/ModuleDesc;)Z flags 401 + +class name java/lang/classfile/constantpool/PackageEntry +method name matches descriptor (Ljava/lang/constant/PackageDesc;)Z flags 401 + +class name java/lang/classfile/constantpool/StringEntry +method name equalsString descriptor (Ljava/lang/String;)Z flags 401 + +class name java/lang/classfile/constantpool/Utf8Entry +method name isFieldType descriptor (Ljava/lang/constant/ClassDesc;)Z flags 401 +method name isMethodType descriptor (Ljava/lang/constant/MethodTypeDesc;)Z flags 401 + +class name java/lang/constant/DynamicCallSiteDesc +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/foreign/Linker$Option +header extends java/lang/Object nestHost java/lang/foreign/Linker sealed true permittedSubclasses jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl flags 601 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName FirstVariadicArg flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$CaptureCallState outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName CaptureCallState flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$Critical outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName Critical flags 4019 +innerclass innerClass java/lang/foreign/Linker$Option outerClass java/lang/foreign/Linker innerClassName Option flags 609 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName LinkerOptionImpl flags 609 + +class name java/lang/invoke/MethodHandleProxies +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +innerclass innerClass java/lang/classfile/ClassFile$Option outerClass java/lang/classfile/ClassFile innerClassName Option flags 609 +innerclass innerClass java/lang/classfile/ClassFile$ClassHierarchyResolverOption outerClass java/lang/classfile/ClassFile innerClassName ClassHierarchyResolverOption flags 609 +innerclass innerClass java/lang/module/ModuleDescriptor$Modifier outerClass java/lang/module/ModuleDescriptor innerClassName Modifier flags 4019 +innerclass innerClass java/lang/module/ModuleDescriptor$Builder outerClass java/lang/module/ModuleDescriptor innerClassName Builder flags 19 +innerclass innerClass java/lang/classfile/CodeBuilder$CatchBuilder outerClass java/lang/classfile/CodeBuilder innerClassName CatchBuilder flags 609 +innerclass innerClass java/lang/classfile/CodeBuilder$BlockCodeBuilder outerClass java/lang/classfile/CodeBuilder innerClassName BlockCodeBuilder flags 609 +innerclass innerClass java/lang/invoke/TypeDescriptor$OfField outerClass java/lang/invoke/TypeDescriptor innerClassName OfField flags 609 + +class name java/lang/invoke/MethodHandles +header extends java/lang/Object nestMembers java/lang/invoke/MethodHandles$Lookup,java/lang/invoke/MethodHandles$Lookup$ClassOption flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +innerclass innerClass java/lang/invoke/VarHandle$AccessMode outerClass java/lang/invoke/VarHandle innerClassName AccessMode flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup$ClassOption outerClass java/lang/invoke/MethodHandles$Lookup innerClassName ClassOption flags 4019 + +class name java/lang/invoke/SegmentVarHandle +header extends java/lang/invoke/VarHandle flags 30 +method name withInvokeExactBehavior descriptor ()Ljava/lang/invoke/SegmentVarHandle; flags 1 +method name withInvokeBehavior descriptor ()Ljava/lang/invoke/SegmentVarHandle; flags 1 +method name withInvokeBehavior descriptor ()Ljava/lang/invoke/VarHandle; flags 1041 +method name withInvokeExactBehavior descriptor ()Ljava/lang/invoke/VarHandle; flags 1041 + +class name java/lang/invoke/VarHandle +header extends java/lang/Object implements java/lang/constant/Constable nestMembers java/lang/invoke/VarHandle$VarHandleDesc,java/lang/invoke/VarHandle$AccessMode sealed true permittedSubclasses java/lang/invoke/IndirectVarHandle,java/lang/invoke/LazyInitializingVarHandle,java/lang/invoke/SegmentVarHandle,java/lang/invoke/VarHandleByteArrayAsChars$ByteArrayViewVarHandle,java/lang/invoke/VarHandleByteArrayAsDoubles$ByteArrayViewVarHandle,java/lang/invoke/VarHandleByteArrayAsFloats$ByteArrayViewVarHandle,java/lang/invoke/VarHandleByteArrayAsInts$ByteArrayViewVarHandle,java/lang/invoke/VarHandleByteArrayAsLongs$ByteArrayViewVarHandle,java/lang/invoke/VarHandleByteArrayAsShorts$ByteArrayViewVarHandle,java/lang/invoke/VarHandleBooleans$Array,java/lang/invoke/VarHandleBooleans$FieldInstanceReadOnly,java/lang/invoke/VarHandleBooleans$FieldStaticReadOnly,java/lang/invoke/VarHandleBytes$Array,java/lang/invoke/VarHandleBytes$FieldInstanceReadOnly,java/lang/invoke/VarHandleBytes$FieldStaticReadOnly,java/lang/invoke/VarHandleChars$Array,java/lang/invoke/VarHandleChars$FieldInstanceReadOnly,java/lang/invoke/VarHandleChars$FieldStaticReadOnly,java/lang/invoke/VarHandleDoubles$Array,java/lang/invoke/VarHandleDoubles$FieldInstanceReadOnly,java/lang/invoke/VarHandleDoubles$FieldStaticReadOnly,java/lang/invoke/VarHandleFloats$Array,java/lang/invoke/VarHandleFloats$FieldInstanceReadOnly,java/lang/invoke/VarHandleFloats$FieldStaticReadOnly,java/lang/invoke/VarHandleInts$Array,java/lang/invoke/VarHandleInts$FieldInstanceReadOnly,java/lang/invoke/VarHandleInts$FieldStaticReadOnly,java/lang/invoke/VarHandleLongs$Array,java/lang/invoke/VarHandleLongs$FieldInstanceReadOnly,java/lang/invoke/VarHandleLongs$FieldStaticReadOnly,java/lang/invoke/VarHandleReferences$Array,java/lang/invoke/VarHandleReferences$FieldInstanceReadOnly,java/lang/invoke/VarHandleReferences$FieldStaticReadOnly,java/lang/invoke/VarHandleShorts$Array,java/lang/invoke/VarHandleShorts$FieldInstanceReadOnly,java/lang/invoke/VarHandleShorts$FieldStaticReadOnly flags 421 +innerclass innerClass java/lang/invoke/VarHandle$AccessMode outerClass java/lang/invoke/VarHandle innerClassName AccessMode flags 4019 +innerclass innerClass java/lang/invoke/VarHandle$VarHandleDesc outerClass java/lang/invoke/VarHandle innerClassName VarHandleDesc flags 19 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsChars$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsChars innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsDoubles$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsDoubles innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsFloats$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsFloats innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsInts$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsInts innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsLongs$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsLongs innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleByteArrayAsShorts$ByteArrayViewVarHandle outerClass java/lang/invoke/VarHandleByteArrayAsShorts innerClassName ByteArrayViewVarHandle flags 408 +innerclass innerClass java/lang/invoke/VarHandleBooleans$Array outerClass java/lang/invoke/VarHandleBooleans innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleBooleans$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleBooleans innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleBooleans$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleBooleans innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleBytes$Array outerClass java/lang/invoke/VarHandleBytes innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleBytes$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleBytes innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleBytes$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleBytes innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleChars$Array outerClass java/lang/invoke/VarHandleChars innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleChars$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleChars innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleChars$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleChars innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleDoubles$Array outerClass java/lang/invoke/VarHandleDoubles innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleDoubles$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleDoubles innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleDoubles$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleDoubles innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleFloats$Array outerClass java/lang/invoke/VarHandleFloats innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleFloats$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleFloats innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleFloats$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleFloats innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleInts$Array outerClass java/lang/invoke/VarHandleInts innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleInts$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleInts innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleInts$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleInts innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleLongs$Array outerClass java/lang/invoke/VarHandleLongs innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleLongs$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleLongs innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleLongs$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleLongs innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleReferences$Array outerClass java/lang/invoke/VarHandleReferences innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleReferences$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleReferences innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleReferences$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleReferences innerClassName FieldStaticReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleShorts$Array outerClass java/lang/invoke/VarHandleShorts innerClassName Array flags 18 +innerclass innerClass java/lang/invoke/VarHandleShorts$FieldInstanceReadOnly outerClass java/lang/invoke/VarHandleShorts innerClassName FieldInstanceReadOnly flags 8 +innerclass innerClass java/lang/invoke/VarHandleShorts$FieldStaticReadOnly outerClass java/lang/invoke/VarHandleShorts innerClassName FieldStaticReadOnly flags 8 + +-class name java/lang/invoke/VarHandleSegmentAsBytes + +-class name java/lang/invoke/VarHandleSegmentAsChars + +-class name java/lang/invoke/VarHandleSegmentAsDoubles + +-class name java/lang/invoke/VarHandleSegmentAsFloats + +-class name java/lang/invoke/VarHandleSegmentAsInts + +-class name java/lang/invoke/VarHandleSegmentAsLongs + +-class name java/lang/invoke/VarHandleSegmentAsShorts + +-class name java/lang/invoke/VarHandleSegmentViewBase + +class name java/lang/module/ModuleDescriptor +header extends java/lang/Object implements java/lang/Comparable nestMembers java/lang/module/ModuleDescriptor$Builder,java/lang/module/ModuleDescriptor$Version,java/lang/module/ModuleDescriptor$Provides,java/lang/module/ModuleDescriptor$Opens,java/lang/module/ModuleDescriptor$Opens$Modifier,java/lang/module/ModuleDescriptor$Exports,java/lang/module/ModuleDescriptor$Exports$Modifier,java/lang/module/ModuleDescriptor$Requires,java/lang/module/ModuleDescriptor$Requires$Modifier,java/lang/module/ModuleDescriptor$Modifier flags 31 signature Ljava/lang/Object;Ljava/lang/Comparable; +innerclass innerClass java/lang/module/ModuleDescriptor$Version outerClass java/lang/module/ModuleDescriptor innerClassName Version flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Modifier outerClass java/lang/module/ModuleDescriptor innerClassName Modifier flags 4019 +innerclass innerClass java/lang/reflect/AccessFlag$Location outerClass java/lang/reflect/AccessFlag innerClassName Location flags 4019 +innerclass innerClass java/lang/module/ModuleDescriptor$Builder outerClass java/lang/module/ModuleDescriptor innerClassName Builder flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Provides outerClass java/lang/module/ModuleDescriptor innerClassName Provides flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Opens outerClass java/lang/module/ModuleDescriptor innerClassName Opens flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Exports outerClass java/lang/module/ModuleDescriptor innerClassName Exports flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Requires outerClass java/lang/module/ModuleDescriptor innerClassName Requires flags 19 +innerclass innerClass java/lang/module/ModuleDescriptor$Opens$Modifier outerClass java/lang/module/ModuleDescriptor$Opens innerClassName Modifier flags 4019 +innerclass innerClass java/lang/module/ModuleDescriptor$Exports$Modifier outerClass java/lang/module/ModuleDescriptor$Exports innerClassName Modifier flags 4019 +innerclass innerClass java/lang/module/ModuleDescriptor$Requires$Modifier outerClass java/lang/module/ModuleDescriptor$Requires innerClassName Modifier flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/ref/Cleaner +-method name register descriptor (Ljava/lang/Object;Ljava/lang/Runnable;)Ljava/lang/ref/Cleaner$Cleanable; +method name register descriptor (Ljava/lang/Object;Ljava/lang/Runnable;)Ljava/lang/ref/Cleaner$Cleanable; flags 1 runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;;; + +class name java/lang/ref/PhantomReference +header extends java/lang/ref/Reference flags 21 signature Ljava/lang/ref/Reference; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} +-method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V +method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V flags 1 signature (TT;Ljava/lang/ref/ReferenceQueue<-TT;>;)V runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;;; + +class name java/lang/ref/Reference +header extends java/lang/Object sealed true permittedSubclasses java/lang/ref/PhantomReference,java/lang/ref/SoftReference,java/lang/ref/WeakReference,java/lang/ref/FinalReference flags 421 signature Ljava/lang/Object; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} + +class name java/lang/ref/ReferenceQueue +header extends java/lang/Object flags 21 signature Ljava/lang/Object; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} + +class name java/lang/ref/SoftReference +header extends java/lang/ref/Reference flags 21 signature Ljava/lang/ref/Reference; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} +-method name descriptor (Ljava/lang/Object;)V +-method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V +method name descriptor (Ljava/lang/Object;)V flags 1 signature (TT;)V runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;; +method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V flags 1 signature (TT;Ljava/lang/ref/ReferenceQueue<-TT;>;)V runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;;; + +class name java/lang/ref/WeakReference +header extends java/lang/ref/Reference flags 21 signature Ljava/lang/ref/Reference; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} +-method name descriptor (Ljava/lang/Object;)V +-method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V +method name descriptor (Ljava/lang/Object;)V flags 1 signature (TT;)V runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;; +method name descriptor (Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V flags 1 signature (TT;Ljava/lang/ref/ReferenceQueue<-TT;>;)V runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;;; + +class name java/lang/reflect/AccessFlag +header extends java/lang/Enum nestMembers java/lang/reflect/AccessFlag$Location flags 4031 signature Ljava/lang/Enum; +innerclass innerClass java/lang/reflect/AccessFlag$Location outerClass java/lang/reflect/AccessFlag innerClassName Location flags 4019 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +method name maskToAccessFlags descriptor (ILjava/lang/reflect/AccessFlag$Location;Ljava/lang/reflect/ClassFileFormatVersion;)Ljava/util/Set; flags 9 signature (ILjava/lang/reflect/AccessFlag$Location;Ljava/lang/reflect/ClassFileFormatVersion;)Ljava/util/Set; + +class name java/lang/reflect/AccessFlag$Location +header extends java/lang/Enum nestHost java/lang/reflect/AccessFlag flags 4031 signature Ljava/lang/Enum; +innerclass innerClass java/lang/reflect/AccessFlag$Location outerClass java/lang/reflect/AccessFlag innerClassName Location flags 4019 +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +method name flagsMask descriptor ()I flags 1 +method name flagsMask descriptor (Ljava/lang/reflect/ClassFileFormatVersion;)I flags 1 +method name flags descriptor ()Ljava/util/Set; flags 1 signature ()Ljava/util/Set; +method name flags descriptor (Ljava/lang/reflect/ClassFileFormatVersion;)Ljava/util/Set; flags 1 signature (Ljava/lang/reflect/ClassFileFormatVersion;)Ljava/util/Set; + +class name java/lang/reflect/ClassFileFormatVersion +field name RELEASE_25 descriptor Ljava/lang/reflect/ClassFileFormatVersion; flags 4019 + +class name java/lang/reflect/Modifier +header extends java/lang/Object flags 31 + +class name java/lang/reflect/ReflectPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/lang/runtime/ObjectMethods +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/lang/runtime/SwitchBootstraps +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +innerclass innerClass java/lang/Enum$EnumDesc outerClass java/lang/Enum innerClassName EnumDesc flags 19 +innerclass innerClass java/lang/classfile/ClassFile$Option outerClass java/lang/classfile/ClassFile innerClassName Option flags 609 +innerclass innerClass java/lang/classfile/ClassFile$StackMapsOption outerClass java/lang/classfile/ClassFile innerClassName StackMapsOption flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup$ClassOption outerClass java/lang/invoke/MethodHandles$Lookup innerClassName ClassOption flags 4019 +innerclass innerClass java/lang/classfile/attribute/StackMapFrameInfo$SimpleVerificationTypeInfo outerClass java/lang/classfile/attribute/StackMapFrameInfo innerClassName SimpleVerificationTypeInfo flags 4019 +innerclass innerClass java/lang/classfile/attribute/StackMapFrameInfo$ObjectVerificationTypeInfo outerClass java/lang/classfile/attribute/StackMapFrameInfo innerClassName ObjectVerificationTypeInfo flags 609 +innerclass innerClass java/lang/classfile/attribute/StackMapFrameInfo$VerificationTypeInfo outerClass java/lang/classfile/attribute/StackMapFrameInfo innerClassName VerificationTypeInfo flags 609 + +class name java/net/HttpURLConnection +-method name getPermission descriptor ()Ljava/security/Permission; +method name getPermission descriptor ()Ljava/security/Permission; thrownTypes java/io/IOException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/net/InterfaceAddress +header extends java/lang/Object flags 31 + +class name java/net/NetPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/net/URLConnection +-method name getPermission descriptor ()Ljava/security/Permission; +method name getPermission descriptor ()Ljava/security/Permission; thrownTypes java/io/IOException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/net/URLDecoder +header extends java/lang/Object flags 31 + +class name java/net/URLEncoder +header extends java/lang/Object flags 31 + +class name java/net/URLPermission +header extends java/security/Permission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/io/ObjectInputStream$GetField outerClass java/io/ObjectInputStream innerClassName GetField flags 409 + +class name java/nio/CharBuffer +method name getChars descriptor (II[CI)V flags 1 + +class name java/nio/charset/CoderResult +header extends java/lang/Object flags 31 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/nio/charset/CodingErrorAction +header extends java/lang/Object flags 31 + +class name java/nio/file/LinkPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/security/DrbgParameters +header extends java/lang/Object nestMembers java/security/DrbgParameters$Reseed,java/security/DrbgParameters$NextBytes,java/security/DrbgParameters$Instantiation,java/security/DrbgParameters$Capability flags 31 +innerclass innerClass java/security/DrbgParameters$Instantiation outerClass java/security/DrbgParameters innerClassName Instantiation flags 19 +innerclass innerClass java/security/DrbgParameters$Capability outerClass java/security/DrbgParameters innerClassName Capability flags 4019 +innerclass innerClass java/security/DrbgParameters$NextBytes outerClass java/security/DrbgParameters innerClassName NextBytes flags 19 +innerclass innerClass java/security/DrbgParameters$Reseed outerClass java/security/DrbgParameters innerClassName Reseed flags 19 + +class name java/security/SecurityPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/security/UnresolvedPermission +header extends java/security/Permission implements java/io/Serializable flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/time/ZoneOffset +header extends java/time/ZoneId implements java/time/temporal/TemporalAccessor,java/time/temporal/TemporalAdjuster,java/lang/Comparable,java/io/Serializable flags 31 signature Ljava/time/ZoneId;Ljava/time/temporal/TemporalAccessor;Ljava/time/temporal/TemporalAdjuster;Ljava/lang/Comparable;Ljava/io/Serializable; runtimeAnnotations @Ljdk/internal/ValueBased; + +class name java/time/format/DecimalStyle +header extends java/lang/Object flags 31 +innerclass innerClass java/util/Locale$Category outerClass java/util/Locale innerClassName Category flags 4019 + +class name java/util/Base64 +header extends java/lang/Object nestMembers java/util/Base64$Decoder,java/util/Base64$Encoder flags 31 +innerclass innerClass java/util/Base64$Encoder outerClass java/util/Base64 innerClassName Encoder flags 9 +innerclass innerClass java/util/Base64$Decoder outerClass java/util/Base64 innerClassName Decoder flags 9 + +class name java/util/Collections +header extends java/lang/Object flags 31 + +class name java/util/Currency +method name availableCurrencies descriptor ()Ljava/util/stream/Stream; flags 9 signature ()Ljava/util/stream/Stream; + +class name java/util/FormattableFlags +header extends java/lang/Object flags 31 + +class name java/util/PropertyPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name java/util/TimeZone +-method name getTimeZone descriptor (Ljava/lang/String;)Ljava/util/TimeZone; +-method name getAvailableIDs descriptor (I)[Ljava/lang/String; +-method name getAvailableIDs descriptor ()[Ljava/lang/String; +method name getTimeZone descriptor (Ljava/lang/String;)Ljava/util/TimeZone; flags 9 +method name getAvailableIDs descriptor (I)[Ljava/lang/String; flags 9 +method name getAvailableIDs descriptor ()[Ljava/lang/String; flags 9 +method name availableIDs descriptor (I)Ljava/util/stream/Stream; flags 9 signature (I)Ljava/util/stream/Stream; +method name availableIDs descriptor ()Ljava/util/stream/Stream; flags 9 signature ()Ljava/util/stream/Stream; + +class name java/util/WeakHashMap +header extends java/util/AbstractMap implements java/util/Map flags 21 signature Ljava/util/AbstractMap;Ljava/util/Map; runtimeTypeAnnotations @Ljdk/internal/RequiresIdentity;{typeParameterIndex=I0,targetType="CLASS_TYPE_PARAMETER"} +innerclass innerClass java/util/Map$Entry outerClass java/util/Map innerClassName Entry flags 609 +-method name put descriptor (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; +method name put descriptor (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; flags 1 signature (TK;TV;)TV; runtimeParameterAnnotations @Ljdk/internal/RequiresIdentity;;; + +class name java/util/concurrent/Executors +header extends java/lang/Object flags 31 +innerclass innerClass java/util/concurrent/ForkJoinPool$ForkJoinWorkerThreadFactory outerClass java/util/concurrent/ForkJoinPool innerClassName ForkJoinWorkerThreadFactory flags 609 +innerclass innerClass java/lang/Thread$UncaughtExceptionHandler outerClass java/lang/Thread innerClassName UncaughtExceptionHandler flags 609 +innerclass innerClass java/lang/Thread$Builder outerClass java/lang/Thread innerClassName Builder flags 609 +innerclass innerClass java/lang/Thread$Builder$OfVirtual outerClass java/lang/Thread$Builder innerClassName OfVirtual flags 609 + +class name java/util/concurrent/ForkJoinPool +header extends java/util/concurrent/AbstractExecutorService implements java/util/concurrent/ScheduledExecutorService nestMembers java/util/concurrent/ForkJoinPool$ManagedBlocker,java/util/concurrent/ForkJoinPool$ForkJoinWorkerThreadFactory flags 21 +innerclass innerClass java/util/concurrent/ForkJoinPool$ForkJoinWorkerThreadFactory outerClass java/util/concurrent/ForkJoinPool innerClassName ForkJoinWorkerThreadFactory flags 609 +innerclass innerClass java/util/concurrent/ForkJoinPool$ManagedBlocker outerClass java/util/concurrent/ForkJoinPool innerClassName ManagedBlocker flags 609 +innerclass innerClass java/lang/Thread$UncaughtExceptionHandler outerClass java/lang/Thread innerClassName UncaughtExceptionHandler flags 609 +method name schedule descriptor (Ljava/lang/Runnable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; flags 1 signature (Ljava/lang/Runnable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture<*>; +method name schedule descriptor (Ljava/util/concurrent/Callable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; flags 1 signature (Ljava/util/concurrent/Callable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; +method name scheduleAtFixedRate descriptor (Ljava/lang/Runnable;JJLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; flags 1 signature (Ljava/lang/Runnable;JJLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture<*>; +method name scheduleWithFixedDelay descriptor (Ljava/lang/Runnable;JJLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; flags 1 signature (Ljava/lang/Runnable;JJLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture<*>; +method name submitWithTimeout descriptor (Ljava/util/concurrent/Callable;JLjava/util/concurrent/TimeUnit;Ljava/util/function/Consumer;)Ljava/util/concurrent/ForkJoinTask; flags 1 signature (Ljava/util/concurrent/Callable;JLjava/util/concurrent/TimeUnit;Ljava/util/function/Consumer<-Ljava/util/concurrent/ForkJoinTask;>;)Ljava/util/concurrent/ForkJoinTask; +method name cancelDelayedTasksOnShutdown descriptor ()V flags 1 +method name getDelayedTaskCount descriptor ()J flags 1 + +class name java/util/concurrent/StructuredTaskScope +header extends java/lang/Object implements java/lang/AutoCloseable nestMembers java/util/concurrent/StructuredTaskScope$TimeoutException,java/util/concurrent/StructuredTaskScope$FailedException,java/util/concurrent/StructuredTaskScope$Configuration,java/util/concurrent/StructuredTaskScope$Joiner,java/util/concurrent/StructuredTaskScope$Subtask,java/util/concurrent/StructuredTaskScope$Subtask$State sealed true permittedSubclasses java/util/concurrent/StructuredTaskScopeImpl flags 601 signature Ljava/lang/Object;Ljava/lang/AutoCloseable; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) +innerclass innerClass java/util/concurrent/StructuredTaskScope$Joiner outerClass java/util/concurrent/StructuredTaskScope innerClassName Joiner flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$TimeoutException outerClass java/util/concurrent/StructuredTaskScope innerClassName TimeoutException flags 19 +innerclass innerClass java/util/concurrent/StructuredTaskScope$FailedException outerClass java/util/concurrent/StructuredTaskScope innerClassName FailedException flags 19 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Configuration outerClass java/util/concurrent/StructuredTaskScope innerClassName Configuration flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask outerClass java/util/concurrent/StructuredTaskScope innerClassName Subtask flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask$State outerClass java/util/concurrent/StructuredTaskScope$Subtask innerClassName State flags 4019 +-method name descriptor (Ljava/lang/String;Ljava/util/concurrent/ThreadFactory;)V +-method name descriptor ()V +-method name ensureOwnerAndJoined descriptor ()V +-method name handleComplete descriptor (Ljava/util/concurrent/StructuredTaskScope$Subtask;)V +-method name fork descriptor (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; +-method name join descriptor ()Ljava/util/concurrent/StructuredTaskScope; +-method name joinUntil descriptor (Ljava/time/Instant;)Ljava/util/concurrent/StructuredTaskScope; +-method name shutdown descriptor ()V +-method name isShutdown descriptor ()Z +-method name close descriptor ()V +-method name toString descriptor ()Ljava/lang/String; +method name open descriptor (Ljava/util/concurrent/StructuredTaskScope$Joiner;Ljava/util/function/Function;)Ljava/util/concurrent/StructuredTaskScope; flags 9 signature (Ljava/util/concurrent/StructuredTaskScope$Joiner<-TT;+TR;>;Ljava/util/function/Function;)Ljava/util/concurrent/StructuredTaskScope; +method name open descriptor (Ljava/util/concurrent/StructuredTaskScope$Joiner;)Ljava/util/concurrent/StructuredTaskScope; flags 9 signature (Ljava/util/concurrent/StructuredTaskScope$Joiner<-TT;+TR;>;)Ljava/util/concurrent/StructuredTaskScope; +method name open descriptor ()Ljava/util/concurrent/StructuredTaskScope; flags 9 signature ()Ljava/util/concurrent/StructuredTaskScope; +method name fork descriptor (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; flags 401 signature (Ljava/util/concurrent/Callable<+TU;>;)Ljava/util/concurrent/StructuredTaskScope$Subtask; +method name fork descriptor (Ljava/lang/Runnable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; flags 401 signature (Ljava/lang/Runnable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; +method name join descriptor ()Ljava/lang/Object; thrownTypes java/lang/InterruptedException flags 401 signature ()TR; +method name isCancelled descriptor ()Z flags 401 +method name close descriptor ()V flags 401 + +class name java/util/concurrent/StructuredTaskScope$Configuration +header extends java/lang/Object nestHost java/util/concurrent/StructuredTaskScope sealed true permittedSubclasses java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl flags 601 classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) +innerclass innerClass java/util/concurrent/StructuredTaskScope$Configuration outerClass java/util/concurrent/StructuredTaskScope innerClassName Configuration flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName ConfigImpl flags 18 +method name withThreadFactory descriptor (Ljava/util/concurrent/ThreadFactory;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 401 +method name withName descriptor (Ljava/lang/String;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 401 +method name withTimeout descriptor (Ljava/time/Duration;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 401 + +class name java/util/concurrent/StructuredTaskScope$FailedException +header extends java/lang/RuntimeException nestHost java/util/concurrent/StructuredTaskScope flags 31 classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) +innerclass innerClass java/util/concurrent/StructuredTaskScope$FailedException outerClass java/util/concurrent/StructuredTaskScope innerClassName FailedException flags 19 + +class name java/util/concurrent/StructuredTaskScope$Joiner +header extends java/lang/Object nestHost java/util/concurrent/StructuredTaskScope flags 601 signature Ljava/lang/Object; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) runtimeAnnotations @Ljava/lang/FunctionalInterface; +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask outerClass java/util/concurrent/StructuredTaskScope innerClassName Subtask flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask$State outerClass java/util/concurrent/StructuredTaskScope$Subtask innerClassName State flags 4019 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Joiner outerClass java/util/concurrent/StructuredTaskScope innerClassName Joiner flags 609 +method name onFork descriptor (Ljava/util/concurrent/StructuredTaskScope$Subtask;)Z flags 1 signature (Ljava/util/concurrent/StructuredTaskScope$Subtask<+TT;>;)Z +method name onComplete descriptor (Ljava/util/concurrent/StructuredTaskScope$Subtask;)Z flags 1 signature (Ljava/util/concurrent/StructuredTaskScope$Subtask<+TT;>;)Z +method name result descriptor ()Ljava/lang/Object; thrownTypes java/lang/Throwable flags 401 signature ()TR; +method name allSuccessfulOrThrow descriptor ()Ljava/util/concurrent/StructuredTaskScope$Joiner; flags 9 signature ()Ljava/util/concurrent/StructuredTaskScope$Joiner;>;>; +method name anySuccessfulResultOrThrow descriptor ()Ljava/util/concurrent/StructuredTaskScope$Joiner; flags 9 signature ()Ljava/util/concurrent/StructuredTaskScope$Joiner; +method name awaitAllSuccessfulOrThrow descriptor ()Ljava/util/concurrent/StructuredTaskScope$Joiner; flags 9 signature ()Ljava/util/concurrent/StructuredTaskScope$Joiner; +method name awaitAll descriptor ()Ljava/util/concurrent/StructuredTaskScope$Joiner; flags 9 signature ()Ljava/util/concurrent/StructuredTaskScope$Joiner; +method name allUntil descriptor (Ljava/util/function/Predicate;)Ljava/util/concurrent/StructuredTaskScope$Joiner; flags 9 signature (Ljava/util/function/Predicate;>;)Ljava/util/concurrent/StructuredTaskScope$Joiner;>;>; + +-class name java/util/concurrent/StructuredTaskScope$ShutdownOnFailure + +-class name java/util/concurrent/StructuredTaskScope$ShutdownOnSuccess + +class name java/util/concurrent/StructuredTaskScope$Subtask +header extends java/lang/Object implements java/util/function/Supplier nestHost java/util/concurrent/StructuredTaskScope sealed true permittedSubclasses java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl flags 601 signature Ljava/lang/Object;Ljava/util/function/Supplier; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask outerClass java/util/concurrent/StructuredTaskScope innerClassName Subtask flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask$State outerClass java/util/concurrent/StructuredTaskScope$Subtask innerClassName State flags 4019 +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName SubtaskImpl flags 18 +-method name task descriptor ()Ljava/util/concurrent/Callable; + +-class name java/util/concurrent/StructuredTaskScope$SubtaskImpl + +class name java/util/concurrent/StructuredTaskScope$TimeoutException +header extends java/lang/RuntimeException nestHost java/util/concurrent/StructuredTaskScope flags 31 classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;STRUCTURED_CONCURRENCY;) +innerclass innerClass java/util/concurrent/StructuredTaskScope$TimeoutException outerClass java/util/concurrent/StructuredTaskScope innerClassName TimeoutException flags 19 + +class name java/util/concurrent/StructuredTaskScopeImpl +header extends java/lang/Object implements java/util/concurrent/StructuredTaskScope nestMembers java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl,java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl flags 30 signature Ljava/lang/Object;Ljava/util/concurrent/StructuredTaskScope; +innerclass innerClass java/util/concurrent/StructuredTaskScope$Joiner outerClass java/util/concurrent/StructuredTaskScope innerClassName Joiner flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName ConfigImpl flags 18 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Configuration outerClass java/util/concurrent/StructuredTaskScope innerClassName Configuration flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName SubtaskImpl flags 18 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask outerClass java/util/concurrent/StructuredTaskScope innerClassName Subtask flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask$State outerClass java/util/concurrent/StructuredTaskScope$Subtask innerClassName State flags 4019 +innerclass innerClass java/util/concurrent/StructuredTaskScope$TimeoutException outerClass java/util/concurrent/StructuredTaskScope innerClassName TimeoutException flags 19 +innerclass innerClass java/util/concurrent/StructuredTaskScope$FailedException outerClass java/util/concurrent/StructuredTaskScope innerClassName FailedException flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name fork descriptor (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; flags 1 signature (Ljava/util/concurrent/Callable<+TU;>;)Ljava/util/concurrent/StructuredTaskScope$Subtask; +method name fork descriptor (Ljava/lang/Runnable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; flags 1 signature (Ljava/lang/Runnable;)Ljava/util/concurrent/StructuredTaskScope$Subtask; +method name join descriptor ()Ljava/lang/Object; thrownTypes java/lang/InterruptedException flags 1 signature ()TR; +method name isCancelled descriptor ()Z flags 1 +method name close descriptor ()V flags 1 +method name toString descriptor ()Ljava/lang/String; flags 1 + +class name java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl +header extends java/lang/Record implements java/util/concurrent/StructuredTaskScope$Configuration nestHost java/util/concurrent/StructuredTaskScopeImpl record true flags 30 +recordcomponent name threadFactory descriptor Ljava/util/concurrent/ThreadFactory; +recordcomponent name name descriptor Ljava/lang/String; +recordcomponent name timeout descriptor Ljava/time/Duration; +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$ConfigImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName ConfigImpl flags 18 +innerclass innerClass java/lang/Thread$Builder outerClass java/lang/Thread innerClassName Builder flags 609 +innerclass innerClass java/lang/Thread$Builder$OfVirtual outerClass java/lang/Thread$Builder innerClassName OfVirtual flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Configuration outerClass java/util/concurrent/StructuredTaskScope innerClassName Configuration flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +method name withThreadFactory descriptor (Ljava/util/concurrent/ThreadFactory;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 1 +method name withName descriptor (Ljava/lang/String;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 1 +method name withTimeout descriptor (Ljava/time/Duration;)Ljava/util/concurrent/StructuredTaskScope$Configuration; flags 1 +method name toString descriptor ()Ljava/lang/String; flags 11 +method name hashCode descriptor ()I flags 11 +method name equals descriptor (Ljava/lang/Object;)Z flags 11 +method name threadFactory descriptor ()Ljava/util/concurrent/ThreadFactory; flags 1 +method name name descriptor ()Ljava/lang/String; flags 1 +method name timeout descriptor ()Ljava/time/Duration; flags 1 + +class name java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl +header extends java/lang/Object implements java/util/concurrent/StructuredTaskScope$Subtask,java/lang/Runnable nestHost java/util/concurrent/StructuredTaskScopeImpl flags 30 signature Ljava/lang/Object;Ljava/util/concurrent/StructuredTaskScope$Subtask;Ljava/lang/Runnable; +innerclass innerClass java/util/concurrent/StructuredTaskScopeImpl$SubtaskImpl outerClass java/util/concurrent/StructuredTaskScopeImpl innerClassName SubtaskImpl flags 18 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask outerClass java/util/concurrent/StructuredTaskScope innerClassName Subtask flags 609 +innerclass innerClass java/util/concurrent/StructuredTaskScope$Subtask$State outerClass java/util/concurrent/StructuredTaskScope$Subtask innerClassName State flags 4019 +method name run descriptor ()V flags 1 +method name state descriptor ()Ljava/util/concurrent/StructuredTaskScope$Subtask$State; flags 1 +method name get descriptor ()Ljava/lang/Object; flags 1 signature ()TT; +method name exception descriptor ()Ljava/lang/Throwable; flags 1 +method name toString descriptor ()Ljava/lang/String; flags 1 + +class name java/util/concurrent/locks/LockSupport +header extends java/lang/Object flags 31 + +class name java/util/concurrent/locks/ReentrantReadWriteLock +header extends java/lang/Object implements java/util/concurrent/locks/ReadWriteLock,java/io/Serializable nestMembers java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock,java/util/concurrent/locks/ReentrantReadWriteLock$ReadLock flags 21 +innerclass innerClass java/util/concurrent/locks/ReentrantReadWriteLock$ReadLock outerClass java/util/concurrent/locks/ReentrantReadWriteLock innerClassName ReadLock flags 9 +innerclass innerClass java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock outerClass java/util/concurrent/locks/ReentrantReadWriteLock innerClassName WriteLock flags 9 +innerclass innerClass java/util/concurrent/locks/AbstractQueuedLongSynchronizer$ConditionObject outerClass java/util/concurrent/locks/AbstractQueuedLongSynchronizer innerClassName ConditionObject flags 1 + +class name java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock +header extends java/lang/Object implements java/util/concurrent/locks/Lock,java/io/Serializable nestHost java/util/concurrent/locks/ReentrantReadWriteLock flags 21 +innerclass innerClass java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock outerClass java/util/concurrent/locks/ReentrantReadWriteLock innerClassName WriteLock flags 9 +innerclass innerClass java/util/concurrent/locks/AbstractQueuedLongSynchronizer$ConditionObject outerClass java/util/concurrent/locks/AbstractQueuedLongSynchronizer innerClassName ConditionObject flags 1 + +class name java/util/zip/Deflater +header extends java/lang/Object implements java/lang/AutoCloseable flags 21 +method name close descriptor ()V flags 1 + +class name java/util/zip/Inflater +header extends java/lang/Object implements java/lang/AutoCloseable flags 21 +method name close descriptor ()V flags 1 + +class name javax/crypto/KDF +header extends java/lang/Object flags 31 +innerclass innerClass java/security/Provider$Service outerClass java/security/Provider innerClassName Service flags 9 + +class name javax/crypto/KDFParameters +header extends java/lang/Object flags 601 + +class name javax/crypto/KDFSpi +header extends java/lang/Object flags 421 + +class name javax/crypto/spec/HKDFParameterSpec +header extends java/lang/Object implements java/security/spec/AlgorithmParameterSpec nestMembers javax/crypto/spec/HKDFParameterSpec$ExtractThenExpand,javax/crypto/spec/HKDFParameterSpec$Expand,javax/crypto/spec/HKDFParameterSpec$Extract,javax/crypto/spec/HKDFParameterSpec$Builder flags 601 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Builder outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Builder flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Expand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Expand flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$ExtractThenExpand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName ExtractThenExpand flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Extract outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Extract flags 19 + +class name javax/crypto/spec/HKDFParameterSpec$Builder +header extends java/lang/Object nestHost javax/crypto/spec/HKDFParameterSpec flags 31 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Builder outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Builder flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Extract outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Extract flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$ExtractThenExpand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName ExtractThenExpand flags 19 + +class name javax/crypto/spec/HKDFParameterSpec$Expand +header extends java/lang/Object implements javax/crypto/spec/HKDFParameterSpec nestHost javax/crypto/spec/HKDFParameterSpec flags 31 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Expand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Expand flags 19 + +class name javax/crypto/spec/HKDFParameterSpec$Extract +header extends java/lang/Object implements javax/crypto/spec/HKDFParameterSpec nestHost javax/crypto/spec/HKDFParameterSpec flags 31 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Extract outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Extract flags 19 + +class name javax/crypto/spec/HKDFParameterSpec$ExtractThenExpand +header extends java/lang/Object implements javax/crypto/spec/HKDFParameterSpec nestHost javax/crypto/spec/HKDFParameterSpec flags 31 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$ExtractThenExpand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName ExtractThenExpand flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Extract outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Extract flags 19 +innerclass innerClass javax/crypto/spec/HKDFParameterSpec$Expand outerClass javax/crypto/spec/HKDFParameterSpec innerClassName Expand flags 19 + +class name javax/net/ssl/SSLPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name javax/security/auth/AuthPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name javax/security/auth/PrivateCredentialPermission +header extends java/security/Permission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name jdk/internal/classfile/impl/AbstractPoolEntry$ClassEntryImpl +method name matches descriptor (Ljava/lang/constant/ClassDesc;)Z flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$ConstantDynamicEntryImpl +field name sym descriptor Ljava/lang/constant/DynamicConstantDesc; flags 1 signature Ljava/lang/constant/DynamicConstantDesc<*>; runtimeAnnotations @Ljdk/internal/vm/annotation/Stable; +method name asSymbol descriptor ()Ljava/lang/constant/DynamicConstantDesc; flags 1 signature ()Ljava/lang/constant/DynamicConstantDesc<*>; + +class name jdk/internal/classfile/impl/AbstractPoolEntry$InvokeDynamicEntryImpl +field name sym descriptor Ljava/lang/constant/DynamicCallSiteDesc; flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/Stable; +method name asSymbol descriptor ()Ljava/lang/constant/DynamicCallSiteDesc; flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$MethodHandleEntryImpl +field name sym descriptor Ljava/lang/constant/DirectMethodHandleDesc; flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/Stable; + +class name jdk/internal/classfile/impl/AbstractPoolEntry$MethodTypeEntryImpl +method name matches descriptor (Ljava/lang/constant/MethodTypeDesc;)Z flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$ModuleEntryImpl +method name matches descriptor (Ljava/lang/constant/ModuleDesc;)Z flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$PackageEntryImpl +method name matches descriptor (Ljava/lang/constant/PackageDesc;)Z flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$StringEntryImpl +method name equalsString descriptor (Ljava/lang/String;)Z flags 1 + +class name jdk/internal/classfile/impl/AbstractPoolEntry$Utf8EntryImpl +method name isFieldType descriptor (Ljava/lang/constant/ClassDesc;)Z flags 1 +method name isMethodType descriptor (Ljava/lang/constant/MethodTypeDesc;)Z flags 1 + +class name jdk/internal/classfile/impl/BlockCodeBuilderImpl +header extends jdk/internal/classfile/impl/NonterminalCodeBuilder implements java/lang/classfile/CodeBuilder$BlockCodeBuilder flags 31 +innerclass innerClass java/lang/classfile/CodeBuilder$BlockCodeBuilder outerClass java/lang/classfile/CodeBuilder innerClassName BlockCodeBuilder flags 609 + +class name jdk/internal/classfile/impl/BoundAttribute$BoundStackMapTableAttribute +method name writeTo descriptor (Ljdk/internal/classfile/impl/BufWriterImpl;)V flags 1 + +class name jdk/internal/classfile/impl/BufWriterImpl +-method name setLabelContext descriptor (Ljdk/internal/classfile/impl/LabelContext;)V +method name setLabelContext descriptor (Ljdk/internal/classfile/impl/LabelContext;Z)V flags 1 +method name labelsMatch descriptor (Ljdk/internal/classfile/impl/LabelContext;)Z flags 1 + +class name jdk/internal/classfile/impl/ChainedClassBuilder +header extends java/lang/Object implements java/lang/classfile/ClassBuilder,java/util/function/Consumer flags 31 signature Ljava/lang/Object;Ljava/lang/classfile/ClassBuilder;Ljava/util/function/Consumer; + +class name jdk/internal/classfile/impl/ChainedFieldBuilder +header extends java/lang/Object implements java/lang/classfile/FieldBuilder flags 31 + +class name jdk/internal/classfile/impl/ChainedMethodBuilder +header extends java/lang/Object implements java/lang/classfile/MethodBuilder flags 31 + +class name jdk/internal/classfile/impl/CodeImpl +header extends jdk/internal/classfile/impl/BoundAttribute$BoundCodeAttribute implements jdk/internal/classfile/impl/LabelContext nestMembers jdk/internal/classfile/impl/CodeImpl$ExceptionHandlerAction flags 31 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundCodeAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundCodeAttribute flags 409 +innerclass innerClass jdk/internal/classfile/impl/CodeImpl$ExceptionHandlerAction outerClass jdk/internal/classfile/impl/CodeImpl innerClassName ExceptionHandlerAction flags 609 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundLineNumberTableAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundLineNumberTableAttribute flags 19 +innerclass innerClass java/lang/classfile/Opcode$Kind outerClass java/lang/classfile/Opcode innerClassName Kind flags 4019 +innerclass innerClass java/lang/classfile/instruction/DiscontinuedInstruction$JsrInstruction outerClass java/lang/classfile/instruction/DiscontinuedInstruction innerClassName JsrInstruction flags 609 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundCharacterRangeTableAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundCharacterRangeTableAttribute flags 19 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundLocalVariableTableAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundLocalVariableTableAttribute flags 19 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundLocalVariableTypeTableAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundLocalVariableTypeTableAttribute flags 19 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundRuntimeVisibleTypeAnnotationsAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundRuntimeVisibleTypeAnnotationsAttribute flags 19 +innerclass innerClass jdk/internal/classfile/impl/BoundAttribute$BoundRuntimeInvisibleTypeAnnotationsAttribute outerClass jdk/internal/classfile/impl/BoundAttribute innerClassName BoundRuntimeInvisibleTypeAnnotationsAttribute flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundArgumentConstantInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundArgumentConstantInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundLoadConstantInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundLoadConstantInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundLoadInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundLoadInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundStoreInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundStoreInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundIncrementInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundIncrementInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundBranchInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundBranchInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundTableSwitchInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundTableSwitchInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundLookupSwitchInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundLookupSwitchInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundFieldInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundFieldInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundInvokeInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundInvokeInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundInvokeInterfaceInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundInvokeInterfaceInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundInvokeDynamicInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundInvokeDynamicInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundNewObjectInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundNewObjectInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundNewPrimitiveArrayInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundNewPrimitiveArrayInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundNewReferenceArrayInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundNewReferenceArrayInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundTypeCheckInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundTypeCheckInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundRetInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundRetInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundNewMultidimensionalArrayInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundNewMultidimensionalArrayInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$BoundJsrInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName BoundJsrInstruction flags 19 +innerclass innerClass java/lang/classfile/instruction/ConstantInstruction$IntrinsicConstantInstruction outerClass java/lang/classfile/instruction/ConstantInstruction innerClassName IntrinsicConstantInstruction flags 609 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$UnboundLoadInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName UnboundLoadInstruction flags 19 +innerclass innerClass jdk/internal/classfile/impl/AbstractInstruction$UnboundStoreInstruction outerClass jdk/internal/classfile/impl/AbstractInstruction innerClassName UnboundStoreInstruction flags 19 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/internal/classfile/impl/DirectCodeBuilder +method name withMaxs descriptor (Ljava/lang/classfile/CodeBuilder;II)V flags 9 + +class name jdk/internal/classfile/impl/LabelContext +method name canWriteDirect descriptor (Ljdk/internal/classfile/impl/LabelContext;)Z flags 1 + +class name jdk/internal/classfile/impl/NonterminalCodeBuilder +header extends java/lang/Object implements java/lang/classfile/CodeBuilder sealed true permittedSubclasses jdk/internal/classfile/impl/ChainedCodeBuilder,jdk/internal/classfile/impl/BlockCodeBuilderImpl flags 421 + +class name jdk/internal/foreign/layout/ValueLayouts$AbstractValueLayout +header extends jdk/internal/foreign/layout/AbstractLayout nestHost jdk/internal/foreign/layout/ValueLayouts sealed true permittedSubclasses jdk/internal/foreign/layout/ValueLayouts$OfBooleanImpl,jdk/internal/foreign/layout/ValueLayouts$OfByteImpl,jdk/internal/foreign/layout/ValueLayouts$OfCharImpl,jdk/internal/foreign/layout/ValueLayouts$OfShortImpl,jdk/internal/foreign/layout/ValueLayouts$OfIntImpl,jdk/internal/foreign/layout/ValueLayouts$OfFloatImpl,jdk/internal/foreign/layout/ValueLayouts$OfLongImpl,jdk/internal/foreign/layout/ValueLayouts$OfDoubleImpl,jdk/internal/foreign/layout/ValueLayouts$OfAddressImpl flags 420 signature ;:Ljava/lang/foreign/ValueLayout;>Ljdk/internal/foreign/layout/AbstractLayout; +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$AbstractValueLayout outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName AbstractValueLayout flags 408 +innerclass innerClass java/lang/foreign/MemoryLayout$PathElement outerClass java/lang/foreign/MemoryLayout innerClassName PathElement flags 609 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfBooleanImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfBooleanImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfByteImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfByteImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfCharImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfCharImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfShortImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfShortImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfIntImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfIntImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfFloatImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfFloatImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfLongImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfLongImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfDoubleImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfDoubleImpl flags 19 +innerclass innerClass jdk/internal/foreign/layout/ValueLayouts$OfAddressImpl outerClass jdk/internal/foreign/layout/ValueLayouts innerClassName OfAddressImpl flags 19 + +class name jdk/internal/lang/stable/StableValueImpl +header extends java/lang/Object implements java/lang/StableValue flags 31 signature Ljava/lang/Object;Ljava/lang/StableValue; +method name trySet descriptor (Ljava/lang/Object;)Z flags 1 signature (TT;)Z runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name setOrThrow descriptor (Ljava/lang/Object;)V flags 1 signature (TT;)V runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name orElseThrow descriptor ()Ljava/lang/Object; flags 1 signature ()TT; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name orElse descriptor (Ljava/lang/Object;)Ljava/lang/Object; flags 1 signature (TT;)TT; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name isSet descriptor ()Z flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name orElseSet descriptor (Ljava/util/function/Supplier;)Ljava/lang/Object; flags 1 signature (Ljava/util/function/Supplier<+TT;>;)TT; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name toString descriptor ()Ljava/lang/String; flags 1 +method name of descriptor ()Ljdk/internal/lang/stable/StableValueImpl; flags 9 signature ()Ljdk/internal/lang/stable/StableValueImpl; +method name wrappedContentsAcquire descriptor ()Ljava/lang/Object; flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; + +class name jdk/internal/vm/vector/VectorSupport +header extends java/lang/Object nestMembers jdk/internal/vm/vector/VectorSupport$VectorMask,jdk/internal/vm/vector/VectorSupport$VectorShuffle,jdk/internal/vm/vector/VectorSupport$Vector,jdk/internal/vm/vector/VectorSupport$VectorPayload,jdk/internal/vm/vector/VectorSupport$VectorSpecies flags 21 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +-method name isNonCapturingLambda descriptor (Ljava/lang/Object;)Z +-method name shuffleIota descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;IIIILjdk/internal/vm/vector/VectorSupport$ShuffleIotaOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; +-method name shuffleToVector descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;ILjdk/internal/vm/vector/VectorSupport$ShuffleToVectorOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; +-method name wrapShuffleIndexes descriptor (Ljava/lang/Class;Ljava/lang/Class;Ljdk/internal/vm/vector/VectorSupport$VectorShuffle;ILjdk/internal/vm/vector/VectorSupport$WrapShuffleIndexesOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; +field name VECTOR_OP_MATHLIB_FIRST descriptor I constantValue 101 flags 19 +field name VECTOR_OP_MATHLIB_LAST descriptor I constantValue 118 flags 19 +method name libraryUnaryOp descriptor (JLjava/lang/Class;Ljava/lang/Class;ILjava/lang/String;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$UnaryOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector; flags 9 signature ;E:Ljava/lang/Object;>(JLjava/lang/Class<+TV;>;Ljava/lang/Class;ILjava/lang/String;TV;Ljdk/internal/vm/vector/VectorSupport$UnaryOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name libraryBinaryOp descriptor (JLjava/lang/Class;Ljava/lang/Class;ILjava/lang/String;Ljdk/internal/vm/vector/VectorSupport$VectorPayload;Ljdk/internal/vm/vector/VectorSupport$VectorPayload;Ljdk/internal/vm/vector/VectorSupport$BinaryOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload; flags 9 signature (JLjava/lang/Class<+TV;>;Ljava/lang/Class;ILjava/lang/String;TV;TV;Ljdk/internal/vm/vector/VectorSupport$BinaryOperation;)TV; runtimeAnnotations @Ljdk/internal/vm/annotation/IntrinsicCandidate; +method name getCPUFeatures descriptor ()Ljava/lang/String; flags 109 +method name loadNativeLibrary descriptor (Ljava/lang/String;)V flags 9 + diff --git a/src/jdk.compiler/share/data/symbols/java.compiler-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.compiler-P.sym.txt new file mode 100644 index 00000000000..2bb9c846013 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.compiler-P.sym.txt @@ -0,0 +1,85 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/lang/model/SourceVersion +field name RELEASE_25 descriptor Ljavax/lang/model/SourceVersion; flags 4019 + +class name javax/lang/model/util/AbstractAnnotationValueVisitor14 +header extends javax/lang/model/util/AbstractAnnotationValueVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractAnnotationValueVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/AbstractAnnotationValueVisitorPreview +header extends javax/lang/model/util/AbstractAnnotationValueVisitor14 flags 421 signature Ljavax/lang/model/util/AbstractAnnotationValueVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/AbstractElementVisitor14 +header extends javax/lang/model/util/AbstractElementVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractElementVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/AbstractElementVisitorPreview +header extends javax/lang/model/util/AbstractElementVisitor14 flags 421 signature Ljavax/lang/model/util/AbstractElementVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/AbstractTypeVisitor14 +header extends javax/lang/model/util/AbstractTypeVisitor9 flags 421 signature Ljavax/lang/model/util/AbstractTypeVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/AbstractTypeVisitorPreview +header extends javax/lang/model/util/AbstractTypeVisitor14 flags 421 signature Ljavax/lang/model/util/AbstractTypeVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/ElementKindVisitor14 +header extends javax/lang/model/util/ElementKindVisitor9 flags 21 signature Ljavax/lang/model/util/ElementKindVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/ElementKindVisitorPreview +header extends javax/lang/model/util/ElementKindVisitor14 flags 21 signature Ljavax/lang/model/util/ElementKindVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/ElementScanner14 +header extends javax/lang/model/util/ElementScanner9 flags 21 signature Ljavax/lang/model/util/ElementScanner9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/ElementScannerPreview +header extends javax/lang/model/util/ElementScanner14 flags 21 signature Ljavax/lang/model/util/ElementScanner14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleAnnotationValueVisitor14 +header extends javax/lang/model/util/SimpleAnnotationValueVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleAnnotationValueVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleAnnotationValueVisitorPreview +header extends javax/lang/model/util/SimpleAnnotationValueVisitor14 flags 21 signature Ljavax/lang/model/util/SimpleAnnotationValueVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleElementVisitor14 +header extends javax/lang/model/util/SimpleElementVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleElementVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleElementVisitorPreview +header extends javax/lang/model/util/SimpleElementVisitor14 flags 21 signature Ljavax/lang/model/util/SimpleElementVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleTypeVisitor14 +header extends javax/lang/model/util/SimpleTypeVisitor9 flags 21 signature Ljavax/lang/model/util/SimpleTypeVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/SimpleTypeVisitorPreview +header extends javax/lang/model/util/SimpleTypeVisitor14 flags 21 signature Ljavax/lang/model/util/SimpleTypeVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/TypeKindVisitor14 +header extends javax/lang/model/util/TypeKindVisitor9 flags 21 signature Ljavax/lang/model/util/TypeKindVisitor9; runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + +class name javax/lang/model/util/TypeKindVisitorPreview +header extends javax/lang/model/util/TypeKindVisitor14 flags 21 signature Ljavax/lang/model/util/TypeKindVisitor14; classAnnotations @Ljdk/internal/javac/PreviewFeature;(feature=eLjdk/internal/javac/PreviewFeature$Feature;LANGUAGE_MODEL;,reflective=Ztrue) runtimeAnnotations @Ljavax/annotation/processing/SupportedSourceVersion;(value=eLjavax/lang/model/SourceVersion;RELEASE_25;) + diff --git a/src/jdk.compiler/share/data/symbols/java.desktop-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.desktop-P.sym.txt new file mode 100644 index 00000000000..23b567b6c05 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.desktop-P.sym.txt @@ -0,0 +1,43 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/awt/Color +-method name createContext descriptor (Ljava/awt/image/ColorModel;Ljava/awt/Rectangle;Ljava/awt/geom/Rectangle2D;Ljava/awt/geom/AffineTransform;Ljava/awt/RenderingHints;)Ljava/awt/PaintContext; +method name createContext descriptor (Ljava/awt/image/ColorModel;Ljava/awt/Rectangle;Ljava/awt/geom/Rectangle2D;Ljava/awt/geom/AffineTransform;Ljava/awt/RenderingHints;)Ljava/awt/PaintContext; flags 1 + +class name javax/swing/plaf/basic/BasicScrollBarUI$ScrollListener +header extends java/lang/Object implements java/awt/event/ActionListener nestHost javax/swing/plaf/basic/BasicScrollBarUI flags 21 +innerclass innerClass javax/swing/plaf/basic/BasicScrollBarUI$ScrollListener outerClass javax/swing/plaf/basic/BasicScrollBarUI innerClassName ScrollListener flags 4 +innerclass innerClass javax/swing/plaf/basic/BasicScrollBarUI$TrackListener outerClass javax/swing/plaf/basic/BasicScrollBarUI innerClassName TrackListener flags 4 + +class name javax/swing/plaf/basic/BasicSliderUI +-method name descriptor ()V + +class name javax/swing/plaf/synth/SynthLookAndFeel +-method name load descriptor (Ljava/net/URL;)V + diff --git a/src/jdk.compiler/share/data/symbols/java.logging-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.logging-P.sym.txt new file mode 100644 index 00000000000..dfcaa64bef7 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.logging-P.sym.txt @@ -0,0 +1,44 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/util/logging/FileHandler +-method name publish descriptor (Ljava/util/logging/LogRecord;)V +method name publish descriptor (Ljava/util/logging/LogRecord;)V flags 1 + +class name java/util/logging/LoggingPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name java/util/logging/SocketHandler +-method name publish descriptor (Ljava/util/logging/LogRecord;)V +method name publish descriptor (Ljava/util/logging/LogRecord;)V flags 1 + +class name java/util/logging/StreamHandler +-method name publish descriptor (Ljava/util/logging/LogRecord;)V +method name publish descriptor (Ljava/util/logging/LogRecord;)V flags 1 + diff --git a/src/jdk.compiler/share/data/symbols/java.management-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.management-P.sym.txt new file mode 100644 index 00000000000..459df392e02 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.management-P.sym.txt @@ -0,0 +1,57 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/lang/management/ManagementPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanPermission +header extends java/security/Permission flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanServerPermission +header extends java/security/BasicPermission flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/MBeanTrustPermission +header extends java/security/BasicPermission flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/modelmbean/DescriptorSupport +-method name descriptor (Ljava/lang/String;)V +-method name toXMLString descriptor ()Ljava/lang/String; +method name descriptor (Ljava/lang/String;)V thrownTypes javax/management/MBeanException,javax/management/RuntimeOperationsException,javax/management/modelmbean/XMLParseException flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +method name toXMLString descriptor ()Ljava/lang/String; flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + +class name javax/management/modelmbean/XMLParseException +header extends java/lang/Exception flags 21 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/management/remote/SubjectDelegationPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + diff --git a/src/jdk.compiler/share/data/symbols/java.net.http-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.net.http-P.sym.txt new file mode 100644 index 00000000000..19ddbb72a38 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.net.http-P.sym.txt @@ -0,0 +1,37 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name java/net/http/HttpResponse +method name connectionLabel descriptor ()Ljava/util/Optional; flags 1 signature ()Ljava/util/Optional; + +class name java/net/http/HttpResponse$BodyHandlers +method name limiting descriptor (Ljava/net/http/HttpResponse$BodyHandler;J)Ljava/net/http/HttpResponse$BodyHandler; flags 9 signature (Ljava/net/http/HttpResponse$BodyHandler;J)Ljava/net/http/HttpResponse$BodyHandler; + +class name java/net/http/HttpResponse$BodySubscribers +method name limiting descriptor (Ljava/net/http/HttpResponse$BodySubscriber;J)Ljava/net/http/HttpResponse$BodySubscriber; flags 9 signature (Ljava/net/http/HttpResponse$BodySubscriber;J)Ljava/net/http/HttpResponse$BodySubscriber; + diff --git a/src/jdk.compiler/share/data/symbols/java.security.jgss-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.security.jgss-P.sym.txt new file mode 100644 index 00000000000..3023fbddc6c --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.security.jgss-P.sym.txt @@ -0,0 +1,36 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/security/auth/kerberos/DelegationPermission +header extends java/security/BasicPermission implements java/io/Serializable flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name javax/security/auth/kerberos/ServicePermission +header extends java/security/Permission implements java/io/Serializable flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/src/jdk.compiler/share/data/symbols/java.xml.crypto-P.sym.txt b/src/jdk.compiler/share/data/symbols/java.xml.crypto-P.sym.txt new file mode 100644 index 00000000000..a6cbe487e88 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/java.xml.crypto-P.sym.txt @@ -0,0 +1,34 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name javax/xml/crypto/dsig/SignatureMethod +field name ECDSA_SHA3_224 descriptor Ljava/lang/String; constantValue http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-224 flags 19 +field name ECDSA_SHA3_256 descriptor Ljava/lang/String; constantValue http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-256 flags 19 +field name ECDSA_SHA3_384 descriptor Ljava/lang/String; constantValue http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-384 flags 19 +field name ECDSA_SHA3_512 descriptor Ljava/lang/String; constantValue http://www.w3.org/2021/04/xmldsig-more#ecdsa-sha3-512 flags 19 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.attach-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.attach-P.sym.txt new file mode 100644 index 00000000000..d947c4babfb --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.attach-P.sym.txt @@ -0,0 +1,32 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/tools/attach/AttachPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.compiler-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.compiler-P.sym.txt new file mode 100644 index 00000000000..eaeedda8287 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.compiler-P.sym.txt @@ -0,0 +1,32 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/source/tree/ImportTree +-method name isModule descriptor ()Z +method name isModule descriptor ()Z flags 401 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.crypto.cryptoki-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.crypto.cryptoki-P.sym.txt new file mode 100644 index 00000000000..55667354e09 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.crypto.cryptoki-P.sym.txt @@ -0,0 +1,31 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name jdk.crypto.cryptoki +header requires name\u0020;java.base\u0020;flags\u0020;8000 provides interface\u0020;java/security/Provider\u0020;impls\u0020;sun/security/pkcs11/SunPKCS11 target macos-aarch64 flags 8000 classAnnotations @Ljdk/internal/javac/ParticipatesInPreview; + diff --git a/src/jdk.compiler/share/data/symbols/jdk.incubator.foreign-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.incubator.foreign-P.sym.txt new file mode 100644 index 00000000000..0f7866c462b --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.incubator.foreign-P.sym.txt @@ -0,0 +1,105 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/internal/foreign/AbstractMemorySegmentImpl +-method name reinterpret descriptor (JLjava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; +-method name reinterpret descriptor (J)Ljava/lang/foreign/MemorySegment; +-method name reinterpret descriptor (Ljava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; +method name reinterpret descriptor (JLjava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; flags 11 signature (JLjava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive;@Ljdk/internal/vm/annotation/ForceInline; +method name reinterpret descriptor (J)Ljava/lang/foreign/MemorySegment; flags 11 runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive;@Ljdk/internal/vm/annotation/ForceInline; +method name reinterpret descriptor (Ljava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; flags 11 signature (Ljava/lang/foreign/Arena;Ljava/util/function/Consumer;)Ljava/lang/foreign/MemorySegment; runtimeAnnotations @Ljdk/internal/reflect/CallerSensitive;@Ljdk/internal/vm/annotation/ForceInline; + +class name jdk/internal/foreign/LayoutPath +header extends java/lang/Object nestMembers jdk/internal/foreign/LayoutPath$DereferenceElement,jdk/internal/foreign/LayoutPath$SequenceElement,jdk/internal/foreign/LayoutPath$SequenceElementByRange,jdk/internal/foreign/LayoutPath$SequenceElementByIndex,jdk/internal/foreign/LayoutPath$GroupElementByIndex,jdk/internal/foreign/LayoutPath$GroupElementByName flags 21 +innerclass innerClass java/lang/invoke/VarHandle$AccessMode outerClass java/lang/invoke/VarHandle innerClassName AccessMode flags 4019 +innerclass innerClass java/lang/foreign/MemoryLayout$PathElement outerClass java/lang/foreign/MemoryLayout innerClassName PathElement flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$DereferenceElement outerClass jdk/internal/foreign/LayoutPath innerClassName DereferenceElement flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$SequenceElement outerClass jdk/internal/foreign/LayoutPath innerClassName SequenceElement flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$SequenceElementByRange outerClass jdk/internal/foreign/LayoutPath innerClassName SequenceElementByRange flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$SequenceElementByIndex outerClass jdk/internal/foreign/LayoutPath innerClassName SequenceElementByIndex flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$GroupElementByIndex outerClass jdk/internal/foreign/LayoutPath innerClassName GroupElementByIndex flags 19 +innerclass innerClass jdk/internal/foreign/LayoutPath$GroupElementByName outerClass jdk/internal/foreign/LayoutPath innerClassName GroupElementByName flags 19 +field name EMPTY_PATH_ELEMENTS descriptor [Ljava/lang/foreign/MemoryLayout$PathElement; flags 19 + +class name jdk/internal/foreign/abi/LinkerOptions +header extends java/lang/Object nestMembers jdk/internal/foreign/abi/LinkerOptions$Critical,jdk/internal/foreign/abi/LinkerOptions$CaptureCallState,jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg,jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl flags 21 +innerclass innerClass java/lang/foreign/Linker$Option outerClass java/lang/foreign/Linker innerClassName Option flags 609 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName LinkerOptionImpl flags 609 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName FirstVariadicArg flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$CaptureCallState outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName CaptureCallState flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$Critical outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName Critical flags 4019 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name capturedCallState descriptor ()Ljava/util/stream/Stream; +method name capturedCallStateMask descriptor ()I flags 1 + +class name jdk/internal/foreign/abi/LinkerOptions$CaptureCallState +header extends java/lang/Record implements jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl nestHost jdk/internal/foreign/abi/LinkerOptions record true flags 31 +recordcomponent name mask descriptor I +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$CaptureCallState outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName CaptureCallState flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName LinkerOptionImpl flags 609 +-method name descriptor (Ljava/util/Set;)V +-method name toString descriptor ()Ljava/lang/String; +-method name hashCode descriptor ()I +-method name equals descriptor (Ljava/lang/Object;)Z +-method name saved descriptor ()Ljava/util/Set; +method name descriptor (I)V flags 1 methodParameters 0:compact +method name equals descriptor (Ljava/lang/Object;)Z flags 1 +method name hashCode descriptor ()I flags 1 +method name toString descriptor ()Ljava/lang/String; flags 1 +method name mask descriptor ()I flags 1 + +class name jdk/internal/foreign/abi/LinkerOptions$Critical +header extends java/lang/Enum implements jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl nestHost jdk/internal/foreign/abi/LinkerOptions flags 4031 signature Ljava/lang/Enum;Ljdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl; +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$Critical outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName Critical flags 4019 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName LinkerOptionImpl flags 609 +-field name ALLOW_HEAP descriptor Ljdk/internal/foreign/abi/LinkerOptions$Critical; +-field name DONT_ALLOW_HEAP descriptor Ljdk/internal/foreign/abi/LinkerOptions$Critical; +-method name descriptor (Z)V +-method name toString descriptor ()Ljava/lang/String; +-method name hashCode descriptor ()I +-method name equals descriptor (Ljava/lang/Object;)Z +field name ALLOW_HEAP descriptor Ljdk/internal/foreign/abi/LinkerOptions$Critical; flags 4019 +field name DONT_ALLOW_HEAP descriptor Ljdk/internal/foreign/abi/LinkerOptions$Critical; flags 4019 +method name values descriptor ()[Ljdk/internal/foreign/abi/LinkerOptions$Critical; flags 9 +method name valueOf descriptor (Ljava/lang/String;)Ljdk/internal/foreign/abi/LinkerOptions$Critical; flags 9 methodParameters 8000:null + +class name jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg +-method name hashCode descriptor ()I +-method name equals descriptor (Ljava/lang/Object;)Z +method name hashCode descriptor ()I flags 1 +method name equals descriptor (Ljava/lang/Object;)Z flags 1 + +class name jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl +header extends java/lang/Object implements java/lang/foreign/Linker$Option nestHost jdk/internal/foreign/abi/LinkerOptions sealed true permittedSubclasses jdk/internal/foreign/abi/LinkerOptions$CaptureCallState,jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg,jdk/internal/foreign/abi/LinkerOptions$Critical flags 601 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$LinkerOptionImpl outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName LinkerOptionImpl flags 609 +innerclass innerClass java/lang/foreign/Linker$Option outerClass java/lang/foreign/Linker innerClassName Option flags 609 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$CaptureCallState outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName CaptureCallState flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$FirstVariadicArg outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName FirstVariadicArg flags 19 +innerclass innerClass jdk/internal/foreign/abi/LinkerOptions$Critical outerClass jdk/internal/foreign/abi/LinkerOptions innerClassName Critical flags 4019 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.incubator.vector-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.incubator.vector-P.sym.txt new file mode 100644 index 00000000000..cae81b02a3d --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.incubator.vector-P.sym.txt @@ -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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/incubator/vector/AbstractVector +header extends jdk/incubator/vector/Vector flags 420 signature Ljdk/incubator/vector/Vector; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Conversion outerClass jdk/incubator/vector/VectorOperators innerClassName Conversion flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/DoubleVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass java/lang/foreign/ValueLayout$OfDouble outerClass java/lang/foreign/ValueLayout innerClassName OfDouble flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Conversion outerClass jdk/incubator/vector/VectorOperators innerClassName Conversion flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/Float16 +header extends java/lang/Number implements java/lang/Comparable flags 31 signature Ljava/lang/Number;Ljava/lang/Comparable; runtimeAnnotations @Ljdk/internal/ValueBased; +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name valueOf descriptor (F)Ljdk/incubator/vector/Float16; +-method name byteValue descriptor ()B +-method name shortValue descriptor ()S +-method name intValue descriptor ()I +-method name floatValue descriptor ()F +-method name doubleValue descriptor ()D +method name valueOf descriptor (F)Ljdk/incubator/vector/Float16; flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name byteValue descriptor ()B flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name shortValue descriptor ()S flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name intValue descriptor ()I flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name floatValue descriptor ()F flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name doubleValue descriptor ()D flags 1 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; + +class name jdk/incubator/vector/FloatVector +header extends jdk/incubator/vector/AbstractVector flags 421 signature Ljdk/incubator/vector/AbstractVector; +innerclass innerClass jdk/incubator/vector/VectorOperators$Operator outerClass jdk/incubator/vector/VectorOperators innerClassName Operator flags 609 +innerclass innerClass java/lang/foreign/ValueLayout$OfFloat outerClass java/lang/foreign/ValueLayout innerClassName OfFloat flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorSpecies outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorSpecies flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorPayload outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorPayload flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Unary outerClass jdk/incubator/vector/VectorOperators innerClassName Unary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Comparison outerClass jdk/incubator/vector/VectorOperators innerClassName Comparison flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$Vector outerClass jdk/internal/vm/vector/VectorSupport innerClassName Vector flags 9 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorMask outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorMask flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Associative outerClass jdk/incubator/vector/VectorOperators innerClassName Associative flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Binary outerClass jdk/incubator/vector/VectorOperators innerClassName Binary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Ternary outerClass jdk/incubator/vector/VectorOperators innerClassName Ternary flags 609 +innerclass innerClass jdk/incubator/vector/VectorOperators$Test outerClass jdk/incubator/vector/VectorOperators innerClassName Test flags 609 +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass jdk/incubator/vector/VectorOperators$Conversion outerClass jdk/incubator/vector/VectorOperators innerClassName Conversion flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + +class name jdk/incubator/vector/VectorShape +-method name forBitSize descriptor (I)Ljdk/incubator/vector/VectorShape; +method name forBitSize descriptor (I)Ljdk/incubator/vector/VectorShape; flags 9 runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; + +class name jdk/incubator/vector/VectorShuffle +header extends jdk/internal/vm/vector/VectorSupport$VectorShuffle flags 421 signature Ljdk/internal/vm/vector/VectorSupport$VectorShuffle; +innerclass innerClass jdk/internal/vm/vector/VectorSupport$VectorShuffle outerClass jdk/internal/vm/vector/VectorSupport innerClassName VectorShuffle flags 9 +innerclass innerClass java/lang/foreign/ValueLayout$OfInt outerClass java/lang/foreign/ValueLayout innerClassName OfInt flags 609 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 +-method name laneSource descriptor (I)I +method name laneSource descriptor (I)I flags 401 +method name fromMemorySegment descriptor (Ljdk/incubator/vector/VectorSpecies;Ljava/lang/foreign/MemorySegment;JLjava/nio/ByteOrder;)Ljdk/incubator/vector/VectorShuffle; flags 19 signature (Ljdk/incubator/vector/VectorSpecies;Ljava/lang/foreign/MemorySegment;JLjava/nio/ByteOrder;)Ljdk/incubator/vector/VectorShuffle; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name intoMemorySegment descriptor (Ljava/lang/foreign/MemorySegment;JLjava/nio/ByteOrder;)V flags 401 + +class name jdk/incubator/vector/VectorSpecies +-method name of descriptor (Ljava/lang/Class;Ljdk/incubator/vector/VectorShape;)Ljdk/incubator/vector/VectorSpecies; +-method name ofLargestShape descriptor (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; +-method name ofPreferred descriptor (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; +-method name elementSize descriptor (Ljava/lang/Class;)I +method name of descriptor (Ljava/lang/Class;Ljdk/incubator/vector/VectorShape;)Ljdk/incubator/vector/VectorSpecies; flags 9 signature (Ljava/lang/Class;Ljdk/incubator/vector/VectorShape;)Ljdk/incubator/vector/VectorSpecies; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name ofLargestShape descriptor (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; flags 9 signature (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name ofPreferred descriptor (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; flags 9 signature (Ljava/lang/Class;)Ljdk/incubator/vector/VectorSpecies; runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; +method name elementSize descriptor (Ljava/lang/Class;)I flags 9 signature (Ljava/lang/Class<*>;)I runtimeAnnotations @Ljdk/internal/vm/annotation/ForceInline; + diff --git a/src/jdk.compiler/share/data/symbols/jdk.jdi-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.jdi-P.sym.txt new file mode 100644 index 00000000000..153c13b1967 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.jdi-P.sym.txt @@ -0,0 +1,32 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/jdi/JDIPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.jfr-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.jfr-P.sym.txt new file mode 100644 index 00000000000..8f7fe9f5699 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.jfr-P.sym.txt @@ -0,0 +1,31 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/jfr/FlightRecorderPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + diff --git a/src/jdk.compiler/share/data/symbols/jdk.jpackage-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.jpackage-P.sym.txt new file mode 100644 index 00000000000..fca76c0b895 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.jpackage-P.sym.txt @@ -0,0 +1,31 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +module name jdk.jpackage +header requires name\u0020;java.base\u0020;flags\u0020;8000,name\u0020;jdk.internal.opt\u0020;flags\u0020;0,name\u0020;jdk.jlink\u0020;flags\u0020;0,name\u0020;java.naming\u0020;flags\u0020;0,name\u0020;java.desktop\u0020;flags\u0020;0 uses jdk/jpackage/internal/Bundler,jdk/jpackage/internal/Bundlers provides interface\u0020;java/util/spi/ToolProvider\u0020;impls\u0020;jdk/jpackage/internal/JPackageToolProvider,interface\u0020;jdk/jpackage/internal/Bundler\u0020;impls\u0020;jdk/jpackage/internal/MacAppBundler\u005C;u002C;jdk/jpackage/internal/MacDmgBundler\u005C;u002C;jdk/jpackage/internal/MacPkgBundler,interface\u0020;jdk/jpackage/internal/Bundlers\u0020;impls\u0020;jdk/jpackage/internal/BasicBundlers target macos-aarch64 moduleMainClass jdk/jpackage/main/Main flags 8000 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.jshell-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.jshell-P.sym.txt new file mode 100644 index 00000000000..116976017d6 --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.jshell-P.sym.txt @@ -0,0 +1,46 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/jshell/JShellConsole +-method name readLine descriptor ()Ljava/lang/String; + +class name jdk/jshell/Snippet$SubKind +-field name MODULE_IMPORT_SUBKIND descriptor Ljdk/jshell/Snippet$SubKind; +field name MODULE_IMPORT_SUBKIND descriptor Ljdk/jshell/Snippet$SubKind; flags 4019 + +class name jdk/jshell/execution/LocalExecutionControl +header extends jdk/jshell/execution/DirectExecutionControl flags 21 +innerclass innerClass jdk/jshell/spi/ExecutionControl$ClassBytecodes outerClass jdk/jshell/spi/ExecutionControl innerClassName ClassBytecodes flags 19 +innerclass innerClass jdk/jshell/spi/ExecutionControl$StoppedException outerClass jdk/jshell/spi/ExecutionControl innerClassName StoppedException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$InternalException outerClass jdk/jshell/spi/ExecutionControl innerClassName InternalException flags 9 +innerclass innerClass java/lang/classfile/CodeBuilder$BlockCodeBuilder outerClass java/lang/classfile/CodeBuilder innerClassName BlockCodeBuilder flags 609 +innerclass innerClass jdk/jshell/spi/ExecutionControl$ClassInstallException outerClass jdk/jshell/spi/ExecutionControl innerClassName ClassInstallException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$NotImplementedException outerClass jdk/jshell/spi/ExecutionControl innerClassName NotImplementedException flags 9 +innerclass innerClass jdk/jshell/spi/ExecutionControl$EngineTerminationException outerClass jdk/jshell/spi/ExecutionControl innerClassName EngineTerminationException flags 9 +innerclass innerClass java/lang/invoke/MethodHandles$Lookup outerClass java/lang/invoke/MethodHandles innerClassName Lookup flags 19 + diff --git a/src/jdk.compiler/share/data/symbols/jdk.net-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.net-P.sym.txt new file mode 100644 index 00000000000..377aa5fb5df --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.net-P.sym.txt @@ -0,0 +1,31 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name jdk/net/NetworkPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + diff --git a/src/jdk.compiler/share/data/symbols/jdk.security.jgss-P.sym.txt b/src/jdk.compiler/share/data/symbols/jdk.security.jgss-P.sym.txt new file mode 100644 index 00000000000..3c4839b8f7a --- /dev/null +++ b/src/jdk.compiler/share/data/symbols/jdk.security.jgss-P.sym.txt @@ -0,0 +1,31 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## +# +class name com/sun/security/jgss/InquireSecContextPermission +header extends java/security/BasicPermission flags 31 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="25") + diff --git a/src/jdk.compiler/share/data/symbols/symbols b/src/jdk.compiler/share/data/symbols/symbols index f7f2946d582..7793033d22f 100644 --- a/src/jdk.compiler/share/data/symbols/symbols +++ b/src/jdk.compiler/share/data/symbols/symbols @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #command used to generate this file: #build.tools.symbolgenerator.CreateSymbols build-description-incremental symbols include.list # -generate platforms 8:9:A:B:C:D:E:F:G:H:I:J:K:L:M:N:O +generate platforms 8:9:A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P platform version 8 files java.activation-8.sym.txt:java.base-8.sym.txt:java.compiler-8.sym.txt:java.corba-8.sym.txt:java.datatransfer-8.sym.txt:java.desktop-8.sym.txt:java.instrument-8.sym.txt:java.logging-8.sym.txt:java.management-8.sym.txt:java.management.rmi-8.sym.txt:java.naming-8.sym.txt:java.prefs-8.sym.txt:java.rmi-8.sym.txt:java.scripting-8.sym.txt:java.security.jgss-8.sym.txt:java.security.sasl-8.sym.txt:java.sql-8.sym.txt:java.sql.rowset-8.sym.txt:java.transaction-8.sym.txt:java.xml-8.sym.txt:java.xml.bind-8.sym.txt:java.xml.crypto-8.sym.txt:java.xml.ws-8.sym.txt:java.xml.ws.annotation-8.sym.txt:jdk.httpserver-8.sym.txt:jdk.management-8.sym.txt:jdk.scripting.nashorn-8.sym.txt:jdk.sctp-8.sym.txt:jdk.security.auth-8.sym.txt:jdk.security.jgss-8.sym.txt platform version 9 base 8 files java.activation-9.sym.txt:java.base-9.sym.txt:java.compiler-9.sym.txt:java.corba-9.sym.txt:java.datatransfer-9.sym.txt:java.desktop-9.sym.txt:java.instrument-9.sym.txt:java.logging-9.sym.txt:java.management-9.sym.txt:java.management.rmi-9.sym.txt:java.naming-9.sym.txt:java.prefs-9.sym.txt:java.rmi-9.sym.txt:java.scripting-9.sym.txt:java.se-9.sym.txt:java.se.ee-9.sym.txt:java.security.jgss-9.sym.txt:java.security.sasl-9.sym.txt:java.smartcardio-9.sym.txt:java.sql-9.sym.txt:java.sql.rowset-9.sym.txt:java.transaction-9.sym.txt:java.xml-9.sym.txt:java.xml.bind-9.sym.txt:java.xml.crypto-9.sym.txt:java.xml.ws-9.sym.txt:java.xml.ws.annotation-9.sym.txt:jdk.accessibility-9.sym.txt:jdk.attach-9.sym.txt:jdk.charsets-9.sym.txt:jdk.compiler-9.sym.txt:jdk.crypto.cryptoki-9.sym.txt:jdk.crypto.ec-9.sym.txt:jdk.dynalink-9.sym.txt:jdk.editpad-9.sym.txt:jdk.hotspot.agent-9.sym.txt:jdk.httpserver-9.sym.txt:jdk.incubator.httpclient-9.sym.txt:jdk.jartool-9.sym.txt:jdk.javadoc-9.sym.txt:jdk.jcmd-9.sym.txt:jdk.jconsole-9.sym.txt:jdk.jdeps-9.sym.txt:jdk.jdi-9.sym.txt:jdk.jdwp.agent-9.sym.txt:jdk.jlink-9.sym.txt:jdk.jshell-9.sym.txt:jdk.jsobject-9.sym.txt:jdk.jstatd-9.sym.txt:jdk.localedata-9.sym.txt:jdk.management-9.sym.txt:jdk.management.agent-9.sym.txt:jdk.naming.dns-9.sym.txt:jdk.naming.rmi-9.sym.txt:jdk.net-9.sym.txt:jdk.pack-9.sym.txt:jdk.policytool-9.sym.txt:jdk.rmic-9.sym.txt:jdk.scripting.nashorn-9.sym.txt:jdk.sctp-9.sym.txt:jdk.security.auth-9.sym.txt:jdk.security.jgss-9.sym.txt:jdk.unsupported-9.sym.txt:jdk.xml.dom-9.sym.txt:jdk.zipfs-9.sym.txt platform version A base 9 files java.activation-A.sym.txt:java.base-A.sym.txt:java.compiler-A.sym.txt:java.corba-A.sym.txt:java.datatransfer-A.sym.txt:java.desktop-A.sym.txt:java.instrument-A.sym.txt:java.logging-A.sym.txt:java.management-A.sym.txt:java.management.rmi-A.sym.txt:java.naming-A.sym.txt:java.prefs-A.sym.txt:java.rmi-A.sym.txt:java.scripting-A.sym.txt:java.se-A.sym.txt:java.se.ee-A.sym.txt:java.security.jgss-A.sym.txt:java.security.sasl-A.sym.txt:java.smartcardio-A.sym.txt:java.sql-A.sym.txt:java.sql.rowset-A.sym.txt:java.transaction-A.sym.txt:java.xml-A.sym.txt:java.xml.bind-A.sym.txt:java.xml.crypto-A.sym.txt:java.xml.ws-A.sym.txt:java.xml.ws.annotation-A.sym.txt:jdk.accessibility-A.sym.txt:jdk.attach-A.sym.txt:jdk.charsets-A.sym.txt:jdk.compiler-A.sym.txt:jdk.crypto.cryptoki-A.sym.txt:jdk.crypto.ec-A.sym.txt:jdk.dynalink-A.sym.txt:jdk.editpad-A.sym.txt:jdk.hotspot.agent-A.sym.txt:jdk.httpserver-A.sym.txt:jdk.incubator.httpclient-A.sym.txt:jdk.jartool-A.sym.txt:jdk.javadoc-A.sym.txt:jdk.jcmd-A.sym.txt:jdk.jconsole-A.sym.txt:jdk.jdeps-A.sym.txt:jdk.jdi-A.sym.txt:jdk.jdwp.agent-A.sym.txt:jdk.jlink-A.sym.txt:jdk.jshell-A.sym.txt:jdk.jsobject-A.sym.txt:jdk.jstatd-A.sym.txt:jdk.localedata-A.sym.txt:jdk.management-A.sym.txt:jdk.management.agent-A.sym.txt:jdk.naming.dns-A.sym.txt:jdk.naming.rmi-A.sym.txt:jdk.net-A.sym.txt:jdk.pack-A.sym.txt:jdk.policytool-A.sym.txt:jdk.rmic-A.sym.txt:jdk.scripting.nashorn-A.sym.txt:jdk.sctp-A.sym.txt:jdk.security.auth-A.sym.txt:jdk.security.jgss-A.sym.txt:jdk.unsupported-A.sym.txt:jdk.xml.dom-A.sym.txt:jdk.zipfs-A.sym.txt @@ -47,3 +47,4 @@ platform version L base K files java.base-L.sym.txt:java.compiler-L.sym.txt:java platform version M base L files java.base-M.sym.txt:java.compiler-M.sym.txt:java.desktop-M.sym.txt:java.xml-M.sym.txt:java.xml.crypto-M.sym.txt:jdk.compiler-M.sym.txt:jdk.crypto.cryptoki-M.sym.txt:jdk.crypto.ec-M.sym.txt:jdk.incubator.foreign-M.sym.txt:jdk.incubator.vector-M.sym.txt:jdk.jartool-M.sym.txt:jdk.jdeps-M.sym.txt:jdk.jfr-M.sym.txt:jdk.jlink-M.sym.txt:jdk.jpackage-M.sym.txt:jdk.jshell-M.sym.txt:jdk.jstatd-M.sym.txt:jdk.unsupported-M.sym.txt platform version N base M files java.base-N.sym.txt:java.compiler-N.sym.txt:java.desktop-N.sym.txt:java.management-N.sym.txt:java.management.rmi-N.sym.txt:jdk.compiler-N.sym.txt:jdk.httpserver-N.sym.txt:jdk.incubator.foreign-N.sym.txt:jdk.javadoc-N.sym.txt:jdk.jshell-N.sym.txt:jdk.localedata-N.sym.txt:jdk.unsupported-N.sym.txt platform version O base N files java.base-O.sym.txt:java.compiler-O.sym.txt:java.datatransfer-O.sym.txt:java.desktop-O.sym.txt:java.instrument-O.sym.txt:java.logging-O.sym.txt:java.management-O.sym.txt:java.management.rmi-O.sym.txt:java.naming-O.sym.txt:java.net.http-O.sym.txt:java.prefs-O.sym.txt:java.rmi-O.sym.txt:java.scripting-O.sym.txt:java.se-O.sym.txt:java.security.jgss-O.sym.txt:java.security.sasl-O.sym.txt:java.smartcardio-O.sym.txt:java.sql-O.sym.txt:java.sql.rowset-O.sym.txt:java.transaction.xa-O.sym.txt:java.xml-O.sym.txt:java.xml.crypto-O.sym.txt:jdk.accessibility-O.sym.txt:jdk.attach-O.sym.txt:jdk.charsets-O.sym.txt:jdk.compiler-O.sym.txt:jdk.crypto.cryptoki-O.sym.txt:jdk.dynalink-O.sym.txt:jdk.editpad-O.sym.txt:jdk.hotspot.agent-O.sym.txt:jdk.httpserver-O.sym.txt:jdk.incubator.foreign-O.sym.txt:jdk.incubator.vector-O.sym.txt:jdk.jartool-O.sym.txt:jdk.javadoc-O.sym.txt:jdk.jcmd-O.sym.txt:jdk.jconsole-O.sym.txt:jdk.jdeps-O.sym.txt:jdk.jdi-O.sym.txt:jdk.jdwp.agent-O.sym.txt:jdk.jfr-O.sym.txt:jdk.jlink-O.sym.txt:jdk.jpackage-O.sym.txt:jdk.jshell-O.sym.txt:jdk.jsobject-O.sym.txt:jdk.jstatd-O.sym.txt:jdk.localedata-O.sym.txt:jdk.management-O.sym.txt:jdk.management.agent-O.sym.txt:jdk.management.jfr-O.sym.txt:jdk.naming.dns-O.sym.txt:jdk.naming.rmi-O.sym.txt:jdk.net-O.sym.txt:jdk.nio.mapmode-O.sym.txt:jdk.sctp-O.sym.txt:jdk.security.auth-O.sym.txt:jdk.security.jgss-O.sym.txt:jdk.unsupported-O.sym.txt:jdk.xml.dom-O.sym.txt:jdk.zipfs-O.sym.txt +platform version P base O files java.base-P.sym.txt:java.compiler-P.sym.txt:java.desktop-P.sym.txt:java.logging-P.sym.txt:java.management-P.sym.txt:java.net.http-P.sym.txt:java.security.jgss-P.sym.txt:java.xml.crypto-P.sym.txt:jdk.attach-P.sym.txt:jdk.compiler-P.sym.txt:jdk.incubator.foreign-P.sym.txt:jdk.incubator.vector-P.sym.txt:jdk.jdi-P.sym.txt:jdk.jfr-P.sym.txt:jdk.jpackage-P.sym.txt:jdk.jshell-P.sym.txt:jdk.net-P.sym.txt:jdk.security.jgss-P.sym.txt diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 3038daf090d..f0e50e58b2b 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -142,6 +142,11 @@ serviceability/sa/TestJmapCoreMetaspace.java 8318754 macosx-aarch64 serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStressTest.java 8315980 linux-all,windows-x64 +serviceability/sa/JhsdbThreadInfoTest.java 8344261 generic-all +serviceability/sa/TestJhsdbJstackLock.java 8344261 generic-all +serviceability/sa/sadebugd/DebugdConnectTest.java 8344261 generic-all +serviceability/attach/RemovingUnixDomainSocketTest.java 8344261 generic-all + ############################################################################# # :hotspot_misc diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java index 5456f560fa1..99c2d27f8d3 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,26 +58,11 @@ public class VMDeprecatedOptions { // { , } // deprecated non-alias flags: {"AllowRedefinitionToAddDeleteMethods", "true"}, - {"LockingMode", "1"}, // deprecated alias flags (see also aliased_jvm_flags): {"CreateMinidumpOnCrash", "false"} } )); - if (Platform.is64bit()) { - deprecated.addAll( - Arrays.asList(new String[][] { - {"UseCompressedClassPointers", "false"}, - }) - ); - } - if (Platform.isLinux()) { - deprecated.addAll( - Arrays.asList(new String[][] { - {"UseOprofile", "false"} - }) - ); - } if (Platform.isX86() || Platform.isX64()) { deprecated.addAll( Arrays.asList(new String[][] { diff --git a/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/ClassReader.java b/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/ClassReader.java index 7e499412dc2..d84c39112db 100644 --- a/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/ClassReader.java +++ b/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/ClassReader.java @@ -226,7 +226,7 @@ public class ClassReader { this.b = classFileBuffer; // Check the class' major_version. This field is after the magic and minor_version fields, which // use 4 and 2 bytes respectively. - if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V25) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V26) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } diff --git a/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/Opcodes.java b/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/Opcodes.java index d6d8e36fc15..da68deacf90 100644 --- a/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/Opcodes.java +++ b/test/hotspot/jtreg/testlibrary/asm/org/objectweb/asm/Opcodes.java @@ -315,6 +315,7 @@ public interface Opcodes { int V23 = 0 << 16 | 67; int V24 = 0 << 16 | 68; int V25 = 0 << 16 | 69; + int V26 = 0 << 16 | 70; /** * Version flag indicating that the class is using 'preview' features. diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index c1303377ddb..8c0e0bccde0 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -834,3 +834,9 @@ java/awt/Checkbox/CheckboxNullLabelTest.java 8340870 windows-all java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all java/awt/Menu/MenuVisibilityTest.java 8161110 macosx-all java/awt/Modal/NativeDialogToFrontBackTest.java 7188049 windows-all,linux-all + +############################################################################ + +# jdk_since_checks + +tools/sincechecker/modules/java.base/JavaBaseCheckSince.java 8358627 generic-all diff --git a/test/langtools/tools/javac/api/TestGetSourceVersions.java b/test/langtools/tools/javac/api/TestGetSourceVersions.java index 26892eca0a1..4df60355aad 100644 --- a/test/langtools/tools/javac/api/TestGetSourceVersions.java +++ b/test/langtools/tools/javac/api/TestGetSourceVersions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 6395981 6458819 7025784 8028543 8028544 8193291 8193292 8193292 8205393 8245585 8245585 8245585 8286034 - * 8296150 8306585 8319414 8330183 8342982 + * 8296150 8306585 8319414 8330183 8342982 8355748 * @summary JavaCompilerTool and Tool must specify version of JLS and JVMS * @author Peter von der Ahé * @modules java.compiler @@ -37,7 +37,7 @@ * RELEASE_8 RELEASE_9 RELEASE_10 RELEASE_11 RELEASE_12 * RELEASE_13 RELEASE_14 RELEASE_15 RELEASE_16 RELEASE_17 * RELEASE_18 RELEASE_19 RELEASE_20 RELEASE_21 RELEASE_22 - * RELEASE_23 RELEASE_24 RELEASE_25 + * RELEASE_23 RELEASE_24 RELEASE_25 RELEASE_26 */ import java.util.EnumSet; diff --git a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java index c12ff311bdb..6afa7ad9e30 100644 --- a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java +++ b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 7157626 8001112 8188870 8173382 8193290 8205619 8245586 8257453 8306586 8330184 - * 8342983 + * 8342983 8355751 * @summary Test major version for all legal combinations for -source and -target * @author sgoel * @@ -61,6 +61,7 @@ public class ClassVersionChecker { TWENTY_THREE("23", 67), TWENTY_FOUR("24", 68), TWENTY_FIVE("25", 69), + TWENTY_SIX("26", 70), ; // Reduce code churn when appending new constants private Version(String release, int classFileVer) { diff --git a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java index 081a156d6a0..e181ef8bf63 100644 --- a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java +++ b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -113,7 +113,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { * corresponding platform visitor type. */ - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static abstract class AbstractAnnotationValueVisitor extends AbstractAnnotationValueVisitorPreview { @@ -125,7 +125,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static abstract class AbstractElementVisitor extends AbstractElementVisitorPreview { /** @@ -136,7 +136,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static abstract class AbstractTypeVisitor extends AbstractTypeVisitorPreview { /** @@ -147,7 +147,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class ElementKindVisitor extends ElementKindVisitorPreview { /** @@ -169,7 +169,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class ElementScanner extends ElementScannerPreview { /** @@ -189,7 +189,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class SimpleAnnotationValueVisitor extends SimpleAnnotationValueVisitorPreview { /** @@ -211,7 +211,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class SimpleElementVisitor extends SimpleElementVisitorPreview { /** @@ -233,7 +233,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class SimpleTypeVisitor extends SimpleTypeVisitorPreview { /** @@ -255,7 +255,7 @@ public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { } } - @SupportedSourceVersion(RELEASE_25) + @SupportedSourceVersion(RELEASE_26) @SuppressWarnings("preview") public static class TypeKindVisitor extends TypeKindVisitorPreview { /** diff --git a/test/langtools/tools/javac/options/HelpOutputColumnWidthTest.java b/test/langtools/tools/javac/options/HelpOutputColumnWidthTest.java index ecc8218b5f5..4cef7e1916b 100644 --- a/test/langtools/tools/javac/options/HelpOutputColumnWidthTest.java +++ b/test/langtools/tools/javac/options/HelpOutputColumnWidthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -47,7 +47,7 @@ import toolbox.Task; public class HelpOutputColumnWidthTest extends TestRunner { - public static final int MAX_COLUMNS = 80; + public static final int MAX_COLUMNS = 84; protected ToolBox tb; diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out index 46c55fa62f3..8c455009ae5 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out @@ -1,2 +1,2 @@ -- compiler.err.preview.feature.disabled.classfile: Bar.class, 25 +- compiler.err.preview.feature.disabled.classfile: Bar.class, 26 1 error diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out index 539b128efd2..26ff05b085a 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out @@ -1,4 +1,4 @@ -- compiler.warn.preview.feature.use.classfile: Bar.class, 25 +- compiler.warn.preview.feature.use.classfile: Bar.class, 26 - compiler.err.warnings.and.werror 1 error 1 warning diff --git a/test/langtools/tools/javac/versions/Versions.java b/test/langtools/tools/javac/versions/Versions.java index 52b0f0d366d..43fcb0353d0 100644 --- a/test/langtools/tools/javac/versions/Versions.java +++ b/test/langtools/tools/javac/versions/Versions.java @@ -26,7 +26,7 @@ * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 * 8000961 8030610 8028546 8188870 8173382 8173382 8193290 8205619 8028563 * 8245147 8245586 8257453 8286035 8306586 8320806 8306586 8319414 8330183 - * 8342982 8356108 + * 8342982 8355748 8356108 * @summary Check interpretation of -target and -source options * @modules java.compiler * jdk.compiler @@ -73,9 +73,9 @@ public class Versions { public static final Set VALID_SOURCES = Set.of("1.8", "1.9", "1.10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", - "23", "24", "25"); + "23", "24", "25", "26"); - public static final String LATEST_MAJOR_VERSION = "69.0"; + public static final String LATEST_MAJOR_VERSION = "70.0"; static enum SourceTarget { EIGHT(true, "52.0", "8"), @@ -96,6 +96,7 @@ public class Versions { TWENTY_THREE(false,"67.0", "23"), TWENTY_FOUR(false,"68.0", "24"), TWENTY_FIVE(false,"69.0", "25"), + TWENTY_SIX(false, "70.0", "26"), ; // Reduce code churn when appending new constants private final boolean dotOne; @@ -566,4 +567,3 @@ public class Versions { return false; } } - From 62fde687088ce72ef33b94e73babf4bfe1395c17 Mon Sep 17 00:00:00 2001 From: Cesar Soares Lucas Date: Thu, 5 Jun 2025 16:43:29 +0000 Subject: [PATCH 175/216] 8357396: Refactor nmethod::make_not_entrant to use Enum instead of "const char*" Reviewed-by: mhaessig, shade --- src/hotspot/share/c1/c1_Runtime1.cpp | 8 +- src/hotspot/share/ci/ciReplay.cpp | 2 +- src/hotspot/share/code/codeCache.cpp | 2 +- src/hotspot/share/code/nmethod.cpp | 14 ++- src/hotspot/share/code/nmethod.hpp | 85 ++++++++++++++++++- .../share/compiler/compilationPolicy.cpp | 4 +- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 9 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 6 +- src/hotspot/share/jvmci/jvmciEnv.hpp | 2 +- src/hotspot/share/jvmci/jvmciRuntime.cpp | 2 +- src/hotspot/share/oops/instanceKlass.cpp | 2 +- src/hotspot/share/oops/method.cpp | 2 +- src/hotspot/share/prims/whitebox.cpp | 2 +- src/hotspot/share/runtime/deoptimization.cpp | 4 +- src/hotspot/share/runtime/javaThread.cpp | 2 +- 15 files changed, 111 insertions(+), 35 deletions(-) diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 7c41c09d378..e2760689daa 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -818,7 +818,7 @@ JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* current, jint trap_request)) Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request); if (action == Deoptimization::Action_make_not_entrant) { - if (nm->make_not_entrant("C1 deoptimize")) { + if (nm->make_not_entrant(nmethod::ChangeReason::C1_deoptimize)) { if (reason == Deoptimization::Reason_tenured) { MethodData* trap_mdo = Deoptimization::get_method_data(current, method, true /*create_if_missing*/); if (trap_mdo != nullptr) { @@ -1110,7 +1110,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, C1StubId stub_id )) // safepoint, but if it's still alive then make it not_entrant. nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); if (nm != nullptr) { - nm->make_not_entrant("C1 code patch"); + nm->make_not_entrant(nmethod::ChangeReason::C1_codepatch); } Deoptimization::deoptimize_frame(current, caller_frame.id()); @@ -1358,7 +1358,7 @@ void Runtime1::patch_code(JavaThread* current, C1StubId stub_id) { // Make sure the nmethod is invalidated, i.e. made not entrant. nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); if (nm != nullptr) { - nm->make_not_entrant("C1 deoptimize for patching"); + nm->make_not_entrant(nmethod::ChangeReason::C1_deoptimize_for_patching); } } @@ -1486,7 +1486,7 @@ JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* current)) nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); assert (nm != nullptr, "no more nmethod?"); - nm->make_not_entrant("C1 predicate failed trap"); + nm->make_not_entrant(nmethod::ChangeReason::C1_predicate_failed_trap); methodHandle m(current, nm->method()); MethodData* mdo = m->method_data(); diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index 5ea4336f35e..f9829e88c4a 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -802,7 +802,7 @@ class CompileReplay : public StackObj { // Make sure the existence of a prior compile doesn't stop this one nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code(); if (nm != nullptr) { - nm->make_not_entrant("CI replay"); + nm->make_not_entrant(nmethod::ChangeReason::CI_replay); } replay_state = this; CompileBroker::compile_method(methodHandle(THREAD, method), entry_bci, comp_level, diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 902d4345622..3a5da1d7cd2 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1361,7 +1361,7 @@ void CodeCache::make_marked_nmethods_deoptimized() { while(iter.next()) { nmethod* nm = iter.method(); if (nm->is_marked_for_deoptimization() && !nm->has_been_deoptimized() && nm->can_be_deoptimized()) { - nm->make_not_entrant("marked for deoptimization"); + nm->make_not_entrant(nmethod::ChangeReason::marked_for_deoptimization); nm->make_deoptimized(); } } diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 510160a6667..acebaae6ba4 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1975,14 +1975,12 @@ void nmethod::invalidate_osr_method() { } } -void nmethod::log_state_change(const char* reason) const { - assert(reason != nullptr, "Must provide a reason"); - +void nmethod::log_state_change(ChangeReason change_reason) const { if (LogCompilation) { if (xtty != nullptr) { ttyLocker ttyl; // keep the following output all in one block xtty->begin_elem("make_not_entrant thread='%zu' reason='%s'", - os::current_thread_id(), reason); + os::current_thread_id(), change_reason_to_string(change_reason)); log_identity(xtty); xtty->stamp(); xtty->end_elem(); @@ -1991,7 +1989,7 @@ void nmethod::log_state_change(const char* reason) const { ResourceMark rm; stringStream ss(NEW_RESOURCE_ARRAY(char, 256), 256); - ss.print("made not entrant: %s", reason); + ss.print("made not entrant: %s", change_reason_to_string(change_reason)); CompileTask::print_ul(this, ss.freeze()); if (PrintCompilation) { @@ -2006,9 +2004,7 @@ void nmethod::unlink_from_method() { } // Invalidate code -bool nmethod::make_not_entrant(const char* reason) { - assert(reason != nullptr, "Must provide a reason"); - +bool nmethod::make_not_entrant(ChangeReason change_reason) { // This can be called while the system is already at a safepoint which is ok NoSafepointVerifier nsv; @@ -2077,7 +2073,7 @@ bool nmethod::make_not_entrant(const char* reason) { assert(success, "Transition can't fail"); // Log the transition once - log_state_change(reason); + log_state_change(change_reason); // Remove nmethod from method. unlink_from_method(); diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 2ce6e5cd361..7453bdfa0ef 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -471,6 +471,85 @@ class nmethod : public CodeBlob { void oops_do_set_strong_done(nmethod* old_head); public: + enum class ChangeReason : u1 { + C1_codepatch, + C1_deoptimize, + C1_deoptimize_for_patching, + C1_predicate_failed_trap, + CI_replay, + JVMCI_invalidate_nmethod, + JVMCI_invalidate_nmethod_mirror, + JVMCI_materialize_virtual_object, + JVMCI_new_installation, + JVMCI_register_method, + JVMCI_replacing_with_new_code, + JVMCI_reprofile, + marked_for_deoptimization, + missing_exception_handler, + not_used, + OSR_invalidation_back_branch, + OSR_invalidation_for_compiling_with_C1, + OSR_invalidation_of_lower_level, + set_native_function, + uncommon_trap, + whitebox_deoptimization, + zombie, + }; + + + static const char* change_reason_to_string(ChangeReason change_reason) { + switch (change_reason) { + case ChangeReason::C1_codepatch: + return "C1 code patch"; + case ChangeReason::C1_deoptimize: + return "C1 deoptimized"; + case ChangeReason::C1_deoptimize_for_patching: + return "C1 deoptimize for patching"; + case ChangeReason::C1_predicate_failed_trap: + return "C1 predicate failed trap"; + case ChangeReason::CI_replay: + return "CI replay"; + case ChangeReason::JVMCI_invalidate_nmethod: + return "JVMCI invalidate nmethod"; + case ChangeReason::JVMCI_invalidate_nmethod_mirror: + return "JVMCI invalidate nmethod mirror"; + case ChangeReason::JVMCI_materialize_virtual_object: + return "JVMCI materialize virtual object"; + case ChangeReason::JVMCI_new_installation: + return "JVMCI new installation"; + case ChangeReason::JVMCI_register_method: + return "JVMCI register method"; + case ChangeReason::JVMCI_replacing_with_new_code: + return "JVMCI replacing with new code"; + case ChangeReason::JVMCI_reprofile: + return "JVMCI reprofile"; + case ChangeReason::marked_for_deoptimization: + return "marked for deoptimization"; + case ChangeReason::missing_exception_handler: + return "missing exception handler"; + case ChangeReason::not_used: + return "not used"; + case ChangeReason::OSR_invalidation_back_branch: + return "OSR invalidation back branch"; + case ChangeReason::OSR_invalidation_for_compiling_with_C1: + return "OSR invalidation for compiling with C1"; + case ChangeReason::OSR_invalidation_of_lower_level: + return "OSR invalidation of lower level"; + case ChangeReason::set_native_function: + return "set native function"; + case ChangeReason::uncommon_trap: + return "uncommon trap"; + case ChangeReason::whitebox_deoptimization: + return "whitebox deoptimization"; + case ChangeReason::zombie: + return "zombie"; + default: { + assert(false, "Unhandled reason"); + return "Unknown"; + } + } + } + // create nmethod with entry_bci static nmethod* new_nmethod(const methodHandle& method, int compile_id, @@ -633,8 +712,8 @@ public: // alive. It is used when an uncommon trap happens. Returns true // if this thread changed the state of the nmethod or false if // another thread performed the transition. - bool make_not_entrant(const char* reason); - bool make_not_used() { return make_not_entrant("not used"); } + bool make_not_entrant(ChangeReason change_reason); + bool make_not_used() { return make_not_entrant(ChangeReason::not_used); } bool is_marked_for_deoptimization() const { return deoptimization_status() != not_marked; } bool has_been_deoptimized() const { return deoptimization_status() == deoptimize_done; } @@ -947,7 +1026,7 @@ public: // Logging void log_identity(xmlStream* log) const; void log_new_nmethod() const; - void log_state_change(const char* reason) const; + void log_state_change(ChangeReason change_reason) const; // Prints block-level comments, including nmethod specific block labels: void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const; diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index 39c90281c79..bab437eaade 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -924,7 +924,7 @@ void CompilationPolicy::compile(const methodHandle& mh, int bci, CompLevel level nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false); if (osr_nm != nullptr && osr_nm->comp_level() > CompLevel_simple) { // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted. - osr_nm->make_not_entrant("OSR invalidation for compiling with C1"); + osr_nm->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_for_compiling_with_C1); } compile(mh, bci, CompLevel_simple, THREAD); } @@ -1516,7 +1516,7 @@ void CompilationPolicy::method_back_branch_event(const methodHandle& mh, const m int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci; print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level); } - nm->make_not_entrant("OSR invalidation, back branch"); + nm->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_back_branch); } } // Fix up next_level if necessary to avoid deopts diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index d45036ced94..001a40f74bc 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -27,6 +27,7 @@ #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmClasses.hpp" +#include "code/nmethod.hpp" #include "code/scopeDesc.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compilerEvent.hpp" @@ -1206,7 +1207,7 @@ C2V_VMENTRY_0(jint, installCode0, (JNIEnv *env, jobject, assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type"); // Clear the link to an old nmethod first JVMCIObject nmethod_mirror = installed_code_handle; - JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, true, JVMCI_CHECK_0); + JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, true, nmethod::ChangeReason::JVMCI_replacing_with_new_code, JVMCI_CHECK_0); } else { assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type"); } @@ -1382,7 +1383,7 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method))) nmethod* code = method->code(); if (code != nullptr) { - code->make_not_entrant("JVMCI reprofile"); + code->make_not_entrant(nmethod::ChangeReason::JVMCI_reprofile); } MethodData* method_data = method->method_data(); @@ -1397,7 +1398,7 @@ C2V_END C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod, jboolean deoptimize)) JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod); - JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, deoptimize, JVMCI_CHECK); + JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, deoptimize, nmethod::ChangeReason::JVMCI_invalidate_nmethod, JVMCI_CHECK); C2V_END C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject)) @@ -1822,7 +1823,7 @@ C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_ if (!fst.current()->is_compiled_frame()) { JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected"); } - fst.current()->cb()->as_nmethod()->make_not_entrant("JVMCI materialize virtual objects"); + fst.current()->cb()->as_nmethod()->make_not_entrant(nmethod::ChangeReason::JVMCI_materialize_virtual_object); } Deoptimization::deoptimize(thread, *fst.current(), Deoptimization::Reason_none); // look for the frame again as it has been updated by deopt (pc, deopt state...) diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index b8474552256..8c9facf8489 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1750,7 +1750,7 @@ void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* c } -void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JVMCI_TRAPS) { +void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nmethod::ChangeReason change_reason, JVMCI_TRAPS) { if (mirror.is_null()) { JVMCI_THROW(NullPointerException); } @@ -1773,7 +1773,7 @@ void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JV if (!deoptimize) { // Prevent future executions of the nmethod but let current executions complete. - nm->make_not_entrant("JVMCI invalidate nmethod mirror"); + nm->make_not_entrant(change_reason); // Do not clear the address field here as the Java code may still // want to later call this method with deoptimize == true. That requires @@ -1782,7 +1782,7 @@ void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JV // Deoptimize the nmethod immediately. DeoptimizationScope deopt_scope; deopt_scope.mark(nm); - nm->make_not_entrant("JVMCI invalidate nmethod mirror"); + nm->make_not_entrant(change_reason); nm->make_deoptimized(); deopt_scope.deoptimize_marked(); diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index 69f6647b0d6..b7b7c8f6771 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -462,7 +462,7 @@ public: // field of `mirror` to prevent it from being called. // If `deoptimize` is true, the nmethod is immediately deoptimized. // The HotSpotNmethod.address field is zero upon returning. - void invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimze, JVMCI_TRAPS); + void invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimze, nmethod::ChangeReason change_reason, JVMCI_TRAPS); void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index bee5f4ea445..1f10e132eff 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -2184,7 +2184,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, tty->print_cr("Replacing method %s", method_name); } if (old != nullptr) { - old->make_not_entrant("JVMCI register method"); + old->make_not_entrant(nmethod::ChangeReason::JVMCI_register_method); } LogTarget(Info, nmethod, install) lt; diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index b3d896b6863..32d7943e1e8 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -3492,7 +3492,7 @@ void InstanceKlass::add_osr_nmethod(nmethod* n) { for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) { nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true); if (inv != nullptr && inv->is_in_use()) { - inv->make_not_entrant("OSR invalidation of lower levels"); + inv->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_of_lower_level); } } } diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index d13458dfa93..1a36fce23aa 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1028,7 +1028,7 @@ void Method::set_native_function(address function, bool post_event_flag) { // If so, we have to make it not_entrant. nmethod* nm = code(); // Put it into local variable to guard against concurrent updates if (nm != nullptr) { - nm->make_not_entrant("set native function"); + nm->make_not_entrant(nmethod::ChangeReason::set_native_function); } } diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index f14c5efc65d..cf3b48c11b5 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -794,7 +794,7 @@ class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation { if (_make_not_entrant) { nmethod* nm = CodeCache::find_nmethod(f->pc()); assert(nm != nullptr, "did not find nmethod"); - nm->make_not_entrant("Whitebox deoptimization"); + nm->make_not_entrant(nmethod::ChangeReason::whitebox_deoptimization); } ++_result; } diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 4042bb01c58..a0d9dd00339 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1826,7 +1826,7 @@ void Deoptimization::deoptimize(JavaThread* thread, frame fr, DeoptReason reason #if INCLUDE_JVMCI address Deoptimization::deoptimize_for_missing_exception_handler(nmethod* nm) { // there is no exception handler for this pc => deoptimize - nm->make_not_entrant("missing exception handler"); + nm->make_not_entrant(nmethod::ChangeReason::missing_exception_handler); // Use Deoptimization::deoptimize for all of its side-effects: // gathering traps statistics, logging... @@ -2455,7 +2455,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr // Recompile if (make_not_entrant) { - if (!nm->make_not_entrant("uncommon trap")) { + if (!nm->make_not_entrant(nmethod::ChangeReason::uncommon_trap)) { return; // the call did not change nmethod's state } diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index 57f93f87d47..f3ad0e0a325 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1337,7 +1337,7 @@ void JavaThread::make_zombies() { // it is a Java nmethod nmethod* nm = CodeCache::find_nmethod(fst.current()->pc()); assert(nm != nullptr, "did not find nmethod"); - nm->make_not_entrant("zombie"); + nm->make_not_entrant(nmethod::ChangeReason::zombie); } } } From fe3be498b83e70a9f4739ddad6642c3aa04a97d3 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Thu, 5 Jun 2025 17:30:01 +0000 Subject: [PATCH 176/216] 8357141: Update to use jtreg 7.5.2 Reviewed-by: erikj, ihse, iris --- make/autoconf/lib-tests.m4 | 2 +- make/conf/github-actions.conf | 2 +- make/conf/jib-profiles.js | 4 ++-- test/docs/TEST.ROOT | 2 +- test/hotspot/jtreg/TEST.ROOT | 2 +- test/jaxp/TEST.ROOT | 2 +- test/jdk/TEST.ROOT | 2 +- test/langtools/TEST.ROOT | 2 +- test/lib-test/TEST.ROOT | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4 index d2a4fcbb191..9eb5ee5a046 100644 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -28,7 +28,7 @@ ################################################################################ # Minimum supported versions -JTREG_MINIMUM_VERSION=7.5.1 +JTREG_MINIMUM_VERSION=7.5.2 GTEST_MINIMUM_VERSION=1.14.0 ################################################################################ diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 27845ffbd7a..d2b6cd23128 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -26,7 +26,7 @@ # Versions and download locations for dependencies used by GitHub Actions (GHA) GTEST_VERSION=1.14.0 -JTREG_VERSION=7.5.1+1 +JTREG_VERSION=7.5.2+1 LINUX_X64_BOOT_JDK_EXT=tar.gz LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-x64_bin.tar.gz diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 9bedc77cc28..91876878046 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1174,9 +1174,9 @@ var getJibProfilesDependencies = function (input, common) { jtreg: { server: "jpg", product: "jtreg", - version: "7.5.1", + version: "7.5.2", build_number: "1", - file: "bundles/jtreg-7.5.1+1.zip", + file: "bundles/jtreg-7.5.2+1.zip", environment_name: "JT_HOME", environment_path: input.get("jtreg", "home_path") + "/bin", configure_args: "--with-jtreg=" + input.get("jtreg", "home_path"), diff --git a/test/docs/TEST.ROOT b/test/docs/TEST.ROOT index 9be915dd4ff..5ca9b1f144f 100644 --- a/test/docs/TEST.ROOT +++ b/test/docs/TEST.ROOT @@ -38,7 +38,7 @@ groups=TEST.groups # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Use new module options useNewOptions=true diff --git a/test/hotspot/jtreg/TEST.ROOT b/test/hotspot/jtreg/TEST.ROOT index 59dd48e5af7..8f4ef153907 100644 --- a/test/hotspot/jtreg/TEST.ROOT +++ b/test/hotspot/jtreg/TEST.ROOT @@ -100,7 +100,7 @@ requires.properties= \ jdk.static # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../../ notation to reach them diff --git a/test/jaxp/TEST.ROOT b/test/jaxp/TEST.ROOT index 7a457d87b69..6398c399f0a 100644 --- a/test/jaxp/TEST.ROOT +++ b/test/jaxp/TEST.ROOT @@ -23,7 +23,7 @@ modules=java.xml groups=TEST.groups # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff --git a/test/jdk/TEST.ROOT b/test/jdk/TEST.ROOT index 30e2f7cab41..97efc340019 100644 --- a/test/jdk/TEST.ROOT +++ b/test/jdk/TEST.ROOT @@ -119,7 +119,7 @@ requires.properties= \ jdk.static # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff --git a/test/langtools/TEST.ROOT b/test/langtools/TEST.ROOT index 9b1c5368e66..e3bd3b74bcf 100644 --- a/test/langtools/TEST.ROOT +++ b/test/langtools/TEST.ROOT @@ -15,7 +15,7 @@ keys=intermittent randomness needs-src needs-src-jdk_javadoc groups=TEST.groups # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Use new module options useNewOptions=true diff --git a/test/lib-test/TEST.ROOT b/test/lib-test/TEST.ROOT index 21b6fba41f2..162e6e15ec2 100644 --- a/test/lib-test/TEST.ROOT +++ b/test/lib-test/TEST.ROOT @@ -29,7 +29,7 @@ keys=randomness # Minimum jtreg version -requiredVersion=7.5.1+1 +requiredVersion=7.5.2+1 # Allow querying of various System properties in @requires clauses requires.extraPropDefns = ../jtreg-ext/requires/VMProps.java From 15178aa298e43be3e27121343432f25884db4e5d Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Thu, 5 Jun 2025 20:19:53 +0000 Subject: [PATCH 177/216] 8357688: Remove unnecessary List.get before remove in PopupFactory Reviewed-by: azvegint, kizune, serb --- .../classes/javax/swing/PopupFactory.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/PopupFactory.java b/src/java.desktop/share/classes/javax/swing/PopupFactory.java index 9789e95e7ff..682cdbd005b 100644 --- a/src/java.desktop/share/classes/javax/swing/PopupFactory.java +++ b/src/java.desktop/share/classes/javax/swing/PopupFactory.java @@ -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 @@ -433,10 +433,8 @@ public class PopupFactory { } else { return null; } - if (cache.size() > 0) { - HeavyWeightPopup r = cache.get(0); - cache.remove(0); - return r; + if (!cache.isEmpty()) { + return cache.removeFirst(); } return null; } @@ -776,10 +774,8 @@ public class PopupFactory { private static LightWeightPopup getRecycledLightWeightPopup() { synchronized (LightWeightPopup.class) { List lightPopupCache = getLightWeightPopupCache(); - if (lightPopupCache.size() > 0) { - LightWeightPopup r = lightPopupCache.get(0); - lightPopupCache.remove(0); - return r; + if (!lightPopupCache.isEmpty()) { + return lightPopupCache.removeFirst(); } return null; } @@ -934,10 +930,8 @@ public class PopupFactory { private static MediumWeightPopup getRecycledMediumWeightPopup() { synchronized (MediumWeightPopup.class) { List mediumPopupCache = getMediumWeightPopupCache(); - if (mediumPopupCache.size() > 0) { - MediumWeightPopup r = mediumPopupCache.get(0); - mediumPopupCache.remove(0); - return r; + if (!mediumPopupCache.isEmpty()) { + return mediumPopupCache.removeFirst(); } return null; } From c793de989facdb532021e1d5ddd01eb0e089b8e6 Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Thu, 5 Jun 2025 21:57:33 +0000 Subject: [PATCH 178/216] 8350212: Track source end positions of declarations that support @SuppressWarnings Co-authored-by: Jan Lahoda Reviewed-by: mcimadamore --- .../com/sun/tools/javac/comp/Lower.java | 4 +- .../classes/com/sun/tools/javac/jvm/Gen.java | 8 +- .../sun/tools/javac/parser/JavacParser.java | 196 +++++++----------- .../com/sun/tools/javac/tree/EndPosTable.java | 31 ++- .../com/sun/tools/javac/tree/JCTree.java | 8 +- .../com/sun/tools/javac/tree/TreeInfo.java | 27 +-- .../share/classes/jdk/jshell/ReplParser.java | 3 +- .../MissingLNTEntryForFinalizerTest.java | 4 +- .../javac/parser/DeclarationEndPositions.java | 119 +++++++++++ .../tools/javac/parser/JavacParserTest.java | 9 +- .../javac/parser/extend/TrialParser.java | 3 +- 11 files changed, 252 insertions(+), 160 deletions(-) create mode 100644 test/langtools/tools/javac/parser/DeclarationEndPositions.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index a544b3948e5..54226155cf8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -3697,7 +3697,7 @@ public class Lower extends TreeTranslator { vardefinit).setType(tree.var.type); indexDef.sym = tree.var.sym; JCBlock body = make.Block(0, List.of(indexDef, tree.body)); - body.endpos = TreeInfo.endPos(tree.body); + body.bracePos = TreeInfo.endPos(tree.body); result = translate(make. ForLoop(List.of(init), cond, @@ -4158,7 +4158,7 @@ public class Lower extends TreeTranslator { stmtList.append(switch2); JCBlock res = make.Block(0L, stmtList.toList()); - res.endpos = TreeInfo.endPos(tree); + res.bracePos = TreeInfo.endPos(tree); return res; } else { JCSwitchExpression switch2 = make.SwitchExpression(make.Ident(dollar_tmp), lb.toList()); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java index 725c7f8063b..14c5420c7c0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -500,7 +500,7 @@ public class Gen extends JCTree.Visitor { c.members().enter(clinit); List clinitStats = clinitCode.toList(); JCBlock block = make.at(clinitStats.head.pos()).Block(0, clinitStats); - block.endpos = TreeInfo.endPos(clinitStats.last()); + block.bracePos = TreeInfo.endPos(clinitStats.last()); methodDefs.append(make.MethodDef(clinit, block)); if (!clinitTAs.isEmpty()) @@ -553,8 +553,8 @@ public class Gen extends JCTree.Visitor { // Find the super() invocation and append the given initializer code. TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.prepend(supercall))); - if (md.body.endpos == Position.NOPOS) - md.body.endpos = TreeInfo.endPos(md.body.stats.last()); + if (md.body.bracePos == Position.NOPOS) + md.body.bracePos = TreeInfo.endPos(md.body.stats.last()); md.sym.appendUniqueTypeAttributes(initTAs); } @@ -1121,7 +1121,7 @@ public class Gen extends JCTree.Visitor { genStats(tree.stats, localEnv); // End the scope of all block-local variables in variable info. if (!env.tree.hasTag(METHODDEF)) { - code.statBegin(tree.endpos); + code.statBegin(tree.bracePos); code.endScopes(limit); code.pendingStatPos = Position.NOPOS; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 1383baa57b8..7ebcd0c844b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -231,8 +231,8 @@ public class JavacParser implements Parser { protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { return keepEndPositions - ? new SimpleEndPosTable(this) - : new EmptyEndPosTable(this); + ? new SimpleEndPosTable() + : new MinimalEndPosTable(); } protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) { @@ -633,12 +633,14 @@ public class JavacParser implements Parser { * * @param tree The tree to be used as index in the hashtable * @param dc The doc comment to associate with the tree, or null. + * @return {@code tree} */ - protected void attach(JCTree tree, Comment dc) { + protected T attach(T tree, Comment dc) { if (keepDocComments && dc != null) { docComments.putComment(tree, dc); } reportDanglingComments(tree, dc); + return tree; } /** Reports all dangling comments associated with the @@ -702,16 +704,35 @@ public class JavacParser implements Parser { endPosTable.setErrorEndPos(errPos); } - protected void storeEnd(JCTree tree, int endpos) { - endPosTable.storeEnd(tree, endpos); + /** + * Store ending position for a tree, the value of which is the greater of + * last error position in {@link #endPosTable} and the given ending position. + * @param tree tree node + * @param endpos the ending position to associate with {@code tree} + * @return {@code tree} + */ + protected T storeEnd(T tree, int endpos) { + return endPosTable.storeEnd(tree, endpos); } - protected T to(T t) { - return endPosTable.to(t); + /** + * Store current token's ending position for a tree, the value of which + * will be the greater of last error position in {@link #endPosTable} + * and the ending position of the current token. + * @param tree tree node + */ + protected T to(T tree) { + return storeEnd(tree, token.endPos); } - protected T toP(T t) { - return endPosTable.toP(t); + /** + * Store current token's ending position for a tree, the value of which + * will be the greater of last error position in {@link #endPosTable} + * and the ending position of the previous token. + * @param tree tree node + */ + protected T toP(T tree) { + return storeEnd(tree, S.prevToken().endPos); } /** Get the start position for a tree node. The start position is @@ -1741,7 +1762,7 @@ public class JavacParser implements Parser { case RBRACE: case EOF: JCSwitchExpression e = to(F.at(switchPos).SwitchExpression(selector, cases.toList())); - e.endpos = token.pos; + e.bracePos = token.pos; accept(RBRACE); return e; default: @@ -2819,9 +2840,9 @@ public class JavacParser implements Parser { syntaxError(token.pos, Errors.Orphaned(token.kind)); switchBlockStatementGroups(); } - // the Block node has a field "endpos" for first char of last token, which is + // the Block node has a field "bracePos" for first char of last token, which is // usually but not necessarily the last char of the last token. - t.endpos = token.pos; + t.bracePos = token.pos; accept(RBRACE); return toP(t); } @@ -3142,7 +3163,7 @@ public class JavacParser implements Parser { accept(LBRACE); List cases = switchBlockStatementGroups(); JCSwitch t = to(F.at(pos).Switch(selector, cases)); - t.endpos = token.endPos; + t.bracePos = token.endPos; accept(RBRACE); return t; } @@ -3658,9 +3679,7 @@ public class JavacParser implements Parser { } else { throw new AssertionError("Unhandled annotation kind: " + kind); } - - storeEnd(ann, S.prevToken().endPos); - return ann; + return toP(ann); } List annotationFieldValuesOpt() { @@ -3835,9 +3854,8 @@ public class JavacParser implements Parser { } } JCVariableDecl result = toP(F.at(pos).VarDef(mods, name, type, init, declaredUsingVar)); - attach(result, dc); result.startPos = startPos; - return result; + return attach(result, dc); } Name restrictedTypeName(JCExpression e, boolean shouldWarn) { @@ -4131,7 +4149,7 @@ public class JavacParser implements Parser { firstTypeDecl = false; } } - List topLevelDefs = isImplicitClass ? constructImplicitClass(defs.toList()) : defs.toList(); + List topLevelDefs = isImplicitClass ? constructImplicitClass(defs.toList(), S.prevToken().endPos) : defs.toList(); JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(topLevelDefs); if (!consumedToplevelDoc) attach(toplevel, firstToken.docComment()); @@ -4141,13 +4159,12 @@ public class JavacParser implements Parser { toplevel.docComments = docComments; if (keepLineMap) toplevel.lineMap = S.getLineMap(); - this.endPosTable.setParser(null); // remove reference to parser toplevel.endPositions = this.endPosTable; return toplevel; } // Restructure top level to be an implicitly declared class. - private List constructImplicitClass(List origDefs) { + private List constructImplicitClass(List origDefs, int endPos) { ListBuffer topDefs = new ListBuffer<>(); ListBuffer defs = new ListBuffer<>(); @@ -4177,6 +4194,7 @@ public class JavacParser implements Parser { JCClassDecl implicit = F.at(primaryPos).ClassDef( implicitMods, name, List.nil(), null, List.nil(), List.nil(), defs.toList()); + storeEnd(implicit, endPos); topDefs.append(implicit); return topDefs.toList(); } @@ -4192,11 +4210,12 @@ public class JavacParser implements Parser { accept(LBRACE); directives = moduleDirectiveList(); accept(RBRACE); + int endPos = S.prevToken().endPos; accept(EOF); - JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives)); - attach(result, dc); - return result; + JCModuleDecl result = F.at(pos).ModuleDef(mods, kind, name, directives); + storeEnd(result, endPos); + return attach(result, dc); } List moduleDirectiveList() { @@ -4386,8 +4405,7 @@ public class JavacParser implements Parser { List defs = classInterfaceOrRecordBody(name, false, false); JCClassDecl result = toP(F.at(pos).ClassDef( mods, name, typarams, extending, implementing, permitting, defs)); - attach(result, dc); - return result; + return attach(result, dc); } protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) { @@ -4434,8 +4452,7 @@ public class JavacParser implements Parser { defs = defs.prepend(field); } JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs)); - attach(result, dc); - return result; + return attach(result, dc); } Name typeName() { @@ -4474,8 +4491,7 @@ public class JavacParser implements Parser { defs = classInterfaceOrRecordBody(name, true, false); JCClassDecl result = toP(F.at(pos).ClassDef( mods, name, typarams, null, extending, permitting, defs)); - attach(result, dc); - return result; + return attach(result, dc); } List permitsClause(JCModifiers mods, String classOrInterface) { @@ -4522,8 +4538,7 @@ public class JavacParser implements Parser { JCClassDecl result = toP(F.at(pos). ClassDef(mods, name, List.nil(), null, implementing, defs)); - attach(result, dc); - return result; + return attach(result, dc); } /** EnumBody = "{" { EnumeratorDeclarationList } [","] @@ -4664,8 +4679,7 @@ public class JavacParser implements Parser { storeEnd(create, S.prevToken().endPos); ident = F.at(identPos).Ident(enumName); JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); - attach(result, dc); - return result; + return attach(result, dc); } /** TypeList = Type {"," Type} @@ -5097,8 +5111,7 @@ public class JavacParser implements Parser { toP(F.at(pos).MethodDef(mods, name, type, typarams, receiverParam, params, thrown, body, defaultValue)); - attach(result, dc); - return result; + return attach(result, dc); } finally { this.receiverParam = prevReceiverParam; } @@ -5395,8 +5408,7 @@ public class JavacParser implements Parser { return mostInnerTypeToReturn; } else { mostInnerArrayType.elemtype = mostInnerTypeToReturn; - storeEnd(type, origEndPos); - return type; + return storeEnd(type, origEndPos); } } @@ -5622,121 +5634,69 @@ public class JavacParser implements Parser { } } - /* - * a functional source tree and end position mappings + /** + * A straightforward {@link EndPosTable} implementation. */ protected static class SimpleEndPosTable extends AbstractEndPosTable { - private final IntHashTable endPosMap; + private final IntHashTable endPosMap = new IntHashTable(); - SimpleEndPosTable(JavacParser parser) { - super(parser); - endPosMap = new IntHashTable(); - } - - public void storeEnd(JCTree tree, int endpos) { - endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos); - } - - protected T to(T t) { - storeEnd(t, parser.token.endPos); - return t; - } - - protected T toP(T t) { - storeEnd(t, parser.S.prevToken().endPos); - return t; + @Override + public T storeEnd(T tree, int endpos) { + endPosMap.put(tree, Math.max(endpos, errorEndPos)); + return tree; } + @Override public int getEndPos(JCTree tree) { int value = endPosMap.get(tree); // As long as Position.NOPOS==-1, this just returns value. return (value == -1) ? Position.NOPOS : value; } + @Override public int replaceTree(JCTree oldTree, JCTree newTree) { int pos = endPosMap.remove(oldTree); - if (pos != -1) { + if (pos != -1 && newTree != null) { storeEnd(newTree, pos); - return pos; } - return Position.NOPOS; + return pos; } } - /* - * a default skeletal implementation without any mapping overhead. + /** + * A minimal implementation that only stores what's required. */ - protected static class EmptyEndPosTable extends AbstractEndPosTable { + protected static class MinimalEndPosTable extends SimpleEndPosTable { - EmptyEndPosTable(JavacParser parser) { - super(parser); + @Override + public T storeEnd(T tree, int endpos) { + switch (tree.getTag()) { + case MODULEDEF: + case PACKAGEDEF: + case CLASSDEF: + case METHODDEF: + case VARDEF: + break; + default: + return tree; + } + return super.storeEnd(tree, endpos); } - - public void storeEnd(JCTree tree, int endpos) { /* empty */ } - - protected T to(T t) { - return t; - } - - protected T toP(T t) { - return t; - } - - public int getEndPos(JCTree tree) { - return Position.NOPOS; - } - - public int replaceTree(JCTree oldTree, JCTree newTree) { - return Position.NOPOS; - } - } protected abstract static class AbstractEndPosTable implements EndPosTable { - /** - * The current parser. - */ - protected JavacParser parser; /** * Store the last error position. */ public int errorEndPos = Position.NOPOS; - public AbstractEndPosTable(JavacParser parser) { - this.parser = parser; - } - - /** - * Store current token's ending position for a tree, the value of which - * will be the greater of last error position and the ending position of - * the current token. - * @param t The tree. - */ - protected abstract T to(T t); - - /** - * Store current token's ending position for a tree, the value of which - * will be the greater of last error position and the ending position of - * the previous token. - * @param t The tree. - */ - protected abstract T toP(T t); - - /** - * Set the error position during the parsing phases, the value of which - * will be set only if it is greater than the last stored error position. - * @param errPos The error position - */ + @Override public void setErrorEndPos(int errPos) { if (errPos > errorEndPos) { errorEndPos = errPos; } } - - public void setParser(JavacParser parser) { - this.parser = parser; - } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java index d68ba838ba1..83fe402c0a7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/EndPosTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, 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 @@ -25,8 +25,21 @@ package com.sun.tools.javac.tree; +import com.sun.tools.javac.util.Position; + /** * Specifies the methods to access a mappings of syntax trees to end positions. + * + *

        + * Implementations must store end positions for at least these node types: + *

          + *
        • {@link JCTree.JCModuleDecl} + *
        • {@link JCTree.JCPackageDecl} + *
        • {@link JCTree.JCClassDecl} + *
        • {@link JCTree.JCMethodDecl} + *
        • {@link JCTree.JCVariableDecl} + *
        + * *

        This is NOT part of any supported API. * If you write code that depends on this, you do so at your own * risk. This code and its internal interfaces are subject to change @@ -40,23 +53,31 @@ public interface EndPosTable { * @param tree JCTree * @return position of the source tree or Positions.NOPOS for non-existent mapping */ - public int getEndPos(JCTree tree); + int getEndPos(JCTree tree); /** * Store ending position for a tree, the value of which is the greater of * last error position and the given ending position. * @param tree The tree. * @param endpos The ending position to associate with the tree. + * @return the {@code tree} */ - public abstract void storeEnd(JCTree tree, int endpos); + T storeEnd(T tree, int endpos); + + /** + * Set the error position during the parsing phases, the value of which + * will be set only if it is greater than the last stored error position. + * @param errPos The error position + */ + void setErrorEndPos(int errPos); /** * Give an old tree and a new tree, the old tree will be replaced with * the new tree, the position of the new tree will be that of the old * tree. * @param oldtree a JCTree to be replaced - * @param newtree a JCTree to be replaced with + * @param newtree a JCTree to be replaced with, or null to just remove {@code oldtree} * @return position of the old tree or Positions.NOPOS for non-existent mapping */ - public int replaceTree(JCTree oldtree, JCTree newtree); + int replaceTree(JCTree oldtree, JCTree newtree); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index de86b7e2c57..debc10c9ff8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1121,7 +1121,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** statements */ public List stats; /** Position of closing brace, optional. */ - public int endpos = Position.NOPOS; + public int bracePos = Position.NOPOS; /** If this block contains record pattern, it is necessary to catch * exceptions from the deconstructors and wrap them. * The {@code patternMatchingCatch} keeps the list of the deconstructor @@ -1330,7 +1330,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public JCExpression selector; public List cases; /** Position of closing brace, optional. */ - public int endpos = Position.NOPOS; + public int bracePos = Position.NOPOS; public boolean hasUnconditionalPattern; public boolean isExhaustive; public boolean patternSwitch; @@ -1430,7 +1430,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public JCExpression selector; public List cases; /** Position of closing brace, optional. */ - public int endpos = Position.NOPOS; + public int bracePos = Position.NOPOS; public boolean hasUnconditionalPattern; public boolean isExhaustive; public boolean patternSwitch; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 5e3b043fb11..ae946c5b6d6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -500,12 +500,12 @@ public class TreeInfo { return tree.pos; } - /** The end position of given tree, if it is a block with - * defined endpos. + /** The closing brace position of given tree, if it is a block with + * defined bracePos. */ public static int endPos(JCTree tree) { - if (tree.hasTag(BLOCK) && ((JCBlock) tree).endpos != Position.NOPOS) - return ((JCBlock) tree).endpos; + if (tree.hasTag(BLOCK) && ((JCBlock) tree).bracePos != Position.NOPOS) + return ((JCBlock) tree).bracePos; else if (tree.hasTag(SYNCHRONIZED)) return endPos(((JCSynchronized) tree).body); else if (tree.hasTag(TRY)) { @@ -513,11 +513,11 @@ public class TreeInfo { return endPos((t.finalizer != null) ? t.finalizer : (t.catchers.nonEmpty() ? t.catchers.last().body : t.body)); } else if (tree.hasTag(SWITCH) && - ((JCSwitch) tree).endpos != Position.NOPOS) { - return ((JCSwitch) tree).endpos; + ((JCSwitch) tree).bracePos != Position.NOPOS) { + return ((JCSwitch) tree).bracePos; } else if (tree.hasTag(SWITCH_EXPRESSION) && - ((JCSwitchExpression) tree).endpos != Position.NOPOS) { - return ((JCSwitchExpression) tree).endpos; + ((JCSwitchExpression) tree).bracePos != Position.NOPOS) { + return ((JCSwitchExpression) tree).bracePos; } else return tree.pos; } @@ -646,11 +646,6 @@ public class TreeInfo { if (tree == null) return Position.NOPOS; - if (endPosTable == null) { - // fall back on limited info in the tree - return endPos(tree); - } - int mapPos = endPosTable.getEndPos(tree); if (mapPos != Position.NOPOS) return mapPos; @@ -731,8 +726,8 @@ public class TreeInfo { /** A DiagnosticPosition with the preferred position set to the - * end position of given tree, if it is a block with - * defined endpos. + * closing brace position of given tree, if it is a block with + * defined closing brace position. */ public static DiagnosticPosition diagEndPos(final JCTree tree) { final int endPos = TreeInfo.endPos(tree); diff --git a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java index 2968bc3e173..0219fa0eaf8 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,6 @@ class ReplParser extends JavacParser { storeEnd(toplevel, S.prevToken().endPos); } toplevel.lineMap = S.getLineMap(); - this.endPosTable.setParser(null); // remove reference to parser toplevel.endPositions = this.endPosTable; return toplevel; } diff --git a/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java b/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java index ff3f2cf3200..95a9ef2dd53 100644 --- a/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java +++ b/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -151,7 +151,7 @@ public class MissingLNTEntryForFinalizerTest { com.sun.tools.javac.code.Type result = super.attribStat(tree, env); if (tree.hasTag(TRY)) { JCTry tryTree = (JCTry)tree; - lineNumber = env.toplevel.lineMap.getLineNumber(tryTree.finalizer.endpos); + lineNumber = env.toplevel.lineMap.getLineNumber(tryTree.finalizer.bracePos); } return result; } diff --git a/test/langtools/tools/javac/parser/DeclarationEndPositions.java b/test/langtools/tools/javac/parser/DeclarationEndPositions.java new file mode 100644 index 00000000000..473d6bc2712 --- /dev/null +++ b/test/langtools/tools/javac/parser/DeclarationEndPositions.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8350212 + * @summary Verify ending source positions are calculated for declarations supporting SuppressWarnings + * @modules jdk.compiler/com.sun.tools.javac.tree + * @run main DeclarationEndPositions + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.Tree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.tree.TreeInfo; + +import java.io.IOException; +import java.net.URI; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +public class DeclarationEndPositions { + + public static void checkEndPosition(Class nodeType, String input, String marker) throws IOException { + + // Create source + var source = new SimpleJavaFileObject(URI.create("file://T.java"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return input; + } + }; + + // Parse source + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, List.of(), List.of(), List.of(source)); + Iterable units = ((JavacTask)task).parse(); + + // Find node and check end position + JCTree.JCCompilationUnit unit = (JCTree.JCCompilationUnit)units.iterator().next(); + unit.accept(new TreeScanner() { + @Override + public Void scan(Tree node, Void aVoid) { + if (nodeType.isInstance(node)) { + JCTree tree = (JCTree)node; + int actual = TreeInfo.getEndPos(tree, unit.endPositions); + int expected = marker.indexOf('^') + 1; + if (actual != expected) { + throw new AssertionError(String.format( + "wrong end pos %d != %d for \"%s\" @ %d", actual, expected, input, tree.pos)); + } + } + return super.scan(node, aVoid); + } + }, null); + } + + public static void main(String... args) throws Exception { + + // JCModuleDecl + checkEndPosition(JCModuleDecl.class, + "/* comment */ module fred { /* comment */ } /* comment */", + " ^ "); + + // JCPackageDecl + checkEndPosition(JCPackageDecl.class, + "/* comment */ package fred; /* comment */", + " ^ "); + + // JCClassDecl + checkEndPosition(JCClassDecl.class, + "/* comment */ class Fred { /* comment */ } /* comment */", + " ^ "); + + // JCMethodDecl + checkEndPosition(JCMethodDecl.class, + "/* comment */ class Fred { void m() { /* comment */ } } /* comment */", + " ^ "); + + // JCVariableDecl + checkEndPosition(JCVariableDecl.class, + "/* comment */ class Fred { int x; } /* comment */", + " ^ "); + checkEndPosition(JCVariableDecl.class, + "/* comment */ class Fred { int x = 123; } /* comment */", + " ^ "); + checkEndPosition(JCVariableDecl.class, + "/* comment */ class A { try {} catch (Error err) {} } /* comment */", + " ^ "); + } +} diff --git a/test/langtools/tools/javac/parser/JavacParserTest.java b/test/langtools/tools/javac/parser/JavacParserTest.java index 6a2850fc8dd..9c6ad617132 100644 --- a/test/langtools/tools/javac/parser/JavacParserTest.java +++ b/test/langtools/tools/javac/parser/JavacParserTest.java @@ -2298,10 +2298,9 @@ public class JavacParserTest extends TestCase { @Test //JDK-8310326 void testUnnamedClassPositions() throws IOException { - String code = """ - void main() { - } - """; + // 0 1 2 + // 012345678901234567890 + String code = "void main() { }"; DiagnosticCollector coll = new DiagnosticCollector<>(); JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll, null, @@ -2313,7 +2312,7 @@ public class JavacParserTest extends TestCase { @Override public Void visitClass(ClassTree node, Void p) { assertEquals("Wrong start position", 0, sp.getStartPosition(cut, node)); - assertEquals("Wrong end position", -1, sp.getEndPosition(cut, node)); + assertEquals("Wrong end position", 15, sp.getEndPosition(cut, node)); assertEquals("Wrong modifiers start position", -1, sp.getStartPosition(cut, node.getModifiers())); assertEquals("Wrong modifiers end position", -1, sp.getEndPosition(cut, node.getModifiers())); return super.visitClass(node, p); diff --git a/test/langtools/tools/javac/parser/extend/TrialParser.java b/test/langtools/tools/javac/parser/extend/TrialParser.java index 539676a90fb..c9a858fbc47 100644 --- a/test/langtools/tools/javac/parser/extend/TrialParser.java +++ b/test/langtools/tools/javac/parser/extend/TrialParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,7 +139,6 @@ class TrialParser extends JavacParser { storeEnd(toplevel, S.prevToken().endPos); } toplevel.lineMap = S.getLineMap(); - this.endPosTable.setParser(null); // remove reference to parser toplevel.endPositions = this.endPosTable; return toplevel; } From 78158f30aee51e14ab203b0127aeb883c010319c Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Thu, 5 Jun 2025 22:13:24 +0000 Subject: [PATCH 179/216] 8358099: PEM spec updates Reviewed-by: mullan --- .../classes/java/security/PEMDecoder.java | 40 ++++++------- .../classes/java/security/PEMEncoder.java | 7 ++- .../classes/java/security/PEMRecord.java | 56 +++++++------------ .../sun/security/provider/X509Factory.java | 2 +- .../share/classes/sun/security/util/Pem.java | 2 +- .../jdk/java/security/PEM/PEMDecoderTest.java | 8 +-- 6 files changed, 48 insertions(+), 67 deletions(-) diff --git a/src/java.base/share/classes/java/security/PEMDecoder.java b/src/java.base/share/classes/java/security/PEMDecoder.java index eeb6decdf40..7279e75cc98 100644 --- a/src/java.base/share/classes/java/security/PEMDecoder.java +++ b/src/java.base/share/classes/java/security/PEMDecoder.java @@ -81,24 +81,24 @@ import java.util.Objects; * {@link PEMRecord}. * *

        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. * *

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

        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. * - *

        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 diff --git a/src/java.base/share/classes/java/security/PEMEncoder.java b/src/java.base/share/classes/java/security/PEMEncoder.java index d5465083330..95fcffe967b 100644 --- a/src/java.base/share/classes/java/security/PEMEncoder.java +++ b/src/java.base/share/classes/java/security/PEMEncoder.java @@ -71,7 +71,7 @@ import java.util.concurrent.locks.ReentrantLock; * OneAsymmetricKey structure using the "PRIVATE KEY" type. * *

        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) { diff --git a/src/java.base/share/classes/java/security/PEMRecord.java b/src/java.base/share/classes/java/security/PEMRecord.java index dfe951a0963..2ce567f9fde 100644 --- a/src/java.base/share/classes/java/security/PEMRecord.java +++ b/src/java.base/share/classes/java/security/PEMRecord.java @@ -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}. * - *

        {@code type} and {@code pem} may not be {@code null}. + *

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

        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); } /** diff --git a/src/java.base/share/classes/sun/security/provider/X509Factory.java b/src/java.base/share/classes/sun/security/provider/X509Factory.java index ec7a1ac998a..1a8ace55fc8 100644 --- a/src/java.base/share/classes/sun/security/provider/X509Factory.java +++ b/src/java.base/share/classes/sun/security/provider/X509Factory.java @@ -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); } diff --git a/src/java.base/share/classes/sun/security/util/Pem.java b/src/java.base/share/classes/sun/security/util/Pem.java index c6e56381771..492017eca29 100644 --- a/src/java.base/share/classes/sun/security/util/Pem.java +++ b/src/java.base/share/classes/sun/security/util/Pem.java @@ -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); } } diff --git a/test/jdk/java/security/PEM/PEMDecoderTest.java b/test/jdk/java/security/PEM/PEMDecoderTest.java index 6486bfc83c7..2ee9d1a69b3 100644 --- a/test/jdk/java/security/PEM/PEMDecoderTest.java +++ b/test/jdk/java/security/PEM/PEMDecoderTest.java @@ -107,8 +107,8 @@ public class PEMDecoderTest { System.err.println("received: " + new String(rec.leadingData())); throw new AssertionError("ecCSRWithData preData wrong"); } - if (rec.pem().lastIndexOf("F") > rec.pem().length() - 5) { - System.err.println("received: " + rec.pem()); + if (rec.content().lastIndexOf("F") > rec.content().length() - 5) { + System.err.println("received: " + rec.content()); throw new AssertionError("ecCSRWithData: " + "End of PEM data has an unexpected character"); } @@ -235,10 +235,10 @@ public class PEMDecoderTest { PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class); String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), ""); try { - PEMData.checkResults(expected, r.pem()); + PEMData.checkResults(expected, r.content()); } catch (AssertionError e) { System.err.println("expected:\n" + expected); - System.err.println("received:\n" + r.pem()); + System.err.println("received:\n" + r.content()); throw e; } From 029e3bf8f582f7399b80c592421b2fd72737e264 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Fri, 6 Jun 2025 02:07:51 +0000 Subject: [PATCH 180/216] 8349914: ZipFile::entries and ZipFile::getInputStream not consistent with each other when there are duplicate entries Co-authored-by: Lance Andersen Reviewed-by: lancea --- .../share/classes/java/util/zip/ZipEntry.java | 7 +- .../share/classes/java/util/zip/ZipFile.java | 18 +- .../zip/ZipFile/DupEntriesGetInputStream.java | 216 ++++++++++++++++++ 3 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 test/jdk/java/util/zip/ZipFile/DupEntriesGetInputStream.java diff --git a/src/java.base/share/classes/java/util/zip/ZipEntry.java b/src/java.base/share/classes/java/util/zip/ZipEntry.java index 836dda141b7..bf0bf55ff98 100644 --- a/src/java.base/share/classes/java/util/zip/ZipEntry.java +++ b/src/java.base/share/classes/java/util/zip/ZipEntry.java @@ -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 @@ -60,6 +60,10 @@ public class ZipEntry implements ZipConstants, Cloneable { byte[] extra; // optional extra field data for entry String comment; // optional comment string for entry int externalFileAttributes = -1; // File type, setuid, setgid, sticky, POSIX permissions + + // entry's LOC offset as noted in the entry's central header, -1 implies undetermined + long locOffset = -1; + /** * Compression method for uncompressed entries. */ @@ -138,6 +142,7 @@ public class ZipEntry implements ZipConstants, Cloneable { extra = e.extra; comment = e.comment; externalFileAttributes = e.externalFileAttributes; + locOffset = e.locOffset; } /** diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 17382181876..7fa507980c2 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -341,7 +341,7 @@ public class ZipFile implements ZipConstants, Closeable { if (pos == -1) { return null; } - in = new ZipFileInputStream(zsrc.cen, pos); + in = new ZipFileInputStream(zsrc.cen, pos, entry.locOffset); switch (CENHOW(zsrc.cen, pos)) { case STORED: synchronized (istreams) { @@ -653,6 +653,7 @@ public class ZipFile implements ZipConstants, Closeable { // read all bits in this field, including sym link attributes e.externalFileAttributes = CENATX_PERMS(cen, pos) & 0xFFFF; } + e.locOffset = CENOFF(cen, pos); int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); @@ -847,10 +848,21 @@ public class ZipFile implements ZipConstants, Closeable { protected long rem; // number of remaining bytes within entry protected long size; // uncompressed size of this entry - ZipFileInputStream(byte[] cen, int cenpos) { + /** + * @param cen the ZIP's CEN + * @param cenpos the entry's offset within the CEN + * @param locOffset the entry's LOC offset in the ZIP stream. If -1 is passed + * then the LOC offset for the entry will be read from the + * entry's central header + */ + ZipFileInputStream(byte[] cen, int cenpos, long locOffset) { rem = CENSIZ(cen, cenpos); size = CENLEN(cen, cenpos); - pos = CENOFF(cen, cenpos); + if (locOffset == -1) { + pos = CENOFF(cen, cenpos); + } else { + pos = locOffset; + } // ZIP64 if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL || pos == ZIP64_MAGICVAL) { diff --git a/test/jdk/java/util/zip/ZipFile/DupEntriesGetInputStream.java b/test/jdk/java/util/zip/ZipFile/DupEntriesGetInputStream.java new file mode 100644 index 00000000000..cbab0b2d910 --- /dev/null +++ b/test/jdk/java/util/zip/ZipFile/DupEntriesGetInputStream.java @@ -0,0 +1,216 @@ +/* + * 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. + * + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HexFormat; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/* + * @test + * @bug 8349914 + * @summary Validate ZipFile::getFileInputStream returns the correct data when + * there are multiple entries with the same filename + * @run junit DupEntriesGetInputStream + */ +class DupEntriesGetInputStream { + + // created through a call to createNormalZIP() + private static final String NORMAL_ZIP_CONTENT_HEX = """ + 504b03041400080808009195c35a00000000000000000000000006000000456e747279310bc9c8 + 2c560022d7bc92a24a054300504b07089bc0e55b0f0000000f000000504b030414000808080091 + 95c35a00000000000000000000000006000000456e747279320bc9c82c560022d7bc92a24a85bc + d2dca4d4228590f27c00504b0708ebda8deb1800000018000000504b03041400080808009195c3 + 5a00000000000000000000000006000000456e747279330bc9c82c560022d7bc92a24a05650563 + 00504b0708d1eafe7d1100000011000000504b010214001400080808009195c35a9bc0e55b0f00 + 00000f000000060000000000000000000000000000000000456e74727931504b01021400140008 + 0808009195c35aebda8deb1800000018000000060000000000000000000000000043000000456e + 74727932504b010214001400080808009195c35ad1eafe7d110000001100000006000000000000 + 000000000000008f000000456e74727933504b050600000000030003009c000000d40000000000 + """; + + // intentionally unused but left here to allow for constructing newer/updated + // NORMAL_ZIP_CONTENT_HEX, when necessary + private static String createNormalZIP() throws IOException { + final ByteArrayOutputStream zipContent = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(zipContent)) { + zos.putNextEntry(new ZipEntry(ENTRY1_NAME)); + zos.write(ENTRY1.getBytes(US_ASCII)); + zos.putNextEntry(new ZipEntry(ENTRY2_NAME)); + zos.write(ENTRY2.getBytes(US_ASCII)); + zos.putNextEntry(new ZipEntry(ENTRY3_NAME)); + zos.write(ENTRY3.getBytes(US_ASCII)); + } + return HexFormat.of().formatHex(zipContent.toByteArray()); + } + + // Entry Names and their data to be added to the ZIP File + private static final String ENTRY1_NAME = "Entry1"; + private static final String ENTRY1 = "This is Entry 1"; + + private static final String ENTRY2_NAME = "Entry2"; + private static final String ENTRY2 = "This is Entry number Two"; + + private static final String ENTRY3_NAME = "Entry3"; + private static final String ENTRY3 = "This is Entry # 3"; + + // ZIP entry and its expected data + record ZIP_ENTRY(String entryName, String data) { + } + + private static final ZIP_ENTRY[] ZIP_ENTRIES = new ZIP_ENTRY[]{ + new ZIP_ENTRY(ENTRY1_NAME, ENTRY1), + new ZIP_ENTRY(ENTRY2_NAME, ENTRY2), + new ZIP_ENTRY(ENTRY1_NAME, ENTRY3) + }; + + private static Path dupEntriesZipFile; + + // 008F LOCAL HEADER #3 04034B50 + // ... + // 00A1 Compressed Length 00000000 + // 00A5 Uncompressed Length 00000000 + // 00A9 Filename Length 0006 + // ... + // 00AD Filename 'Entry3' + private static final int ENTRY3_FILENAME_LOC_OFFSET = 0x00AD; + + // 013C CENTRAL HEADER #3 02014B50 + // ... + // 0150 Compressed Length 00000011 + // 0154 Uncompressed Length 00000011 + // 0158 Filename Length 0006 + // ... + // 016A Filename 'Entry3' + private static final int ENTRY3_FILENAME_CEN_OFFSET = 0x016A; + + @BeforeAll + static void createDupEntriesZIP() throws Exception { + final byte[] originalZIPContent = HexFormat.of().parseHex( + NORMAL_ZIP_CONTENT_HEX.replace("\n", "")); + final ByteBuffer buf = ByteBuffer.wrap(originalZIPContent).order(LITTLE_ENDIAN); + // replace the file name literal "Entry3" with the literal "Entry1", both in the + // LOC header and the CEN of Entry3 + final int locEntry3LastCharOffset = ENTRY3_FILENAME_LOC_OFFSET + ENTRY3_NAME.length() - 1; + buf.put(locEntry3LastCharOffset, (byte) 49); // 49 represents the character "1" + final int cenEntry3LastCharOffset = ENTRY3_FILENAME_CEN_OFFSET + ENTRY3_NAME.length() - 1; + buf.put(cenEntry3LastCharOffset, (byte) 49); // 49 represents the character "1" + buf.rewind(); + // write out the manipulated ZIP content, containing duplicate entries, into a file + // so that it can be read using ZipFile + dupEntriesZipFile = Files.createTempFile(Path.of("."), "8349914-", ".zip"); + Files.write(dupEntriesZipFile, buf.array()); + System.out.println("created ZIP file with duplicate entries at " + dupEntriesZipFile); + } + + /* + * Validate that the correct ZipEntry data is returned when a List is used + * to access entries returned from ZipFile::entries + * + * @throws IOException if an error occurs + */ + @Test + public void testUsingListEntries() throws IOException { + System.out.println("Processing entries via Collections.list()"); + try (ZipFile zf = new ZipFile(dupEntriesZipFile.toFile())) { + var entryNumber = 0; + for (var e : Collections.list(zf.entries())) { + verifyEntry(entryNumber++, zf, e); + } + } + } + + /* + * Validate that the correct ZipEntry data is returned when a ZipEntryIterator + * is used to access entries returned from ZipFile::entries + * + * @throws IOException if an error occurs + */ + @Test + public void testUsingZipEntryIterator() throws IOException { + System.out.println("Processing entries via a ZipEntryIterator"); + try (ZipFile zf = new ZipFile(dupEntriesZipFile.toFile())) { + Enumeration entries = zf.entries(); + var entryNumber = 0; + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + verifyEntry(entryNumber++, zf, entry); + } + } + } + + /* + * Validate that the correct ZipEntry data is returned when a EntrySpliterator + * is used to access entries returned from ZipFile::stream + * + * @throws IOException if an error occurs + */ + @Test + public void testUsingEntrySpliterator() throws IOException { + System.out.println("Processing entries via a EntrySpliterator"); + AtomicInteger eNumber = new AtomicInteger(0); + try (ZipFile zf = new ZipFile(dupEntriesZipFile.toFile())) { + zf.stream().forEach(e -> { + try { + verifyEntry(eNumber.getAndIncrement(), zf, e); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + } + } + + /* + * Verify the ZipEntry returned matches what is expected + * + * @param entryNumber offset into ZIP_ENTRIES containing the expected value + * to be returned + * @param zf ZipFile containing the entry + * @param e ZipEntry to validate + * @throws IOException + */ + private static void verifyEntry(int entryNumber, ZipFile zf, ZipEntry e) throws IOException { + System.out.println("Validating Entry: " + entryNumber); + assertEquals(ZIP_ENTRIES[entryNumber].entryName(), e.getName()); + try (var in = zf.getInputStream(e)) { + var entryData = new String(in.readAllBytes(), StandardCharsets.UTF_8); + assertEquals(ZIP_ENTRIES[entryNumber].data(), entryData); + } + } +} From 28acca609bbb8ade0af88b536c8c88b7fa43849a Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Fri, 6 Jun 2025 03:50:06 +0000 Subject: [PATCH 181/216] 8358653: [s390] Clean up comments regarding frame manager Reviewed-by: mdoerr --- src/hotspot/cpu/s390/frame_s390.hpp | 2 +- src/hotspot/cpu/s390/register_s390.hpp | 6 +++--- src/hotspot/cpu/s390/runtime_s390.cpp | 2 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 2 +- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 16 ++++++++-------- .../s390/templateInterpreterGenerator_s390.cpp | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hotspot/cpu/s390/frame_s390.hpp b/src/hotspot/cpu/s390/frame_s390.hpp index 85e957fe992..ad754706367 100644 --- a/src/hotspot/cpu/s390/frame_s390.hpp +++ b/src/hotspot/cpu/s390/frame_s390.hpp @@ -410,7 +410,7 @@ // C2I adapter frames: // - // STACK (interpreted called from compiled, on entry to frame manager): + // STACK (interpreted called from compiled, on entry to template interpreter): // // [TOP_C2I_FRAME] // [JIT_FRAME] diff --git a/src/hotspot/cpu/s390/register_s390.hpp b/src/hotspot/cpu/s390/register_s390.hpp index e7fdaa58d1a..a33145db02c 100644 --- a/src/hotspot/cpu/s390/register_s390.hpp +++ b/src/hotspot/cpu/s390/register_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -414,7 +414,7 @@ constexpr FloatRegister Z_FARG2 = Z_F2; constexpr FloatRegister Z_FARG3 = Z_F4; constexpr FloatRegister Z_FARG4 = Z_F6; -// Register declarations to be used in frame manager assembly code. +// Register declarations to be used in template interpreter assembly code. // Use only non-volatile registers in order to keep values across C-calls. // Register to cache the integer value on top of the operand stack. @@ -439,7 +439,7 @@ constexpr Register Z_bcp = Z_R13; // Bytecode which is dispatched (short lived!). constexpr Register Z_bytecode = Z_R14; -// Temporary registers to be used within frame manager. We can use +// Temporary registers to be used within template interpreter. We can use // the nonvolatile ones because the call stub has saved them. // Use only non-volatile registers in order to keep values across C-calls. constexpr Register Z_tmp_1 = Z_R10; diff --git a/src/hotspot/cpu/s390/runtime_s390.cpp b/src/hotspot/cpu/s390/runtime_s390.cpp index 8f96ff55ccb..99a33716b8b 100644 --- a/src/hotspot/cpu/s390/runtime_s390.cpp +++ b/src/hotspot/cpu/s390/runtime_s390.cpp @@ -118,7 +118,7 @@ ExceptionBlob* OptoRuntime::generate_exception_blob() { __ z_lgr(Z_SP, saved_sp); // [Z_RET] isn't null was possible in hotspot5 but not in sapjvm6. - // C2I adapter extensions are now removed by a resize in the frame manager + // C2I adapter extensions are now removed by a resize in the template interpreter // (unwind_initial_activation_pending_exception). #ifdef ASSERT __ z_ltgr(handle_exception, handle_exception); diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index bd5bbf4c7e5..cb1f12504fd 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -2139,7 +2139,7 @@ static address gen_c2i_adapter(MacroAssembler *masm, Register value = Z_R12; // Remember the senderSP so we can pop the interpreter arguments off of the stack. - // In addition, frame manager expects initial_caller_sp in Z_R10. + // In addition, template interpreter expects initial_caller_sp in Z_R10. __ z_lgr(sender_SP, Z_SP); // This should always fit in 14 bit immediate. diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 1e9136cdca9..d3f6540a3ea 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -115,7 +115,7 @@ class StubGenerator: public StubCodeGenerator { // [SP+176] - thread : Thread* // address generate_call_stub(address& return_address) { - // Set up a new C frame, copy Java arguments, call frame manager + // Set up a new C frame, copy Java arguments, call template interpreter // or native_entry, and process result. StubGenStubId stub_id = StubGenStubId::call_stub_id; @@ -272,10 +272,10 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("call {"); { - // Call frame manager or native entry. + // Call template interpreter or native entry. // - // Register state on entry to frame manager / native entry: + // Register state on entry to template interpreter / native entry: // // Z_ARG1 = r_top_of_arguments_addr - intptr_t *sender tos (prepushed) // Lesp = (SP) + copied_arguments_offset - 8 @@ -290,7 +290,7 @@ class StubGenerator: public StubCodeGenerator { __ z_lgr(Z_esp, r_top_of_arguments_addr); // - // Stack on entry to frame manager / native entry: + // Stack on entry to template interpreter / native entry: // // F0 [TOP_IJAVA_FRAME_ABI] // [outgoing Java arguments] @@ -300,7 +300,7 @@ class StubGenerator: public StubCodeGenerator { // // Do a light-weight C-call here, r_new_arg_entry holds the address - // of the interpreter entry point (frame manager or native entry) + // of the interpreter entry point (template interpreter or native entry) // and save runtime-value of return_pc in return_address // (call by reference argument). return_address = __ call_stub(r_new_arg_entry); @@ -309,11 +309,11 @@ class StubGenerator: public StubCodeGenerator { { BLOCK_COMMENT("restore registers {"); - // Returned from frame manager or native entry. + // Returned from template interpreter or native entry. // Now pop frame, process result, and return to caller. // - // Stack on exit from frame manager / native entry: + // Stack on exit from template interpreter / native entry: // // F0 [ABI] // ... @@ -330,7 +330,7 @@ class StubGenerator: public StubCodeGenerator { __ pop_frame(); // Reload some volatile registers which we've spilled before the call - // to frame manager / native entry. + // to template interpreter / native entry. // Access all locals via frame pointer, because we know nothing about // the topmost frame's size. __ z_lg(r_arg_result_addr, result_address_offset, r_entryframe_fp); diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index e387d60b594..e03d891496a 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1217,7 +1217,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // Various method entries -// Math function, frame manager must set up an interpreter state, etc. +// Math function, template interpreter must set up an interpreter state, etc. address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { // Decide what to do: Use same platform specific instructions and runtime calls as compilers. From e918a59b1dacf273620aee334517bebfb1fb1a0f Mon Sep 17 00:00:00 2001 From: Volkan Yazici Date: Fri, 6 Jun 2025 06:26:09 +0000 Subject: [PATCH 182/216] 8357821: Revert incorrectly named JavaLangAccess::unchecked* methods Reviewed-by: pminborg --- .../share/classes/java/io/DataInputStream.java | 4 ++-- .../classes/java/io/ObjectInputStream.java | 4 ++-- .../share/classes/java/lang/System.java | 6 +++--- .../share/classes/java/util/zip/ZipCoder.java | 2 +- .../jdk/internal/access/JavaLangAccess.java | 18 +++++++++--------- .../classfile/impl/AbstractPoolEntry.java | 4 ++-- .../share/classes/sun/nio/cs/CESU_8.java | 2 +- .../share/classes/sun/nio/cs/DoubleByte.java | 2 +- .../share/classes/sun/nio/cs/ISO_8859_1.java | 2 +- .../share/classes/sun/nio/cs/SingleByte.java | 2 +- .../share/classes/sun/nio/cs/US_ASCII.java | 2 +- .../share/classes/sun/nio/cs/UTF_8.java | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/java.base/share/classes/java/io/DataInputStream.java b/src/java.base/share/classes/java/io/DataInputStream.java index fa6fecf83da..daf75b1318f 100644 --- a/src/java.base/share/classes/java/io/DataInputStream.java +++ b/src/java.base/share/classes/java/io/DataInputStream.java @@ -595,7 +595,7 @@ loop: while (true) { int chararr_count=0; in.readFully(bytearr, 0, utflen); - int ascii = JLA.uncheckedCountPositives(bytearr, 0, utflen); + int ascii = JLA.countPositives(bytearr, 0, utflen); if (ascii == utflen) { String str; if (trusted) { @@ -621,7 +621,7 @@ loop: while (true) { } if (ascii != 0) { - JLA.uncheckedInflateBytesToChars(bytearr, 0, chararr, 0, ascii); + JLA.inflateBytesToChars(bytearr, 0, chararr, 0, ascii); count += ascii; chararr_count += ascii; } diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index b9593fa2c2f..daed5f3cce5 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -3536,7 +3536,7 @@ public class ObjectInputStream if (utflen > 0 && utflen < Integer.MAX_VALUE) { // Scan for leading ASCII chars int avail = end - pos; - int ascii = JLA.uncheckedCountPositives(buf, pos, Math.min(avail, (int)utflen)); + int ascii = JLA.countPositives(buf, pos, Math.min(avail, (int)utflen)); if (ascii == utflen) { // Complete match, consume the buf[pos ... pos + ascii] range and return. // Modified UTF-8 and ISO-8859-1 are both ASCII-compatible encodings bytes @@ -3549,7 +3549,7 @@ public class ObjectInputStream // Avoid allocating a StringBuilder if there's enough data in buf and // cbuf is large enough if (avail >= utflen && utflen <= CHAR_BUF_SIZE) { - JLA.uncheckedInflateBytesToChars(buf, pos, cbuf, 0, ascii); + JLA.inflateBytesToChars(buf, pos, cbuf, 0, ascii); pos += ascii; int cbufPos = readUTFSpan(ascii, utflen - ascii); return new String(cbuf, 0, cbufPos); diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index bcdbc39e665..0175558d313 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -2118,7 +2118,7 @@ public final class System { return ModuleLayer.layers(loader); } - public int uncheckedCountPositives(byte[] bytes, int offset, int length) { + public int countPositives(byte[] bytes, int offset, int length) { return StringCoding.countPositives(bytes, offset, length); } public int countNonZeroAscii(String s) { @@ -2145,11 +2145,11 @@ public final class System { return String.getBytesUTF8NoRepl(s); } - public void uncheckedInflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len) { + public void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len) { StringLatin1.inflate(src, srcOff, dst, dstOff, len); } - public int uncheckedDecodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len) { + public int decodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len) { return String.decodeASCII(src, srcOff, dst, dstOff, len); } diff --git a/src/java.base/share/classes/java/util/zip/ZipCoder.java b/src/java.base/share/classes/java/util/zip/ZipCoder.java index bbf1c10112a..0c3282e3518 100644 --- a/src/java.base/share/classes/java/util/zip/ZipCoder.java +++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java @@ -266,7 +266,7 @@ class ZipCoder { return 0; } int end = off + len; - int asciiLen = JLA.uncheckedCountPositives(a, off, len); + int asciiLen = JLA.countPositives(a, off, len); if (asciiLen != len) { // Non-ASCII, fall back to decoding a String // We avoid using decoder() here since the UTF8ZipCoder is diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 5109e7b2a5b..e8343274cac 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -302,10 +302,10 @@ public interface JavaLangAccess { /** * Count the number of leading positive bytes in the range. - *

        - * WARNING: This method does not perform any bound checks. + * + * @implSpec Implementations of this method must perform bounds checks. */ - int uncheckedCountPositives(byte[] ba, int off, int len); + int countPositives(byte[] ba, int off, int len); /** * Count the number of leading non-zero ascii chars in the String. @@ -390,20 +390,20 @@ public interface JavaLangAccess { /** * Inflated copy from {@code byte[]} to {@code char[]}, as defined by * {@code StringLatin1.inflate}. - *

        - * WARNING: This method does not perform any bound checks. + * + * @implSpec Implementations of this method must perform bounds checks. */ - void uncheckedInflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len); + void inflateBytesToChars(byte[] src, int srcOff, char[] dst, int dstOff, int len); /** * Decodes ASCII from the source byte array into the destination * char array. - *

        - * WARNING: This method does not perform any bound checks. + * + * @implSpec Implementations of this method must perform bounds checks. * * @return the number of bytes successfully decoded, at most len */ - int uncheckedDecodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len); + int decodeASCII(byte[] src, int srcOff, char[] dst, int dstOff, int len); /** * Returns the initial `System.in` to determine if it is replaced diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java index ab7f0847bbd..962a2057585 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java @@ -218,7 +218,7 @@ public abstract sealed class AbstractPoolEntry { * two-times-three-byte format instead. */ private void inflate() { - int singleBytes = JLA.uncheckedCountPositives(rawBytes, offset, rawLen); + int singleBytes = JLA.countPositives(rawBytes, offset, rawLen); int hash = ArraysSupport.hashCodeOfUnsigned(rawBytes, offset, singleBytes, 0); if (singleBytes == rawLen) { this.contentHash = hash; @@ -233,7 +233,7 @@ public abstract sealed class AbstractPoolEntry { char[] chararr = new char[rawLen]; int chararr_count = singleBytes; // Inflate prefix of bytes to characters - JLA.uncheckedInflateBytesToChars(rawBytes, offset, chararr, 0, singleBytes); + JLA.inflateBytesToChars(rawBytes, offset, chararr, 0, singleBytes); int px = offset + singleBytes; int utfend = offset + rawLen; diff --git a/src/java.base/share/classes/sun/nio/cs/CESU_8.java b/src/java.base/share/classes/sun/nio/cs/CESU_8.java index a6e233873a8..a9a25e151ad 100644 --- a/src/java.base/share/classes/sun/nio/cs/CESU_8.java +++ b/src/java.base/share/classes/sun/nio/cs/CESU_8.java @@ -196,7 +196,7 @@ class CESU_8 extends Unicode int dp = doff + dst.position(); int dl = doff + dst.limit(); - int n = JLA.uncheckedDecodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; diff --git a/src/java.base/share/classes/sun/nio/cs/DoubleByte.java b/src/java.base/share/classes/sun/nio/cs/DoubleByte.java index c4c9856a60b..4738f51515b 100644 --- a/src/java.base/share/classes/sun/nio/cs/DoubleByte.java +++ b/src/java.base/share/classes/sun/nio/cs/DoubleByte.java @@ -168,7 +168,7 @@ public class DoubleByte { try { if (isASCIICompatible) { - int n = JLA.uncheckedDecodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); + int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); dp += n; sp += n; } diff --git a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java index 241171d8deb..39215bfa93d 100644 --- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java +++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java @@ -87,7 +87,7 @@ public class ISO_8859_1 int dl = doff + dst.limit(); int decodeLen = Math.min(sl - sp, dl - dp); - JLA.uncheckedInflateBytesToChars(sa, sp, da, dp, decodeLen); + JLA.inflateBytesToChars(sa, sp, da, dp, decodeLen); sp += decodeLen; dp += decodeLen; src.position(sp - soff); diff --git a/src/java.base/share/classes/sun/nio/cs/SingleByte.java b/src/java.base/share/classes/sun/nio/cs/SingleByte.java index fe66f3216a4..d802cc85aa8 100644 --- a/src/java.base/share/classes/sun/nio/cs/SingleByte.java +++ b/src/java.base/share/classes/sun/nio/cs/SingleByte.java @@ -95,7 +95,7 @@ public class SingleByte } if (isASCIICompatible) { - int n = JLA.uncheckedDecodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); + int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(dl - dp, sl - sp)); sp += n; dp += n; } diff --git a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java index 627b1433d61..bb84ab1bd4b 100644 --- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java +++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java @@ -83,7 +83,7 @@ public class US_ASCII int dl = doff + dst.limit(); // ASCII only loop - int n = JLA.uncheckedDecodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; src.position(sp - soff); diff --git a/src/java.base/share/classes/sun/nio/cs/UTF_8.java b/src/java.base/share/classes/sun/nio/cs/UTF_8.java index 89a199db99b..54e479f838a 100644 --- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java +++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java @@ -227,7 +227,7 @@ public final class UTF_8 extends Unicode { int dp = doff + dst.position(); int dl = doff + dst.limit(); - int n = JLA.uncheckedDecodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); + int n = JLA.decodeASCII(sa, sp, da, dp, Math.min(sl - sp, dl - dp)); sp += n; dp += n; From bb2611ad43a2feaebc2246fdbac2179a40115d67 Mon Sep 17 00:00:00 2001 From: Volkan Yazici Date: Fri, 6 Jun 2025 06:53:10 +0000 Subject: [PATCH 183/216] 8357993: Use "stdin.encoding" for reading System.in with InputStreamReader/Scanner [hotspot] Reviewed-by: cjplummer, sspitsyn --- .../share/classes/sun/jvm/hotspot/CLHSDB.java | 7 ++++--- .../classes/jdk/jfr/internal/jfc/model/UserInterface.java | 6 ++++-- .../jvmti/AttachOnDemand/attach010/attach010Agent00.java | 5 +++-- .../jtreg/vmTestbase/nsk/share/jpda/BindServer.java | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CLHSDB.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CLHSDB.java index 3ed34ef1ae9..565d9e83329 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CLHSDB.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CLHSDB.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import sun.jvm.hotspot.*; import sun.jvm.hotspot.debugger.*; import java.io.*; +import java.nio.charset.Charset; import java.util.*; public class CLHSDB { @@ -106,8 +107,8 @@ public class CLHSDB { }; - BufferedReader in = - new BufferedReader(new InputStreamReader(System.in)); + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + BufferedReader in = new BufferedReader(new InputStreamReader(System.in, charset)); CommandProcessor cp = new CommandProcessor(di, in, System.out, System.err); cp.run(true); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/UserInterface.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/UserInterface.java index 7d9fc2478ba..f397fc4ec7d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/UserInterface.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/UserInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package jdk.jfr.internal.jfc.model; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.Charset; public final class UserInterface { @@ -40,7 +41,8 @@ public final class UserInterface { public String readLine() throws AbortException { try { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + Charset charset = Charset.forName(System.getProperty("stdin.encoding"), Charset.defaultCharset()); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in, charset)); String line = br.readLine(); if (line == null || line.equalsIgnoreCase("Q")) { println(); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach010/attach010Agent00.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach010/attach010Agent00.java index 877c1e3862e..1e0abf4e11e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach010/attach010Agent00.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach010/attach010Agent00.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, 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 @@ -60,7 +60,8 @@ public class attach010Agent00 extends AbstractJarAgent { FileInputStream newInputStream = new FileInputStream(inStreamFileName); System.setIn(newInputStream); - BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(System.in)); + BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader( + System.in, System.getProperty("stdin.encoding"))); int readValue = Integer.parseInt(inputStreamReader.readLine()); if (readValue != valueToWrite) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/BindServer.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/BindServer.java index 2ed334e0386..58a7ca2a703 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/BindServer.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jpda/BindServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -173,7 +173,7 @@ public final class BindServer { } BufferedReader stdIn = new BufferedReader( - new InputStreamReader(System.in)); + new InputStreamReader(System.in, System.getProperty("stdin.encoding"))); try (ListeningThread listeningThread = new ListeningThread(this)) { listeningThread.bind(); listeningThread.start(); From d1b788005bdf11f1426baa8e811c121a956482c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Maillard?= Date: Fri, 6 Jun 2025 08:16:15 +0000 Subject: [PATCH 184/216] 8357951: Remove the IdealLoopTree* loop parameter from PhaseIdealLoop::loop_iv_phi Reviewed-by: thartmann, mhaessig --- src/hotspot/share/opto/loopnode.cpp | 12 ++++++------ src/hotspot/share/opto/loopnode.hpp | 4 ++-- src/hotspot/share/opto/loopopts.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index 195d48b37c6..3130df54681 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -458,7 +458,7 @@ Node* PhaseIdealLoop::loop_iv_incr(Node* incr, Node* x, IdealLoopTree* loop, Nod return incr; } -Node* PhaseIdealLoop::loop_iv_stride(Node* incr, IdealLoopTree* loop, Node*& xphi) { +Node* PhaseIdealLoop::loop_iv_stride(Node* incr, Node*& xphi) { assert(incr->Opcode() == Op_AddI || incr->Opcode() == Op_AddL, "caller resp."); // Get merge point xphi = incr->in(1); @@ -474,7 +474,7 @@ Node* PhaseIdealLoop::loop_iv_stride(Node* incr, IdealLoopTree* loop, Node*& xph return stride; } -PhiNode* PhaseIdealLoop::loop_iv_phi(Node* xphi, Node* phi_incr, Node* x, IdealLoopTree* loop) { +PhiNode* PhaseIdealLoop::loop_iv_phi(Node* xphi, Node* phi_incr, Node* x) { if (!xphi->is_Phi()) { return nullptr; // Too much math on the trip counter } @@ -1481,11 +1481,11 @@ void PhaseIdealLoop::check_counted_loop_shape(IdealLoopTree* loop, Node* x, Basi assert(incr != nullptr && incr->Opcode() == Op_Add(bt), "no incr"); Node* xphi = nullptr; - Node* stride = loop_iv_stride(incr, loop, xphi); + Node* stride = loop_iv_stride(incr, xphi); assert(stride != nullptr, "no stride"); - PhiNode* phi = loop_iv_phi(xphi, phi_incr, x, loop); + PhiNode* phi = loop_iv_phi(xphi, phi_incr, x); assert(phi != nullptr && phi->in(LoopNode::LoopBackControl) == incr, "No phi"); @@ -1650,7 +1650,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_ assert(incr->Opcode() == Op_Add(iv_bt), "wrong increment code"); Node* xphi = nullptr; - Node* stride = loop_iv_stride(incr, loop, xphi); + Node* stride = loop_iv_stride(incr, xphi); if (stride == nullptr) { return false; @@ -1664,7 +1664,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_ jlong stride_con = stride->get_integer_as_long(iv_bt); assert(stride_con != 0, "missed some peephole opt"); - PhiNode* phi = loop_iv_phi(xphi, phi_incr, x, loop); + PhiNode* phi = loop_iv_phi(xphi, phi_incr, x); if (phi == nullptr || (trunc1 == nullptr && phi->in(LoopNode::LoopBackControl) != incr) || diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 0f87ed6763d..7670f6c620e 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1280,8 +1280,8 @@ public: Node* loop_exit_control(Node* x, IdealLoopTree* loop); Node* loop_exit_test(Node* back_control, IdealLoopTree* loop, Node*& incr, Node*& limit, BoolTest::mask& bt, float& cl_prob); Node* loop_iv_incr(Node* incr, Node* x, IdealLoopTree* loop, Node*& phi_incr); - Node* loop_iv_stride(Node* incr, IdealLoopTree* loop, Node*& xphi); - PhiNode* loop_iv_phi(Node* xphi, Node* phi_incr, Node* x, IdealLoopTree* loop); + Node* loop_iv_stride(Node* incr, Node*& xphi); + PhiNode* loop_iv_phi(Node* xphi, Node* phi_incr, Node* x); bool is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_bt); diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 070749cfe1f..912d8452d21 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -4271,13 +4271,13 @@ bool PhaseIdealLoop::duplicate_loop_backedge(IdealLoopTree *loop, Node_List &old } assert(in->Opcode() == Op_AddI, "wrong increment code"); Node* xphi = nullptr; - Node* stride = loop_iv_stride(in, loop, xphi); + Node* stride = loop_iv_stride(in, xphi); if (stride == nullptr) { continue; } - PhiNode* phi = loop_iv_phi(xphi, nullptr, head, loop); + PhiNode* phi = loop_iv_phi(xphi, nullptr, head); if (phi == nullptr || (trunc1 == nullptr && phi->in(LoopNode::LoopBackControl) != incr) || (trunc1 != nullptr && phi->in(LoopNode::LoopBackControl) != trunc1)) { From 65fda5c02aeb1832bc88dc83ee8465cd8ad89179 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Fri, 6 Jun 2025 08:16:37 +0000 Subject: [PATCH 185/216] 8358593: Add ucontext accessors for *BSD on Aarch64 Co-authored-by: Greg Lewis Co-authored-by: Kurt Miller Reviewed-by: aph --- .../os_cpu/bsd_aarch64/os_bsd_aarch64.cpp | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp index ae352641516..ad32ee150e8 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp @@ -81,14 +81,12 @@ #endif #define SPELL_REG_SP "sp" -#define SPELL_REG_FP "fp" #ifdef __APPLE__ // see darwin-xnu/osfmk/mach/arm/_structs.h // 10.5 UNIX03 member name prefixes #define DU3_PREFIX(s, m) __ ## s.__ ## m -#endif #define context_x uc_mcontext->DU3_PREFIX(ss,x) #define context_fp uc_mcontext->DU3_PREFIX(ss,fp) @@ -97,6 +95,31 @@ #define context_pc uc_mcontext->DU3_PREFIX(ss,pc) #define context_cpsr uc_mcontext->DU3_PREFIX(ss,cpsr) #define context_esr uc_mcontext->DU3_PREFIX(es,esr) +#endif + +#ifdef __FreeBSD__ +# define context_x uc_mcontext.mc_gpregs.gp_x +# define context_fp context_x[REG_FP] +# define context_lr uc_mcontext.mc_gpregs.gp_lr +# define context_sp uc_mcontext.mc_gpregs.gp_sp +# define context_pc uc_mcontext.mc_gpregs.gp_elr +#endif + +#ifdef __NetBSD__ +# define context_x uc_mcontext.__gregs +# define context_fp uc_mcontext.__gregs[_REG_FP] +# define context_lr uc_mcontext.__gregs[_REG_LR] +# define context_sp uc_mcontext.__gregs[_REG_SP] +# define context_pc uc_mcontext.__gregs[_REG_ELR] +#endif + +#ifdef __OpenBSD__ +# define context_x sc_x +# define context_fp sc_x[REG_FP] +# define context_lr sc_lr +# define context_sp sc_sp +# define context_pc sc_elr +#endif #define REG_BCP context_x[22] @@ -497,9 +520,11 @@ int os::extra_bang_size_in_bytes() { return 0; } +#ifdef __APPLE__ void os::current_thread_enable_wx(WXMode mode) { pthread_jit_write_protect_np(mode == WXExec); } +#endif static inline void atomic_copy64(const volatile void *src, volatile void *dst) { *(jlong *) dst = *(const jlong *) src; From b2e7cda6a0bd21fa3c4ffe2a67da4953f1ca3f1f Mon Sep 17 00:00:00 2001 From: Fernando Guallini Date: Fri, 6 Jun 2025 09:53:25 +0000 Subject: [PATCH 186/216] 8358171: Additional code coverage for PEM API Reviewed-by: ascarpino --- test/jdk/java/security/PEM/PEMData.java | 221 +++++++++++++++--- .../jdk/java/security/PEM/PEMDecoderTest.java | 80 ++++++- .../jdk/java/security/PEM/PEMEncoderTest.java | 77 +++++- .../java/security/PEM/PEMMultiThreadTest.java | 97 ++++++++ .../security/PEM/java.security-anotherAlgo | 1 + .../java/security/PEM/java.security-emptyAlgo | 1 + .../EncryptedPrivateKeyInfo/EncryptKey.java | 45 ++++ .../EncryptedPrivateKeyInfo/GetKey.java | 33 ++- .../sun/security/pkcs/pkcs8/PKCS8Test.java | 15 +- .../jdk/test/lib/security/SecurityUtils.java | 6 +- 10 files changed, 533 insertions(+), 43 deletions(-) create mode 100644 test/jdk/java/security/PEM/PEMMultiThreadTest.java create mode 100644 test/jdk/java/security/PEM/java.security-anotherAlgo create mode 100644 test/jdk/java/security/PEM/java.security-emptyAlgo diff --git a/test/jdk/java/security/PEM/PEMData.java b/test/jdk/java/security/PEM/PEMData.java index e1f32cdbb7c..2c8c60fcccc 100644 --- a/test/jdk/java/security/PEM/PEMData.java +++ b/test/jdk/java/security/PEM/PEMData.java @@ -27,6 +27,7 @@ import javax.crypto.EncryptedPrivateKeyInfo; import java.security.DEREncodable; import java.security.KeyPair; import java.security.PEMRecord; +import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.*; import java.util.ArrayList; @@ -45,7 +46,7 @@ class PEMData { KwDdi3cNwu7YYD/QtJ+9+AEBdoqhRANCAASL+REY4vvAI9M3gonaml5K3lRgHq5w +OO4oO0VNduC44gUN1nrk7/wdNSpL+xXNEX52Dsff+2RD/fop224ANvB -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); public static final Entry rsapriv = new Entry("rsapriv", """ @@ -65,7 +66,68 @@ class PEMData { 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob WqcWcoJqfdLEyBT+ -----END PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); + + public static final Entry rsaCrtCoefZeroPriv = new Entry("rsaCrtCoefZeroPriv", + """ + -----BEGIN RSA PRIVATE KEY----- + MIIEIwIBAAKCAQEAuZAPiPMlA5R0oOIbxbq+gOmBRcvptIT+0pmG6rZ6H//r7A/Z + MRwen0iO2GuhlyUgOk9Fja/TMBrNX99boVDEZtL4oxRTJibdLNjfQqPeFhs3NNvv + CJJEGD91Dq/fGbWv1TMZcEywqqYSdERDEA7yluw87I7YZc9kXVBwRw5AedvoXOL/ + z5yPjK8W7FTCLHSVKiD/X3P3ZX9TmFjTIbRH15Do5sRxsPdrZczYjWdXFXNQEUuF + sVFGHFbB/AJiZlGYqMU+hEIErE35sHrKpZYkj9YovYQe0SBJyuROPl8wmz0Cd69s + rhg142Qf23RPhclBuCNAQQOkefeCppg4IFFh7QIDAQABAoIBADlKHlm4Q7m2uElB + dbSWwqEXNnefjJBUrT3E84/8dXjysNppTDNqzJN9uchcdn+tESWfeshTO97yr2yF + j4se3fwm72ed60vwnMFvVYKECBmIHoO90S8yxT49PT0jFDyiSN6IT7bJnpOZAUKP + HqtTCheJaQfZ1DqejIx4vKlbX5GfShwPQV0Q7KeKnfxhryhAbM5Y5UT8grQGBQU7 + aQUZuasQV10APVRaz39VU8/hzBc081LR3O0tjnZcrMAQ7ANsP9Gu3My04cnQ5WBo + P8uCCaSPSkrzCvjd9YYkdnwXMbVCfALOa+MxBddMi4IQG0qI28Bpw6dkKziPxage + KcAQnAsCgYEA0/CwzUlyrG6f+FF3uAvPVn/jEhWatJb7Me7lkhO3suV92brb1pQo + 1W1jHdx0OqMuCVfIJ4bXkTwKuvLQGcWJzNWUVh4Tij/ZAV0Ssw2cKbBSCQGNIFsx + Ux0V9tDSYJsEdk+Y5grloDNJokYYCCpF5bz/6QYmX+t3yzjyVSvcNeMCgYEA4COU + ezUXKLSWD+jJZXpS5yopB7oXAg7mmonlc1DRuaIxspwBrbXPLQ/neN8Sefpz9Nxn + 4ksPxGbLnJh0wGCnxSu0Qfn4eNVSsulag4IQmbCO2UBsdXNCJB5KlDpRlVhvvviH + Zpz2Dkdx+itLf1EV841MCtPAHZJwrs6i6JntEe8CgYEAgJYdjs+rJXcQ04YKDr4L + k72PtR8qd7rKuObqnhAcegvGqV03mB7YD3WIl0tzsUfj3INHysOC8njtQbOkEp7J + Fl/W2dDxpgVK0gr4F26AesKhYxlv2Fu7t2OEOfVETpx+vpFYgOnHm8TCPhQs7HdJ + ZTOgSG8UxUmFquToEkjEGGUCgYB6AMP8wKxHeuzH4iVl+EySCa/lxdRqSWQasH7V + 4yMVkYTNvP9o57LKy4Jql7n97Wca3LIrSkJd3LpuFcpPQQ1xVNW8p+0pEK0AN+cN + +ElC7wkCln+y+rcA5AAiaRApY8cHw04oe72vjhIrY0+oEKILPVkr95D2R9TQQigI + xmh1vwIBAA== + -----END RSA PRIVATE KEY----- + """, RSAPrivateKey.class, "SunRsaSign"); + + public static final Entry rsapsspriv = new Entry("rsapsspriv", + """ + -----BEGIN PRIVATE KEY----- + MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEAn3qFQtvj9JVqVPRh + mMMRyT17GiUY+NWOwUHx5bHqfhlHJoCllctSU/YXzrH4Da1w7sSeaMmAKYMW4X5k + rn9hnKOhgHnm2nkZBaVNQeyrseuDnfwWtLXjnj8rEKpgf9UPRUeXGRSoAb1qpwBf + epFtLSKZrzswZY2u2UEUGJERABi6Qp+cIZ8uXzBkIsMgrhb50xsdysZ9+qq95z0i + N1vh/V+Yi2fYpSYVDE8aMWdpvs0oWGvoLQjRgElJx/SknndAfLD42HPYZyyXevyJ + RgUf+NP0V7c+UtE7m7pgMs1hhxHSmUNdfH9GnOSg9m3+L3WqhaNNWB4aKMqFyhlM + EsAuawIDAQABAoIBAAMJ9yXIgeYEaN54j67fsg7nJIQ228HLc/5xGWvFQaYofidu + K87twm0GKKWlf4gR24U5QEQtPst2YNu9fav+PRJv4yEgcYqNOdxWg4veN4Fa7wr2 + JZ/zmARJHjLMRFgl67YSwKmCMBdkZXa24PA5et6cJQM7+gFIELe5b+lt7j3VsxQ7 + JpTJyp3I73lXcJrzcb/OCTxobFPLtkVSgKUNwae26xlNqXX4fQfLp99LHGnkmG3k + Wlzjs6dUi4fl4yLAJYMxEwxQbSbmY66ZKnM4SkT/YHx67gyJw2CMRp4FQDg94Sor + 0IDDKiSMGzcjuCuUl27/qTuv+iMgCqNB7CSPXtECgYEAvqN8ZuZXeUKz4tn6wxJk + k1utCl3pSM5PLMF4J43uvX49HF1i3svXrwxzJqug6kPXvB7cuB6U2DFIM3lh2jNE + u2w0U/5zVz2yEI9EaRjnOXePLsSWjOiC+5MGTafJWy5vZ8+zaWL9tjtUH5hsg1cB + ZMlXtWrI+AmAUAv6FFDZaHECgYEA1igXzRMGgXAT+YX0wdZQcRMy9jD5WIYIiCex + 6/WRE2LDM855ZBwTU5gyqZC2MWC3yn1ASDraxKdH1m3872Q0NVJfsOaLvBk1HuPk + dlSHRKO2GeO9m5/YzrZm9jpGs0IH6DKOah/t0aCd2CFxt6qef2wOUmXTCK6tyCXN + EiUmEpsCgYAMue85E1Ftl+VYVILn+Ndb+ve/RGupX5RrgXLa+R+h6MZ9mUJbazI3 + zlX1k+mHGgZR2aGUbP40vH18ajL9FQUWme+YV9ktTsIPVvETLwVokbGuRpNiTrdH + whXeoz/O5Xesb3Ijq+cR/j3sagl8bxd5ufMv+jP2UvQM4+/K4WbSEQKBgGuZeVvw + UzR1u5ODWpaJt6EYpGJN+PohXegLCbokh9/Vn35IH3XNJWi677mCnAfzMGTsyX+B + Eqn74nw6hvtAvXqNCMc5DrxTbf03Q3KwxcYW+0fGxV2L0sMJonHUlfE7G/3uaN+p + azQIH0aYhypg74HWKNv9jSqvmWEWnRKg16BBAoGAGLAqCRCP8wxqRVZZjhUJ+5JN + b6PrykDxCKhlA6JqZKuCYzvXhLABq/7miNDg0CmRREl+yKXlkEoFl4g9LtP7wfjX + n4us/WNmh+GPZYxlCJSNRTjgk7pm5TjVH5YWURDEnjIHZ7yxbAFlvNUhI1mF5g97 + KVcB4fjBitP1h8P+MoY= + -----END PRIVATE KEY----- + """, RSAPrivateKey.class, "SunRsaSign"); public static final Entry rsaprivbc = new Entry("rsaprivbc", """ @@ -85,14 +147,14 @@ class PEMData { 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob WqcWcoJqfdLEyBT+ -----END PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); public static final Entry ec25519priv = new Entry("ed25519priv", """ -----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I -----END PRIVATE KEY----- - """, EdECPrivateKey.class); + """, EdECPrivateKey.class, "SunEC"); public static final Entry rsapub = new Entry("rsapub", """ @@ -102,7 +164,20 @@ class PEMData { MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h XCYEHZS1cqd8wokFPwIDAQAB -----END PUBLIC KEY----- - """, RSAPublicKey.class); + """, RSAPublicKey.class, "SunRsaSign"); + + public static final Entry rsapsspub = new Entry("rsapsspub", + """ + -----BEGIN PUBLIC KEY----- + MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBAJ96hULb4/SValT0YZjDEck9 + exolGPjVjsFB8eWx6n4ZRyaApZXLUlP2F86x+A2tcO7EnmjJgCmDFuF+ZK5/YZyj + oYB55tp5GQWlTUHsq7Hrg538FrS1454/KxCqYH/VD0VHlxkUqAG9aqcAX3qRbS0i + ma87MGWNrtlBFBiREQAYukKfnCGfLl8wZCLDIK4W+dMbHcrGffqqvec9Ijdb4f1f + mItn2KUmFQxPGjFnab7NKFhr6C0I0YBJScf0pJ53QHyw+Nhz2Gcsl3r8iUYFH/jT + 9Fe3PlLRO5u6YDLNYYcR0plDXXx/RpzkoPZt/i91qoWjTVgeGijKhcoZTBLALmsC + AwEAAQ== + -----END PUBLIC KEY----- + """, RSAPublicKey.class, "SunRsaSign"); public static final Entry rsapubbc = new Entry("rsapubbc", """ @@ -112,14 +187,14 @@ class PEMData { MtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarbD6D4yRY1hWHluiuOtzhxuueCuf9h XCYEHZS1cqd8wokFPwIDAQAB -----END PUBLIC KEY----- - """, RSAPublicKey.class); + """, RSAPublicKey.class, "SunRsaSign"); public static final Entry ecsecp256pub = new Entry("ecsecp256pub", """ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/kRGOL7wCPTN4KJ2ppeSt5UYB6u cPjjuKDtFTXbguOIFDdZ65O/8HTUqS/sVzRF+dg7H3/tkQ/36KdtuADbwQ== -----END PUBLIC KEY----- - """, ECPublicKey.class); + """, ECPublicKey.class, "SunEC"); // EC key with explicit parameters -- Not currently supported by SunEC public static final String pubec_explicit = """ @@ -152,7 +227,7 @@ class PEMData { P4c4mySRy5N3plFQUp3pIB7wqshi1t6hkdg7gRGjMtJpIPIXynEqRy2mIw2GrKTtu3dqrW+ndarb D6D4yRY1hWHluiuOtzhxuueCuf9hXCYEHZS1cqd8wokFPwIDAQAB -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunRsaSign"); public static final Entry oasrfc8410 = new Entry("oasrfc8410", """ @@ -161,7 +236,24 @@ class PEMData { oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB Z9w7lshQhqowtrbLDFw4rXAxZuE= -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); + + public static final Entry oasxdh = new Entry("oasxdh", + """ + -----BEGIN PRIVATE KEY----- + MFECAQEwBQYDK2VuBCIEIIrMS7w5YxuBTyPFiaFvp6ILiGET7wY9ybk7Qqhe3hSq + gSEAB7ODPxRePrPnJMaj3f47blVx6c5bfxcllQzLp4bW5x4= + -----END PRIVATE KEY----- + """, KeyPair.class, "SunEC"); + + public static final Entry oasec = new Entry("oasec", + """ + -----BEGIN PRIVATE KEY----- + MIGFAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBCcwJQIBAQQgkGEVbZE1yAiO11Ya + eepcrBQL+HpVE4fy0V6jbpJcmkiBQgAERCqYYmN9uNT9Z1O2Z2VC3Zag9eUAhz7G + p8DqC21VrIgpqVQ4BrcWsieNg9fSd4N2hgfMpk9PCQwJQ8ifCMiBVQ== + -----END PRIVATE KEY----- + """, KeyPair.class, "SunEC"); public static final Entry rsaOpenSSL = new Entry("rsaOpenSSL", """ @@ -192,7 +284,7 @@ class PEMData { EcgIOtkvoTrJ9Cquvuj+O7/d2yNoH0SZQ4IYJKq47/Z4kKhwXzJnBCCCBKgkjfub RTQSNnSEgTaBD29l7FrhNRHX9lIKFZ23caCTBS6o3q3+KgPbq7ao -----END RSA PRIVATE KEY----- - """, RSAPrivateKey.class); + """, RSAPrivateKey.class, "SunRsaSign"); static final Entry ed25519ep8 = new Entry("ed25519ep8", """ @@ -202,11 +294,11 @@ class PEMData { vdMyi46+Dw7cOjwEQLtx5ME0NOOo7vlCGm3H/4j+Tf5UXrMb1UrkPjqc8OiLbC0n IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo= -----END ENCRYPTED PRIVATE KEY----- - """, EdECPrivateKey.class, "fish".toCharArray()); + """, EdECPrivateKey.class, "SunEC", "fish".toCharArray()); // This is not meant to be decrypted and to stay as an EKPI static final Entry ed25519ekpi = new Entry("ed25519ekpi", - ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, null); + ed25519ep8.pem(), EncryptedPrivateKeyInfo.class, "SunEC", null); static final Entry rsaCert = new Entry("rsaCert", """ @@ -237,7 +329,7 @@ class PEMData { 8gOYV33zkPhziWJt4uFMFIi7N2DLEk5UVZv1KTLZlfPl55DRs7j/Sb4vKHpB17AO meVknxVvifDVY0TIz57t28Accsk6ClBCxNPluPU/8YLGAZJYsdDXjGcndQ13s5G7 -----END CERTIFICATE----- - """, X509Certificate.class); + """, X509Certificate.class, "SUN"); static final Entry ecCert = new Entry("ecCert", """ @@ -249,7 +341,68 @@ class PEMData { lU3G9QAwCgYIKoZIzj0EAwIDSAAwRQIgMwYld7aBzkcRt9mn27YOed5+n0xN1y8Q VEcFjLI/tBYCIQDU3szDZ/PK2mUZwtgQxLqHdh+f1JY0UwQS6M8QUvoDHw== -----END CERTIFICATE----- - """, X509Certificate.class); + """, X509Certificate.class, "SUN"); + + private static final Entry rsaCrl = new Entry("rsaCrl", + """ + -----BEGIN X509 CRL----- + MIIBRTCBrwIBATANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQGEwJVUzEaMBgGA1UE + ChMRVGVzdCBDZXJ0aWZpY2F0ZXMxITAfBgNVBAMTGEJhc2ljIEhUVFAgVVJJIFBl + ZXIgMSBDQRcNMDUwNjAzMjE0NTQ3WhcNMTUwNjAxMjE0NTQ3WqAvMC0wHwYDVR0j + BBgwFoAUa+bxcvx1zVdUhvIEd9hcfbmFdw4wCgYDVR0UBAMCAQEwDQYJKoZIhvcN + AQEFBQADgYEAZ+21yt1pJn2FU6vBwpFtAKVeBCCCqJVFiRxT84XbUw0BpLrCFvlk + FOo6tC95aoV7vPGwOEyUNbKJJOCzLliIwV1PPfgZQV20xohSIPISHdUjmlyttglv + AuEvltGnbP7ENxw18HxvM20XmHz+akuFu6npI6MkBjfoxvlq1bcdTrI= + -----END X509 CRL----- + """, X509CRL.class, "SUN"); + + // Few random manipulated Base64 characters in PEM content + private static final Entry invalidDer = new Entry("invalidDER", """ + -----BEGIN PRIVATE KEY----- + MIICeAIBADANBhkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOtjMnCzPy4jCeZb + OdOvmvU3jl7+cvPFgL5MfqDCM5a8yI0yImg/hzibJJHLk3emUVBSnekgHvCqyGLW + 3qGR2DuBEaMy0mkg8hfKcSpHLaYjDYaspO27d2qtb6d1qtsPoPjJFjWFYeW6K463 + OHG654K5/2FcJgQdlLVyp3zCiQU/AgMBAAECgYEAwNkDkTv5rlX8nWLuLJV5kh/T + H9a93SRZxw8qy5Bv7bZ7ZNfHP7uUkHbi7iPojKWRhwo43692SdzR0dCSk7LGgN9q + CYvndsYR6gifVGBi0WF+St4+NdtcQ3VlNdsojy2BdIx0oC+r7i3bn+zc968O/kI+ + EgdgrMcjjFqyx6tMHpECQQD8TYPKGHyN7Jdy28llCoUX/sL/yZ2vIi5mnDAFE5ae + KZQSkNAXG+8i9Qbs/Wdd5S3oZDqu+6DBn9gib80pYY05AkEA7tY59Oy8ka7nBlGP + g6Wo1usF2bKqk8vjko9ioZQay7f86aB10QFcAjCr+cCUm16Lc9DwzWl02nNggRZa + Jz8eNwJBAO+1zfLjFOPb14F/JHdlaVKE8EwKCFDuztsapd0M4Vtf8Zk6ERsDpU63 + Ml9T2zOwnM9g+whpdjDAZ59ATdJ1JrECQQDReJQ2SxeL0lGPCiOLu9RcQp7L81aF + 79G1bgp8WlAyEjlAkloiqEWRKiz7DDuKFR7Lwhognng9S+n87aS+PS57AkBh75t8 + 6onPAs4hkm+63dfzCojvEkALevO8J3OVX7YS5q9J1r75wDn60Ob0Zh+iiorpx8Ob + WqcWcoJqfdLEyBT+ + -----END PRIVATE KEY----- + """, DEREncodable.class, null); + + private static final Entry invalidPEM = new Entry("invalidPEM", """ + -----BEGIN INVALID PEM----- + MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2 + GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8 + 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM + """, DEREncodable.class, null); + + private static final Entry invalidHeader = new Entry("invalidHeader", """ + ---BEGIN PRIVATE KEY--- + MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I + -----END PRIVATE KEY----- + """, DEREncodable.class, null); + + private static final Entry invalidFooter = new Entry("invalidFooter", """ + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIFFZsmD+OKk67Cigc84/2fWtlKsvXWLSoMJ0MHh4jI4I + ---END PRIVATE KEY--- + """, DEREncodable.class, null); + + private static final Entry incorrectFooter = new Entry("incorrectFooter", """ + -----BEGIN PRIVATE KEY----- + MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDBVS52ZSKZ0oES7twD2 + GGwRIVu3uHlGIwlu0xzFe7sgIPntca2bHfYMhgGxrlCm0q+hZANiAAQNWgwWfLX8 + 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM + 8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM= + -----END PUBLIC KEY----- + """, DEREncodable.class, null); // EC cert with explicit parameters -- Not currently supported by SunEC static final String ecCertEX = """ @@ -280,7 +433,7 @@ class PEMData { 8pYVjvwbfvDF9f+Oa9w6JjrfpWwFAUI6b1OPgrNUh+yXtUXnQNXnfUcIu0Os53bM 8fTqPkQl6RyWEDHeXqJK8zTBHMeBq9nLfDPSbzQgLDyC64Orn0D8exM= -----END PRIVATE KEY----- - """, KeyPair.class); + """, KeyPair.class, "SunEC"); public static final Entry ecCSR = new Entry("ecCSR", """ @@ -297,7 +450,7 @@ class PEMData { MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW -----END CERTIFICATE REQUEST----- - """, PEMRecord.class); + """, PEMRecord.class, "SunEC"); public static final String preData = "TEXT BLAH TEXT BLAH" + System.lineSeparator(); @@ -318,39 +471,41 @@ class PEMData { MQYMBGZpc2gwCgYIKoZIzj0EAwIDRwAwRAIgUBTdrMDE4BqruYRh1rRyKQBf48WR kIX8R4dBK9h1VRcCIEBR2Mzvku/huTbWTwKVlXBZeEmwIlxKwpRepPtViXcW -----END CERTIFICATE REQUEST----- - """ + postData, PEMRecord.class); + """ + postData, PEMRecord.class, "SunEC"); final static Pattern CR = Pattern.compile("\r"); final static Pattern LF = Pattern.compile("\n"); final static Pattern LSDEFAULT = Pattern.compile(System.lineSeparator()); - public record Entry(String name, String pem, Class clazz, char[] password, + public record Entry(String name, String pem, Class clazz, String provider, char[] password, byte[] der) { - public Entry(String name, String pem, Class clazz, char[] password, + public Entry(String name, String pem, Class clazz, String provider, char[] password, byte[] der) { this.name = name; this.pem = pem; this.clazz = clazz; + this.provider = provider; this.password = password; - if (pem != null && pem.length() > 0) { + if (pem != null && pem.length() > 0 && + !name.contains("incorrect") && !name.contains("invalid")) { String[] pemtext = pem.split("-----"); this.der = Base64.getMimeDecoder().decode(pemtext[2]); } else { this.der = null; } } - Entry(String name, String pem, Class clazz, char[] password) { - this(name, pem, clazz, password, null); + Entry(String name, String pem, Class clazz, String provider, char[] password) { + this(name, pem, clazz, provider, password, null); } - Entry(String name, String pem, Class clazz) { - this(name, pem, clazz, null, null); + Entry(String name, String pem, Class clazz, String provider) { + this(name, pem, clazz, provider, null, null); } public Entry newClass(String name, Class c) { - return new Entry(name, pem, c, password); + return new Entry(name, pem, c, provider, password); } public Entry newClass(Class c) { @@ -360,20 +515,20 @@ class PEMData { Entry makeCRLF(String name) { return new Entry(name, Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r\n"), - clazz, password()); + clazz, provider, password()); } Entry makeCR(String name) { return new Entry(name, Pattern.compile(System.lineSeparator()).matcher(pem).replaceAll("\r"), - clazz, password()); + clazz, provider, password()); } Entry makeNoCRLF(String name) { return new Entry(name, LF.matcher(CR.matcher(pem).replaceAll("")). replaceAll(""), - clazz, password()); + clazz, provider, password()); } } @@ -401,10 +556,12 @@ class PEMData { static { pubList.add(rsapub); + pubList.add(rsapsspub); pubList.add(rsapubbc); pubList.add(ecsecp256pub.makeCR("ecsecp256pub-r")); pubList.add(ecsecp256pub.makeCRLF("ecsecp256pub-rn")); privList.add(rsapriv); + privList.add(rsapsspriv); privList.add(rsaprivbc); privList.add(ecsecp256); privList.add(ecsecp384); @@ -413,9 +570,12 @@ class PEMData { privList.add(rsaOpenSSL); oasList.add(oasrfc8410); oasList.add(oasbcpem); + oasList.add(oasec); + oasList.add(oasxdh); certList.add(rsaCert); certList.add(ecCert); + certList.add(rsaCrl); entryList.addAll(pubList); entryList.addAll(privList); @@ -429,6 +589,11 @@ class PEMData { failureEntryList.add(new Entry("emptyPEM", "", DEREncodable.class, null)); failureEntryList.add(new Entry("nullPEM", null, DEREncodable.class, null)); + failureEntryList.add(incorrectFooter); + failureEntryList.add(invalidPEM); + failureEntryList.add(invalidDer); + failureEntryList.add(invalidHeader); + failureEntryList.add(invalidFooter); } static void checkResults(PEMData.Entry entry, String result) { diff --git a/test/jdk/java/security/PEM/PEMDecoderTest.java b/test/jdk/java/security/PEM/PEMDecoderTest.java index 2ee9d1a69b3..90d67af2f8d 100644 --- a/test/jdk/java/security/PEM/PEMDecoderTest.java +++ b/test/jdk/java/security/PEM/PEMDecoderTest.java @@ -26,6 +26,7 @@ /* * @test * @bug 8298420 + * @library /test/lib * @modules java.base/sun.security.pkcs * java.base/sun.security.util * @summary Testing basic PEM API decoding @@ -37,23 +38,27 @@ import java.io.*; import java.lang.Class; import java.nio.charset.StandardCharsets; import java.security.*; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.interfaces.*; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; +import java.security.spec.*; import java.util.*; import java.util.Arrays; +import jdk.test.lib.Asserts; +import sun.security.pkcs.PKCS8Key; import sun.security.util.Pem; public class PEMDecoderTest { static HexFormat hex = HexFormat.of(); - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { System.out.println("Decoder test:"); - PEMData.entryList.forEach(PEMDecoderTest::test); + PEMData.entryList.forEach(entry -> test(entry, false)); + System.out.println("Decoder test withFactory:"); + PEMData.entryList.forEach(entry -> test(entry, true)); System.out.println("Decoder test returning DEREncodable class:"); PEMData.entryList.forEach(entry -> test(entry, DEREncodable.class)); System.out.println("Decoder test with encrypted PEM:"); @@ -95,7 +100,11 @@ public class PEMDecoderTest { System.out.println("Check a Signature/Verify op is successful:"); PEMData.privList.forEach(PEMDecoderTest::testSignature); - PEMData.oasList.forEach(PEMDecoderTest::testSignature); + PEMData.oasList.stream().filter(e -> !e.name().endsWith("xdh")) + .forEach(PEMDecoderTest::testSignature); + + System.out.println("Checking if decode() returns a PKCS8Key and can generate a pub"); + PEMData.oasList.forEach(PEMDecoderTest::testPKCS8Key); System.out.println("Checking if ecCSR:"); test(PEMData.ecCSR); @@ -182,6 +191,10 @@ public class PEMDecoderTest { } catch (Exception e) { throw new AssertionError("error getting key", e); } + testCertTypeConverter(PEMData.ecCert); + + System.out.println("Decoder test testCoefZero:"); + testCoefZero(PEMData.rsaCrtCoefZeroPriv); } static void testInputStream() throws IOException { @@ -231,6 +244,24 @@ public class PEMDecoderTest { throw new AssertionError("Failed"); } + // test that X509 CERTIFICATE is converted to CERTIFICATE in PEM + static void testCertTypeConverter(PEMData.Entry entry) throws CertificateEncodingException { + String certPem = entry.pem().replace("CERTIFICATE", "X509 CERTIFICATE"); + Asserts.assertEqualsByteArray(entry.der(), + PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded()); + + certPem = entry.pem().replace("CERTIFICATE", "X.509 CERTIFICATE"); + Asserts.assertEqualsByteArray(entry.der(), + PEMDecoder.of().decode(certPem, X509Certificate.class).getEncoded()); + } + + // test that when the crtCoeff is zero, the key is decoded but only the modulus and private + // exponent are used resulting in a different der + static void testCoefZero(PEMData.Entry entry) { + RSAPrivateKey decoded = PEMDecoder.of().decode(entry.pem(), RSAPrivateKey.class); + Asserts.assertNotEqualsByteArray(decoded.getEncoded(), entry.der()); + } + static void testPEMRecord(PEMData.Entry entry) { PEMRecord r = PEMDecoder.of().decode(entry.pem(), PEMRecord.class); String expected = entry.pem().split("-----")[2].replace(System.lineSeparator(), ""); @@ -333,13 +364,26 @@ public class PEMDecoderTest { // Change the Entry to use the given class as the expected class returned static DEREncodable test(PEMData.Entry entry, Class c) { - return test(entry.newClass(c)); + return test(entry.newClass(c), false); } // Run test with a given Entry static DEREncodable test(PEMData.Entry entry) { + return test(entry, false); + } + + // Run test with a given Entry + static DEREncodable test(PEMData.Entry entry, boolean withFactory) { + System.out.printf("Testing %s %s%n", entry.name(), entry.provider()); try { - DEREncodable r = test(entry.pem(), entry.clazz(), PEMDecoder.of()); + PEMDecoder pemDecoder; + if (withFactory) { + Provider provider = Security.getProvider(entry.provider()); + pemDecoder = PEMDecoder.of().withFactory(provider); + } else { + pemDecoder = PEMDecoder.of(); + } + DEREncodable r = test(entry.pem(), entry.clazz(), pemDecoder); System.out.println("PASS (" + entry.name() + ")"); return r; } catch (Exception | AssertionError e) { @@ -412,6 +456,19 @@ public class PEMDecoderTest { } } + private static void testPKCS8Key(PEMData.Entry entry) { + try { + PKCS8Key key = PEMDecoder.of().decode(entry.pem(), PKCS8Key.class); + PKCS8EncodedKeySpec spec = + new PKCS8EncodedKeySpec(key.getEncoded()); + + KeyFactory kf = KeyFactory.getInstance(key.getAlgorithm()); + kf.generatePublic(spec); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + static void testClass(PEMData.Entry entry, Class clazz) throws IOException { var pk = PEMDecoder.of().decode(entry.pem(), clazz); } @@ -472,9 +529,15 @@ public class PEMDecoderTest { "should not be null"); } + AlgorithmParameterSpec spec = null; String algorithm = switch(privateKey.getAlgorithm()) { case "EC" -> "SHA256withECDSA"; case "EdDSA" -> "EdDSA"; + case "RSASSA-PSS" -> { + spec = new PSSParameterSpec( + "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1); + yield "RSASSA-PSS"; + } case null -> { System.out.println("Algorithm is null " + entry.name()); @@ -487,6 +550,9 @@ public class PEMDecoderTest { try { if (d instanceof PrivateKey) { s = Signature.getInstance(algorithm); + if (spec != null) { + s.setParameter(spec); + } s.initSign(privateKey); s.update(data); s.sign(); diff --git a/test/jdk/java/security/PEM/PEMEncoderTest.java b/test/jdk/java/security/PEM/PEMEncoderTest.java index c8b19c313a5..3d1948ba2fe 100644 --- a/test/jdk/java/security/PEM/PEMEncoderTest.java +++ b/test/jdk/java/security/PEM/PEMEncoderTest.java @@ -26,9 +26,15 @@ /* * @test * @bug 8298420 + * @library /test/lib * @summary Testing basic PEM API encoding * @enablePreview * @modules java.base/sun.security.util + * @run main PEMEncoderTest PBEWithHmacSHA256AndAES_128 + * @run main/othervm -Djava.security.properties=${test.src}/java.security-anotherAlgo + * PEMEncoderTest PBEWithHmacSHA512AndAES_256 + * @run main/othervm -Djava.security.properties=${test.src}/java.security-emptyAlgo + * PEMEncoderTest PBEWithHmacSHA256AndAES_128 */ import sun.security.util.Pem; @@ -39,13 +45,22 @@ import javax.crypto.spec.PBEParameterSpec; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidParameterSpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import java.util.*; +import jdk.test.lib.security.SecurityUtils; + +import static jdk.test.lib.Asserts.assertEquals; +import static jdk.test.lib.Asserts.assertThrows; + public class PEMEncoderTest { static Map keymap; + static String pkcs8DefaultAlgExpect; public static void main(String[] args) throws Exception { + pkcs8DefaultAlgExpect = args[0]; PEMEncoder encoder = PEMEncoder.of(); // These entries are removed @@ -63,7 +78,12 @@ public class PEMEncoderTest { System.out.println("New instance re-encode testToString:"); keymap.keySet().stream().forEach(key -> testToString(key, PEMEncoder.of())); - + System.out.println("Same instance Encoder testEncodedKeySpec:"); + testEncodedKeySpec(encoder); + System.out.println("New instance Encoder testEncodedKeySpec:"); + testEncodedKeySpec(PEMEncoder.of()); + System.out.println("Same instance Encoder testEmptyKey:"); + testEmptyAndNullKey(encoder); keymap = generateObjKeyMap(PEMData.encryptedList); System.out.println("Same instance Encoder match test:"); keymap.keySet().stream().forEach(key -> testEncryptedMatch(key, encoder)); @@ -86,6 +106,13 @@ public class PEMEncoderTest { PEMRecord pemRecord = d.decode(PEMData.ed25519ep8.pem(), PEMRecord.class); PEMData.checkResults(PEMData.ed25519ep8, pemRecord.toString()); + + // test PemRecord is encapsulated with PEM header and footer on encoding + String[] pemLines = PEMData.ed25519ep8.pem().split("\n"); + String[] pemNoHeaderFooter = Arrays.copyOfRange(pemLines, 1, pemLines.length - 1); + PEMRecord pemR = new PEMRecord("ENCRYPTED PRIVATE KEY", String.join("\n", + pemNoHeaderFooter)); + PEMData.checkResults(PEMData.ed25519ep8.pem(), encoder.encodeToString(pemR)); } static Map generateObjKeyMap(List list) { @@ -145,10 +172,12 @@ public class PEMEncoderTest { static void testEncrypted(String key, PEMEncoder encoder) { PEMData.Entry entry = PEMData.getEntry(key); try { - encoder.withEncryption( + String pem = encoder.withEncryption( (entry.password() != null ? entry.password() : "fish".toCharArray())) .encodeToString(keymap.get(key)); + + verifyEncriptionAlg(pem); } catch (RuntimeException e) { throw new AssertionError("Encrypted encoder failed with " + entry.name(), e); @@ -157,6 +186,11 @@ public class PEMEncoderTest { System.out.println("PASS: " + entry.name()); } + private static void verifyEncriptionAlg(String pem) { + var epki = PEMDecoder.of().decode(pem, EncryptedPrivateKeyInfo.class); + assertEquals(epki.getAlgName(), pkcs8DefaultAlgExpect); + } + /* Test cannot verify PEM was the same as known PEM because we have no public access to the AlgoritmID.params and PBES2Parameters. @@ -195,5 +229,42 @@ public class PEMEncoderTest { PEMData.checkResults(entry, result); System.out.println("PASS: " + entry.name()); } -} + static void testEncodedKeySpec(PEMEncoder encoder) throws NoSuchAlgorithmException { + KeyPair kp = getKeyPair(); + encoder.encodeToString(new X509EncodedKeySpec(kp.getPublic().getEncoded())); + encoder.encodeToString(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded())); + System.out.println("PASS: testEncodedKeySpec"); + } + private static void testEmptyAndNullKey(PEMEncoder encoder) throws NoSuchAlgorithmException { + KeyPair kp = getKeyPair(); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(kp.getPublic(), new EmptyKey()))); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(kp.getPublic(), null))); + + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(new EmptyKey(), kp.getPrivate()))); + assertThrows(IllegalArgumentException.class, () -> encoder.encode( + new KeyPair(null, kp.getPrivate()))); + System.out.println("PASS: testEmptyKey"); + } + + private static KeyPair getKeyPair() throws NoSuchAlgorithmException { + Provider provider = Security.getProvider("SunRsaSign"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider); + kpg.initialize(SecurityUtils.getTestKeySize("RSA")); + return kpg.generateKeyPair(); + } + + private static class EmptyKey implements PublicKey, PrivateKey { + @Override + public String getAlgorithm() { return "Test"; } + + @Override + public String getFormat() { return "Test"; } + + @Override + public byte[] getEncoded() { return new byte[0]; } + } +} diff --git a/test/jdk/java/security/PEM/PEMMultiThreadTest.java b/test/jdk/java/security/PEM/PEMMultiThreadTest.java new file mode 100644 index 00000000000..f345a3c129d --- /dev/null +++ b/test/jdk/java/security/PEM/PEMMultiThreadTest.java @@ -0,0 +1,97 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8298420 + * @library /test/lib + * @summary Testing PEM API is thread safe + * @enablePreview + * @modules java.base/sun.security.util + */ + +import java.security.*; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import jdk.test.lib.security.SecurityUtils; + +public class PEMMultiThreadTest { + static final int THREAD_COUNT = 5; + static final int KEYS_COUNT = 50; + + public static void main(String[] args) throws Exception { + PEMEncoder encoder = PEMEncoder.of(); + try (ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT)) { + Map keys = new HashMap<>(); + Map encoded = Collections.synchronizedMap(new HashMap<>()); + Map decoded = Collections.synchronizedMap(new HashMap<>()); + final CountDownLatch encodingComplete = new CountDownLatch(KEYS_COUNT); + final CountDownLatch decodingComplete = new CountDownLatch(KEYS_COUNT); + + // Generate keys and encode them in parallel + for (int i = 0; i < KEYS_COUNT; i++) { + final int finalI = i; + KeyPair kp = getKeyPair(); + keys.put(finalI, kp.getPublic()); + + ex.submit(() -> { + encoded.put(finalI, encoder.encodeToString(kp.getPublic())); + encodingComplete.countDown(); + }); + } + encodingComplete.await(); + + // Decode keys in parallel + PEMDecoder decoder = PEMDecoder.of(); + for (Map.Entry entry : encoded.entrySet()) { + ex.submit(() -> { + decoded.put(entry.getKey(), decoder.decode(entry.getValue(), PublicKey.class) + .toString()); + decodingComplete.countDown(); + }); + } + decodingComplete.await(); + + // verify all keys were properly encoded and decoded comparing with the original key map + for (Map.Entry kp : keys.entrySet()) { + if (!decoded.get(kp.getKey()).equals(kp.getValue().toString())) { + throw new RuntimeException("a key was not properly encoded and decoded: " + decoded); + } + } + } + + System.out.println("PASS: testThreadSafety"); + } + + private static KeyPair getKeyPair() throws NoSuchAlgorithmException { + String alg = "EC"; + KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg); + kpg.initialize(SecurityUtils.getTestKeySize(alg)); + return kpg.generateKeyPair(); + } +} diff --git a/test/jdk/java/security/PEM/java.security-anotherAlgo b/test/jdk/java/security/PEM/java.security-anotherAlgo new file mode 100644 index 00000000000..c084f465fa2 --- /dev/null +++ b/test/jdk/java/security/PEM/java.security-anotherAlgo @@ -0,0 +1 @@ +jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA512AndAES_256 diff --git a/test/jdk/java/security/PEM/java.security-emptyAlgo b/test/jdk/java/security/PEM/java.security-emptyAlgo new file mode 100644 index 00000000000..deb2ab7aa45 --- /dev/null +++ b/test/jdk/java/security/PEM/java.security-emptyAlgo @@ -0,0 +1 @@ +jdk.epkcs8.defaultAlgorithm= diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java index d1fccd9730a..3fe8cfcfbfa 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/EncryptKey.java @@ -25,11 +25,15 @@ /** * @test + * @library /test/lib + * @modules java.base/sun.security.util * @bug 8298420 * @summary Testing encryptKey * @enablePreview */ +import sun.security.util.Pem; + import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; import javax.crypto.spec.PBEParameterSpec; @@ -37,8 +41,13 @@ import javax.crypto.spec.SecretKeySpec; import java.security.AlgorithmParameters; import java.security.PEMDecoder; import java.security.PrivateKey; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; import java.util.Arrays; +import static jdk.test.lib.Asserts.assertEquals; + public class EncryptKey { private static final String encEdECKey = @@ -56,6 +65,8 @@ public class EncryptKey { passwdText.getBytes(), "PBE"); public static void main(String[] args) throws Exception { + Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey, EncryptedPrivateKeyInfo.class); PrivateKey priKey = PEMDecoder.of().withDecryption(password). @@ -71,6 +82,19 @@ public class EncryptKey { " with expected."); } + // Test encryptKey(PrivateKey, char[], String, ...) with provider + e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, char[], String, ...) with provider and null algorithm + e = EncryptedPrivateKeyInfo.encryptKey(priKey, password, null, null, + p); + assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO); + // Test encryptKey(PrivateKey, Key, String, ...) e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), ap.getParameterSpec(PBEParameterSpec.class),null, null); @@ -78,5 +102,26 @@ public class EncryptKey { throw new AssertionError("encryptKey() didn't match" + " with expected."); } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and null random + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p, null); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and SecureRandom + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, ekpi.getAlgName(), + ap.getParameterSpec(PBEParameterSpec.class), p, new SecureRandom()); + if (!Arrays.equals(ekpi.getEncryptedData(), e.getEncryptedData())) { + throw new AssertionError("encryptKey() didn't match" + + " with expected."); + } + + // Test encryptKey(PrivateKey, Key, String, ...) with provider and null algorithm + e = EncryptedPrivateKeyInfo.encryptKey(priKey, key, null, null, + p, new SecureRandom()); + assertEquals(e.getAlgName(), Pem.DEFAULT_ALGO); } } diff --git a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java index 7c8951b3417..b1917ffa84d 100644 --- a/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java +++ b/test/jdk/javax/crypto/EncryptedPrivateKeyInfo/GetKey.java @@ -35,6 +35,8 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.PEMDecoder; import java.security.PrivateKey; +import java.security.Provider; +import java.security.Security; import java.util.Arrays; public class GetKey { @@ -48,12 +50,29 @@ public class GetKey { IycFtI70ciPjgwDSjtCcPxR8fSxJPrm2yOJsRVo= -----END ENCRYPTED PRIVATE KEY----- """; + private static final String encDHECKey = + """ + -----BEGIN ENCRYPTED PRIVATE KEY----- + MIIBvDBmBgkqhkiG9w0BBQ0wWTA4BgkqhkiG9w0BBQwwKwQUN8pkErJx7aqH0fJF + BcOadPKiuRoCAhAAAgEQMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBAT1Vwd + gU4rTd6zy7lKr4wmBIIBUMe+2+O0AG6t4CMSHcDVceRg2jvbs5PmPjW4Ka5mDich + hVEsjSpJLbUyJdbji6UaiUpuWgvYSMLZ10pfhOFw/ssXwCw+JrlXUqDpQGLaW8ZR + zSL3CoozTI2Y6EBdWt53KbySwtZMoTpW/W3vPi98bJXtR635msf6gYXmSUP7DyoJ + 79dxz3pRYsnOuBe0yZ2wTq9iMgTMudzLJAFX2qyi+3KOb1g5Va9DYAqJmzCYOd74 + +I+0gGNFtSc1vGQYr3cAfcKT8AZ1RHE4IkpnpgFD5HsZ8f4hy0yK8juk9NE9Gzuy + B929LBXk6V3L0MKzIABS3QvAlhWETM6XtGBDugzAgsooo9lEHLwYRldvOlL+QYyE + CtqDmXOrgEMWvxWGEFCTKYhKkqMKjU3y3GiozEEdb9j2okW1s30yHQjIoj0OR4nB + D8GeP0QnY73NfbOw7z81TA== + -----END ENCRYPTED PRIVATE KEY----- + """; private static final String passwdText = "fish"; private static final char[] password = passwdText.toCharArray(); private static final SecretKey key = new SecretKeySpec( passwdText.getBytes(), "PBE"); public static void main(String[] args) throws Exception { + Provider p = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + EncryptedPrivateKeyInfo ekpi = PEMDecoder.of().decode(encEdECKey, EncryptedPrivateKeyInfo.class); PrivateKey priKey = PEMDecoder.of().withDecryption(password). @@ -66,11 +85,23 @@ public class GetKey { + "match with expected."); } - // Test getKey(key, provider) + // Test getKey(key, provider) provider null if (!Arrays.equals(priKey.getEncoded(), ekpi.getKey(key, null).getEncoded())) { throw new AssertionError("getKey(key, provider) " + "didn't match with expected."); } + + // Test getKey(key, provider) with provider + EncryptedPrivateKeyInfo ekpiDH = PEMDecoder.of().decode(encDHECKey, + EncryptedPrivateKeyInfo.class); + PrivateKey priKeyDH = PEMDecoder.of().withDecryption(password). + decode(encDHECKey, PrivateKey.class); + + if (!Arrays.equals(priKeyDH.getEncoded(), + ekpiDH.getKey(key, p).getEncoded())) { + throw new AssertionError("getKey(key, provider) " + + "didn't match with expected."); + } } } diff --git a/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java b/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java index 49cca69971f..9bb5502ad9f 100644 --- a/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java +++ b/test/jdk/sun/security/pkcs/pkcs8/PKCS8Test.java @@ -31,10 +31,13 @@ * java.base/sun.security.provider * java.base/sun.security.x509 * @run main PKCS8Test + * @run main/othervm -Dtest.provider.name=SunJCE PKCS8Test */ import java.math.BigInteger; import java.security.InvalidKeyException; +import java.security.Provider; +import java.security.Security; import java.util.Arrays; import java.util.HexFormat; @@ -45,6 +48,7 @@ import sun.security.provider.DSAPrivateKey; public class PKCS8Test { + static Provider provider; static final String FORMAT = "PKCS#8"; static final String EXPECTED_ALG_ID_CHRS = "DSA, \n" + "\tp: 02\n\tq: 03\n\tg: 04\n"; @@ -59,7 +63,7 @@ public class PKCS8Test { "0403020101"); // PrivateKey OCTET int x = 1 public static void main(String[] args) throws Exception { - + provider = Security.getProvider(System.getProperty("test.provider.name")); byte[] encodedKey = new DSAPrivateKey( BigInteger.valueOf(1), BigInteger.valueOf(2), @@ -73,7 +77,8 @@ public class PKCS8Test { .toString(encodedKey)); } - PKCS8Key decodedKey = (PKCS8Key)PKCS8Key.parseKey(encodedKey); + PKCS8Key decodedKey = provider == null ? (PKCS8Key)PKCS8Key.parseKey(encodedKey) : + (PKCS8Key)PKCS8Key.parseKey(encodedKey, provider); assert(ALGORITHM.equalsIgnoreCase(decodedKey.getAlgorithm())); assert(FORMAT.equalsIgnoreCase(decodedKey.getFormat())); @@ -126,7 +131,11 @@ public class PKCS8Test { original[1] = (byte) (length - 2); // the length field inside DER original[4] = (byte) newVersion; // the version inside DER try { - PKCS8Key.parseKey(original); + if (provider == null) { + PKCS8Key.parseKey(original); + } else { + PKCS8Key.parseKey(original, provider); + } } catch (InvalidKeyException e) { throw new RuntimeException(e); } diff --git a/test/lib/jdk/test/lib/security/SecurityUtils.java b/test/lib/jdk/test/lib/security/SecurityUtils.java index 7509488225e..be6ff1cc0e3 100644 --- a/test/lib/jdk/test/lib/security/SecurityUtils.java +++ b/test/lib/jdk/test/lib/security/SecurityUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -45,6 +45,8 @@ public final class SecurityUtils { private enum KeySize{ RSA(2048), DSA(2048), + Ed25519(256), + EC(256), DH(2048); private final int keySize; @@ -145,6 +147,8 @@ public final class SecurityUtils { return switch (algo) { case "RSA" -> KeySize.RSA.keySize; case "DSA" -> KeySize.DSA.keySize; + case "Ed25519" -> KeySize.Ed25519.keySize; + case "EC" -> KeySize.EC.keySize; case "DH", "DiffieHellman" -> KeySize.DH.keySize; default -> throw new RuntimeException("Test key size not defined for " + algo); }; From 9658cecde34a6e9cd39656d21a4ae8bc42da5956 Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Fri, 6 Jun 2025 13:59:17 +0000 Subject: [PATCH 187/216] 8358685: [TEST] AOTLoggingTag.java failed with missing log message Reviewed-by: iklam, shade --- .../runtime/cds/appcds/aotCache/AOTLoggingTag.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java index 5499063ebbd..896df7ca496 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java @@ -34,7 +34,6 @@ * @run driver AOTLoggingTag */ -import java.io.File; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.helpers.ClassFileInstaller; import jdk.test.lib.process.OutputAnalyzer; @@ -59,7 +58,7 @@ public class AOTLoggingTag { "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "train"); - out.shouldContain("[info][aot] Writing binary AOTConfiguration file:"); + out.shouldContain("[aot] Writing binary AOTConfiguration file:"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -71,7 +70,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); - out.shouldContain("[info][aot] Opened AOT configuration file hello.aotconfig"); + out.shouldContain("[aot] Opened AOT configuration file hello.aotconfig"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -81,7 +80,7 @@ public class AOTLoggingTag { "-Xlog:aot", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[info][aot] Opened AOT cache hello.aot"); + out.shouldContain("[aot] Opened AOT cache hello.aot"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -92,7 +91,7 @@ public class AOTLoggingTag { "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); out.shouldNotContain("No tag set matches selection: aot+heap"); - out.shouldContain("[info][aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); + out.shouldContain("[aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); out.shouldHaveExitValue(0); //---------------------------------------------------------------------- @@ -102,7 +101,7 @@ public class AOTLoggingTag { "-XX:AOTMode=on", "-cp", appJar, helloClass); out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldContain("[error][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); + out.shouldContain("[aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details."); out.shouldNotHaveExitValue(0); } From 8adb052b46f90e8a0605cfc5ddc667acb7c61952 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 6 Jun 2025 14:11:27 +0000 Subject: [PATCH 188/216] 8341778: Some javac tests ignore the result of JavacTask::call Reviewed-by: shade --- .../gc/g1/unloading/GenClassPoolJar.java | 4 ++- test/langtools/tools/javac/T6358024.java | 4 ++- test/langtools/tools/javac/T6358166.java | 4 ++- test/langtools/tools/javac/T6361619.java | 7 +++-- test/langtools/tools/javac/T6395974.java | 4 ++- test/langtools/tools/javac/T6397286.java | 1 + .../tools/javac/T6458823/T6458823.java | 4 ++- .../TryWithResources/TwrAvoidNullCheck.java | 4 ++- .../TryWithResources/TwrSimpleClose.java | 4 ++- .../tools/javac/api/6406133/T6406133.java | 4 ++- .../tools/javac/api/6410643/T6410643.java | 1 + .../tools/javac/api/6412656/T6412656.java | 4 ++- .../tools/javac/api/6423003/T6423003.java | 3 +- .../tools/javac/api/6731573/T6731573.java | 4 ++- .../tools/javac/api/7086261/T7086261.java | 4 ++- .../tools/javac/api/8007344/Test.java | 19 +++++++++--- test/langtools/tools/javac/api/DiagSpans.java | 30 ++++++++++++------- test/langtools/tools/javac/api/T6357331.java | 4 ++- .../tools/javac/api/TestTreePath.java | 4 ++- .../api/taskListeners/EventsBalancedTest.java | 4 ++- .../ImproveFatalErrorHandling.java | 4 ++- test/langtools/tools/javac/lib/DPrinter.java | 4 ++- .../tools/javac/modules/QueryBeforeEnter.java | 4 ++- .../patterns/SOEDeeplyNestedBlocksTest.java | 6 ++-- .../tools/javac/positions/TreeEndPosTest.java | 4 ++- .../javac/processing/6348499/T6348499.java | 4 ++- .../javac/processing/6414633/T6414633.java | 4 ++- .../javac/processing/6430209/T6430209.java | 4 ++- .../tools/javac/processing/T6439826.java | 4 ++- .../tools/javac/processing/T8142931.java | 4 ++- .../processing/model/LocalInAnonymous.java | 12 ++++++-- .../options/TestNoteOnImplicitProcessing.java | 8 +++-- .../processing/rounds/CompleteOnClosed.java | 4 ++- 33 files changed, 135 insertions(+), 48 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java index fb3fb4d0e8e..cea00fc2efc 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java +++ b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassPoolJar.java @@ -187,7 +187,9 @@ public class GenClassPoolJar { StandardJavaFileManager sjfm = compiler.getStandardFileManager(null, null, null); Iterable fileObjects = sjfm.getJavaFileObjects(files); JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, optionList, null, fileObjects); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } sjfm.close(); } diff --git a/test/langtools/tools/javac/T6358024.java b/test/langtools/tools/javac/T6358024.java index 86bc37afda9..7388ce55cef 100644 --- a/test/langtools/tools/javac/T6358024.java +++ b/test/langtools/tools/javac/T6358024.java @@ -87,7 +87,9 @@ public class T6358024 extends AbstractProcessor { Arrays.asList(f)); MyTaskListener tl = new MyTaskListener(); task.setTaskListener(tl); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (tl.started != expect) throw new AssertionError("Unexpected number of TaskListener events; " + "expected " + expect + ", found " + tl.started); diff --git a/test/langtools/tools/javac/T6358166.java b/test/langtools/tools/javac/T6358166.java index e1aa2e00bbf..d3d4b2ae162 100644 --- a/test/langtools/tools/javac/T6358166.java +++ b/test/langtools/tools/javac/T6358166.java @@ -75,7 +75,9 @@ public class T6358166 extends AbstractProcessor { JavacTool tool = JavacTool.create(); JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, allArgs, null, List.of(f), context); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } JavaCompiler c = JavaCompiler.instance(context); if (c.errorCount() != 0) diff --git a/test/langtools/tools/javac/T6361619.java b/test/langtools/tools/javac/T6361619.java index 67450129e3e..1f299a8f4c3 100644 --- a/test/langtools/tools/javac/T6361619.java +++ b/test/langtools/tools/javac/T6361619.java @@ -50,7 +50,8 @@ public class T6361619 extends AbstractProcessor { final PrintWriter out = new PrintWriter(System.err, true); - Iterable flags = Arrays.asList("-processorpath", testClassDir, + Iterable flags = Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "-processorpath", testClassDir, "-processor", self, "-d", "."); DiagnosticListener dl = new DiagnosticListener() { @@ -69,7 +70,9 @@ public class T6361619 extends AbstractProcessor { task.setTaskListener(tl); // should complete, without exceptions - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } } diff --git a/test/langtools/tools/javac/T6395974.java b/test/langtools/tools/javac/T6395974.java index e8d2b716735..623a9563695 100644 --- a/test/langtools/tools/javac/T6395974.java +++ b/test/langtools/tools/javac/T6395974.java @@ -63,7 +63,9 @@ public class T6395974 { MyTaskListener tl = new MyTaskListener(); task.setTaskListener(tl); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } } } diff --git a/test/langtools/tools/javac/T6397286.java b/test/langtools/tools/javac/T6397286.java index 5153a61aa77..8e8ef882aa2 100644 --- a/test/langtools/tools/javac/T6397286.java +++ b/test/langtools/tools/javac/T6397286.java @@ -56,6 +56,7 @@ public class T6397286 { }); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); throw new AssertionError("no exception thrown"); } catch (RuntimeException e) { diff --git a/test/langtools/tools/javac/T6458823/T6458823.java b/test/langtools/tools/javac/T6458823/T6458823.java index 91736229e5a..cd23066edc8 100644 --- a/test/langtools/tools/javac/T6458823/T6458823.java +++ b/test/langtools/tools/javac/T6458823/T6458823.java @@ -66,7 +66,9 @@ public class T6458823 { files.add(new File(T6458823.class.getResource("TestClass.java").toURI())); final CompilationTask task = compiler.getTask(null, fm, diagColl, options, null, fm.getJavaFileObjectsFromFiles(files)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } int diagCount = 0; for (Diagnostic diag : diagColl.getDiagnostics()) { if (diag.getKind() != Diagnostic.Kind.WARNING) { diff --git a/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java b/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java index f095b92b571..045558374c7 100644 --- a/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java +++ b/test/langtools/tools/javac/TryWithResources/TwrAvoidNullCheck.java @@ -76,7 +76,9 @@ public class TwrAvoidNullCheck { DumpLower.preRegister(ctx); Iterable files = Arrays.asList(new ToolBox.JavaSource(code)); JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } boolean hasNullCheck = ((DumpLower) DumpLower.instance(ctx)).hasNullCheck; diff --git a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java index af3f4ea19ef..11691a43040 100644 --- a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java +++ b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java @@ -89,7 +89,9 @@ public class TwrSimpleClose { JFMImpl fm = new JFMImpl(sfm)) { Iterable files = Arrays.asList(new ToolBox.JavaSource(code)); JavacTask task = (JavacTask) compiler.getTask(null, fm, null, null, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (fm.classBytes.size() != 1) { throw new AssertionError(); diff --git a/test/langtools/tools/javac/api/6406133/T6406133.java b/test/langtools/tools/javac/api/6406133/T6406133.java index 70e2fbe5fe6..24ddba1e602 100644 --- a/test/langtools/tools/javac/api/6406133/T6406133.java +++ b/test/langtools/tools/javac/api/6406133/T6406133.java @@ -90,7 +90,9 @@ public class T6406133 extends ToolTester { task = tool.getTask(pw, fm, listener, null, null, compilationUnits); task.setProcessors(Arrays.asList(processor)); task.setLocale(locale); //6443132 - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } if (!processor.locale.equals(locale)) throw new AssertionError("Error in diagnostic localization during annotation processing"); String res = useListener ? listener.result : pw.toString(); diff --git a/test/langtools/tools/javac/api/6410643/T6410643.java b/test/langtools/tools/javac/api/6410643/T6410643.java index a551f802d62..d8f5c798249 100644 --- a/test/langtools/tools/javac/api/6410643/T6410643.java +++ b/test/langtools/tools/javac/api/6410643/T6410643.java @@ -53,6 +53,7 @@ public class T6410643 extends ToolTester { void test(String... args) { task = tool.getTask(null, null, null, null, null, null); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); throw new AssertionError("Error expected"); } catch (IllegalStateException e) { diff --git a/test/langtools/tools/javac/api/6412656/T6412656.java b/test/langtools/tools/javac/api/6412656/T6412656.java index b7976e036fd..cfea162ae98 100644 --- a/test/langtools/tools/javac/api/6412656/T6412656.java +++ b/test/langtools/tools/javac/api/6412656/T6412656.java @@ -47,7 +47,9 @@ public class T6412656 extends ToolTester { task = tool.getTask(null, fm, null, null, Collections.singleton(T6412656.class.getName()), null); task.setProcessors(Collections.singleton(new MyProc(this))); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (count == 0) throw new AssertionError("Annotation processor not run"); System.out.println("OK"); diff --git a/test/langtools/tools/javac/api/6423003/T6423003.java b/test/langtools/tools/javac/api/6423003/T6423003.java index 893f2dd6344..58d055e9685 100644 --- a/test/langtools/tools/javac/api/6423003/T6423003.java +++ b/test/langtools/tools/javac/api/6423003/T6423003.java @@ -41,11 +41,12 @@ public class T6423003 extends ToolTester { void test(String... args) { task = tool.getTask(null, fm, null, Arrays.asList("-Xlint:all"), null, null); try { + // no need to check the result of JavacTask::call, reevaluate if the test is modified task.call(); + throw new AssertionError("Expected IllegalStateException not thrown"); } catch (IllegalStateException ex) { return; } - throw new AssertionError("Expected IllegalStateException not thrown"); } public static void main(String... args) throws IOException { try (T6423003 t = new T6423003()) { diff --git a/test/langtools/tools/javac/api/6731573/T6731573.java b/test/langtools/tools/javac/api/6731573/T6731573.java index 0d7ceb8fd2f..892b8e63ffb 100644 --- a/test/langtools/tools/javac/api/6731573/T6731573.java +++ b/test/langtools/tools/javac/api/6731573/T6731573.java @@ -93,7 +93,9 @@ public class T6731573 extends ToolTester { if (sourceLine.optValue != null) options.add(sourceLine.optValue); task = tool.getTask(pw, fm, null, options, null, compilationUnits); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } checkErrorLine(pw.toString(), diagType.shouldDisplaySource(sourceLine), options); diff --git a/test/langtools/tools/javac/api/7086261/T7086261.java b/test/langtools/tools/javac/api/7086261/T7086261.java index 1bc2d1a2dc8..391e71c94a7 100644 --- a/test/langtools/tools/javac/api/7086261/T7086261.java +++ b/test/langtools/tools/javac/api/7086261/T7086261.java @@ -71,7 +71,9 @@ public class T7086261 { try (JavaFileManager jfm = javac.getStandardFileManager(null, null, null)) { JavaCompiler.CompilationTask task = javac.getTask(null, jfm, new DiagnosticChecker(), null, null, Arrays.asList(new ErroneousSource())); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } } } diff --git a/test/langtools/tools/javac/api/8007344/Test.java b/test/langtools/tools/javac/api/8007344/Test.java index c99b77a101f..d230fb6086b 100644 --- a/test/langtools/tools/javac/api/8007344/Test.java +++ b/test/langtools/tools/javac/api/8007344/Test.java @@ -38,6 +38,7 @@ import java.io.File; import java.io.PrintWriter; import java.util.Arrays; +import java.util.List; import java.util.Set; import javax.annotation.processing.RoundEnvironment; @@ -75,6 +76,12 @@ public class Test { } } + static final List OPTIONS = List.of( + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"); + PrintWriter out; int errors; @@ -102,10 +109,12 @@ public class Test { Iterable files, PrintWriter out, int expectedDocComments) { out.println("Test annotation processor"); - JavacTask task = javac.getTask(out, fm, null, null, null, files); + JavacTask task = javac.getTask(out, fm, null, OPTIONS, null, files); AnnoProc ap = new AnnoProc(DocTrees.instance(task)); task.setProcessors(Arrays.asList(ap)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } ap.checker.checkDocComments(expectedDocComments); } @@ -113,10 +122,12 @@ public class Test { Iterable files, PrintWriter out, int expectedDocComments) { out.println("Test task listener"); - JavacTask task = javac.getTask(out, fm, null, null, null, files); + JavacTask task = javac.getTask(out, fm, null, OPTIONS, null, files); TaskListnr tl = new TaskListnr(DocTrees.instance(task)); task.addTaskListener(tl); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } tl.checker.checkDocComments(expectedDocComments); } diff --git a/test/langtools/tools/javac/api/DiagSpans.java b/test/langtools/tools/javac/api/DiagSpans.java index e4cdc6a5f07..527fe1aad62 100644 --- a/test/langtools/tools/javac/api/DiagSpans.java +++ b/test/langtools/tools/javac/api/DiagSpans.java @@ -72,7 +72,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -87,7 +88,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -102,7 +104,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -118,7 +121,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -134,7 +138,8 @@ public class DiagSpans extends TestRunner { } """, '/', - '^'); + '^', + false); } @Test @@ -158,7 +163,8 @@ public class DiagSpans extends TestRunner { class Sub2 extends Base2 {} """, '/', - '^'); + '^', + true); } @Test @@ -175,7 +181,8 @@ public class DiagSpans extends TestRunner { class Sub1 extends Base1 {} """, '/', - '^'); + '^', + false); } @Test @@ -192,10 +199,11 @@ public class DiagSpans extends TestRunner { class Sub1 extends Base1 {} """, '/', - '^'); + '^', + false); } - private void runDiagSpanTest(String code, char spanMarker, char prefMarker) throws Exception { + private void runDiagSpanTest(String code, char spanMarker, char prefMarker, boolean succCompilationExpected) throws Exception { var realCode = new StringBuilder(); var expectedError = new ArrayList(); int startPos = -1; @@ -238,7 +246,9 @@ public class DiagSpans extends TestRunner { }; var sourceFiles = List.of(new JFOImpl(realCode.toString())); var task = compiler.getTask(null, null, dl, null, null, sourceFiles); - task.call(); + if (task.call() != succCompilationExpected) { + throw new AssertionError("unexpected compilation result"); + } if (!Objects.equals(expectedError, actualErrors)) { throw new AssertionError("Expected error spans not found, expected: " + expectedError + ", actual: " + actualErrors); diff --git a/test/langtools/tools/javac/api/T6357331.java b/test/langtools/tools/javac/api/T6357331.java index 5253ebededd..0bc4ff98a53 100644 --- a/test/langtools/tools/javac/api/T6357331.java +++ b/test/langtools/tools/javac/api/T6357331.java @@ -53,7 +53,9 @@ public class T6357331 public void finished(TaskEvent e) { } }); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } // now the compilation is over, we expect IllegalStateException (not NPE) try { diff --git a/test/langtools/tools/javac/api/TestTreePath.java b/test/langtools/tools/javac/api/TestTreePath.java index b3887619947..7a016f42545 100644 --- a/test/langtools/tools/javac/api/TestTreePath.java +++ b/test/langtools/tools/javac/api/TestTreePath.java @@ -116,7 +116,9 @@ public class TestTreePath extends AbstractProcessor { null, null, null, Arrays.asList("-processor", this.getClass().getName()), null, tests); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } } diff --git a/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java b/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java index bd01d192b6e..759ec8d66ac 100644 --- a/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java +++ b/test/langtools/tools/javac/api/taskListeners/EventsBalancedTest.java @@ -79,7 +79,9 @@ public class EventsBalancedTest { task.setTaskListener(listener); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } for (Entry e : listener.kind2Count.entrySet()) { if (e.getValue() != null && e.getValue() != 0) { diff --git a/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java b/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java index de55cd8d5f7..278d8863b4a 100644 --- a/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java +++ b/test/langtools/tools/javac/fatalErrors/ImproveFatalErrorHandling.java @@ -76,7 +76,9 @@ public class ImproveFatalErrorHandling extends TestRunner { .getSystemJavaCompiler() .getTask(null, null, null, null, null, files); Context context = task.getContext(); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } JavaCompiler compiler = context.get(compilerKey); compiler.closeables = com.sun.tools.javac.util.List.of( new CloseException1(), new CloseException2(), diff --git a/test/langtools/tools/javac/lib/DPrinter.java b/test/langtools/tools/javac/lib/DPrinter.java index 6fa2f17dc67..5092e0698c2 100644 --- a/test/langtools/tools/javac/lib/DPrinter.java +++ b/test/langtools/tools/javac/lib/DPrinter.java @@ -1602,7 +1602,9 @@ public class DPrinter { } }); - task.call(); + if (!task.call()) { + throw new AssertionError("compilation failed at DPrinter.Main::run"); + } } TaskEvent.Kind getKind(String s) { diff --git a/test/langtools/tools/javac/modules/QueryBeforeEnter.java b/test/langtools/tools/javac/modules/QueryBeforeEnter.java index 226c6aed8e3..293b6302eec 100644 --- a/test/langtools/tools/javac/modules/QueryBeforeEnter.java +++ b/test/langtools/tools/javac/modules/QueryBeforeEnter.java @@ -359,7 +359,9 @@ public class QueryBeforeEnter extends ModuleTestBase { "-Xplugin:test"), null, fm.getJavaFileObjects(testSource)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } Main.compile(new String[] {"--processor-path", processorPath, diff --git a/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java b/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java index 4e738cce028..8f64b4cff37 100644 --- a/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java +++ b/test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java @@ -34,7 +34,7 @@ import javax.tools.*; public class SOEDeeplyNestedBlocksTest { - static final int NESTING_DEPTH = 1000; + static final int NESTING_DEPTH = 500; public static void main(String... args) { var lines = new ArrayList(); @@ -48,7 +48,9 @@ public class SOEDeeplyNestedBlocksTest { var source = SimpleJavaFileObject.forSource(URI.create("mem://Test.java"), String.join("\n", lines)); var compiler = ToolProvider.getSystemJavaCompiler(); var task = compiler.getTask(null, null, noErrors, null, null, List.of(source)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } } static DiagnosticListener noErrors = d -> { diff --git a/test/langtools/tools/javac/positions/TreeEndPosTest.java b/test/langtools/tools/javac/positions/TreeEndPosTest.java index 990053a7d4e..dc87409f4b2 100644 --- a/test/langtools/tools/javac/positions/TreeEndPosTest.java +++ b/test/langtools/tools/javac/positions/TreeEndPosTest.java @@ -174,7 +174,9 @@ public class TreeEndPosTest { compiler.getTask(writer, javaFileManager, dc, options, null, sources); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } for (Diagnostic diagnostic : (List) dc.getDiagnostics()) { long actualStart = diagnostic.getStartPosition(); long actualEnd = diagnostic.getEndPosition(); diff --git a/test/langtools/tools/javac/processing/6348499/T6348499.java b/test/langtools/tools/javac/processing/6348499/T6348499.java index f8f8c30bdd7..266caa1e14f 100644 --- a/test/langtools/tools/javac/processing/6348499/T6348499.java +++ b/test/langtools/tools/javac/processing/6348499/T6348499.java @@ -61,7 +61,9 @@ public class T6348499 { "-processorpath", testClassPath); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); // Expect the following 1 multi-line diagnostic, and no output to log diff --git a/test/langtools/tools/javac/processing/6414633/T6414633.java b/test/langtools/tools/javac/processing/6414633/T6414633.java index d38d1acdd82..5ee7b5e646d 100644 --- a/test/langtools/tools/javac/processing/6414633/T6414633.java +++ b/test/langtools/tools/javac/processing/6414633/T6414633.java @@ -60,7 +60,9 @@ public class T6414633 { String[] opts = { "-proc:only", "-processor", A.class.getName() }; JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } // two annotations on the same element -- expect 2 diags from the processor if (dl.diags != 2) diff --git a/test/langtools/tools/javac/processing/6430209/T6430209.java b/test/langtools/tools/javac/processing/6430209/T6430209.java index 2f79b36a3e1..1371b7c09d6 100644 --- a/test/langtools/tools/javac/processing/6430209/T6430209.java +++ b/test/langtools/tools/javac/processing/6430209/T6430209.java @@ -66,7 +66,9 @@ public class T6430209 { "-processorpath", testClassPath); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, null, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); s = s.replace(System.getProperty("line.separator"), "\n"); diff --git a/test/langtools/tools/javac/processing/T6439826.java b/test/langtools/tools/javac/processing/T6439826.java index 846d77c3a7e..fed293d4e5e 100644 --- a/test/langtools/tools/javac/processing/T6439826.java +++ b/test/langtools/tools/javac/processing/T6439826.java @@ -55,7 +55,9 @@ public class T6439826 extends AbstractProcessor { "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } String s = out.toString(); System.err.print(s); // Expect the following 2 diagnostics, and no output to log diff --git a/test/langtools/tools/javac/processing/T8142931.java b/test/langtools/tools/javac/processing/T8142931.java index 5abeac83687..8ade5e19767 100644 --- a/test/langtools/tools/javac/processing/T8142931.java +++ b/test/langtools/tools/javac/processing/T8142931.java @@ -62,7 +62,9 @@ public class T8142931 extends AbstractProcessor { "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = (JavacTask)tool.getTask(out, fm, dl, opts, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } String s = out.toString(); System.err.print(s); System.err.println(dl.count + " diagnostics; " + s.length() + " characters"); diff --git a/test/langtools/tools/javac/processing/model/LocalInAnonymous.java b/test/langtools/tools/javac/processing/model/LocalInAnonymous.java index 6cbbe512784..616062bb542 100644 --- a/test/langtools/tools/javac/processing/model/LocalInAnonymous.java +++ b/test/langtools/tools/javac/processing/model/LocalInAnonymous.java @@ -81,7 +81,9 @@ public class LocalInAnonymous { List options = Arrays.asList("-d", classes.toString()); StringWriter out = new StringWriter(); JavacTask task = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } @@ -103,7 +105,9 @@ public class LocalInAnonymous { } } }); - task2.call(); + if (!task2.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } @@ -112,7 +116,9 @@ public class LocalInAnonymous { "-processorpath", System.getProperty("test.classes"), "-processor", Processor.class.getName()); JavacTask task3 = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files); - task3.call(); + if (!task3.call()) { + throw new AssertionError("test failed due to a compilation error"); + } if (!out.toString().isEmpty()) { throw new AssertionError("Unexpected output: " + out); } diff --git a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java index 73089a9a3cf..181c29eeb56 100644 --- a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java +++ b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java @@ -323,7 +323,9 @@ public class TestNoteOnImplicitProcessing extends TestRunner { List options = List.of("-classpath", jarFile.toString(), "-XDrawDiagnostics"); CompilationTask task = provider.getTask(compilerOut, null, null, options, null, inputFile); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } verifyMessages(out, compilerOut, false, false); } @@ -335,7 +337,9 @@ public class TestNoteOnImplicitProcessing extends TestRunner { (Processor) processorClass.getDeclaredConstructor().newInstance(); task.setProcessors(List.of(processor)); - task.call(); + if (!task.call()) { + throw new AssertionError("test failed due to a compilation error"); + } verifyMessages(out, compilerOut, false, true); } diff --git a/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java b/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java index 1ebc6b2acec..f724d605e51 100644 --- a/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java +++ b/test/langtools/tools/javac/processing/rounds/CompleteOnClosed.java @@ -56,7 +56,9 @@ public class CompleteOnClosed extends JavacTestingAbstractProcessor { Iterable files = Arrays.asList(new ToolBox.JavaSource(source)); Iterable options = Arrays.asList("-processor", "CompleteOnClosed"); CompilationTask task = compiler.getTask(null, null, collector, options, null, files); - task.call(); + if (task.call()) { + throw new AssertionError("test compilation was expected to fail"); + } for (Diagnostic d : collector.getDiagnostics()) { System.out.println(d.toString()); } From 026975a1aa290613934ae421bbc56326627bad8d Mon Sep 17 00:00:00 2001 From: Alexandre Iline Date: Fri, 6 Jun 2025 15:05:43 +0000 Subject: [PATCH 189/216] 8358721: Update JCov for class file version 70 Reviewed-by: iris, alanb, erikj --- make/conf/jib-profiles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 91876878046..d4877604a90 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1192,8 +1192,8 @@ var getJibProfilesDependencies = function (input, common) { server: "jpg", product: "jcov", version: "3.0", - build_number: "1", - file: "bundles/jcov-3.0+1.zip", + build_number: "3", + file: "bundles/jcov-3.0+3.zip", environment_name: "JCOV_HOME", }, From d024f58e61ec27f6c13fde5dadb95c31875815d6 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Fri, 6 Jun 2025 20:07:43 +0000 Subject: [PATCH 190/216] 8358809: Improve link to stdin.encoding from java.lang.IO Reviewed-by: naoto --- src/java.base/share/classes/java/lang/IO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/IO.java b/src/java.base/share/classes/java/lang/IO.java index 1f88de7e238..4630d8a3be2 100644 --- a/src/java.base/share/classes/java/lang/IO.java +++ b/src/java.base/share/classes/java/lang/IO.java @@ -38,7 +38,7 @@ import java.nio.charset.StandardCharsets; *

        * 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. From d7352559195b9e052c3eb24d773c0d6c10dc23ad Mon Sep 17 00:00:00 2001 From: Rajan Halade Date: Fri, 6 Jun 2025 21:35:21 +0000 Subject: [PATCH 191/216] 8345414: Google CAInterop test failures Reviewed-by: weijun Backport-of: 8e9ba788ae04a9a617a393709bf2c51a0c157206 --- .../certification/CAInterop.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 2bfd3ea7603..5612ad4a8a2 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -635,20 +635,20 @@ public class CAInterop { "https://revoked.sfig2.catest.starfieldtech.com"); case "globalsigneccrootcar4" -> - new CATestURLs("https://good.gsr4.demo.pki.goog", - "https://revoked.gsr4.demo.pki.goog"); + new CATestURLs("https://good.gsr4.demosite.pki.goog", + "https://revoked.gsr4.demosite.pki.goog"); case "gtsrootcar1" -> - new CATestURLs("https://good.gtsr1.demo.pki.goog", - "https://revoked.gtsr1.demo.pki.goog"); + new CATestURLs("https://good.gtsr1.demosite.pki.goog", + "https://revoked.gtsr1.demosite.pki.goog"); case "gtsrootcar2" -> - new CATestURLs("https://good.gtsr2.demo.pki.goog", - "https://revoked.gtsr2.demo.pki.goog"); + new CATestURLs("https://good.gtsr2.demosite.pki.goog", + "https://revoked.gtsr2.demosite.pki.goog"); case "gtsrootecccar3" -> - new CATestURLs("https://good.gtsr3.demo.pki.goog", - "https://revoked.gtsr3.demo.pki.goog"); + new CATestURLs("https://good.gtsr3.demosite.pki.goog", + "https://revoked.gtsr3.demosite.pki.goog"); case "gtsrootecccar4" -> - new CATestURLs("https://good.gtsr4.demo.pki.goog", - "https://revoked.gtsr4.demo.pki.goog"); + new CATestURLs("https://good.gtsr4.demosite.pki.goog", + "https://revoked.gtsr4.demosite.pki.goog"); case "microsoftecc2017" -> new CATestURLs("https://acteccroot2017.pki.microsoft.com", From e94ad551c6d31b91ec066f92f9bbdb956f54e887 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Sat, 7 Jun 2025 20:34:34 +0000 Subject: [PATCH 192/216] 8342639: Global operator new in adlc has wrong exception spec Reviewed-by: kvn, mdoerr --- src/hotspot/share/adlc/main.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hotspot/share/adlc/main.cpp b/src/hotspot/share/adlc/main.cpp index 16fd4ddcf93..4e8a96617e8 100644 --- a/src/hotspot/share/adlc/main.cpp +++ b/src/hotspot/share/adlc/main.cpp @@ -481,7 +481,3 @@ int get_legal_text(FileBuff &fbuf, char **legal_text) *legal_text = legal_start; return (int) (legal_end - legal_start); } - -void *operator new( size_t size, int, const char *, int ) throw() { - return ::operator new( size ); -} From 6c616c71ec9a8ee6e0203921deef20d09db39698 Mon Sep 17 00:00:00 2001 From: Daniel Skantz Date: Mon, 9 Jun 2025 06:11:05 +0000 Subject: [PATCH 193/216] 8357822: C2: Multiple string optimization tests are no longer testing string concatenation optimizations Reviewed-by: rcastanedalo, epeter --- test/hotspot/jtreg/compiler/c2/Test7046096.java | 14 +++++++++++++- .../hotspot/jtreg/compiler/c2/Test7179138_2.java | 13 +++++++++++++ .../Implicit01/cs_disabled/TestDescription.java | 16 +++++++++++++++- .../Implicit01/cs_enabled/TestDescription.java | 16 +++++++++++++++- .../Merge01/cs_disabled/TestDescription.java | 16 +++++++++++++++- .../Merge01/cs_enabled/TestDescription.java | 16 +++++++++++++++- 6 files changed, 86 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/Test7046096.java b/test/hotspot/jtreg/compiler/c2/Test7046096.java index 46eb935e2d0..fb73bba4373 100644 --- a/test/hotspot/jtreg/compiler/c2/Test7046096.java +++ b/test/hotspot/jtreg/compiler/c2/Test7046096.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 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 @@ -30,6 +30,18 @@ * compiler.c2.Test7046096 */ + +/* + * @test id=stringConcatInline + * @bug 7046096 8357822 + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * + * @compile -XDstringConcat=inline Test7046096.java + * @run main/othervm -Xbatch compiler.c2.Test7046096 + */ + + package compiler.c2; public class Test7046096 { diff --git a/test/hotspot/jtreg/compiler/c2/Test7179138_2.java b/test/hotspot/jtreg/compiler/c2/Test7179138_2.java index 4e89f6aced0..5f96ea942ef 100644 --- a/test/hotspot/jtreg/compiler/c2/Test7179138_2.java +++ b/test/hotspot/jtreg/compiler/c2/Test7179138_2.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Skip Balk. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,6 +33,18 @@ * @author Skip Balk */ + +/* + * @test id=stringConcatInline + * @bug 7179138 + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * + * @compile -XDstringConcat=inline Test7179138_2.java + * @run main/othervm -Xbatch -XX:-TieredCompilation compiler.c2.Test7179138_2 + */ + + package compiler.c2; public class Test7179138_2 { diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java index 2eddeafa2c9..13bc3b4d640 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_disabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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,3 +33,17 @@ * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Implicit01.java + * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java index 7e7295f5108..87e8bdcbcc7 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Implicit01/cs_enabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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,3 +33,17 @@ * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Implicit01.java + * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Implicit01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java index c56a554b1da..cbbe4d97ee4 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_disabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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,3 +33,17 @@ * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Merge01.java + * @run main/othervm -XX:-CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 + */ + diff --git a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java index 3c082fefd25..c6fc8d67de6 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/vm/compiler/optimizations/stringconcat/implicit/Merge01/cs_enabled/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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,3 +33,17 @@ * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 */ + +/* + * @test id=stringConcatInline + * + * @summary The same test with an updated compile directive that produces + * StringBuilder-backed string concatenations. + * VM Testbase keywords: [jit, quick] + * + * @library /vmTestbase + * /test/lib + * @compile -XDstringConcat=inline ../../Merge01.java + * @run main/othervm -XX:+CompactStrings vm.compiler.optimizations.stringconcat.implicit.Merge01 + */ + From 91f12600d2b188ca98c5c575a34b85f5835399a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 9 Jun 2025 06:23:17 +0000 Subject: [PATCH 194/216] 8345067: C2: enable implicit null checks for ZGC reads Reviewed-by: aboldtch, kvn, epeter --- src/hotspot/cpu/aarch64/aarch64.ad | 4 + src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad | 13 +- .../cpu/aarch64/macroAssembler_aarch64.hpp | 19 +- src/hotspot/cpu/ppc/gc/z/z_ppc.ad | 2 + src/hotspot/cpu/ppc/ppc.ad | 4 + src/hotspot/cpu/riscv/gc/z/z_riscv.ad | 1 + src/hotspot/cpu/riscv/riscv.ad | 4 + src/hotspot/cpu/x86/gc/z/z_x86_64.ad | 4 + src/hotspot/cpu/x86/x86_64.ad | 4 + src/hotspot/share/adlc/output_h.cpp | 2 + src/hotspot/share/opto/block.hpp | 8 + src/hotspot/share/opto/lcm.cpp | 103 ++++---- src/hotspot/share/opto/machnode.hpp | 7 + src/hotspot/share/opto/output.cpp | 6 +- .../gcbarriers/TestImplicitNullChecks.java | 231 ++++++++++++++++++ .../compiler/lib/ir_framework/IRNode.java | 5 + 16 files changed, 363 insertions(+), 54 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index f367362b4d8..75baef153f8 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3921,6 +3921,10 @@ ins_attrib ins_alignment(4); // Required alignment attribute (must // compute_padding() function must be // provided for the instruction +// Whether this node is expanded during code emission into a sequence of +// instructions and the first instruction can perform an implicit null check. +ins_attrib ins_is_late_expanded_null_check_candidate(false); + //----------OPERANDS----------------------------------------------------------- // Operand definitions must precede instruction definitions for correct parsing // in the ADLC because operands constitute user defined types which are used in diff --git a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad index 47abaae3d5b..78dc5d56bbd 100644 --- a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad +++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad @@ -106,6 +106,13 @@ instruct zLoadP(iRegPNoSp dst, memory8 mem, rFlagsReg cr) match(Set dst (LoadP mem)); predicate(UseZGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0); effect(TEMP dst, KILL cr); + // The main load is a candidate to implement implicit null checks, as long as + // legitimize_address() does not require a preceding lea instruction to + // materialize the memory operand. The absence of a preceding lea instruction + // is guaranteed for immLoffset8 memory operands, because these do not lead to + // out-of-range offsets (see definition of immLoffset8). Fortunately, + // immLoffset8 memory operands are the most common ones in practice. + ins_is_late_expanded_null_check_candidate(opnd_array(1)->opcode() == INDOFFL8); ins_cost(4 * INSN_COST); @@ -117,7 +124,11 @@ instruct zLoadP(iRegPNoSp dst, memory8 mem, rFlagsReg cr) // Fix up any out-of-range offsets. assert_different_registers(rscratch2, as_Register($mem$$base)); assert_different_registers(rscratch2, $dst$$Register); - ref_addr = __ legitimize_address(ref_addr, 8, rscratch2); + int size = 8; + assert(!this->is_late_expanded_null_check_candidate() || + !MacroAssembler::legitimize_address_requires_lea(ref_addr, size), + "an instruction that can be used for implicit null checking should emit the candidate memory access first"); + ref_addr = __ legitimize_address(ref_addr, size, rscratch2); } __ ldr($dst$$Register, ref_addr); z_load_barrier(masm, this, ref_addr, $dst$$Register, rscratch1); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index d77bc92875f..f5f0f630c0c 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -129,16 +129,21 @@ class MacroAssembler: public Assembler { a.lea(this, r); } + // Whether materializing the given address for a LDR/STR requires an + // additional lea instruction. + static bool legitimize_address_requires_lea(const Address &a, int size) { + return a.getMode() == Address::base_plus_offset && + !Address::offset_ok_for_immed(a.offset(), exact_log2(size)); + } + /* Sometimes we get misaligned loads and stores, usually from Unsafe accesses, and these can exceed the offset range. */ Address legitimize_address(const Address &a, int size, Register scratch) { - if (a.getMode() == Address::base_plus_offset) { - if (! Address::offset_ok_for_immed(a.offset(), exact_log2(size))) { - block_comment("legitimize_address {"); - lea(scratch, a); - block_comment("} legitimize_address"); - return Address(scratch); - } + if (legitimize_address_requires_lea(a, size)) { + block_comment("legitimize_address {"); + lea(scratch, a); + block_comment("} legitimize_address"); + return Address(scratch); } return a; } diff --git a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad index 65fb206ad7e..0872932ccb2 100644 --- a/src/hotspot/cpu/ppc/gc/z/z_ppc.ad +++ b/src/hotspot/cpu/ppc/gc/z/z_ppc.ad @@ -141,6 +141,7 @@ instruct zLoadP(iRegPdst dst, memoryAlg4 mem, flagsRegCR0 cr0) %{ match(Set dst (LoadP mem)); effect(TEMP_DEF dst, KILL cr0); + ins_is_late_expanded_null_check_candidate(true); ins_cost(MEMORY_REF_COST); predicate((UseZGC && n->as_Load()->barrier_data() != 0) @@ -160,6 +161,7 @@ instruct zLoadP_acq(iRegPdst dst, memoryAlg4 mem, flagsRegCR0 cr0) %{ match(Set dst (LoadP mem)); effect(TEMP_DEF dst, KILL cr0); + ins_is_late_expanded_null_check_candidate(true); ins_cost(3 * MEMORY_REF_COST); // Predicate on instruction order is implicitly present due to the predicate of the cheaper zLoadP operation diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 128e566d0f3..d8e00cfef89 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -4036,6 +4036,10 @@ ins_attrib ins_field_cbuf_insts_offset(-1); ins_attrib ins_field_load_ic_hi_node(0); ins_attrib ins_field_load_ic_node(0); +// Whether this node is expanded during code emission into a sequence of +// instructions and the first instruction can perform an implicit null check. +ins_attrib ins_is_late_expanded_null_check_candidate(false); + //----------OPERANDS----------------------------------------------------------- // Operand definitions must precede instruction definitions for correct // parsing in the ADLC because operands constitute user defined types diff --git a/src/hotspot/cpu/riscv/gc/z/z_riscv.ad b/src/hotspot/cpu/riscv/gc/z/z_riscv.ad index fd9a1d43afc..e3847019bb3 100644 --- a/src/hotspot/cpu/riscv/gc/z/z_riscv.ad +++ b/src/hotspot/cpu/riscv/gc/z/z_riscv.ad @@ -96,6 +96,7 @@ instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp, rFlagsReg cr) match(Set dst (LoadP mem)); predicate(UseZGC && n->as_Load()->barrier_data() != 0); effect(TEMP dst, TEMP tmp, KILL cr); + ins_is_late_expanded_null_check_candidate(true); ins_cost(4 * DEFAULT_COST); diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index e838ee184fb..0d44acc803f 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -2619,6 +2619,10 @@ ins_attrib ins_alignment(4); // Required alignment attribute (must // compute_padding() function must be // provided for the instruction +// Whether this node is expanded during code emission into a sequence of +// instructions and the first instruction can perform an implicit null check. +ins_attrib ins_is_late_expanded_null_check_candidate(false); + //----------OPERANDS----------------------------------------------------------- // Operand definitions must precede instruction definitions for correct parsing // in the ADLC because operands constitute user defined types which are used in diff --git a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad index 045aa5d5381..e66b4b0da7a 100644 --- a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad +++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad @@ -118,6 +118,10 @@ instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr) predicate(UseZGC && n->as_Load()->barrier_data() != 0); match(Set dst (LoadP mem)); effect(TEMP dst, KILL cr); + // The main load is a candidate to implement implicit null checks. The + // barrier's slow path includes an identical reload, which does not need to be + // registered in the exception table because it is dominated by the main one. + ins_is_late_expanded_null_check_candidate(true); ins_cost(125); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 22490ba7bb3..d17bdf5e2c9 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2055,6 +2055,10 @@ ins_attrib ins_alignment(1); // Required alignment attribute (must // compute_padding() function must be // provided for the instruction +// Whether this node is expanded during code emission into a sequence of +// instructions and the first instruction can perform an implicit null check. +ins_attrib ins_is_late_expanded_null_check_candidate(false); + //----------OPERANDS----------------------------------------------------------- // Operand definitions must precede instruction definitions for correct parsing // in the ADLC because operands constitute user defined types which are used in diff --git a/src/hotspot/share/adlc/output_h.cpp b/src/hotspot/share/adlc/output_h.cpp index b62bc43791f..cbcc00efa3b 100644 --- a/src/hotspot/share/adlc/output_h.cpp +++ b/src/hotspot/share/adlc/output_h.cpp @@ -1626,6 +1626,8 @@ void ArchDesc::declareClasses(FILE *fp) { while (attr != nullptr) { if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) { fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val); + } else if (strcmp (attr->_ident, "ins_is_late_expanded_null_check_candidate") == 0) { + fprintf(fp, " virtual bool is_late_expanded_null_check_candidate() const { return %s; }\n", attr->_val); } else if (strcmp (attr->_ident, "ins_cost") != 0 && strncmp(attr->_ident, "ins_field_", 10) != 0 && // Must match function in node.hpp: return type bool, no prefix "ins_". diff --git a/src/hotspot/share/opto/block.hpp b/src/hotspot/share/opto/block.hpp index c5a3a589407..e6a98c28e77 100644 --- a/src/hotspot/share/opto/block.hpp +++ b/src/hotspot/share/opto/block.hpp @@ -464,6 +464,14 @@ class PhaseCFG : public Phase { Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx); void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx); + // Ensure that n happens at b or above, i.e. at a block that dominates b. + // We expect n to be an orphan node without further inputs. + void ensure_node_is_at_block_or_above(Node* n, Block* b); + + // Move node n from its current placement into the end of block b. + // Move also outgoing Mach projections. + void move_node_and_its_projections_to_block(Node* n, Block* b); + // Detect implicit-null-check opportunities. Basically, find null checks // with suitable memory ops nearby. Use the memory op to do the null check. // I can generate a memory op if there is not one nearby. diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp index 4df3bbab731..0fe246a7679 100644 --- a/src/hotspot/share/opto/lcm.cpp +++ b/src/hotspot/share/opto/lcm.cpp @@ -76,6 +76,36 @@ static bool needs_explicit_null_check_for_read(Node *val) { return true; } +void PhaseCFG::move_node_and_its_projections_to_block(Node* n, Block* b) { + assert(!is_CFG(n), "cannot move CFG node"); + Block* old = get_block_for_node(n); + old->find_remove(n); + b->add_inst(n); + map_node_to_block(n, b); + // Check for Mach projections that also need to be moved. + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* out = n->fast_out(i); + if (!out->is_MachProj()) { + continue; + } + assert(!n->is_MachProj(), "nested projections are not allowed"); + move_node_and_its_projections_to_block(out, b); + } +} + +void PhaseCFG::ensure_node_is_at_block_or_above(Node* n, Block* b) { + assert(!is_CFG(n), "cannot move CFG node"); + Block* current = get_block_for_node(n); + if (current->dominates(b)) { + return; // n is already placed above b, do nothing. + } + // We only expect nodes without further inputs, like MachTemp or load Base. + assert(n->req() == 0 || (n->req() == 1 && n->in(0) == (Node*)C->root()), + "need for recursive hoisting not expected"); + assert(b->dominates(current), "precondition: can only move n to b if b dominates n"); + move_node_and_its_projections_to_block(n, b); +} + //------------------------------implicit_null_check---------------------------- // Detect implicit-null-check opportunities. Basically, find null checks // with suitable memory ops nearby. Use the memory op to do the null check. @@ -160,12 +190,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo Node *m = val->out(i); if( !m->is_Mach() ) continue; MachNode *mach = m->as_Mach(); - if (mach->barrier_data() != 0) { + if (mach->barrier_data() != 0 && + !mach->is_late_expanded_null_check_candidate()) { // Using memory accesses with barriers to perform implicit null checks is - // not supported. These operations might expand into multiple assembly - // instructions during code emission, including new memory accesses (e.g. - // in G1's pre-barrier), which would invalidate the implicit null - // exception table. + // only supported if these are explicit marked as emitting a candidate + // memory access instruction at their initial address. If not marked as + // such, barrier-tagged operations might expand into one or several memory + // access instructions located at arbitrary offsets from the initial + // address, which would invalidate the implicit null exception table. continue; } was_store = false; @@ -321,6 +353,14 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo // Ignore DecodeN val which could be hoisted to where needed. if( is_decoden ) continue; } + if (mach->in(j)->is_MachTemp()) { + assert(mach->in(j)->outcnt() == 1, "MachTemp nodes should not be shared"); + // Ignore MachTemp inputs, they can be safely hoisted with the candidate. + // MachTemp nodes have no inputs themselves and are only used to reserve + // a scratch register for the implementation of the node (e.g. in + // late-expanded GC barriers). + continue; + } // Block of memory-op input Block *inb = get_block_for_node(mach->in(j)); Block *b = block; // Start from nul check @@ -388,38 +428,24 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo // Hoist it up to the end of the test block together with its inputs if they exist. for (uint i = 2; i < val->req(); i++) { // DecodeN has 2 regular inputs + optional MachTemp or load Base inputs. - Node *temp = val->in(i); - Block *tempb = get_block_for_node(temp); - if (!tempb->dominates(block)) { - assert(block->dominates(tempb), "sanity check: temp node placement"); - // We only expect nodes without further inputs, like MachTemp or load Base. - assert(temp->req() == 0 || (temp->req() == 1 && temp->in(0) == (Node*)C->root()), - "need for recursive hoisting not expected"); - tempb->find_remove(temp); - block->add_inst(temp); - map_node_to_block(temp, block); - } - } - valb->find_remove(val); - block->add_inst(val); - map_node_to_block(val, block); - // DecodeN on x86 may kill flags. Check for flag-killing projections - // that also need to be hoisted. - for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { - Node* n = val->fast_out(j); - if( n->is_MachProj() ) { - get_block_for_node(n)->find_remove(n); - block->add_inst(n); - map_node_to_block(n, block); - } + // Inputs of val may already be early enough, but if not move them together with val. + ensure_node_is_at_block_or_above(val->in(i), block); } + move_node_and_its_projections_to_block(val, block); } } + + // Move any MachTemp inputs to the end of the test block. + for (uint i = 0; i < best->req(); i++) { + Node* n = best->in(i); + if (n == nullptr || !n->is_MachTemp()) { + continue; + } + ensure_node_is_at_block_or_above(n, block); + } + // Hoist the memory candidate up to the end of the test block. - Block *old_block = get_block_for_node(best); - old_block->find_remove(best); - block->add_inst(best); - map_node_to_block(best, block); + move_node_and_its_projections_to_block(best, block); // Move the control dependence if it is pinned to not-null block. // Don't change it in other cases: null or dominating control. @@ -429,17 +455,6 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo best->set_req(0, proj->in(0)->in(0)); } - // Check for flag-killing projections that also need to be hoisted - // Should be DU safe because no edge updates. - for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { - Node* n = best->fast_out(j); - if( n->is_MachProj() ) { - get_block_for_node(n)->find_remove(n); - block->add_inst(n); - map_node_to_block(n, block); - } - } - // proj==Op_True --> ne test; proj==Op_False --> eq test. // One of two graph shapes got matched: // (IfTrue (If (Bool NE (CmpP ptr null)))) diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 5fd262d54e1..3594806b91e 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -386,6 +386,13 @@ public: // Returns true if this node is a check that can be implemented with a trap. virtual bool is_TrapBasedCheckNode() const { return false; } + + // Whether this node is expanded during code emission into a sequence of + // instructions and the first instruction can perform an implicit null check. + virtual bool is_late_expanded_null_check_candidate() const { + return false; + } + void set_removed() { add_flag(Flag_is_removed_by_peephole); } bool get_removed() { return (flags() & Flag_is_removed_by_peephole) != 0; } diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 930c355fa62..f0a7b742998 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -2015,8 +2015,10 @@ void PhaseOutput::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_s // Handle implicit null exception table updates if (n->is_MachNullCheck()) { - assert(n->in(1)->as_Mach()->barrier_data() == 0, - "Implicit null checks on memory accesses with barriers are not yet supported"); + MachNode* access = n->in(1)->as_Mach(); + assert(access->barrier_data() == 0 || + access->is_late_expanded_null_check_candidate(), + "Implicit null checks on memory accesses with barriers are only supported on nodes explicitly marked as null-check candidates"); uint block_num = block->non_connector_successor(0)->_pre_order; _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos()); continue; diff --git a/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java b/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java new file mode 100644 index 00000000000..a77a51312de --- /dev/null +++ b/test/hotspot/jtreg/compiler/gcbarriers/TestImplicitNullChecks.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.gcbarriers; + +import compiler.lib.ir_framework.*; +import java.lang.invoke.VarHandle; +import java.lang.invoke.MethodHandles; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import jdk.test.lib.Asserts; + +/** + * @test + * @summary Test that implicit null checks are generated as expected for + different GC memory accesses. + * @library /test/lib / + * @run driver compiler.gcbarriers.TestImplicitNullChecks + */ + + +public class TestImplicitNullChecks { + + static class Outer { + Object f; + } + + static class OuterWithVolatileField { + volatile Object f; + } + + static final VarHandle fVarHandle; + static { + MethodHandles.Lookup l = MethodHandles.lookup(); + try { + fVarHandle = l.findVarHandle(Outer.class, "f", Object.class); + } catch (Exception e) { + throw new Error(e); + } + } + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:CompileCommand=inline,java.lang.ref.*::*", + "-XX:-TieredCompilation"); + } + + @Test + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoad(Outer o) { + return o.f; + } + + @Test + // On aarch64, volatile loads always use indirect memory operands, which + // leads to a pattern that cannot be exploited by the current C2 analysis. + // On PPC64, volatile loads are preceded by membar_volatile instructions, + // which also inhibits the current C2 analysis. + @IR(applyIfPlatformAnd = {"aarch64", "false", "ppc", "false"}, + applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadVolatile(OuterWithVolatileField o) { + return o.f; + } + + @Run(test = {"testLoad", + "testLoadVolatile"}, + mode = RunMode.STANDALONE) + static void runLoadTests() { + { + Outer o = new Outer(); + // Trigger compilation with implicit null check. + for (int i = 0; i < 10_000; i++) { + testLoad(o); + } + // Trigger null pointer exception. + o = null; + boolean nullPointerException = false; + try { + testLoad(o); + } catch (NullPointerException e) { nullPointerException = true; } + Asserts.assertTrue(nullPointerException); + } + { + OuterWithVolatileField o = new OuterWithVolatileField(); + // Trigger compilation with implicit null check. + for (int i = 0; i < 10_000; i++) { + testLoadVolatile(o); + } + // Trigger null pointer exception. + o = null; + boolean nullPointerException = false; + try { + testLoadVolatile(o); + } catch (NullPointerException e) { nullPointerException = true; } + Asserts.assertTrue(nullPointerException); + } + } + + @Test + // G1 and ZGC stores cannot be currently used to implement implicit null + // checks, because they expand into multiple memory access instructions that + // are not necessarily located at the initial instruction start address. + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static void testStore(Outer o, Object o1) { + o.f = o1; + } + + @Run(test = {"testStore"}) + static void runStoreTests() { + { + Outer o = new Outer(); + Object o1 = new Object(); + testStore(o, o1); + } + } + + @Test + // G1 and ZGC compare-and-exchange operations cannot be currently used to + // implement implicit null checks, because they expand into multiple memory + // access instructions that are not necessarily located at the initial + // instruction start address. The same holds for testCompareAndSwap and + // testGetAndSet below. + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) { + return fVarHandle.compareAndExchange(o, oldVal, newVal); + } + + @Test + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) { + return fVarHandle.compareAndSet(o, oldVal, newVal); + } + + @Test + @IR(applyIfOr = {"UseZGC", "true", "UseG1GC", "true"}, + failOn = IRNode.NULL_CHECK, + phase = CompilePhase.FINAL_CODE) + static Object testGetAndSet(Outer o, Object newVal) { + return fVarHandle.getAndSet(o, newVal); + } + + @Run(test = {"testCompareAndExchange", + "testCompareAndSwap", + "testGetAndSet"}) + static void runAtomicTests() { + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testCompareAndExchange(o, oldVal, newVal); + } + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testCompareAndSwap(o, oldVal, newVal); + } + { + Outer o = new Outer(); + Object oldVal = new Object(); + Object newVal = new Object(); + testGetAndSet(o, newVal); + } + } + + @Test + // G1 reference loads use indirect memory operands, which leads to a pattern + // that cannot be exploited by the current C2 analysis. The same holds for + // testLoadWeakReference. + @IR(applyIf = {"UseZGC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadSoftReference(SoftReference ref) { + return ref.get(); + } + + @Test + @IR(applyIf = {"UseZGC", "true"}, + counts = {IRNode.NULL_CHECK, "1"}, + phase = CompilePhase.FINAL_CODE) + static Object testLoadWeakReference(WeakReference ref) { + return ref.get(); + } + + @Run(test = {"testLoadSoftReference", + "testLoadWeakReference"}) + static void runReferenceTests() { + { + Object o1 = new Object(); + SoftReference sref = new SoftReference(o1); + Object o2 = testLoadSoftReference(sref); + } + { + Object o1 = new Object(); + WeakReference wref = new WeakReference(o1); + Object o2 = testLoadWeakReference(wref); + } + } + +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 96b62a2b12a..9388e1a8892 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1499,6 +1499,11 @@ public class IRNode { trapNodes(NULL_ASSERT_TRAP, "null_assert"); } + public static final String NULL_CHECK = PREFIX + "NULL_CHECK" + POSTFIX; + static { + machOnlyNameRegex(NULL_CHECK, "NullCheck"); + } + public static final String NULL_CHECK_TRAP = PREFIX + "NULL_CHECK_TRAP" + POSTFIX; static { trapNodes(NULL_CHECK_TRAP, "null_check"); From 52338c94f610611a9e89a6ccbe6f2c6cd768b50a Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Mon, 9 Jun 2025 07:00:51 +0000 Subject: [PATCH 195/216] 8358520: Improve lazy computation in BreakIteratorResourceBundle and related classes Reviewed-by: naoto, jlu --- .../classes/java/util/ResourceBundle.java | 33 ++++--- .../BreakIteratorResourceBundle.java | 25 +++-- .../resources/OpenListResourceBundle.java | 94 ++++++++----------- 3 files changed, 65 insertions(+), 87 deletions(-) diff --git a/src/java.base/share/classes/java/util/ResourceBundle.java b/src/java.base/share/classes/java/util/ResourceBundle.java index fb88a38903a..b3807ac770a 100644 --- a/src/java.base/share/classes/java/util/ResourceBundle.java +++ b/src/java.base/share/classes/java/util/ResourceBundle.java @@ -54,6 +54,7 @@ import java.net.URL; import java.net.URLConnection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.spi.ResourceBundleControlProvider; import java.util.spi.ResourceBundleProvider; @@ -487,7 +488,20 @@ public abstract class ResourceBundle { /** * A Set of the keys contained only in this ResourceBundle. */ - private volatile Set keySet; + private final Supplier> keySet = StableValue.supplier( + new Supplier<>() { public Set get() { return keySet0(); }}); + + private Set keySet0() { + final Set keys = new HashSet<>(); + final Enumeration enumKeys = getKeys(); + while (enumKeys.hasMoreElements()) { + final String key = enumKeys.nextElement(); + if (handleGetObject(key) != null) { + keys.add(key); + } + } + return keys; + } /** * Sole constructor. (For invocation by subclass constructors, typically @@ -2298,22 +2312,7 @@ public abstract class ResourceBundle { * @since 1.6 */ protected Set handleKeySet() { - if (keySet == null) { - synchronized (this) { - if (keySet == null) { - Set keys = new HashSet<>(); - Enumeration enumKeys = getKeys(); - while (enumKeys.hasMoreElements()) { - String key = enumKeys.nextElement(); - if (handleGetObject(key) != null) { - keys.add(key); - } - } - keySet = keys; - } - } - } - return keySet; + return keySet.get(); } diff --git a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java index 3a55e7ccb8c..d7c575962f6 100644 --- a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; /** * BreakIteratorResourceBundle is an abstract class for loading BreakIterator @@ -49,7 +50,15 @@ public abstract class BreakIteratorResourceBundle extends ResourceBundle { // those keys must be added to NON_DATA_KEYS. private static final Set NON_DATA_KEYS = Set.of("BreakIteratorClasses"); - private volatile Set keys; + private final Supplier> keys = StableValue.supplier( + new Supplier<>() { public Set get() { return keys0(); }}); + + private Set keys0() { + final ResourceBundle info = getBreakIteratorInfo(); + final Set k = info.keySet(); + k.removeAll(NON_DATA_KEYS); + return k; + } /** * Returns an instance of the corresponding {@code BreakIteratorInfo} (basename). @@ -84,16 +93,6 @@ public abstract class BreakIteratorResourceBundle extends ResourceBundle { @Override protected Set handleKeySet() { - if (keys == null) { - ResourceBundle info = getBreakIteratorInfo(); - Set k = info.keySet(); - k.removeAll(NON_DATA_KEYS); - synchronized (this) { - if (keys == null) { - keys = k; - } - } - } - return keys; + return keys.get(); } } diff --git a/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java b/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java index d375930dde0..0c16f508018 100644 --- a/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -44,8 +44,11 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; + import sun.util.ResourceBundleEnumeration; /** @@ -69,12 +72,9 @@ public abstract class OpenListResourceBundle extends ResourceBundle { // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification. @Override protected Object handleGetObject(String key) { - if (key == null) { - throw new NullPointerException(); - } - - loadLookupTablesIfNecessary(); - return lookup.get(key); // this class ignores locales + Objects.requireNonNull(key); + return lookup.get() + .get(key); // this class ignores locales } /** @@ -93,26 +93,13 @@ public abstract class OpenListResourceBundle extends ResourceBundle { */ @Override protected Set handleKeySet() { - loadLookupTablesIfNecessary(); - return lookup.keySet(); + return lookup.get() + .keySet(); } @Override public Set keySet() { - if (keyset != null) { - return keyset; - } - Set ks = createSet(); - ks.addAll(handleKeySet()); - if (parent != null) { - ks.addAll(parent.keySet()); - } - synchronized (this) { - if (keyset == null) { - keyset = ks; - } - } - return keyset; + return keyset.get(); } /** @@ -120,38 +107,6 @@ public abstract class OpenListResourceBundle extends ResourceBundle { */ protected abstract Object[][] getContents(); - /** - * Load lookup tables if they haven't been loaded already. - */ - void loadLookupTablesIfNecessary() { - if (lookup == null) { - loadLookup(); - } - } - - /** - * We lazily load the lookup hashtable. This function does the - * loading. - */ - private void loadLookup() { - Object[][] contents = getContents(); - Map temp = createMap(contents.length); - for (int i = 0; i < contents.length; ++i) { - // key must be non-null String, value must be non-null - String key = (String) contents[i][0]; - Object value = contents[i][1]; - if (key == null || value == null) { - throw new NullPointerException(); - } - temp.put(key, value); - } - synchronized (this) { - if (lookup == null) { - lookup = temp; - } - } - } - /** * Lets subclasses provide specialized Map implementations. * Default uses HashMap. @@ -164,6 +119,31 @@ public abstract class OpenListResourceBundle extends ResourceBundle { return new HashSet<>(); } - private volatile Map lookup; - private volatile Set keyset; + private final Supplier> lookup = StableValue.supplier( + new Supplier<>() { public Map get() { return lookup0(); }}); + + private Map lookup0() { + final Object[][] contents = getContents(); + final Map temp = createMap(contents.length); + for (Object[] content : contents) { + // key must be non-null String, value must be non-null + final String key = Objects.requireNonNull((String) content[0]); + final Object value = Objects.requireNonNull(content[1]); + temp.put(key, value); + } + return temp; + } + + private final Supplier> keyset = StableValue.supplier( + new Supplier<>() { public Set get() { return keyset0(); }}); + + private Set keyset0() { + final Set ks = createSet(); + ks.addAll(handleKeySet()); + if (parent != null) { + ks.addAll(parent.keySet()); + } + return ks; + } + } From 1c72b350e417bd210dc6b66eba5afe0e3bc6306c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Sikstr=C3=B6m?= Date: Mon, 9 Jun 2025 09:03:12 +0000 Subject: [PATCH 196/216] 8357053: ZGC: Improved utility for ZPageAge Co-authored-by: Axel Boldt-Christmas Reviewed-by: sjohanss, stefank --- src/hotspot/share/gc/z/zAllocator.cpp | 3 +- src/hotspot/share/gc/z/zAllocator.hpp | 4 +- src/hotspot/share/gc/z/zAllocator.inline.hpp | 5 +- src/hotspot/share/gc/z/zGeneration.cpp | 10 ++-- src/hotspot/share/gc/z/zPageAge.hpp | 18 ++++++- src/hotspot/share/gc/z/zPageAge.inline.hpp | 52 +++++++++++++++++++ src/hotspot/share/gc/z/zRelocate.cpp | 12 ++--- .../share/gc/z/zRelocationSetSelector.cpp | 17 +++--- .../share/gc/z/zRelocationSetSelector.hpp | 10 ++-- .../gc/z/zRelocationSetSelector.inline.hpp | 24 ++++----- src/hotspot/share/gc/z/zStat.cpp | 18 +++---- src/hotspot/share/gc/z/z_globals.hpp | 2 +- src/hotspot/share/utilities/enumIterator.hpp | 27 ++++++++-- test/hotspot/gtest/gc/z/test_zPageAge.cpp | 47 +++++++++++++++++ 14 files changed, 191 insertions(+), 58 deletions(-) create mode 100644 src/hotspot/share/gc/z/zPageAge.inline.hpp create mode 100644 test/hotspot/gtest/gc/z/test_zPageAge.cpp diff --git a/src/hotspot/share/gc/z/zAllocator.cpp b/src/hotspot/share/gc/z/zAllocator.cpp index 22f3b6ba112..dd1ab3b712a 100644 --- a/src/hotspot/share/gc/z/zAllocator.cpp +++ b/src/hotspot/share/gc/z/zAllocator.cpp @@ -23,6 +23,7 @@ #include "gc/z/zAllocator.hpp" #include "gc/z/zObjectAllocator.hpp" +#include "gc/z/zPageAge.inline.hpp" ZAllocatorEden* ZAllocator::_eden; ZAllocatorForRelocation* ZAllocator::_relocation[ZAllocator::_relocation_allocators]; @@ -47,7 +48,7 @@ ZPageAge ZAllocatorForRelocation::install() { for (uint i = 0; i < ZAllocator::_relocation_allocators; ++i) { if (_relocation[i] == nullptr) { _relocation[i] = this; - return static_cast(i + 1); + return to_zpageage(i + 1); } } diff --git a/src/hotspot/share/gc/z/zAllocator.hpp b/src/hotspot/share/gc/z/zAllocator.hpp index 45a70888f9d..ec4c0ec1c9c 100644 --- a/src/hotspot/share/gc/z/zAllocator.hpp +++ b/src/hotspot/share/gc/z/zAllocator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ class ZPage; class ZAllocator { public: - static constexpr uint _relocation_allocators = static_cast(ZPageAge::old); + static constexpr uint _relocation_allocators = ZPageAgeCount - 1; protected: ZObjectAllocator _object_allocator; diff --git a/src/hotspot/share/gc/z/zAllocator.inline.hpp b/src/hotspot/share/gc/z/zAllocator.inline.hpp index ba558a1b0f3..ec64676dbf0 100644 --- a/src/hotspot/share/gc/z/zAllocator.inline.hpp +++ b/src/hotspot/share/gc/z/zAllocator.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,13 +28,14 @@ #include "gc/z/zAddress.inline.hpp" #include "gc/z/zHeap.hpp" +#include "gc/z/zPageAge.inline.hpp" inline ZAllocatorEden* ZAllocator::eden() { return _eden; } inline ZAllocatorForRelocation* ZAllocator::relocation(ZPageAge page_age) { - return _relocation[static_cast(page_age) - 1]; + return _relocation[untype(page_age - 1)]; } inline ZAllocatorForRelocation* ZAllocator::old() { diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 772c5a0a98b..534f0195c90 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -41,6 +41,7 @@ #include "gc/z/zHeap.inline.hpp" #include "gc/z/zJNICritical.hpp" #include "gc/z/zMark.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zPageAllocator.hpp" #include "gc/z/zRelocationSet.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" @@ -699,11 +700,10 @@ uint ZGenerationYoung::compute_tenuring_threshold(ZRelocationSetSelectorStats st uint last_populated_age = 0; size_t last_populated_live = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { const size_t young_live = stats.small(age).live() + stats.medium(age).live() + stats.large(age).live(); if (young_live > 0) { - last_populated_age = i; + last_populated_age = untype(age); last_populated_live = young_live; if (young_live_last > 0) { young_life_expectancy_sum += double(young_live) / double(young_live_last); @@ -842,8 +842,8 @@ void ZGenerationYoung::mark_start() { // Retire allocating pages ZAllocator::eden()->retire_pages(); - for (ZPageAge i = ZPageAge::survivor1; i <= ZPageAge::survivor14; i = static_cast(static_cast(i) + 1)) { - ZAllocator::relocation(i)->retire_pages(); + for (ZPageAge age : ZPageAgeRangeSurvivor) { + ZAllocator::relocation(age)->retire_pages(); } // Reset allocated/reclaimed/used statistics diff --git a/src/hotspot/share/gc/z/zPageAge.hpp b/src/hotspot/share/gc/z/zPageAge.hpp index b7b1688b830..3209790c008 100644 --- a/src/hotspot/share/gc/z/zPageAge.hpp +++ b/src/hotspot/share/gc/z/zPageAge.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -24,6 +24,7 @@ #ifndef SHARE_GC_Z_ZPAGEAGE_HPP #define SHARE_GC_Z_ZPAGEAGE_HPP +#include "utilities/enumIterator.hpp" #include "utilities/globalDefinitions.hpp" enum class ZPageAge : uint8_t { @@ -45,6 +46,19 @@ enum class ZPageAge : uint8_t { old }; -constexpr uint ZPageAgeMax = static_cast(ZPageAge::old); +constexpr uint ZPageAgeCount = static_cast(ZPageAge::old) + 1; +constexpr ZPageAge ZPageAgeLastPlusOne = static_cast(ZPageAgeCount); + +ENUMERATOR_RANGE(ZPageAge, + ZPageAge::eden, + ZPageAge::old); + +using ZPageAgeRange = EnumRange; + +constexpr ZPageAgeRange ZPageAgeRangeEden = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeYoung = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeSurvivor = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeRelocation = ZPageAgeRange::create(); +constexpr ZPageAgeRange ZPageAgeRangeOld = ZPageAgeRange::create(); #endif // SHARE_GC_Z_ZPAGEAGE_HPP diff --git a/src/hotspot/share/gc/z/zPageAge.inline.hpp b/src/hotspot/share/gc/z/zPageAge.inline.hpp new file mode 100644 index 00000000000..0944caa69a6 --- /dev/null +++ b/src/hotspot/share/gc/z/zPageAge.inline.hpp @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#ifndef SHARE_GC_Z_ZPAGEAGE_INLINE_HPP +#define SHARE_GC_Z_ZPAGEAGE_INLINE_HPP + +#include "gc/z/zPageAge.hpp" + +#include "utilities/checkedCast.hpp" + +#include + +inline uint untype(ZPageAge age) { + return static_cast(age); +} + +inline ZPageAge to_zpageage(uint age) { + assert(age < ZPageAgeCount, "Invalid age"); + return static_cast(age); +} + +inline ZPageAge operator+(ZPageAge age, size_t size) { + const auto size_value = checked_cast>(size); + return to_zpageage(untype(age) + size_value); +} + +inline ZPageAge operator-(ZPageAge age, size_t size) { + const auto size_value = checked_cast>(size); + return to_zpageage(untype(age) - size_value); +} + +#endif // SHARE_GC_Z_ZPAGEAGE_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zRelocate.cpp b/src/hotspot/share/gc/z/zRelocate.cpp index df2dd8a01cb..b45d8b70e72 100644 --- a/src/hotspot/share/gc/z/zRelocate.cpp +++ b/src/hotspot/share/gc/z/zRelocate.cpp @@ -488,11 +488,11 @@ public: } ZPage* shared(ZPageAge age) { - return _shared[static_cast(age) - 1]; + return _shared[untype(age - 1)]; } void set_shared(ZPageAge age, ZPage* page) { - _shared[static_cast(age) - 1] = page; + _shared[untype(age - 1)] = page; } ZPage* alloc_and_retire_target_page(ZForwarding* forwarding, ZPage* target) { @@ -570,11 +570,11 @@ private: ZPage* target(ZPageAge age) { - return _target[static_cast(age) - 1]; + return _target[untype(age - 1)]; } void set_target(ZPageAge age, ZPage* page) { - _target[static_cast(age) - 1] = page; + _target[untype(age - 1)] = page; } size_t object_alignment() const { @@ -1232,12 +1232,12 @@ ZPageAge ZRelocate::compute_to_age(ZPageAge from_age) { return ZPageAge::old; } - const uint age = static_cast(from_age); + const uint age = untype(from_age); if (age >= ZGeneration::young()->tenuring_threshold()) { return ZPageAge::old; } - return static_cast(age + 1); + return to_zpageage(age + 1); } class ZFlipAgePagesTask : public ZTask { diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp index e9ef66a19dc..aac4fd51271 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp @@ -25,6 +25,7 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zForwarding.inline.hpp" #include "gc/z/zPage.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" @@ -117,8 +118,8 @@ void ZRelocationSetSelectorGroup::select_inner() { const int npages = _live_pages.length(); int selected_from = 0; int selected_to = 0; - size_t npages_selected[ZPageAgeMax + 1] = { 0 }; - size_t selected_live_bytes[ZPageAgeMax + 1] = { 0 }; + size_t npages_selected[ZPageAgeCount] = { 0 }; + size_t selected_live_bytes[ZPageAgeCount] = { 0 }; size_t selected_forwarding_entries = 0; size_t from_live_bytes = 0; @@ -149,8 +150,8 @@ void ZRelocationSetSelectorGroup::select_inner() { if (diff_reclaimable > _fragmentation_limit) { selected_from = from; selected_to = to; - selected_live_bytes[static_cast(page->age())] += page_live_bytes; - npages_selected[static_cast(page->age())] += 1; + selected_live_bytes[untype(page->age())] += page_live_bytes; + npages_selected[untype(page->age())] += 1; selected_forwarding_entries = from_forwarding_entries; } @@ -172,7 +173,7 @@ void ZRelocationSetSelectorGroup::select_inner() { _forwarding_entries = selected_forwarding_entries; // Update statistics - for (uint i = 0; i <= ZPageAgeMax; ++i) { + for (uint i = 0; i < ZPageAgeCount; ++i) { _stats[i]._relocate = selected_live_bytes[i]; _stats[i]._npages_selected = npages_selected[i]; } @@ -200,7 +201,7 @@ void ZRelocationSetSelectorGroup::select() { } ZRelocationSetSelectorGroupStats s{}; - for (uint i = 0; i <= ZPageAgeMax; ++i) { + for (uint i = 0; i < ZPageAgeCount; ++i) { s._npages_candidates += _stats[i].npages_candidates(); s._total += _stats[i].total(); s._empty += _stats[i].empty(); @@ -239,8 +240,8 @@ void ZRelocationSetSelector::select() { ZRelocationSetSelectorStats ZRelocationSetSelector::stats() const { ZRelocationSetSelectorStats stats; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { + const uint i = untype(age); stats._small[i] = _small.stats(age); stats._medium[i] = _medium.stats(age); stats._large[i] = _large.stats(age); diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp index b6ec2347153..21772405f25 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -62,9 +62,9 @@ class ZRelocationSetSelectorStats { friend class ZRelocationSetSelector; private: - ZRelocationSetSelectorGroupStats _small[ZPageAgeMax + 1]; - ZRelocationSetSelectorGroupStats _medium[ZPageAgeMax + 1]; - ZRelocationSetSelectorGroupStats _large[ZPageAgeMax + 1]; + ZRelocationSetSelectorGroupStats _small[ZPageAgeCount]; + ZRelocationSetSelectorGroupStats _medium[ZPageAgeCount]; + ZRelocationSetSelectorGroupStats _large[ZPageAgeCount]; size_t _has_relocatable_pages; @@ -90,7 +90,7 @@ private: ZArray _live_pages; ZArray _not_selected_pages; size_t _forwarding_entries; - ZRelocationSetSelectorGroupStats _stats[ZPageAgeMax + 1]; + ZRelocationSetSelectorGroupStats _stats[ZPageAgeCount]; bool is_disabled(); bool is_selectable(); diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp index 7cd0a005aac..7740e0764a6 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zPage.inline.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "utilities/powerOfTwo.hpp" inline size_t ZRelocationSetSelectorGroupStats::npages_candidates() const { @@ -60,15 +61,15 @@ inline bool ZRelocationSetSelectorStats::has_relocatable_pages() const { } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::small(ZPageAge age) const { - return _small[static_cast(age)]; + return _small[untype(age)]; } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::medium(ZPageAge age) const { - return _medium[static_cast(age)]; + return _medium[untype(age)]; } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::large(ZPageAge age) const { - return _large[static_cast(age)]; + return _large[untype(age)]; } inline bool ZRelocationSetSelectorGroup::pre_filter_page(const ZPage* page, size_t live_bytes) const { @@ -113,7 +114,7 @@ inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { } const size_t size = page->size(); - const uint age = static_cast(page->age()); + const uint age = untype(page->age()); _stats[age]._npages_candidates++; _stats[age]._total += size; _stats[age]._live += live; @@ -122,7 +123,7 @@ inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { inline void ZRelocationSetSelectorGroup::register_empty_page(ZPage* page) { const size_t size = page->size(); - const uint age = static_cast(page->age()); + const uint age = untype(page->age()); _stats[age]._npages_candidates++; _stats[age]._total += size; _stats[age]._empty += size; @@ -141,7 +142,7 @@ inline size_t ZRelocationSetSelectorGroup::forwarding_entries() const { } inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorGroup::stats(ZPageAge age) const { - return _stats[static_cast(age)]; + return _stats[untype(age)]; } inline void ZRelocationSetSelector::register_live_page(ZPage* page) { @@ -188,8 +189,7 @@ inline void ZRelocationSetSelector::clear_empty_pages() { inline size_t ZRelocationSetSelector::total() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).total() + _medium.stats(age).total() + _large.stats(age).total(); } return sum; @@ -197,8 +197,7 @@ inline size_t ZRelocationSetSelector::total() const { inline size_t ZRelocationSetSelector::empty() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).empty() + _medium.stats(age).empty() + _large.stats(age).empty(); } return sum; @@ -206,8 +205,7 @@ inline size_t ZRelocationSetSelector::empty() const { inline size_t ZRelocationSetSelector::relocate() const { size_t sum = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { sum += _small.stats(age).relocate() + _medium.stats(age).relocate() + _large.stats(age).relocate(); } return sum; diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index ec751cbb693..bfde904c1e7 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -30,6 +30,7 @@ #include "gc/z/zGeneration.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zNMethodTable.hpp" +#include "gc/z/zPageAge.inline.hpp" #include "gc/z/zPageAllocator.inline.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zStat.hpp" @@ -1499,9 +1500,7 @@ void ZStatRelocation::print_page_summary() { summary.relocate += stats.relocate(); }; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); - + for (ZPageAge age : ZPageAgeRange()) { account_page_size(small_summary, _selector_stats.small(age)); account_page_size(medium_summary, _selector_stats.medium(age)); account_page_size(large_summary, _selector_stats.large(age)); @@ -1557,13 +1556,13 @@ void ZStatRelocation::print_age_table() { .center("Large") .end()); - size_t live[ZPageAgeMax + 1] = {}; - size_t total[ZPageAgeMax + 1] = {}; + size_t live[ZPageAgeCount] = {}; + size_t total[ZPageAgeCount] = {}; uint oldest_none_empty_age = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { + uint i = untype(age); auto summarize_pages = [&](const ZRelocationSetSelectorGroupStats& stats) { live[i] += stats.live(); total[i] += stats.total(); @@ -1579,7 +1578,7 @@ void ZStatRelocation::print_age_table() { } for (uint i = 0; i <= oldest_none_empty_age; ++i) { - ZPageAge age = static_cast(i); + ZPageAge age = to_zpageage(i); FormatBuffer<> age_str(""); if (age == ZPageAge::eden) { @@ -1791,8 +1790,7 @@ void ZStatHeap::at_select_relocation_set(const ZRelocationSetSelectorStats& stat ZLocker locker(&_stat_lock); size_t live = 0; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast(i); + for (ZPageAge age : ZPageAgeRange()) { live += stats.small(age).live() + stats.medium(age).live() + stats.large(age).live(); } _at_mark_end.live = live; diff --git a/src/hotspot/share/gc/z/z_globals.hpp b/src/hotspot/share/gc/z/z_globals.hpp index e1f525e5372..d818cf9fc3f 100644 --- a/src/hotspot/share/gc/z/z_globals.hpp +++ b/src/hotspot/share/gc/z/z_globals.hpp @@ -113,7 +113,7 @@ \ product(int, ZTenuringThreshold, -1, DIAGNOSTIC, \ "Young generation tenuring threshold, -1 for dynamic computation")\ - range(-1, static_cast(ZPageAgeMax)) \ + range(-1, static_cast(ZPageAgeCount) - 1) \ \ develop(bool, ZVerifyOops, false, \ "Verify accessed oops") \ diff --git a/src/hotspot/share/utilities/enumIterator.hpp b/src/hotspot/share/utilities/enumIterator.hpp index 6fa7f071f4a..42cc405fcd7 100644 --- a/src/hotspot/share/utilities/enumIterator.hpp +++ b/src/hotspot/share/utilities/enumIterator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,14 @@ #ifndef SHARE_UTILITIES_ENUMITERATOR_HPP #define SHARE_UTILITIES_ENUMITERATOR_HPP -#include -#include #include "memory/allStatic.hpp" #include "metaprogramming/enableIf.hpp" #include "metaprogramming/primitiveConversions.hpp" #include "utilities/debug.hpp" +#include +#include + // Iteration support for enums. // // E is enum type, U is underlying type of E. @@ -147,6 +148,12 @@ public: assert(value <= end, "out of range"); } + template + static constexpr void assert_in_range() { + static_assert(_start <= static_cast(Value), "out of range"); + static_assert(static_cast(Value) <= _end, "out of range"); + } + // Convert an enumerator value to the corresponding underlying type. static constexpr Underlying underlying_value(T value) { return static_cast(value); @@ -229,6 +236,12 @@ class EnumRange { assert(size() > 0, "empty range"); } + struct ConstExprConstructTag {}; + + constexpr EnumRange(T start, T end, ConstExprConstructTag) : + _start(Traits::underlying_value(start)), + _end(Traits::underlying_value(end)) {} + public: using EnumType = T; using Iterator = EnumIterator; @@ -252,6 +265,14 @@ public: assert(start <= end, "invalid range"); } + template + static constexpr EnumRange create() { + Traits::template assert_in_range(); + Traits::template assert_in_range(); + static_assert(Start <= End, "invalid range"); + return EnumRange(Start, End, ConstExprConstructTag{}); + } + // Return an iterator for the start of the range. constexpr Iterator begin() const { return Iterator(Traits::enumerator(_start)); diff --git a/test/hotspot/gtest/gc/z/test_zPageAge.cpp b/test/hotspot/gtest/gc/z/test_zPageAge.cpp new file mode 100644 index 00000000000..1c93a380db7 --- /dev/null +++ b/test/hotspot/gtest/gc/z/test_zPageAge.cpp @@ -0,0 +1,47 @@ +/* + * 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 "gc/z/zPageAge.hpp" +#include "unittest.hpp" + +TEST(ZPageAgeRangeTest, test) { + ZPageAgeRange rangeEden = ZPageAgeRangeEden; + EXPECT_EQ(rangeEden.first(), ZPageAge::eden); + EXPECT_EQ(rangeEden.last(), ZPageAge::eden); + + ZPageAgeRange rangeYoung = ZPageAgeRangeYoung; + EXPECT_EQ(rangeYoung.first(), ZPageAge::eden); + EXPECT_EQ(rangeYoung.last(), ZPageAge::survivor14); + + ZPageAgeRange rangeSurvivor = ZPageAgeRangeSurvivor; + EXPECT_EQ(rangeSurvivor.first(), ZPageAge::survivor1); + EXPECT_EQ(rangeSurvivor.last(), ZPageAge::survivor14); + + ZPageAgeRange rangeRelocation = ZPageAgeRangeRelocation; + EXPECT_EQ(rangeRelocation.first(), ZPageAge::survivor1); + EXPECT_EQ(rangeRelocation.last(), ZPageAge::old); + + ZPageAgeRange rangeOld = ZPageAgeRangeOld; + EXPECT_EQ(rangeOld.first(), ZPageAge::old); + EXPECT_EQ(rangeOld.last(), ZPageAge::old); +} From 2103dc15cb662fd8795b1b51d9cb61c389bed7a0 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Mon, 9 Jun 2025 13:35:01 +0000 Subject: [PATCH 197/216] 8358452: JNI exception pending in Java_sun_awt_screencast_ScreencastHelper_remoteDesktopKeyImpl of screencast_pipewire.c:1214 (ID: 51119) Reviewed-by: psadhukhan, serb, aivanov, avu --- .../unix/native/libawt_xawt/awt/screencast_pipewire.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c index ec12445c87b..ea921d3f636 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c @@ -1016,6 +1016,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); isGtkMainThread = gtk->g_main_context_is_owner(gtk->g_main_context_default()); DEBUG_SCREENCAST( @@ -1121,7 +1122,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; - + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); DEBUG_SCREENCAST("moving mouse to\n\t%d %d\n\twith token |%s|\n", jx, jy, token); @@ -1151,6 +1152,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, mouse pressing %d\n", result, buttons) @@ -1178,6 +1180,7 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopMou const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, mouse wheel %d\n", result, jWheelAmt) @@ -1206,13 +1209,14 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_remoteDesktopKey int key = awt_getX11KeySym(jkey); AWT_UNLOCK(); - if (key == NoSymbol) { + if (key == NoSymbol || (*env)->ExceptionCheck(env)) { return RESULT_ERROR; } const gchar *token = jtoken ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + JNU_CHECK_EXCEPTION_RETURN(env, RESULT_ERROR); gboolean result = initPortal(token, NULL, 0); DEBUG_SCREENCAST("init result %b, key %d -> %d isPress %b\n", result, jkey, key, isPress) From eb8ee8bdc7c170910abc9aa18de1e22677160358 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 9 Jun 2025 16:01:18 +0000 Subject: [PATCH 198/216] 8358731: Remove jdk.internal.access.JavaAWTAccess.java Reviewed-by: dfuchs, serb --- .../jdk/internal/access/JavaAWTAccess.java | 36 -- .../jdk/internal/access/SharedSecrets.java | 11 - .../share/classes/sun/awt/AppContext.java | 63 --- .../logging/LogManagerAppContextDeadlock.java | 381 ------------- .../java/util/logging/TestGetLoggerNPE.java | 99 ---- .../util/logging/TestUILoggerContext.java | 520 ------------------ 6 files changed, 1110 deletions(-) delete mode 100644 src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java delete mode 100644 test/jdk/java/util/logging/LogManagerAppContextDeadlock.java delete mode 100644 test/jdk/java/util/logging/TestGetLoggerNPE.java delete mode 100644 test/jdk/java/util/logging/TestUILoggerContext.java diff --git a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java deleted file mode 100644 index a4c170ca918..00000000000 --- a/src/java.base/share/classes/jdk/internal/access/JavaAWTAccess.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.access; - -public interface JavaAWTAccess { - - // Returns the AppContext used for applet logging isolation, or null if - // no isolation is required. - // If there's no applet, or if the caller is a stand alone application, - // or running in the main app context, returns null. - // Otherwise, returns the AppContext of the calling applet. - public Object getAppletContext(); -} diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java index bc955a76abb..5c6212d0bf6 100644 --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java @@ -59,7 +59,6 @@ import javax.security.auth.x500.X500Principal; */ public class SharedSecrets { - private static JavaAWTAccess javaAWTAccess; private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansAccess javaBeansAccess; private static JavaLangAccess javaLangAccess; @@ -321,16 +320,6 @@ public class SharedSecrets { javaUtilZipFileAccess = access; } - public static void setJavaAWTAccess(JavaAWTAccess jaa) { - javaAWTAccess = jaa; - } - - public static JavaAWTAccess getJavaAWTAccess() { - // this may return null in which case calling code needs to - // provision for. - return javaAWTAccess; - } - public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) { javaAWTFontAccess = jafa; } diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index a35d89f6a0c..3b93f1d2755 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -42,8 +42,6 @@ import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import java.lang.ref.SoftReference; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; @@ -746,67 +744,6 @@ public final class AppContext { return changeSupport.getPropertyChangeListeners(propertyName); } - // Set up JavaAWTAccess in SharedSecrets - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - private boolean hasRootThreadGroup(final AppContext ecx) { - return ecx.threadGroup.getParent() == null; - } - - /** - * Returns the AppContext used for applet logging isolation, or null if - * the default global context can be used. - * If there's no applet, or if the caller is a stand alone application, - * or running in the main app context, returns null. - * Otherwise, returns the AppContext of the calling applet. - * @return null if the global default context can be used, - * an AppContext otherwise. - **/ - public Object getAppletContext() { - // There's no AppContext: return null. - // No need to call getAppContext() if numAppContext == 0: - // it means that no AppContext has been created yet, and - // we don't want to trigger the creation of a main app - // context since we don't need it. - if (numAppContexts.get() == 0) return null; - - AppContext ecx = null; - - // Not sure we really need to re-check numAppContexts here. - // If all applets have gone away then we could have a - // numAppContexts coming back to 0. So we recheck - // it here because we don't want to trigger the - // creation of a main AppContext in that case. - // This is probably not 100% MT-safe but should reduce - // the window of opportunity in which that issue could - // happen. - if (numAppContexts.get() > 0) { - // Defaults to thread group caching. - // This is probably not required as we only really need - // isolation in a deployed applet environment, in which - // case ecx will not be null when we reach here - // However it helps emulate the deployed environment, - // in tests for instance. - ecx = ecx != null ? ecx : getAppContext(); - } - - // getAppletContext() may be called when initializing the main - // app context - in which case mainAppContext will still be - // null. To work around this issue we simply use - // AppContext.threadGroup.getParent() == null instead, since - // mainAppContext is the only AppContext which should have - // the root TG as its thread group. - // See: JDK-8023258 - final boolean isMainAppContext = ecx == null - || mainAppContext == ecx - || mainAppContext == null && hasRootThreadGroup(ecx); - - return isMainAppContext ? null : ecx; - } - - }); - } - public static T getSoftReferenceValue(Object key, Supplier supplier) { diff --git a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java deleted file mode 100644 index f39b46b43d1..00000000000 --- a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.util.Enumeration; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/** - * @test - * @bug 8065991 - * @summary check that when LogManager is initialized, a deadlock similar - * to that described in 8065709 will not occur. - * @modules java.base/jdk.internal.access - * java.logging - * java.management - * @run main/othervm LogManagerAppContextDeadlock UNSECURE - * @run main/othervm LogManagerAppContextDeadlock SECURE - * - * @author danielfuchs - */ -public class LogManagerAppContextDeadlock { - - public static final Semaphore sem = new Semaphore(0); - public static final Semaphore sem2 = new Semaphore(0); - public static final Semaphore sem3 = new Semaphore(-2); - public static volatile boolean goOn = true; - public static volatile Exception thrown; - - // Emulate EventQueue - static class FakeEventQueue { - static final Logger logger = Logger.getLogger("foo"); - } - - // Emulate AppContext - static class FakeAppContext { - - static final AtomicInteger numAppContexts = new AtomicInteger(0); - static final class FakeAppContextLock {} - static final FakeAppContextLock lock = new FakeAppContextLock(); - static volatile FakeAppContext appContext; - - final FakeEventQueue queue; - FakeAppContext() { - appContext = this; - numAppContexts.incrementAndGet(); - // release sem2 to let Thread t2 call Logger.getLogger(). - sem2.release(); - try { - // Wait until we JavaAWTAccess is called by LogManager. - // Thread 2 will call Logger.getLogger() which will - // trigger a call to JavaAWTAccess - which will release - // sem, thus ensuring that Thread #2 is where we want it. - sem.acquire(); - System.out.println("Sem acquired: Thread #2 has called JavaAWTAccess"); - } catch(InterruptedException x) { - Thread.interrupted(); - } - queue = new FakeEventQueue(); - } - - static FakeAppContext getAppContext() { - synchronized (lock) { - if (numAppContexts.get() == 0) { - return new FakeAppContext(); - } - return appContext; - } - } - - static { - SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - @Override - public Object getAppletContext() { - if (numAppContexts.get() == 0) return null; - // We are in JavaAWTAccess, we can release sem and let - // FakeAppContext constructor proceeed. - System.out.println("Releasing Sem"); - sem.release(); - return getAppContext(); - } - - }); - } - - } - - - // Test with or without a security manager - public static enum TestCase { - UNSECURE, SECURE; - public void run() throws Exception { - System.out.println("Running test case: " + name()); - Configure.setUp(this); - test(this); - } - } - - public static void test(TestCase test) throws Exception { - Thread t1 = new Thread() { - @Override - public void run() { - sem3.release(); - System.out.println("FakeAppContext.getAppContext()"); - FakeAppContext.getAppContext(); - System.out.println("Done: FakeAppContext.getAppContext()"); - } - }; - t1.setDaemon(true); - t1.start(); - Thread t2 = new Thread() { - public Object logger; - public void run() { - sem3.release(); - try { - // Wait until Thread1 is in FakeAppContext constructor - sem2.acquire(); - System.out.println("Sem2 acquired: Thread #1 will be waiting to acquire Sem"); - } catch (InterruptedException ie) { - Thread.interrupted(); - } - System.out.println("Logger.getLogger(name).info(name)"); - // stick the logger in an instance variable to prevent it - // from being garbage collected before the main thread - // calls LogManager.getLogger() below. - logger = Logger.getLogger(test.name());//.info(name); - System.out.println("Done: Logger.getLogger(name).info(name)"); - } - }; - t2.setDaemon(true); - t2.start(); - System.out.println("Should exit now..."); - Thread detector = new DeadlockDetector(); - detector.start(); - - // Wait for the 3 threads to start - sem3.acquire(); - - // Now wait for t1 & t2 to finish, or for a deadlock to be detected. - while (goOn && (t1.isAlive() || t2.isAlive())) { - if (t2.isAlive()) t2.join(1000); - if (test == TestCase.UNSECURE && System.getSecurityManager() == null) { - // if there's no security manager, AppContext.getAppContext() is - // not called - so Thread t2 will not end up calling - // sem.release(). In that case we must release the semaphore here - // so that t1 can proceed. - if (LogManager.getLogManager().getLogger(TestCase.UNSECURE.name()) != null) { - // means Thread t2 has created the logger - sem.release(); - } - } - if (t1.isAlive()) t1.join(1000); - } - if (thrown != null) { - throw thrown; - } - } - - // Thrown by the deadlock detector - static final class DeadlockException extends RuntimeException { - public DeadlockException(String message) { - super(message); - } - @Override - public void printStackTrace() { - } - } - - public static void main(String[] args) throws Exception { - - if (args.length == 0) { - args = new String[] { "SECURE" }; - } - - // If we don't initialize LogManager here, there will be - // a deadlock. - // See - // for more details. - Logger.getLogger("main").info("starting..."); - try { - TestCase.valueOf(args[0]).run(); - System.out.println("Test "+args[0]+" Passed"); - } catch(Throwable t) { - System.err.println("Test " + args[0] +" failed: " + t); - t.printStackTrace(); - } - } - - // Called by the deadlock detector when a deadlock is found. - static void fail(Exception x) { - x.printStackTrace(); - if (thrown == null) { - thrown = x; - } - goOn = false; - } - - // A thread that detect deadlocks. - static final class DeadlockDetector extends Thread { - - public DeadlockDetector() { - this.setDaemon(true); - } - - @Override - public void run() { - sem3.release(); - Configure.doPrivileged(this::loop); - } - public void loop() { - while(goOn) { - try { - long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); - ids = ids == null ? new long[0] : ids; - if (ids.length == 1) { - throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); - } else if (ids.length > 0) { - ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids, Integer.MAX_VALUE); - System.err.println("Found "+ids.length+" deadlocked threads: "); - for (ThreadInfo inf : infos) { - System.err.println(inf); - } - throw new DeadlockException("Found "+ids.length+" deadlocked threads"); - } - Thread.sleep(100); - } catch(InterruptedException | RuntimeException x) { - fail(x); - } - } - } - - } - - // A helper class to configure the security manager for the test, - // and bypass it when needed. - static class Configure { - static Policy policy = null; - static final ThreadLocal allowAll = new ThreadLocal() { - @Override - protected AtomicBoolean initialValue() { - return new AtomicBoolean(false); - } - }; - static void setUp(TestCase test) { - switch (test) { - case SECURE: - if (policy == null && System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } else if (policy == null) { - policy = new SimplePolicy(TestCase.SECURE, allowAll); - Policy.setPolicy(policy); - System.setSecurityManager(new SecurityManager()); - } - if (System.getSecurityManager() == null) { - throw new IllegalStateException("No SecurityManager."); - } - if (policy == null) { - throw new IllegalStateException("policy not configured"); - } - break; - case UNSECURE: - if (System.getSecurityManager() != null) { - throw new IllegalStateException("SecurityManager already set"); - } - break; - default: - new InternalError("No such testcase: " + test); - } - } - static void doPrivileged(Runnable run) { - allowAll.get().set(true); - try { - run.run(); - } finally { - allowAll.get().set(false); - } - } - } - - // A Helper class to build a set of permissions. - static final class PermissionsBuilder { - final Permissions perms; - public PermissionsBuilder() { - this(new Permissions()); - } - public PermissionsBuilder(Permissions perms) { - this.perms = perms; - } - public PermissionsBuilder add(Permission p) { - perms.add(p); - return this; - } - public PermissionsBuilder addAll(PermissionCollection col) { - if (col != null) { - for (Enumeration e = col.elements(); e.hasMoreElements(); ) { - perms.add(e.nextElement()); - } - } - return this; - } - public Permissions toPermissions() { - final PermissionsBuilder builder = new PermissionsBuilder(); - builder.addAll(perms); - return builder.perms; - } - } - - // Policy for the test... - public static class SimplePolicy extends Policy { - - static final Policy DEFAULT_POLICY = Policy.getPolicy(); - - final Permissions permissions; - final Permissions allPermissions; - final ThreadLocal allowAll; // actually: this should be in a thread locale - public SimplePolicy(TestCase test, ThreadLocal allowAll) { - this.allowAll = allowAll; - // we don't actually need any permission to create our - // FileHandlers because we're passing invalid parameters - // which will make the creation fail... - permissions = new Permissions(); - permissions.add(new RuntimePermission("accessClassInPackage.jdk.internal.access")); - - // these are used for configuring the test itself... - allPermissions = new Permissions(); - allPermissions.add(new java.security.AllPermission()); - - } - - @Override - public boolean implies(ProtectionDomain domain, Permission permission) { - if (allowAll.get().get()) return allPermissions.implies(permission); - return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission); - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return new PermissionsBuilder().addAll(allowAll.get().get() - ? allPermissions : permissions).toPermissions(); - } - } - -} diff --git a/test/jdk/java/util/logging/TestGetLoggerNPE.java b/test/jdk/java/util/logging/TestGetLoggerNPE.java deleted file mode 100644 index 02c57b75067..00000000000 --- a/test/jdk/java/util/logging/TestGetLoggerNPE.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -import java.io.PrintStream; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8025512 - * - * @summary NPE with logging while launching webstart - * - * @modules java.base/jdk.internal.access - * java.logging - * @build TestGetLoggerNPE - * @run main/othervm TestGetLoggerNPE getLogger - * @run main/othervm TestGetLoggerNPE getLogManager - */ -public class TestGetLoggerNPE { - static volatile Throwable thrown = null; - public static void main(String[] args) throws Exception { - final String testCase = args.length == 0 ? "getLogger" : args[0]; - final JavaAWTAccessStub access = new JavaAWTAccessStub(); - SharedSecrets.setJavaAWTAccess(access); - final ThreadGroup tg = new ThreadGroup("TestGroup"); - Thread t = new Thread(tg, "test") { - public void run() { - try { - access.setContext(Context.ONE); - final PrintStream out = System.out; - System.setOut(null); - try { - if ("getLogger".equals(testCase)) { - Logger.getLogger("sun.plugin"); - } else { - LogManager.getLogManager(); - } - } finally { - System.setOut(out); - } - - System.out.println(Logger.global); - } catch (Throwable x) { - x.printStackTrace(); - thrown = x; - } - } - }; - t.start(); - t.join(); - if (thrown == null) { - System.out.println("PASSED: " + testCase); - } else { - System.err.println("FAILED: " + testCase); - throw new Error("Test failed: " + testCase + " - " + thrown, thrown); - } - - } - - static enum Context { ONE, TWO }; - - static final class JavaAWTAccessStub implements JavaAWTAccess { - private static final InheritableThreadLocal context = new InheritableThreadLocal<>(); - - - public void setContext(Context context) { - JavaAWTAccessStub.context.set(context); - } - - @Override - public Object getAppletContext() { - return context.get(); - } - - } - -} diff --git a/test/jdk/java/util/logging/TestUILoggerContext.java b/test/jdk/java/util/logging/TestUILoggerContext.java deleted file mode 100644 index d5e170a1100..00000000000 --- a/test/jdk/java/util/logging/TestUILoggerContext.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; - -/* - * @test - * @bug 8017174 8010727 8019945 - * @summary NPE when using Logger.getAnonymousLogger or - * LogManager.getLogManager().getLogger - * - * @modules java.base/jdk.internal.access - * java.logging - * @run main/othervm TestUILoggerContext LoadingUIContext - * @run main/othervm TestUILoggerContext LoadingMain - * @run main/othervm TestUILoggerContext One - * @run main/othervm TestUILoggerContext Two - * @run main/othervm TestUILoggerContext Three - * @run main/othervm TestUILoggerContext Four - * @run main/othervm TestUILoggerContext Five - * @run main/othervm TestUILoggerContext Six - * @run main/othervm TestUILoggerContext Seven - * @run main/othervm TestUILoggerContext - */ - -// NOTE: We run in other VM in order to cause LogManager class to be loaded anew. -public class TestUILoggerContext { - - // The bridge class initializes the logging system. - // It stubs the UI context in order to simulate context changes. - // - public static class Bridge { - - private static class JavaAWTAccessStub implements JavaAWTAccess { - boolean active = true; - - private static class TestExc { - private final Map map = new HashMap<>(); - void put(Object key, Object v) { map.put(key, v); } - Object get(Object key) { return map.get(key); } - void remove(Object o) { map.remove(o); } - public static TestExc exc(Object o) { - return TestExc.class.cast(o); - } - } - - TestExc exc; - - @Override - public Object getAppletContext() { return active ? exc : null; } - } - - static final JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub(); - public static void init() { - SharedSecrets.setJavaAWTAccess(javaAwtAccess); - } - - public static void changeContext() { - System.out.println("... Switching to a new UI context ..."); - javaAwtAccess.active = true; - javaAwtAccess.exc = new JavaAWTAccessStub.TestExc(); - } - - public static void desactivate() { - System.out.println("... Running with no UI context ..."); - javaAwtAccess.exc = null; - javaAwtAccess.active = false; - } - - public static class CustomAnonymousLogger extends Logger { - public CustomAnonymousLogger() { - this(""); - } - public CustomAnonymousLogger(String name) { - super(null, null); - System.out.println( " LogManager: " +LogManager.getLogManager()); - System.out.println( " getLogger: " +LogManager.getLogManager().getLogger(name)); - setParent(LogManager.getLogManager().getLogger(name)); - } - } - - public static class CustomLogger extends Logger { - CustomLogger(String name) { - super(name, null); - } - } - } - - public static enum TestCase { - LoadingUIContext, LoadingMain, One, Two, Three, Four, Five, Six, Seven; - public void test() { - switch(this) { - // When run - each of these two tests must be - // run before any other tests and before each other. - case LoadingUIContext: testLoadingUIContext(); break; - case LoadingMain: testLoadingMain(); break; - case One: testOne(); break; - case Two: testTwo(); break; - case Three: testThree(); break; - case Four: testFour(); break; - case Five: testFive(); break; - case Six: testSix(); break; - case Seven: testSeven(); break; - } - } - public String describe() { - switch(this) { - case LoadingUIContext: - return "Test that when the LogManager class is" - + " loaded with UI context first," - + "\n all LoggerContexts are correctly initialized"; - case LoadingMain: - return "Test that when the LogManager class is" - + " loaded in the main thread first," - + "\n all LoggerContexts are correctly initialized"; - case One: - return "Test that Logger.getAnonymousLogger()" - + " and new CustomAnonymousLogger() don't throw NPE"; - case Two: - return "Test that Logger.getLogger(\"\")" - + " does not return null nor throws NPE"; - case Three: - return "Test that LogManager.getLogManager().getLogger(\"\")" - + " does not return null nor throws NPE"; - case Four: - return "Test that Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not return null,\n and that" - + " new CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME)" - + " does not throw NPE"; - case Five: - return "Test that LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME)" - + "\n does not return null nor throws NPE"; - case Six: - return "Test that manager.getLogger(Logger.GLOBAL_LOGGER_NAME)" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"global\" in that" - + " non default instance."; - case Seven: return "Test that manager.getLogger(\"\")" - + " returns null\n when manager is not the default" - + " LogManager instance.\n" - + "Test adding a new logger named \"\" in that" - + " non default instance."; - default: return "Undefined"; - } - } - }; - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - Bridge.init(); - EnumSet tests = EnumSet.noneOf(TestCase.class); - for (String arg : args) { - tests.add(TestCase.valueOf(arg)); - } - if (args.length == 0) { - tests = EnumSet.complementOf(EnumSet.of(TestCase.LoadingMain)); - } - final EnumSet loadingTests = - EnumSet.of(TestCase.LoadingUIContext, TestCase.LoadingMain); - int testrun = 0; - for (TestCase test : tests) { - if (loadingTests.contains(test)) { - if (testrun > 0) { - throw new UnsupportedOperationException("Test case " - + test + " must be executed first!"); - } - } - System.out.println("Testing "+ test+": "); - System.out.println(test.describe()); - try { - test.test(); - } catch (Exception x) { - throw new Error(String.valueOf(test) - + "failed: "+x+"\n "+"FAILED: "+test.describe()+"\n", x); - } finally { - testrun++; - } - Bridge.changeContext(); - System.out.println("PASSED: "+ test); - } - } - - public static void testLoadingUIContext() { - Bridge.changeContext(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.desactivate(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - } - - public static void testLoadingMain() { - Bridge.desactivate(); - - Logger bar = new Bridge.CustomLogger("com.foo.Bar"); - LogManager.getLogManager().addLogger(bar); - assertNotNull(bar.getParent()); - testParent(bar); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(bar.getName())); - - Bridge.changeContext(); - - Logger foo = new Bridge.CustomLogger("com.foo.Foo"); - boolean b = LogManager.getLogManager().addLogger(foo); - assertEquals(Boolean.TRUE, Boolean.valueOf(b)); - assertNotNull(foo.getParent()); - testParent(foo); - testParent(LogManager.getLogManager().getLogger("global")); - testParent(LogManager.getLogManager().getLogger(foo.getName())); - - } - - public static void testOne() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getAnonymousLogger(); - Logger logger1b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger2 = Logger.getAnonymousLogger(); - Logger logger2b = Logger.getAnonymousLogger(); - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(); - Logger logger3b = new Bridge.CustomAnonymousLogger(); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(); - Logger logger4b = new Bridge.CustomAnonymousLogger(); - } - } - - - public static void testTwo() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(""); - Logger logger1b = Logger.getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = Logger.getLogger(""); - Logger logger2b = Logger.getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testThree() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(""); - Logger logger1b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - Logger logger2 = LogManager.getLogManager().getLogger(""); - Logger logger2b = LogManager.getLogManager().getLogger(""); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - assertEquals(logger1, logger2); - } - } - - public static void testFour() { - for (int i=0; i<3 ; i++) { - Logger logger1 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - Bridge.changeContext(); - - Logger logger2 = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - - Bridge.changeContext(); - Logger logger3 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Bridge.changeContext(); - Logger logger4 = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = new Bridge.CustomAnonymousLogger(Logger.GLOBAL_LOGGER_NAME); - } - } - - public static void testFive() { - for (int i=0; i<3 ; i++) { - Logger logger1 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger1); - assertNotNull(logger1b); - assertEquals(logger1, logger1b); - - Bridge.changeContext(); - - Logger logger2 = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, logger2b); - - assertEquals(logger1, logger2); - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - * off. - **/ - public static void testSix() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger1b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - assertNull(manager.getLogger("")); - assertNull(manager.getLogger("")); - - for (int j = 0; j<3; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger expected = global; - Logger logger3 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger3b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertEquals(expected, logger3); - assertEquals(expected, logger3b); - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger4 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger4b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger4); - assertNotNull(logger4b); - expected = global; - assertEquals(logger4, expected); - assertEquals(logger4b, expected); - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = null; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - } - - } - } - - /** - * This test is designed to test the behavior of additional LogManager instances. - * It must be noted that if the security manager is off, then calling - * Bridge.changeContext() has actually no effect. - **/ - public static void testSeven() { - for (int i=0; i<3 ; i++) { - Bridge.desactivate(); - LogManager manager = new LogManager() {}; - Logger logger1 = manager.getLogger(""); - Logger logger1b = manager.getLogger(""); - assertNull(logger1); - assertNull(logger1b); - Logger global = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global); - Logger logger2 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger2b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - assertNotNull(logger2); - assertNotNull(logger2b); - assertEquals(logger2, global); - assertEquals(logger2b, global); - Logger logger3 = manager.getLogger(""); - Logger logger3b = manager.getLogger(""); - assertNull(logger3); - assertNull(logger3b); - Logger root = new Bridge.CustomLogger(""); - manager.addLogger(root); - Logger logger4 = manager.getLogger(""); - Logger logger4b = manager.getLogger(""); - assertNotNull(logger4); - assertNotNull(logger4b); - assertEquals(logger4, root); - assertEquals(logger4b, root); - - for (int j = 0 ; j < 3 ; j++) { - Bridge.changeContext(); - - // this is not a supported configuration: - // We are in an UI context with several log managers. - // We however need to check our assumptions... - - // UI context => root logger and global logger should also be null. - - Logger logger5 = manager.getLogger(""); - Logger logger5b = manager.getLogger(""); - Logger expectedRoot = root; - assertEquals(logger5, expectedRoot); - assertEquals(logger5b, expectedRoot); - - assertEquals(global, manager.getLogger(Logger.GLOBAL_LOGGER_NAME)); - - Logger global2 = new Bridge.CustomLogger(Logger.GLOBAL_LOGGER_NAME); - manager.addLogger(global2); - Logger logger6 = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger logger6b = manager.getLogger(Logger.GLOBAL_LOGGER_NAME); - Logger expectedGlobal = global; - - assertNotNull(logger6); - assertNotNull(logger6b); - assertEquals(logger6, expectedGlobal); - assertEquals(logger6b, expectedGlobal); - assertEquals(root, manager.getLogger("")); - - Logger root2 = new Bridge.CustomLogger(""); - manager.addLogger(root2); - expectedRoot = root; - Logger logger7 = manager.getLogger(""); - Logger logger7b = manager.getLogger(""); - assertNotNull(logger7); - assertNotNull(logger7b); - assertEquals(logger7, expectedRoot); - assertEquals(logger7b, expectedRoot); - } - } - } - - public static void testParent(Logger logger) { - Logger l = logger; - while (l.getParent() != null) { - l = l.getParent(); - } - assertEquals("", l.getName()); - } - - public static class TestError extends RuntimeException { - public TestError(String msg) { - super(msg); - } - } - - public static void assertNotNull(Object obj) { - if (obj == null) throw new NullPointerException(); - } - - public static void assertNull(Object obj) { - if (obj != null) throw new TestError("Null expected, got "+obj); - } - - public static void assertEquals(Object o1, Object o2) { - if (o1 != o2) { - throw new TestError(o1 + " != " + o2); - } - } - - public static void assertNotEquals(Object o1, Object o2) { - if (o1 == o2) { - throw new TestError(o1 + " == " + o2); - } - } -} From cae1fd3385e0635beeac34a2287627e556155783 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 9 Jun 2025 16:08:18 +0000 Subject: [PATCH 199/216] 8357632: CDS test failures on static JDK Reviewed-by: ccheung, dholmes --- src/hotspot/share/cds/cdsConfig.cpp | 22 ++++++++++++++----- test/hotspot/jtreg/ProblemList-StaticJdk.txt | 9 -------- .../runtime/cds/NonJVMVariantLocation.java | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index b3c13b63aff..b93238eca88 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -110,12 +110,24 @@ const char* CDSConfig::default_archive_path() { // before CDSConfig::ergo_initialize() is called. assert(_cds_ergo_initialize_started, "sanity"); if (_default_archive_path == nullptr) { - char jvm_path[JVM_MAXPATHLEN]; - os::jvm_path(jvm_path, sizeof(jvm_path)); - char *end = strrchr(jvm_path, *os::file_separator()); - if (end != nullptr) *end = '\0'; stringStream tmp; - tmp.print("%s%sclasses", jvm_path, os::file_separator()); + if (is_vm_statically_linked()) { + // It's easier to form the path using JAVA_HOME as os::jvm_path + // gives the path to the launcher executable on static JDK. + const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib"); + tmp.print("%s%s%s%s%s%sclasses", + Arguments::get_java_home(), os::file_separator(), + subdir, os::file_separator(), + Abstract_VM_Version::vm_variant(), os::file_separator()); + } else { + // Assume .jsa is in the same directory where libjvm resides on + // non-static JDK. + char jvm_path[JVM_MAXPATHLEN]; + os::jvm_path(jvm_path, sizeof(jvm_path)); + char *end = strrchr(jvm_path, *os::file_separator()); + if (end != nullptr) *end = '\0'; + tmp.print("%s%sclasses", jvm_path, os::file_separator()); + } #ifdef _LP64 if (!UseCompressedOops) { tmp.print_raw("_nocoops"); diff --git a/test/hotspot/jtreg/ProblemList-StaticJdk.txt b/test/hotspot/jtreg/ProblemList-StaticJdk.txt index c872a97b301..cb727e470f3 100644 --- a/test/hotspot/jtreg/ProblemList-StaticJdk.txt +++ b/test/hotspot/jtreg/ProblemList-StaticJdk.txt @@ -42,12 +42,3 @@ gtest/MetaspaceGtests.java#no-ccs 8356201 generic-all gtest/NMTGtests.java#nmt-detail 8356201 generic-all gtest/NMTGtests.java#nmt-off 8356201 generic-all gtest/NMTGtests.java#nmt-summary 8356201 generic-all - -# Need CDS archive -runtime/cds/NonJVMVariantLocation.java 8357632 generic-all -runtime/cds/TestCDSVMCrash.java 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#coops_coh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#coops_nocoh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#nocoops_coh 8357632 generic-all -runtime/cds/TestDefaultArchiveLoading.java#nocoops_nocoh 8357632 generic-all -serviceability/jvmti/RedefineClasses/RedefineSharedClass.java 8357632 generic-all diff --git a/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java b/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java index 81e931e450e..24772d620ad 100644 --- a/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java +++ b/test/hotspot/jtreg/runtime/cds/NonJVMVariantLocation.java @@ -26,6 +26,7 @@ * @test * @summary Test that CDS archive can be loaded if the archive is in a non-JVM variant directory. * @bug 8353504 + * @requires !jdk.static * @requires vm.cds * @requires vm.flagless * @requires vm.flavor == "server" From a377773fa76b46ac98533c61bc1410485390115e Mon Sep 17 00:00:00 2001 From: kieran-farrell Date: Mon, 9 Jun 2025 17:39:39 +0000 Subject: [PATCH 200/216] 8358617: java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java fails with 403 due to system proxies Reviewed-by: dfuchs --- .../HttpURLConnection/HttpURLConnectionExpectContinueTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java index c9b8bc85b70..e701e234d83 100644 --- a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java +++ b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java @@ -429,7 +429,7 @@ public class HttpURLConnectionExpectContinueTest { .port(control.serverSocket.getLocalPort()) .toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); connection.setDoOutput(true); connection.setReadTimeout(5000); connection.setUseCaches(false); From 156187accc1c3e2a897ced011727a5c8d8e1b0cf Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 9 Jun 2025 17:58:49 +0000 Subject: [PATCH 201/216] 8356978: Convert unicode sequences in Java source code to UTF-8 Co-authored-by: Alexey Ivanov Reviewed-by: naoto, prr, joehw --- src/demo/share/jfc/Stylepad/HelloWorld.java | 14 +++++--------- .../sun/text/resources/JavaTimeSupplementary.java | 14 +++++++------- .../sun/text/resources/ext/FormatData_ja.java | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/demo/share/jfc/Stylepad/HelloWorld.java b/src/demo/share/jfc/Stylepad/HelloWorld.java index c4e7a8aee40..59ea1b45335 100644 --- a/src/demo/share/jfc/Stylepad/HelloWorld.java +++ b/src/demo/share/jfc/Stylepad/HelloWorld.java @@ -187,22 +187,18 @@ public class HelloWorld { new Run("none", "Hello from Cupertino") }), new Paragraph("title", new Run[] { - new Run("none", "\u53F0\u5317\u554F\u5019\u60A8\u0021") + new Run("none", "台北問候您!") }), new Paragraph("title", new Run[] { - new Run("none", "\u0391\u03B8\u03B7\u03BD\u03B1\u03B9\u0020" // Greek - + "\u03B1\u03C3\u03C0\u03B1\u03B6\u03BF\u03BD" - + "\u03C4\u03B1\u03B9\u0020\u03C5\u03BC\u03B1" - + "\u03C2\u0021") + new Run("none", "Αθηναι ασπαζονται υμας!") // Greek }), new Paragraph("title", new Run[] { - new Run("none", "\u6771\u4eac\u304b\u3089\u4eca\u65e5\u306f") + new Run("none", "東京から今日は") }), new Paragraph("title", new Run[] { - new Run("none", "\u05e9\u05dc\u05d5\u05dd \u05de\u05d9\u05e8\u05d5" - + "\u05e9\u05dc\u05d9\u05dd") + new Run("none", "שלום מירושלים") }), new Paragraph("title", new Run[] { - new Run("none", "\u0633\u0644\u0627\u0645") + new Run("none", "سلام") }), }; } diff --git a/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java b/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java index 7b041591c6a..cbcb724d258 100644 --- a/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java +++ b/src/java.base/share/classes/sun/text/resources/JavaTimeSupplementary.java @@ -232,8 +232,8 @@ public class JavaTimeSupplementary extends OpenListResourceBundle { "Sha.", "Ram.", "Shaw.", - "Dhu\u02bbl-Q.", - "Dhu\u02bbl-H.", + "Dhuʻl-Q.", + "Dhuʻl-H.", "", } }, @@ -241,16 +241,16 @@ public class JavaTimeSupplementary extends OpenListResourceBundle { new String[] { "Muharram", "Safar", - "Rabi\u02bb I", - "Rabi\u02bb II", + "Rabiʻ I", + "Rabiʻ II", "Jumada I", "Jumada II", "Rajab", - "Sha\u02bbban", + "Shaʻban", "Ramadan", "Shawwal", - "Dhu\u02bbl-Qi\u02bbdah", - "Dhu\u02bbl-Hijjah", + "Dhuʻl-Qiʻdah", + "Dhuʻl-Hijjah", "", } }, diff --git a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java index fe210146db8..d9a3ebafe14 100644 --- a/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java +++ b/src/jdk.localedata/share/classes/sun/text/resources/ext/FormatData_ja.java @@ -87,7 +87,7 @@ public class FormatData_ja extends ParallelListResourceBundle { return new Object[][] { { "japanese.FirstYear", new String[] { // first year name - "\u5143", // "Gan"-nen + "元", // "Gan"-nen } }, }; From eb256deb8021d5b243ef782eb9e2622472909e97 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 9 Jun 2025 18:33:00 +0000 Subject: [PATCH 202/216] 8358326: Use oopFactory array allocation Reviewed-by: fparain, stefank --- src/hotspot/share/jvmci/jvmciEnv.cpp | 3 +-- src/hotspot/share/memory/oopFactory.cpp | 20 ++++++++-------- src/hotspot/share/oops/objArrayKlass.cpp | 8 +++---- src/hotspot/share/oops/objArrayKlass.hpp | 9 ++++--- src/hotspot/share/oops/typeArrayKlass.cpp | 6 ++--- src/hotspot/share/oops/typeArrayKlass.hpp | 9 ++++--- src/hotspot/share/prims/jni.cpp | 8 ++++--- src/hotspot/share/prims/vectorSupport.cpp | 5 ++-- src/hotspot/share/runtime/deoptimization.cpp | 4 ++-- src/hotspot/share/runtime/reflection.cpp | 25 +++++++++++--------- 10 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 8c9facf8489..851ead247f1 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -1463,8 +1463,7 @@ JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) { JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) { JavaThread* THREAD = JavaThread::current(); // For exception macros. if (is_hotspot()) { - Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlass())->array_klass(CHECK_(JVMCIObject())); - objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject())); + objArrayOop result = oopFactory::new_objArray(Universe::byteArrayKlass(), length, CHECK_(JVMCIObject())); return wrap(result); } else { JNIAccessMark jni(this, THREAD); diff --git a/src/hotspot/share/memory/oopFactory.cpp b/src/hotspot/share/memory/oopFactory.cpp index 949b4fe134b..b2a468d3a23 100644 --- a/src/hotspot/share/memory/oopFactory.cpp +++ b/src/hotspot/share/memory/oopFactory.cpp @@ -40,41 +40,41 @@ #include "utilities/utf8.hpp" typeArrayOop oopFactory::new_boolArray(int length, TRAPS) { - return Universe::boolArrayKlass()->allocate(length, THREAD); + return Universe::boolArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_charArray(int length, TRAPS) { - return Universe::charArrayKlass()->allocate(length, THREAD); + return Universe::charArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_floatArray(int length, TRAPS) { - return Universe::floatArrayKlass()->allocate(length, THREAD); + return Universe::floatArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_doubleArray(int length, TRAPS) { - return Universe::doubleArrayKlass()->allocate(length, THREAD); + return Universe::doubleArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_byteArray(int length, TRAPS) { - return Universe::byteArrayKlass()->allocate(length, THREAD); + return Universe::byteArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_shortArray(int length, TRAPS) { - return Universe::shortArrayKlass()->allocate(length, THREAD); + return Universe::shortArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_intArray(int length, TRAPS) { - return Universe::intArrayKlass()->allocate(length, THREAD); + return Universe::intArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_longArray(int length, TRAPS) { - return Universe::longArrayKlass()->allocate(length, THREAD); + return Universe::longArrayKlass()->allocate_instance(length, THREAD); } // create java.lang.Object[] objArrayOop oopFactory::new_objectArray(int length, TRAPS) { assert(Universe::objectArrayKlass() != nullptr, "Too early?"); - return Universe::objectArrayKlass()->allocate(length, THREAD); + return Universe::objectArrayKlass()->allocate_instance(length, THREAD); } typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) { @@ -88,7 +88,7 @@ typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) { typeArrayOop oopFactory::new_typeArray(BasicType type, int length, TRAPS) { TypeArrayKlass* klass = Universe::typeArrayKlass(type); - return klass->allocate(length, THREAD); + return klass->allocate_instance(length, THREAD); } // Create a Java array that points to Symbol. diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp index 7af6b963052..e1fcc25f150 100644 --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -44,7 +44,7 @@ #include "runtime/mutexLocker.hpp" #include "utilities/macros.hpp" -ObjArrayKlass* ObjArrayKlass::allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) { +ObjArrayKlass* ObjArrayKlass::allocate_klass(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS) { assert(ObjArrayKlass::header_size() <= InstanceKlass::header_size(), "array klasses must be same size as InstanceKlass"); @@ -100,7 +100,7 @@ ObjArrayKlass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_da } // Initialize instance variables - ObjArrayKlass* oak = ObjArrayKlass::allocate(loader_data, n, element_klass, name, CHECK_NULL); + ObjArrayKlass* oak = ObjArrayKlass::allocate_klass(loader_data, n, element_klass, name, CHECK_NULL); ModuleEntry* module = oak->module(); assert(module != nullptr, "No module entry for array"); @@ -149,7 +149,7 @@ size_t ObjArrayKlass::oop_size(oop obj) const { return objArrayOop(obj)->object_size(); } -objArrayOop ObjArrayKlass::allocate(int length, TRAPS) { +objArrayOop ObjArrayKlass::allocate_instance(int length, TRAPS) { check_array_allocation_length(length, arrayOopDesc::max_array_length(T_OBJECT), CHECK_NULL); size_t size = objArrayOopDesc::object_size(length); return (objArrayOop)Universe::heap()->array_allocate(this, size, length, @@ -160,7 +160,7 @@ oop ObjArrayKlass::multi_allocate(int rank, jint* sizes, TRAPS) { int length = *sizes; ArrayKlass* ld_klass = lower_dimension(); // If length < 0 allocate will throw an exception. - objArrayOop array = allocate(length, CHECK_NULL); + objArrayOop array = allocate_instance(length, CHECK_NULL); objArrayHandle h_array (THREAD, array); if (rank > 1) { if (length != 0) { diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index c44c8d28f62..11fe4f2a521 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -33,8 +33,10 @@ class ClassLoaderData; // ObjArrayKlass is the klass for objArrays class ObjArrayKlass : public ArrayKlass { - friend class VMStructs; + friend class Deoptimization; friend class JVMCIVMStructs; + friend class oopFactory; + friend class VMStructs; public: static const KlassKind Kind = ObjArrayKlassKind; @@ -47,7 +49,9 @@ class ObjArrayKlass : public ArrayKlass { // Constructor ObjArrayKlass(int n, Klass* element_klass, Symbol* name); - static ObjArrayKlass* allocate(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS); + static ObjArrayKlass* allocate_klass(ClassLoaderData* loader_data, int n, Klass* k, Symbol* name, TRAPS); + + objArrayOop allocate_instance(int length, TRAPS); public: // For dummy objects ObjArrayKlass() {} @@ -78,7 +82,6 @@ class ObjArrayKlass : public ArrayKlass { static ObjArrayKlass* allocate_objArray_klass(ClassLoaderData* loader_data, int n, Klass* element_klass, TRAPS); - objArrayOop allocate(int length, TRAPS); oop multi_allocate(int rank, jint* sizes, TRAPS); // Copying diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp index 39385bb0184..bdf37c7db49 100644 --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -50,7 +50,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type, ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data(); - TypeArrayKlass* ak = TypeArrayKlass::allocate(null_loader_data, type, sym, CHECK_NULL); + TypeArrayKlass* ak = TypeArrayKlass::allocate_klass(null_loader_data, type, sym, CHECK_NULL); // Call complete_create_array_klass after all instance variables have been initialized. complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL); @@ -65,7 +65,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type, return ak; } -TypeArrayKlass* TypeArrayKlass::allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { +TypeArrayKlass* TypeArrayKlass::allocate_klass(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS) { assert(TypeArrayKlass::header_size() <= InstanceKlass::header_size(), "array klasses must be same size as InstanceKlass"); @@ -101,7 +101,7 @@ oop TypeArrayKlass::multi_allocate(int rank, jint* last_size, TRAPS) { // For typeArrays this is only called for the last dimension assert(rank == 1, "just checking"); int length = *last_size; - return allocate(length, THREAD); + return allocate_instance(length, THREAD); } diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index fa4e301e3e4..22600702fe2 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -33,6 +33,8 @@ class ClassLoaderData; // It contains the type and size of the elements class TypeArrayKlass : public ArrayKlass { + friend class Deoptimization; + friend class oopFactory; friend class VMStructs; public: @@ -43,7 +45,10 @@ class TypeArrayKlass : public ArrayKlass { // Constructor TypeArrayKlass(BasicType type, Symbol* name); - static TypeArrayKlass* allocate(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS); + static TypeArrayKlass* allocate_klass(ClassLoaderData* loader_data, BasicType type, Symbol* name, TRAPS); + + typeArrayOop allocate_common(int length, bool do_zero, TRAPS); + typeArrayOop allocate_instance(int length, TRAPS) { return allocate_common(length, true, THREAD); } public: TypeArrayKlass() {} // For dummy objects. @@ -66,8 +71,6 @@ class TypeArrayKlass : public ArrayKlass { size_t oop_size(oop obj) const; // Allocation - typeArrayOop allocate_common(int length, bool do_zero, TRAPS); - typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); } oop multi_allocate(int rank, jint* sizes, TRAPS); oop protection_domain() const { return nullptr; } diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 228244bbd05..5a43baeb8d8 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -2285,9 +2285,11 @@ JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass ele jobjectArray ret = nullptr; DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret); Klass* ek = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)); - Klass* ak = ek->array_klass(CHECK_NULL); - ObjArrayKlass::cast(ak)->initialize(CHECK_NULL); - objArrayOop result = ObjArrayKlass::cast(ak)->allocate(length, CHECK_NULL); + + // Make sure bottom_klass is initialized. + ek->initialize(CHECK_NULL); + objArrayOop result = oopFactory::new_objArray(ek, length, CHECK_NULL); + oop initial_value = JNIHandles::resolve(initialElement); if (initial_value != nullptr) { // array already initialized with null for (int index = 0; index < length; index++) { diff --git a/src/hotspot/share/prims/vectorSupport.cpp b/src/hotspot/share/prims/vectorSupport.cpp index c907ddb4885..002f737e788 100644 --- a/src/hotspot/share/prims/vectorSupport.cpp +++ b/src/hotspot/share/prims/vectorSupport.cpp @@ -28,6 +28,7 @@ #include "code/location.hpp" #include "jni.h" #include "jvm.h" +#include "memory/oopFactory.hpp" #include "oops/klass.inline.hpp" #include "oops/typeArrayOop.inline.hpp" #include "prims/vectorSupport.hpp" @@ -109,9 +110,7 @@ Handle VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, frame* f int elem_size = type2aelembytes(elem_bt); // On-heap vector values are represented as primitive arrays. - TypeArrayKlass* tak = Universe::typeArrayKlass(elem_bt); - - typeArrayOop arr = tak->allocate(num_elem, CHECK_NH); // safepoint + typeArrayOop arr = oopFactory::new_typeArray(elem_bt, num_elem, CHECK_NH); // safepoint if (location.is_register()) { // Value was in a callee-saved register. diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index a0d9dd00339..ed84f2b294f 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1274,11 +1274,11 @@ bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap* assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); int len = sv->field_size() / type2size[ak->element_type()]; InternalOOMEMark iom(THREAD); - obj = ak->allocate(len, THREAD); + obj = ak->allocate_instance(len, THREAD); } else if (k->is_objArray_klass()) { ObjArrayKlass* ak = ObjArrayKlass::cast(k); InternalOOMEMark iom(THREAD); - obj = ak->allocate(sv->field_size(), THREAD); + obj = ak->allocate_instance(sv->field_size(), THREAD); } if (obj == nullptr) { diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 9e165f76829..2a0af9d2d09 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -320,9 +320,16 @@ void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value } } + +// Conversion +static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror) { + assert(java_lang_Class::is_primitive(basic_type_mirror), + "just checking"); + return java_lang_Class::primitive_type(basic_type_mirror); +} + static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { - assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); - BasicType type = java_lang_Class::primitive_type(basic_type_mirror); + BasicType type = basic_type_mirror_to_basic_type(basic_type_mirror); if (type == T_VOID) { THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); } @@ -339,8 +346,11 @@ arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { THROW_MSG_NULL(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length)); } if (java_lang_Class::is_primitive(element_mirror)) { - Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); - return TypeArrayKlass::cast(tak)->allocate(length, THREAD); + BasicType type = basic_type_mirror_to_basic_type(element_mirror); + if (type == T_VOID) { + THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); + } + return oopFactory::new_typeArray(type, length, CHECK_NULL); } else { Klass* k = java_lang_Class::as_Klass(element_mirror); if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) { @@ -907,13 +917,6 @@ static methodHandle resolve_interface_call(InstanceKlass* klass, return methodHandle(THREAD, info.selected_method()); } -// Conversion -static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror) { - assert(java_lang_Class::is_primitive(basic_type_mirror), - "just checking"); - return java_lang_Class::primitive_type(basic_type_mirror); -} - // Narrowing of basic types. Used to create correct jvalues for // boolean, byte, char and short return return values from interpreter // which are returned as ints. Throws IllegalArgumentException. From fcb68ea22d020d567c560c7bd5976d3c070d9806 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 9 Jun 2025 19:03:21 +0000 Subject: [PATCH 203/216] 8358626: Emit UTF-8 CLDR resources Reviewed-by: erikj, vyazici --- make/modules/java.base/Gensrc.gmk | 5 ++++- make/modules/jdk.localedata/Gensrc.gmk | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/make/modules/java.base/Gensrc.gmk b/make/modules/java.base/Gensrc.gmk index 3a482388bec..e4a019ed584 100644 --- a/make/modules/java.base/Gensrc.gmk +++ b/make/modules/java.base/Gensrc.gmk @@ -46,6 +46,8 @@ CLDR_GEN_DONE := $(GENSRC_DIR)/_cldr-gensrc.marker TZ_DATA_DIR := $(MODULE_SRC)/share/data/tzdata ZONENAME_TEMPLATE := $(MODULE_SRC)/share/classes/java/time/format/ZoneName.java.template +# The `-utf8` option is used even for US English, as some names +# may contain non-ASCII characters, such as “Türkiye”. $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ $(wildcard $(CLDR_DATA_DIR)/main/en*.xml) \ $(wildcard $(CLDR_DATA_DIR)/supplemental/*.xml) \ @@ -61,7 +63,8 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ -basemodule \ -year $(COPYRIGHT_YEAR) \ -zntempfile $(ZONENAME_TEMPLATE) \ - -tzdatadir $(TZ_DATA_DIR)) + -tzdatadir $(TZ_DATA_DIR) \ + -utf8) $(TOUCH) $@ TARGETS += $(CLDR_GEN_DONE) diff --git a/make/modules/jdk.localedata/Gensrc.gmk b/make/modules/jdk.localedata/Gensrc.gmk index a3c5cdf82e8..93b863df66f 100644 --- a/make/modules/jdk.localedata/Gensrc.gmk +++ b/make/modules/jdk.localedata/Gensrc.gmk @@ -45,7 +45,8 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \ -baselocales "en-US" \ -year $(COPYRIGHT_YEAR) \ -o $(GENSRC_DIR) \ - -tzdatadir $(TZ_DATA_DIR)) + -tzdatadir $(TZ_DATA_DIR) \ + -utf8) $(TOUCH) $@ TARGETS += $(CLDR_GEN_DONE) From cd9b1bc820540184c79dd1957edc7ad4e8e469dc Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Mon, 9 Jun 2025 20:49:33 +0000 Subject: [PATCH 204/216] 8358426: Improve lazy computation in Locale Reviewed-by: naoto, liach --- .../share/classes/java/util/Locale.java | 180 +++++------------- .../classes/java/util/LocaleISOData.java | 91 ++++++++- .../classes/sun/util/locale/BaseLocale.java | 18 +- 3 files changed, 148 insertions(+), 141 deletions(-) diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index 993495ff5ab..9059d196861 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -48,8 +48,8 @@ import java.io.Serializable; import java.text.NumberFormat; import java.text.MessageFormat; import java.text.ParsePosition; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.function.Supplier; import java.util.spi.LocaleNameProvider; import java.util.stream.Stream; @@ -733,58 +733,24 @@ public final class Locale implements Cloneable, Serializable { * @see #getISOCountries(Locale.IsoCountryCode) * @since 9 */ - public static enum IsoCountryCode { + public enum IsoCountryCode { /** * PART1_ALPHA2 is used to represent the ISO3166-1 alpha-2 two letter * country codes. */ - PART1_ALPHA2 { - @Override - Set createCountryCodeSet() { - return Set.of(Locale.getISOCountries()); - } - }, + PART1_ALPHA2, /** * * PART1_ALPHA3 is used to represent the ISO3166-1 alpha-3 three letter * country codes. */ - PART1_ALPHA3 { - @Override - Set createCountryCodeSet() { - return LocaleISOData.computeISO3166_1Alpha3Countries(); - } - }, + PART1_ALPHA3, /** * PART3 is used to represent the ISO3166-3 four letter country codes. */ - PART3 { - @Override - Set createCountryCodeSet() { - return Set.of(LocaleISOData.ISO3166_3); - } - }; - - /** - * Concrete implementation of this method attempts to compute value - * for iso3166CodesMap for each IsoCountryCode type key. - */ - abstract Set createCountryCodeSet(); - - /** - * Map to hold country codes for each ISO3166 part. - */ - private static final Map> iso3166CodesMap = new ConcurrentHashMap<>(); - - /** - * This method is called from Locale class to retrieve country code set - * for getISOCountries(type) - */ - static Set retrieveISOCountryCodes(IsoCountryCode type) { - return iso3166CodesMap.computeIfAbsent(type, IsoCountryCode::createCountryCodeSet); - } + PART3 } /** @@ -1004,30 +970,28 @@ public final class Locale implements Cloneable, Serializable { return getInstance(baseloc, extensions); } - static Locale getInstance(BaseLocale baseloc, LocaleExtensions extensions) { if (extensions == null) { Locale locale = CONSTANT_LOCALES.get(baseloc); if (locale != null) { return locale; } - return LocaleCache.cache(baseloc); + return LOCALE_CACHE.get().computeIfAbsent(baseloc, LOCALE_CREATOR); } else { LocaleKey key = new LocaleKey(baseloc, extensions); - return LocaleCache.cache(key); + return LOCALE_CACHE.get().computeIfAbsent(key, LOCALE_CREATOR); } } - private static final class LocaleCache implements Function { - private static final ReferencedKeyMap LOCALE_CACHE - = ReferencedKeyMap.create(true, ReferencedKeyMap.concurrentHashMapSupplier()); - - private static final Function LOCALE_CREATOR = new LocaleCache(); - - public static Locale cache(Object key) { - return LOCALE_CACHE.computeIfAbsent(key, LOCALE_CREATOR); - } + private static final Supplier> LOCALE_CACHE = + StableValue.supplier(new Supplier<>() { + @Override + public ReferencedKeyMap get() { + return ReferencedKeyMap.create(true, ReferencedKeyMap.concurrentHashMapSupplier()); + } + }); + private static final Function LOCALE_CREATOR = new Function<>() { @Override public Locale apply(Object key) { if (key instanceof BaseLocale base) { @@ -1036,7 +1000,7 @@ public final class Locale implements Cloneable, Serializable { LocaleKey lk = (LocaleKey)key; return new Locale(lk.base, lk.exts); } - } + }; private static final class LocaleKey { @@ -1301,12 +1265,8 @@ public final class Locale implements Cloneable, Serializable { * @return An array of ISO 3166 two-letter country codes. */ public static String[] getISOCountries() { - if (isoCountries == null) { - isoCountries = getISO2Table(LocaleISOData.isoCountryTable); - } - String[] result = new String[isoCountries.length]; - System.arraycopy(isoCountries, 0, result, 0, isoCountries.length); - return result; + String[] countries = LocaleISOData.ISO_3166_1_ALPHA2.get(); + return Arrays.copyOf(countries, countries.length); } /** @@ -1319,7 +1279,11 @@ public final class Locale implements Cloneable, Serializable { */ public static Set getISOCountries(IsoCountryCode type) { Objects.requireNonNull(type); - return IsoCountryCode.retrieveISOCountryCodes(type); + return switch (type) { + case PART1_ALPHA2 -> Set.of(LocaleISOData.ISO_3166_1_ALPHA2.get()); + case PART1_ALPHA3 -> LocaleISOData.ISO_3166_1_ALPHA3.get(); + case PART3 -> LocaleISOData.ISO_3166_3.get(); + }; } /** @@ -1339,22 +1303,8 @@ public final class Locale implements Cloneable, Serializable { * @return An array of ISO 639 two-letter language codes. */ public static String[] getISOLanguages() { - String[] languages = Locale.isoLanguages; - if (languages == null) { - Locale.isoLanguages = languages = getISO2Table(LocaleISOData.isoLanguageTable); - } - String[] result = new String[languages.length]; - System.arraycopy(languages, 0, result, 0, languages.length); - return result; - } - - private static String[] getISO2Table(String table) { - int len = table.length() / 5; - String[] isoTable = new String[len]; - for (int i = 0, j = 0; i < len; i++, j += 5) { - isoTable[i] = table.substring(j, j + 2); - } - return isoTable; + String[] languages = LocaleISOData.ISO_639.get(); + return Arrays.copyOf(languages, languages.length); } /** @@ -1683,61 +1633,54 @@ public final class Locale implements Cloneable, Serializable { * @since 1.7 */ public String toLanguageTag() { - String lTag = this.languageTag; - if (lTag != null) { - return lTag; - } + return languageTag.get(); + } + private String computeLanguageTag() { LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions); - StringBuilder buf = new StringBuilder(); + StringBuilder bldr = new StringBuilder(); String subtag = tag.language(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.canonicalizeLanguage(subtag)); + bldr.append(LanguageTag.canonicalizeLanguage(subtag)); } subtag = tag.script(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeScript(subtag)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeScript(subtag)); } subtag = tag.region(); if (!subtag.isEmpty()) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeRegion(subtag)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeRegion(subtag)); } Listsubtags = tag.variants(); for (String s : subtags) { - buf.append(LanguageTag.SEP); + bldr.append(LanguageTag.SEP); // preserve casing - buf.append(s); + bldr.append(s); } subtags = tag.extensions(); for (String s : subtags) { - buf.append(LanguageTag.SEP); - buf.append(LanguageTag.canonicalizeExtension(s)); + bldr.append(LanguageTag.SEP); + bldr.append(LanguageTag.canonicalizeExtension(s)); } subtag = tag.privateuse(); if (!subtag.isEmpty()) { - if (buf.length() > 0) { - buf.append(LanguageTag.SEP); + if (bldr.length() > 0) { + bldr.append(LanguageTag.SEP); } - buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP); + bldr.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP); // preserve casing - buf.append(subtag); + bldr.append(subtag); } - String langTag = buf.toString(); - synchronized (this) { - if (this.languageTag == null) { - this.languageTag = langTag; - } - } - return langTag; + return bldr.toString(); } /** @@ -1961,7 +1904,7 @@ public final class Locale implements Cloneable, Serializable { return lang; } - String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable); + String language3 = LocaleISOData.getISO3LangCode(lang); if (language3 == null) { throw new MissingResourceException("Couldn't find 3-letter language code for " + lang, "FormatData_" + toString(), "ShortLanguage"); @@ -1983,7 +1926,7 @@ public final class Locale implements Cloneable, Serializable { * three-letter country abbreviation is not available for this locale. */ public String getISO3Country() throws MissingResourceException { - String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable); + String country3 = LocaleISOData.getISO3CtryCode(baseLocale.getRegion()); if (country3 == null) { throw new MissingResourceException("Couldn't find 3-letter country code for " + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry"); @@ -1991,27 +1934,6 @@ public final class Locale implements Cloneable, Serializable { return country3; } - private static String getISO3Code(String iso2Code, String table) { - int codeLength = iso2Code.length(); - if (codeLength == 0) { - return ""; - } - - int tableLength = table.length(); - int index = tableLength; - if (codeLength == 2) { - char c1 = iso2Code.charAt(0); - char c2 = iso2Code.charAt(1); - for (index = 0; index < tableLength; index += 5) { - if (table.charAt(index) == c1 - && table.charAt(index + 1) == c2) { - break; - } - } - } - return index < tableLength ? table.substring(index + 2, index + 5) : null; - } - /** * Returns a name for the locale's language that is appropriate for display to the * user. @@ -2393,7 +2315,13 @@ public final class Locale implements Cloneable, Serializable { private static volatile Locale defaultDisplayLocale; private static volatile Locale defaultFormatLocale; - private transient volatile String languageTag; + private final transient Supplier languageTag = + StableValue.supplier(new Supplier<>() { + @Override + public String get() { + return computeLanguageTag(); + } + }); /** * Return an array of the display names of the variant. @@ -2587,10 +2515,6 @@ public final class Locale implements Cloneable, Serializable { baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions); } - private static volatile String[] isoLanguages; - - private static volatile String[] isoCountries; - private static String convertOldISOCodes(String language) { // we accept both the old and the new ISO codes for the languages whose ISO // codes have changed, but we always store the NEW code, unless the property diff --git a/src/java.base/share/classes/java/util/LocaleISOData.java b/src/java.base/share/classes/java/util/LocaleISOData.java index c2090d3be19..29e0b28be01 100644 --- a/src/java.base/share/classes/java/util/LocaleISOData.java +++ b/src/java.base/share/classes/java/util/LocaleISOData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,11 +25,47 @@ package java.util; +import java.util.function.Supplier; + +// Methods and suppliers for producing ISO 639/3166 resources used by Locale. class LocaleISOData { + + static final Supplier ISO_639 = + StableValue.supplier(new Supplier<>() { + @Override + public String[] get() { + return getISO2Table(isoLanguageTable); + } + }); + + static final Supplier ISO_3166_1_ALPHA2 = + StableValue.supplier(new Supplier<>() { + @Override + public String[] get() { + return getISO2Table(isoCountryTable); + } + }); + + static final Supplier> ISO_3166_1_ALPHA3 = + StableValue.supplier(new Supplier<>() { + @Override + public Set get() { + return computeISO3166_1Alpha3Countries(); + } + }); + + static final Supplier> ISO_3166_3 = + StableValue.supplier(new Supplier<>() { + @Override + public Set get() { + return Set.of(ISO3166_3); + } + }); + /** * The 2- and 3-letter ISO 639 language codes. */ - static final String isoLanguageTable = + private static final String isoLanguageTable = "aa" + "aar" // Afar + "ab" + "abk" // Abkhazian + "ae" + "ave" // Avestan @@ -223,7 +259,7 @@ class LocaleISOData { /** * The 2- and 3-letter ISO 3166 country codes. */ - static final String isoCountryTable = + private static final String isoCountryTable = "AD" + "AND" // Andorra, Principality of + "AE" + "ARE" // United Arab Emirates + "AF" + "AFG" // Afghanistan @@ -480,18 +516,60 @@ class LocaleISOData { /** * Array to hold country codes for ISO3166-3. */ - static final String[] ISO3166_3 = { + private static final String[] ISO3166_3 = { "AIDJ", "ANHH", "BQAQ", "BUMM", "BYAA", "CSHH", "CSXX", "CTKI", "DDDE", "DYBJ", "FQHH", "FXFR", "GEHH", "HVBF", "JTUM", "MIUM", "NHVU", "NQAQ", "NTHH", "PCHH", "PUUM", "PZPA", "RHZW", "SKIN", "SUHH", "TPTL", "VDVN", "WKUM", "YDYE", "YUCS", "ZRCD" }; + static String getISO3LangCode(String language) { + return getISO3Code(language, isoLanguageTable); + } + + static String getISO3CtryCode(String country) { + return getISO3Code(country, isoCountryTable); + } + + private static String getISO3Code(String iso2Code, String table) { + int codeLength = iso2Code.length(); + if (codeLength == 0) { + return ""; + } + + int tableLength = table.length(); + int index = tableLength; + if (codeLength == 2) { + char c1 = iso2Code.charAt(0); + char c2 = iso2Code.charAt(1); + for (index = 0; index < tableLength; index += 5) { + if (table.charAt(index) == c1 + && table.charAt(index + 1) == c2) { + break; + } + } + } + return index < tableLength ? table.substring(index + 2, index + 5) : null; + } + + /** + * This method computes an array of alpha-2 codes from either ISO639 or + * ISO3166. + */ + private static String[] getISO2Table(String table) { + int len = table.length() / 5; + String[] isoTable = new String[len]; + for (int i = 0, j = 0; i < len; i++, j += 5) { + isoTable[i] = table.substring(j, j + 2); + } + return isoTable; + } + /** * This method computes a set of ISO3166-1 alpha-3 country codes from * existing isoCountryTable. */ - static Set computeISO3166_1Alpha3Countries() { + private static Set computeISO3166_1Alpha3Countries() { int tableLength = isoCountryTable.length(); String[] isoTable = new String[tableLength / 5]; for (int i = 0, index = 0; index < tableLength; i++, index += 5) { @@ -500,6 +578,5 @@ class LocaleISOData { return Set.of(isoTable); } - private LocaleISOData() { - } + private LocaleISOData() {} } diff --git a/src/java.base/share/classes/sun/util/locale/BaseLocale.java b/src/java.base/share/classes/sun/util/locale/BaseLocale.java index d1fe8d24b72..529ca1b0c13 100644 --- a/src/java.base/share/classes/sun/util/locale/BaseLocale.java +++ b/src/java.base/share/classes/sun/util/locale/BaseLocale.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -38,6 +38,7 @@ import jdk.internal.util.StaticProperty; import jdk.internal.vm.annotation.Stable; import java.util.StringJoiner; +import java.util.function.Supplier; public final class BaseLocale { @@ -90,6 +91,15 @@ public final class BaseLocale { } } + // Interned BaseLocale cache + private static final Supplier> CACHE = + StableValue.supplier(new Supplier<>() { + @Override + public ReferencedKeySet get() { + return ReferencedKeySet.create(true, ReferencedKeySet.concurrentHashMapSupplier()); + } + }); + public static final String SEP = "_"; private final String language; @@ -164,11 +174,7 @@ public final class BaseLocale { // Obtain the "interned" BaseLocale from the cache. The returned // "interned" instance can subsequently be used by the Locale // instance which guarantees the locale components are properly cased/interned. - class InterningCache { // TODO: StableValue - private static final ReferencedKeySet CACHE = - ReferencedKeySet.create(true, ReferencedKeySet.concurrentHashMapSupplier()); - } - return InterningCache.CACHE.intern(new BaseLocale( + return CACHE.get().intern(new BaseLocale( language.intern(), // guaranteed to be lower-case LocaleUtils.toTitleString(script).intern(), region.intern(), // guaranteed to be upper-case From ef45c8154cea2ec910788d3c19e91d3eed75708e Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 9 Jun 2025 20:59:30 +0000 Subject: [PATCH 205/216] 8346237: Obsolete the UseOprofile flag Reviewed-by: coleenp, kvn --- src/hotspot/os/linux/globals_linux.hpp | 5 +--- src/hotspot/os/linux/os_linux.cpp | 38 ------------------------- src/hotspot/share/memory/heap.cpp | 10 ------- src/hotspot/share/memory/heap.hpp | 5 +--- src/hotspot/share/runtime/arguments.cpp | 4 ++- 5 files changed, 5 insertions(+), 57 deletions(-) diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp index 331690ec3ee..542e034f59f 100644 --- a/src/hotspot/os/linux/globals_linux.hpp +++ b/src/hotspot/os/linux/globals_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,9 +35,6 @@ range, \ constraint) \ \ - product(bool, UseOprofile, false, \ - "(Deprecated) enable support for Oprofile profiler") \ - \ product(bool, UseTransparentHugePages, false, \ "Use MADV_HUGEPAGE for large pages") \ \ diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 807014e7b0c..3aa83895ff1 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2820,44 +2820,6 @@ void os::jvm_path(char *buf, jint buflen) { //////////////////////////////////////////////////////////////////////////////// // Virtual Memory -// Rationale behind this function: -// current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable -// mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get -// samples for JITted code. Here we create private executable mapping over the code cache -// and then we can use standard (well, almost, as mapping can change) way to provide -// info for the reporting script by storing timestamp and location of symbol -void linux_wrap_code(char* base, size_t size) { - static volatile jint cnt = 0; - - static_assert(sizeof(off_t) == 8, "Expected Large File Support in this file"); - - if (!UseOprofile) { - return; - } - - char buf[PATH_MAX+1]; - int num = Atomic::add(&cnt, 1); - - snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d", - os::get_temp_directory(), os::current_process_id(), num); - unlink(buf); - - int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU); - - if (fd != -1) { - off_t rv = ::lseek(fd, size-2, SEEK_SET); - if (rv != (off_t)-1) { - if (::write(fd, "", 1) == 1) { - mmap(base, size, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0); - } - } - ::close(fd); - unlink(buf); - } -} - static bool recoverable_mmap_error(int err) { // See if the error is one we can let the caller handle. This // list of errno values comes from JBS-6843484. I can't find a diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index bcb9d2e6114..b111c61f15a 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -189,14 +189,6 @@ static size_t align_to_page_size(size_t size) { } -void CodeHeap::on_code_mapping(char* base, size_t size) { -#ifdef LINUX - extern void linux_wrap_code(char* base, size_t size); - linux_wrap_code(base, size); -#endif -} - - bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_size) { assert(rs.size() >= committed_size, "reserved < committed"); assert(is_aligned(committed_size, rs.page_size()), "must be page aligned"); @@ -213,7 +205,6 @@ bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_s return false; } - on_code_mapping(_memory.low(), _memory.committed_size()); _number_of_committed_segments = size_to_segments(_memory.committed_size()); _number_of_reserved_segments = size_to_segments(_memory.reserved_size()); assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking"); @@ -250,7 +241,6 @@ bool CodeHeap::expand_by(size_t size) { } char* base = _memory.low() + _memory.committed_size(); if (!_memory.expand_by(dm)) return false; - on_code_mapping(base, dm); size_t i = _number_of_committed_segments; _number_of_committed_segments = size_to_segments(_memory.committed_size()); assert(_number_of_reserved_segments == size_to_segments(_memory.reserved_size()), "number of reserved segments should not change"); diff --git a/src/hotspot/share/memory/heap.hpp b/src/hotspot/share/memory/heap.hpp index e54f99c8c54..d0e4230fe2b 100644 --- a/src/hotspot/share/memory/heap.hpp +++ b/src/hotspot/share/memory/heap.hpp @@ -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 @@ -146,9 +146,6 @@ class CodeHeap : public CHeapObj { void* next_used(HeapBlock* b) const; HeapBlock* block_start(void* p) const; - // to perform additional actions on creation of executable code - void on_code_mapping(char* base, size_t size); - public: CodeHeap(const char* name, const CodeBlobType code_blob_type); diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 7592d233f0c..a4b2994ac55 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -530,7 +530,6 @@ static SpecialFlag const special_jvm_flags[] = { { "UseSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, #ifdef LINUX { "UseLinuxPosixThreadCPUClocks", JDK_Version::jdk(24), JDK_Version::jdk(25), JDK_Version::jdk(26) }, - { "UseOprofile", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::jdk(27) }, #endif { "LockingMode", JDK_Version::jdk(24), JDK_Version::jdk(26), JDK_Version::jdk(27) }, #ifdef _LP64 @@ -542,6 +541,9 @@ static SpecialFlag const special_jvm_flags[] = { // -------------- Obsolete Flags - sorted by expired_in -------------- { "PerfDataSamplingInterval", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::jdk(26) }, +#ifdef LINUX + { "UseOprofile", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::jdk(27) }, +#endif { "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() }, { "ZGenerational", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::undefined() }, { "ZMarkStackSpaceLimit", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::undefined() }, From d186dacdb7b91dc9a28b703ce3c8ea007fc450b6 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 9 Jun 2025 21:54:55 +0000 Subject: [PATCH 206/216] 8357591: Re-enable CDS test cases for jvmci after JDK-8345826 Reviewed-by: dholmes, kvn --- .../runtime/cds/appcds/LambdaWithUseImplMethodHandle.java | 2 -- .../appcds/aotCache/AOTCacheSupportForCustomLoaders.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/JavaAgent.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java | 2 -- .../runtime/cds/appcds/aotCache/SpecialCacheNames.java | 2 -- .../jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java | 2 -- .../runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java | 2 -- .../appcds/aotClassLinking/AOTLoaderConstraintsTest.java | 2 -- .../runtime/cds/appcds/aotClassLinking/AddExports.java | 2 -- .../jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java | 2 -- .../jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java | 2 -- .../runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java | 6 ------ .../cds/appcds/aotClassLinking/FakeCodeLocation.java | 2 -- .../cds/appcds/aotClassLinking/GeneratedInternedString.java | 2 -- .../cds/appcds/aotClassLinking/LambdaInExcludedClass.java | 2 -- .../cds/appcds/aotClassLinking/MethodHandleTest.java | 2 -- .../appcds/aotClassLinking/NonFinalStaticWithInitVal.java | 2 -- .../cds/appcds/aotClassLinking/StringConcatStress.java | 2 -- .../cds/appcds/aotClassLinking/TestSetupAOTTest.java | 2 -- .../runtime/cds/appcds/aotClassLinking/TrainingRun.java | 2 -- .../cds/appcds/aotClassLinking/WeakReferenceTest.java | 2 -- .../runtime/cds/appcds/aotProfile/AOTProfileFlags.java | 2 -- .../cds/appcds/cacheObject/ArchiveHeapTestClass.java | 2 -- .../appcds/methodHandles/MethodHandlesAsCollectorTest.java | 2 -- .../appcds/methodHandles/MethodHandlesCastFailureTest.java | 2 -- .../cds/appcds/methodHandles/MethodHandlesGeneralTest.java | 2 -- .../cds/appcds/methodHandles/MethodHandlesInvokersTest.java | 2 -- .../methodHandles/MethodHandlesPermuteArgumentsTest.java | 2 -- .../methodHandles/MethodHandlesSpreadArgumentsTest.java | 2 -- .../cds/appcds/resolvedConstants/AOTLinkedLambdas.java | 2 -- .../cds/appcds/resolvedConstants/AOTLinkedVarHandles.java | 2 -- 34 files changed, 72 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java index 0c747168945..6b7a4f68bbf 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java @@ -28,8 +28,6 @@ * @summary CDS cannot archive lambda proxy with useImplMethodHandle * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build pkg1.BaseWithProtectedMethod * @build pkg2.Child diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java index ae00477e67b..9461957ef2c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheSupportForCustomLoaders.java @@ -27,8 +27,6 @@ * @summary Test AOT cache support for array classes in custom class loaders. * @bug 8353298 8356838 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build ReturnIntegerAsString * @build AOTCacheSupportForCustomLoaders diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java index 4f2ff4f0f76..c808cd95bc7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ExcludedClasses.java @@ -26,8 +26,6 @@ * @test * @summary Test how various AOT optimizations handle classes that are excluded from the AOT cache. * @requires vm.cds.write.archived.java.heap - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * /test/hotspot/jtreg/runtime/cds/appcds/aotCache/test-classes * @build ExcludedClasses CustyWithLoop diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java index 007e51004ec..f3326ac1ed6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HelloAOTCache.java @@ -27,8 +27,6 @@ * @test * @summary Sanity test for AOTCache * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build HelloAOTCache * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloAOTCacheApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java index 7965be8d00a..070f6df9834 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/JavaAgent.java @@ -28,8 +28,6 @@ * @summary -javaagent should be allowed in AOT workflow. However, classes transformed/redefined by agents will not * be cached. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build JavaAgent JavaAgentTransformer Util * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar JavaAgentApp JavaAgentApp$ShouldBeTransformed diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java index abbdd3551b7..c558d293b2a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/ManagementAgent.java @@ -28,8 +28,6 @@ * @bug 8352187 * @summary ManagementAgent will not be started during AOT cache creation. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build HelloAOTCache * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloAOTCacheApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java index 0fff74236f1..014524afde6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/PackageInfoClass.java @@ -27,8 +27,6 @@ * @summary AOT cache handling for package-info class loaded by jdk/internal/loader/ClassLoaders$BootClassLoader * @bug 8354558 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/jdk/java/lang/Package/bootclasspath/boot * @build PackageInfoClass foo.Foo foo.MyAnnotation foo.package-info * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar foo.Foo foo.package-info foo.MyAnnotation diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java index 89aa9e441a4..e9d9c70a358 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/SpecialCacheNames.java @@ -27,8 +27,6 @@ * @summary Use special characters in the name of the cache file specified by -XX:AOTCacheOutput * Make sure these characters are passed to the child JVM process that assembles the cache. * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build SpecialCacheNames * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java index 18caa08c117..50b47e4424d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/VerifierFailOver.java @@ -26,8 +26,6 @@ * @test * @summary Sanity test for AOTCache * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build VerifierFailOver_Helper * @build VerifierFailOver diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java index 96f08004fb2..a7c7362b845 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTCacheWithZGC.java @@ -28,8 +28,6 @@ * @bug 8352775 * @requires vm.cds * @requires vm.gc.Z - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build AOTCacheWithZGC * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar AOTCacheWithZGCApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java index 63be2038907..f82cf2737fb 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTLoaderConstraintsTest.java @@ -26,8 +26,6 @@ * @test Make sure loader constraints are passed from AOT preimage to final image. * @bug 8348426 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build AOTLoaderConstraintsTest BootClass * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar BootClass diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java index 2a63a4837c2..fc3e945cf9d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddExports.java @@ -28,8 +28,6 @@ * @bug 8352437 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddExports */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java index 5ae8c4a6bb8..d3626d30c7e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddOpens.java @@ -26,8 +26,6 @@ * @test * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddOpens * @summary sanity test the --add-opens option diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java index c1dbc602755..5c9364aa079 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AddReads.java @@ -27,8 +27,6 @@ * @bug 8354083 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @run driver AddReads * @summary sanity test the --add-reads option diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java index 90fd0f33bab..30f7ce12ca0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -29,8 +29,6 @@ /* * @test id=static * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build InitiatingLoaderTester BadOldClassA BadOldClassB * @build jdk.test.whitebox.WhiteBox BulkLoaderTest SimpleCusty @@ -45,8 +43,6 @@ /* * @test id=dynamic * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build InitiatingLoaderTester BadOldClassA BadOldClassB * @build jdk.test.whitebox.WhiteBox BulkLoaderTest SimpleCusty @@ -61,8 +57,6 @@ /* * @test id=aot * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @build jdk.test.whitebox.WhiteBox InitiatingLoaderTester BadOldClassA BadOldClassB * @build BulkLoaderTest SimpleCusty diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java index 1ffc904963a..5da2e2754e8 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/FakeCodeLocation.java @@ -26,8 +26,6 @@ * @test Do not cache classes that are loaded from a fake location. * @bug 8352001 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build FakeCodeLocation * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar FakeCodeLocationApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java index dcb1c59c09f..0ee59bf5afd 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/GeneratedInternedString.java @@ -28,8 +28,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build GeneratedInternedString * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar GeneratedInternedStringApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java index 9ed2524bff1..c91e999c40f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/LambdaInExcludedClass.java @@ -27,8 +27,6 @@ * @bug 8349888 * @requires vm.cds.supports.aot.class.linking * @requires vm.gc.Epsilon - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build LambdaInExcludedClass * @run driver jdk.test.lib.helpers.ClassFileInstaller LambdaInExcludedClassApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java index f7a26a39db1..972dc287af5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/MethodHandleTest.java @@ -27,8 +27,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build MethodHandleTest * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar mh.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java index ba21f5f98fb..17ff399d23c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/NonFinalStaticWithInitVal.java @@ -27,8 +27,6 @@ * @summary Handling of non-final static string that has an initial value * @bug 8356125 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build NonFinalStaticWithInitVal_Helper * @build NonFinalStaticWithInitVal diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java index 3786c294791..81bf28010b1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/StringConcatStress.java @@ -34,8 +34,6 @@ /* * @test id=aot * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build StringConcatStress * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar StringConcatStressApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java index f88af3caed5..118b4c6af1d 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TestSetupAOTTest.java @@ -28,8 +28,6 @@ * is used for running HotSpot tests in the "AOT mode" * (E.g., make test JTREG=AOT_JDK=true TEST=open/test/hotspot/jtreg/runtime/invokedynamic) * @requires vm.cds - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/setup_aot * @build TestSetupAOTTest JavacBenchApp TestSetupAOT * @run driver jdk.test.lib.helpers.ClassFileInstaller diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java index fd896fd6958..df466151f98 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/TrainingRun.java @@ -27,8 +27,6 @@ * @summary -XX:AOTMode=record should not interfere with app execution: (1) thread creation; (2) exit code * @bug 8351327 * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib * @build TrainingRun * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar MyTestApp diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java index ae5cd5b3429..3b33d63b0d2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/WeakReferenceTest.java @@ -27,8 +27,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking * @requires vm.debug - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds * @build WeakReferenceTest * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar weakref.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java index e2285a59600..fe9c7e7bbb7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotProfile/AOTProfileFlags.java @@ -26,8 +26,6 @@ * @test * @summary Sanity test of combinations of the diagnostic flags [+-]AOTRecordTraining and [+-]AOTReplayTraining * @requires vm.cds - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @requires vm.cds.supports.aot.class.linking * @requires vm.flagless * @library /test/lib /test/setup_aot /test/hotspot/jtreg/runtime/cds/appcds/test-classes diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java index 819db99a549..fed56937f2f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java @@ -28,8 +28,6 @@ * @summary Test for the -XX:ArchiveHeapTestClass flag * @requires vm.debug == true & vm.cds.write.archived.java.heap * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @modules java.logging * @library /test/jdk/lib/testlibrary /test/lib * /test/hotspot/jtreg/runtime/cds/appcds diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java index ba7c0def86a..1061207f764 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesAsCollectorTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java index 3f5008ca8c3..3349d146e10 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesCastFailureTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java index 70f02b9a3d7..bba3f367505 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesGeneralTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java index 7de76f5e99a..9ce57a9c66b 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesInvokersTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java index 1e4bfebce9d..8f75eff0dc7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesPermuteArgumentsTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java index 19755121282..8b431232825 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java @@ -28,8 +28,6 @@ * @summary Run the MethodHandlesSpreadArgumentsTest.java test in CDSAppTester::AOT workflow. * @requires vm.cds & vm.compMode != "Xcomp" * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @comment Some of the tests run excessively slowly with -Xcomp. The original * tests aren't executed with -Xcomp in the CI pipeline, so let's exclude * the generated tests from -Xcomp execution as well. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java index e187f408fb4..ecfaa265923 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java @@ -28,8 +28,6 @@ * @bug 8340836 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes/ * @build AOTLinkedLambdas * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java index e262c55beea..4586b94b519 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java @@ -28,8 +28,6 @@ * @bug 8343245 * @requires vm.cds * @requires vm.cds.supports.aot.class.linking - * @comment work around JDK-8345635 - * @requires !vm.jvmci.enabled * @library /test/lib * @build AOTLinkedVarHandles * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar From bcf860703dc0244fef1d380cb7323282de76970c Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 9 Jun 2025 22:25:20 +0000 Subject: [PATCH 207/216] 8355792: Remove expired flags in JDK 26 Reviewed-by: coleenp, kvn --- src/hotspot/share/runtime/arguments.cpp | 4 -- src/java.base/share/man/java.md | 65 ++----------------------- 2 files changed, 3 insertions(+), 66 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index a4b2994ac55..a49116fd91d 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -528,9 +528,6 @@ static SpecialFlag const special_jvm_flags[] = { { "DynamicDumpSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "RequireSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "UseSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, -#ifdef LINUX - { "UseLinuxPosixThreadCPUClocks", JDK_Version::jdk(24), JDK_Version::jdk(25), JDK_Version::jdk(26) }, -#endif { "LockingMode", JDK_Version::jdk(24), JDK_Version::jdk(26), JDK_Version::jdk(27) }, #ifdef _LP64 { "UseCompressedClassPointers", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::undefined() }, @@ -540,7 +537,6 @@ static SpecialFlag const special_jvm_flags[] = { // -------------- Obsolete Flags - sorted by expired_in -------------- - { "PerfDataSamplingInterval", JDK_Version::undefined(), JDK_Version::jdk(25), JDK_Version::jdk(26) }, #ifdef LINUX { "UseOprofile", JDK_Version::jdk(25), JDK_Version::jdk(26), JDK_Version::jdk(27) }, #endif diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index bb010e6e1c7..fc8cbb23aff 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -2917,71 +2917,12 @@ when they're used. ## Removed Java Options -These `java` options have been removed in JDK @@VERSION_SPECIFICATION@@ and using them results in an error of: - -> `Unrecognized VM option` *option-name* - -`-XX:RTMAbortRatio=`*abort\_ratio* -: Specifies the RTM abort ratio is specified as a percentage (%) of all - executed RTM transactions. If a number of aborted transactions becomes - greater than this ratio, then the compiled code is deoptimized. This ratio - is used when the `-XX:+UseRTMDeopt` option is enabled. The default value of - this option is 50. This means that the compiled code is deoptimized if 50% - of all transactions are aborted. - -`-XX:RTMRetryCount=`*number\_of\_retries* -: Specifies the number of times that the RTM locking code is retried, when it - is aborted or busy, before falling back to the normal locking mechanism. - The default value for this option is 5. The `-XX:UseRTMLocking` option must - be enabled. - -`-XX:+UseRTMDeopt` -: Autotunes RTM locking depending on the abort ratio. This ratio is specified - by the `-XX:RTMAbortRatio` option. If the number of aborted transactions - exceeds the abort ratio, then the method containing the lock is deoptimized - and recompiled with all locks as normal locks. This option is disabled by - default. The `-XX:+UseRTMLocking` option must be enabled. - -`-XX:+UseRTMLocking` -: Generates Restricted Transactional Memory (RTM) locking code for all - inflated locks, with the normal locking mechanism as the fallback handler. - This option is disabled by default. Options related to RTM are available - only on x86 CPUs that support Transactional Synchronization Extensions (TSX). - - RTM is part of Intel's TSX, which is an x86 instruction set extension and - facilitates the creation of multithreaded applications. RTM introduces the - new instructions `XBEGIN`, `XABORT`, `XEND`, and `XTEST`. The `XBEGIN` and - `XEND` instructions enclose a set of instructions to run as a transaction. - If no conflict is found when running the transaction, then the memory and - register modifications are committed together at the `XEND` instruction. - The `XABORT` instruction can be used to explicitly abort a transaction and - the `XTEST` instruction checks if a set of instructions is being run in a - transaction. - - A lock on a transaction is inflated when another thread tries to access the - same transaction, thereby blocking the thread that didn't originally - request access to the transaction. RTM requires that a fallback set of - operations be specified in case a transaction aborts or fails. An RTM lock - is a lock that has been delegated to the TSX's system. - - RTM improves performance for highly contended locks with low conflict in a - critical region (which is code that must not be accessed by more than one - thread concurrently). RTM also improves the performance of coarse-grain - locking, which typically doesn't perform well in multithreaded - applications. (Coarse-grain locking is the strategy of holding locks for - long periods to minimize the overhead of taking and releasing locks, while - fine-grained locking is the strategy of trying to achieve maximum - parallelism by locking only when necessary and unlocking as soon as - possible.) Also, for lightly contended locks that are used by different - threads, RTM can reduce false cache line sharing, also known as cache line - ping-pong. This occurs when multiple threads from different processors are - accessing different resources, but the resources share the same cache line. - As a result, the processors repeatedly invalidate the cache lines of other - processors, which forces them to read from main memory instead of their - cache. +No documented java options have been removed in JDK @@VERSION_SPECIFICATION@@. For the lists and descriptions of options removed in previous releases see the *Removed Java Options* section in: +- [The `java` Command, Release 25](https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html) + - [The `java` Command, Release 24](https://docs.oracle.com/en/java/javase/24/docs/specs/man/java.html) - [The `java` Command, Release 23](https://docs.oracle.com/en/java/javase/23/docs/specs/man/java.html) From 92be7821f5d5cbf5fe0244b41b2b7b1ada898df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Tue, 10 Jun 2025 00:21:18 +0000 Subject: [PATCH 208/216] 8353950: Clipboard interaction on Windows is unstable 8332271: Reading data from the clipboard from multiple threads crashes the JVM Reviewed-by: abhiscxk, dnguyen --- .../sun/awt/datatransfer/SunClipboard.java | 22 ++---- .../classes/sun/awt/windows/WClipboard.java | 52 ++++++++++--- .../native/libawt/windows/awt_Clipboard.cpp | 45 +++++++---- .../ConcurrentClipboardAccessTest.java | 77 +++++++++++++++++++ 4 files changed, 150 insertions(+), 46 deletions(-) create mode 100644 test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java b/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java index 898cabd2855..edffbf59878 100644 --- a/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java +++ b/src/java.desktop/share/classes/sun/awt/datatransfer/SunClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, 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 @@ -204,8 +204,9 @@ public abstract class SunClipboard extends Clipboard byte[] data = null; Transferable localeTransferable = null; + openClipboard(null); + try { - openClipboard(null); long[] formats = getClipboardFormats(); Long lFormat = DataTransferer.getInstance(). @@ -318,12 +319,7 @@ public abstract class SunClipboard extends Clipboard * @since 1.5 */ protected long[] getClipboardFormatsOpenClose() { - try { - openClipboard(null); - return getClipboardFormats(); - } finally { - closeClipboard(); - } + return getClipboardFormats(); } /** @@ -356,15 +352,7 @@ public abstract class SunClipboard extends Clipboard flavorListeners.add(listener); if (numberOfFlavorListeners++ == 0) { - long[] currentFormats = null; - try { - openClipboard(null); - currentFormats = getClipboardFormats(); - } catch (final IllegalStateException ignored) { - } finally { - closeClipboard(); - } - this.currentFormats = currentFormats; + this.currentFormats = getClipboardFormats(); registerClipboardViewerChecked(); } diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java b/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java index e16b1805295..110dfb8d637 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -29,7 +29,9 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; +import java.lang.System.Logger.Level; import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.SunClipboard; @@ -51,8 +53,12 @@ final class WClipboard extends SunClipboard { private boolean isClipboardViewerRegistered; + private final ReentrantLock clipboardLocked = new ReentrantLock(); + WClipboard() { super("System"); + // Register java side of the clipboard with the native side + registerClipboard(); } @Override @@ -104,18 +110,42 @@ final class WClipboard extends SunClipboard { /** * Call the Win32 OpenClipboard function. If newOwner is non-null, - * we also call EmptyClipboard and take ownership. + * we also call EmptyClipboard and take ownership. If this method call + * succeeds, it must be followed by a call to {@link #closeClipboard()}. * * @throws IllegalStateException if the clipboard has not been opened */ @Override - public native void openClipboard(SunClipboard newOwner) throws IllegalStateException; + public void openClipboard(SunClipboard newOwner) throws IllegalStateException { + if (!clipboardLocked.tryLock()) { + throw new IllegalStateException("Failed to acquire clipboard lock"); + } + try { + openClipboard0(newOwner); + } catch (IllegalStateException ex) { + clipboardLocked.unlock(); + throw ex; + } + } + /** * Call the Win32 CloseClipboard function if we have clipboard ownership, * does nothing if we have not ownership. */ @Override - public native void closeClipboard(); + public void closeClipboard() { + if (clipboardLocked.isLocked()) { + try { + closeClipboard0(); + } finally { + clipboardLocked.unlock(); + } + } + } + + private native void openClipboard0(SunClipboard newOwner) throws IllegalStateException; + private native void closeClipboard0(); + /** * Call the Win32 SetClipboardData function. */ @@ -157,16 +187,12 @@ final class WClipboard extends SunClipboard { return; } - long[] formats = null; try { - openClipboard(null); - formats = getClipboardFormats(); - } catch (IllegalStateException exc) { - // do nothing to handle the exception, call checkChange(null) - } finally { - closeClipboard(); + long[] formats = getClipboardFormats(); + checkChange(formats); + } catch (Throwable ex) { + System.getLogger(WClipboard.class.getName()).log(Level.DEBUG, "Failed to process handleContentsChanged", ex); } - checkChange(formats); } /** @@ -214,4 +240,6 @@ final class WClipboard extends SunClipboard { } }; } + + private native void registerClipboard(); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp index 2aadcd5a08c..1232f189ca2 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -69,9 +69,8 @@ void AwtClipboard::RegisterClipboardViewer(JNIEnv *env, jobject jclipboard) { return; } - if (theCurrentClipboard == NULL) { - theCurrentClipboard = env->NewGlobalRef(jclipboard); - } + DASSERT(AwtClipboard::theCurrentClipboard != NULL); + DASSERT(env->IsSameObject(AwtClipboard::theCurrentClipboard, jclipboard)); jclass cls = env->GetObjectClass(jclipboard); AwtClipboard::handleContentsChangedMID = @@ -128,11 +127,13 @@ Java_sun_awt_windows_WClipboard_init(JNIEnv *env, jclass cls) * Signature: (Lsun/awt/windows/WClipboard;)V */ JNIEXPORT void JNICALL -Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, +Java_sun_awt_windows_WClipboard_openClipboard0(JNIEnv *env, jobject self, jobject newOwner) { TRY; + DASSERT(AwtClipboard::theCurrentClipboard != NULL); + DASSERT(newOwner == NULL || env->IsSameObject(AwtClipboard::theCurrentClipboard, newOwner)); DASSERT(::GetOpenClipboardWindow() != AwtToolkit::GetInstance().GetHWnd()); if (!::OpenClipboard(AwtToolkit::GetInstance().GetHWnd())) { @@ -142,10 +143,6 @@ Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, } if (newOwner != NULL) { AwtClipboard::GetOwnership(); - if (AwtClipboard::theCurrentClipboard != NULL) { - env->DeleteGlobalRef(AwtClipboard::theCurrentClipboard); - } - AwtClipboard::theCurrentClipboard = env->NewGlobalRef(newOwner); } CATCH_BAD_ALLOC; @@ -157,7 +154,7 @@ Java_sun_awt_windows_WClipboard_openClipboard(JNIEnv *env, jobject self, * Signature: ()V */ JNIEXPORT void JNICALL -Java_sun_awt_windows_WClipboard_closeClipboard(JNIEnv *env, jobject self) +Java_sun_awt_windows_WClipboard_closeClipboard0(JNIEnv *env, jobject self) { TRY; @@ -297,23 +294,25 @@ Java_sun_awt_windows_WClipboard_getClipboardFormats { TRY; - DASSERT(::GetOpenClipboardWindow() == AwtToolkit::GetInstance().GetHWnd()); + unsigned int cFormats = 128; // Allocate enough space to hold all + unsigned int pcFormatsOut = 0; + unsigned int lpuiFormats[128] = { 0 }; - jsize nFormats = ::CountClipboardFormats(); - jlongArray formats = env->NewLongArray(nFormats); + VERIFY(::GetUpdatedClipboardFormats(lpuiFormats, 128, &pcFormatsOut)); + + jlongArray formats = env->NewLongArray(pcFormatsOut); if (formats == NULL) { throw std::bad_alloc(); } - if (nFormats == 0) { + if (pcFormatsOut == 0) { return formats; } jboolean isCopy; jlong *lFormats = env->GetLongArrayElements(formats, &isCopy), *saveFormats = lFormats; - UINT num = 0; - for (jsize i = 0; i < nFormats; i++, lFormats++) { - *lFormats = num = ::EnumClipboardFormats(num); + for (unsigned int i = 0; i < pcFormatsOut; i++, lFormats++) { + *lFormats = lpuiFormats[i]; } env->ReleaseLongArrayElements(formats, saveFormats, 0); @@ -478,4 +477,16 @@ Java_sun_awt_windows_WClipboard_getClipboardData CATCH_BAD_ALLOC_RET(NULL); } +/* + * Class: sun_awt_windows_WClipboard + * Method: registerClipboard + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_awt_windows_WClipboard_registerClipboard(JNIEnv *env, jobject self) +{ + DASSERT(AwtClipboard::theCurrentClipboard == NULL); + AwtClipboard::theCurrentClipboard = env->NewGlobalRef(self); +} + } /* extern "C" */ diff --git a/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java b/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java new file mode 100644 index 00000000000..db98b06ea9d --- /dev/null +++ b/test/jdk/java/awt/Clipboard/ConcurrentClipboardAccessTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + @test + @bug 8332271 + @summary tests that concurrent access to the clipboard does not crash the JVM + @key headful + @requires (os.family == "windows") + @run main ConcurrentClipboardAccessTest + */ +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; + +public class ConcurrentClipboardAccessTest { + + public static void main(String[] args) { + Thread clipboardLoader1 = new Thread(new ClipboardLoader()); + clipboardLoader1.setDaemon(true); + clipboardLoader1.start(); + Thread clipboardLoader2 = new Thread(new ClipboardLoader()); + clipboardLoader2.setDaemon(true); + clipboardLoader2.start(); + long start = System.currentTimeMillis(); + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + long now = System.currentTimeMillis(); + if ((now - start) > (10L * 1000L)) { + break; + } + } + // Test is considered successful if the concurrent repeated reading + // from clipboard succeeds for the allotted time and the JVM does not + // crash. + System.out.println("Shutdown normally"); + } + + public static class ClipboardLoader implements Runnable { + + @Override + public void run() { + final Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + while (true) { + try { + if (systemClipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + systemClipboard.getData(DataFlavor.stringFlavor); + } + } catch (Exception ignored) { + } + } + } + } +} From ca7b885873712a5ae503cb82c915d709034a69f7 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 10 Jun 2025 06:15:13 +0000 Subject: [PATCH 209/216] 8358749: Fix input checks in Vector API intrinsics Co-authored-by: Vladimir Ivanov Reviewed-by: vlivanov, sviswanathan --- src/hotspot/share/opto/vectorIntrinsics.cpp | 79 +++++++++++++-------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 13acc0469eb..5ff2590a190 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -318,8 +318,10 @@ bool LibraryCallKit::inline_vector_nary_operation(int n) { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (opr == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !opr->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -587,7 +589,11 @@ bool LibraryCallKit::inline_vector_mask_operation() { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); Node* mask = argument(4); - if (mask_klass == nullptr || elem_klass == nullptr || mask->is_top() || vlen == nullptr) { + if (mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + oper == nullptr || !oper->is_con() || + mask->is_top()) { return false; // dead code } @@ -647,9 +653,11 @@ bool LibraryCallKit::inline_vector_frombits_coerced() { // MODE_BITS_COERCED_LONG_TO_MASK for VectorMask.fromLong operation. const TypeInt* mode = gvn().type(argument(5))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || mode == nullptr || - bits_type == nullptr || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || - !vlen->is_con() || !mode->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + bits_type == nullptr || + mode == nullptr || !mode->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s bitwise=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -775,8 +783,10 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) { const TypeInt* vlen = gvn().type(argument(2))->isa_int(); const TypeInt* from_ms = gvn().type(argument(6))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || !from_ms->is_con() || - vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + from_ms == nullptr || !from_ms->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s from_ms=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -983,9 +993,11 @@ bool LibraryCallKit::inline_vector_mem_masked_operation(bool is_store) { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); const TypeInt* from_ms = gvn().type(argument(7))->isa_int(); - if (vector_klass == nullptr || mask_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || mask_klass->const_oop() == nullptr || from_ms == nullptr || - elem_klass->const_oop() == nullptr || !vlen->is_con() || !from_ms->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + from_ms == nullptr || !from_ms->is_con()) { log_if_needed(" ** missing constant: vclass=%s mclass=%s etype=%s vlen=%s from_ms=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -1222,8 +1234,10 @@ bool LibraryCallKit::inline_vector_gather_scatter(bool is_scatter) { const TypeInt* vlen = gvn().type(argument(3))->isa_int(); const TypeInstPtr* vector_idx_klass = gvn().type(argument(4))->isa_instptr(); - if (vector_klass == nullptr || elem_klass == nullptr || vector_idx_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || vector_idx_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + vector_idx_klass == nullptr || vector_idx_klass->const_oop() == nullptr) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s viclass=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(2)->Opcode()], @@ -1409,8 +1423,10 @@ bool LibraryCallKit::inline_vector_reduction() { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (opr == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !opr->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -1547,8 +1563,10 @@ bool LibraryCallKit::inline_vector_test() { const TypeInstPtr* elem_klass = gvn().type(argument(2))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(3))->isa_int(); - if (cond == nullptr || vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - !cond->is_con() || vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (cond == nullptr || !cond->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: cond=%s vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2505,10 +2523,10 @@ bool LibraryCallKit::inline_vector_extract() { const TypeInt* vlen = gvn().type(argument(2))->isa_int(); const TypeInt* idx = gvn().type(argument(4))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || idx == nullptr) { - return false; // dead code - } - if (vector_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() || + idx == nullptr || !idx->is_con()) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2811,9 +2829,11 @@ bool LibraryCallKit::inline_vector_compress_expand() { const TypeInstPtr* elem_klass = gvn().type(argument(3))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(4))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || mask_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || mask_klass->const_oop() == nullptr || - elem_klass->const_oop() == nullptr || !vlen->is_con() || !opr->is_con()) { + if (opr == nullptr || !opr->is_con() || + vector_klass == nullptr || vector_klass->const_oop() == nullptr || + mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: opr=%s vclass=%s mclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -2892,9 +2912,9 @@ bool LibraryCallKit::inline_index_vector() { const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(2))->isa_int(); - if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - vector_klass->const_oop() == nullptr || !vlen->is_con() || - elem_klass->const_oop() == nullptr) { + if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con() ) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], @@ -3026,8 +3046,9 @@ bool LibraryCallKit::inline_index_partially_in_upper_range() { const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr(); const TypeInt* vlen = gvn().type(argument(2))->isa_int(); - if (mask_klass == nullptr || elem_klass == nullptr || vlen == nullptr || - mask_klass->const_oop() == nullptr || elem_klass->const_oop() == nullptr || !vlen->is_con()) { + if (mask_klass == nullptr || mask_klass->const_oop() == nullptr || + elem_klass == nullptr || elem_klass->const_oop() == nullptr || + vlen == nullptr || !vlen->is_con()) { log_if_needed(" ** missing constant: mclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], From 7c9c8ba363521a7bfb58e1a8285459f717769889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Maillard?= Date: Tue, 10 Jun 2025 07:27:10 +0000 Subject: [PATCH 210/216] 8356780: PhaseMacroExpand::_has_locks is unused Reviewed-by: mhaessig, chagedorn, kvn, mchevalier --- src/hotspot/share/opto/macro.cpp | 2 -- src/hotspot/share/opto/macro.hpp | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index c6ed2411fe3..8f21ee13e79 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2407,7 +2407,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() { } } // Next, attempt to eliminate allocations - _has_locks = false; progress = true; while (progress) { progress = false; @@ -2431,7 +2430,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() { case Node::Class_Lock: case Node::Class_Unlock: assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); - _has_locks = true; break; case Node::Class_ArrayCopy: break; diff --git a/src/hotspot/share/opto/macro.hpp b/src/hotspot/share/opto/macro.hpp index 4654789a290..7f27688a57a 100644 --- a/src/hotspot/share/opto/macro.hpp +++ b/src/hotspot/share/opto/macro.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,9 +83,6 @@ private: // projections extracted from a call node CallProjections _callprojs; - // Additional data collected during macro expansion - bool _has_locks; - void expand_allocate(AllocateNode *alloc); void expand_allocate_array(AllocateArrayNode *alloc); void expand_allocate_common(AllocateNode* alloc, @@ -199,7 +196,7 @@ private: Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc); public: - PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn), _has_locks(false) { + PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn) { _igvn.set_delay_transform(true); } From 3ff83ec49e561c44dd99508364b8ba068274b63a Mon Sep 17 00:00:00 2001 From: Varada M Date: Tue, 10 Jun 2025 08:17:52 +0000 Subject: [PATCH 211/216] 8358159: Empty mode/padding in cipher transformations Reviewed-by: amitkumar, valeriep --- .../share/classes/javax/crypto/Cipher.java | 18 ++++-- .../crypto/Cipher/TestEmptyModePadding.java | 56 +++++++++++++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 3de732c6687..e729a984811 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -454,19 +454,25 @@ public class Cipher { String[] parts = tokenizeTransformation(transformation); String alg = parts[0]; - String mode = parts[1]; - String pad = parts[2]; + String mode = (parts[1].length() == 0 ? null : parts[1]); + String pad = (parts[2].length() == 0 ? null : parts[2]); - if ((mode.length() == 0) && (pad.length() == 0)) { + if ((mode == null) && (pad == null)) { // Algorithm only Transform tr = new Transform(alg, "", null, null); return Collections.singletonList(tr); } else { // Algorithm w/ at least mode or padding or both List list = new ArrayList<>(4); - list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); - list.add(new Transform(alg, "/" + mode, null, pad)); - list.add(new Transform(alg, "//" + pad, mode, null)); + if ((mode != null) && (pad != null)) { + list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); + } + if (mode != null) { + list.add(new Transform(alg, "/" + mode, null, pad)); + } + if (pad != null) { + list.add(new Transform(alg, "//" + pad, mode, null)); + } list.add(new Transform(alg, "", mode, pad)); return list; } diff --git a/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java b/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java new file mode 100644 index 00000000000..bd36e7f3ca7 --- /dev/null +++ b/test/jdk/javax/crypto/Cipher/TestEmptyModePadding.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025 IBM Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8358159 + * @summary test that the Cipher.getInstance() handles + * transformations with empty mode and/or padding + * @run main TestEmptyModePadding + */ + + +import java.security.*; +import javax.crypto.*; + +public class TestEmptyModePadding { + + public static void main(String[] args) throws Exception { + Provider provider = Security.getProvider(System.getProperty("test.provider.name", "SunJCE")); + + test("AES", provider); + test("AES/ECB/PKCS5Padding", provider); + test("AES//PKCS5Padding", provider); // Empty mode + test("AES/CBC/", provider); // Empty padding + test("AES/ /NoPadding", provider); // Mode is a space + test("AES/CBC/ ", provider); // Padding is a space + test("AES/ / ", provider); // Both mode and padding are spaces + test("AES//", provider); // Both mode and padding are missing + + } + + private static void test(String transformation, Provider provider) throws Exception { + Cipher c = Cipher.getInstance(transformation, provider); + } +} From 0582bd290d5a8b6344ae7ada36492cc2f33df050 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 10 Jun 2025 11:01:50 +0000 Subject: [PATCH 212/216] 8357639: DigestEchoClient fails intermittently due to: java.io.IOException: Data received while in pool Reviewed-by: djelinski --- .../jdk/internal/net/http/SocketTube.java | 78 +++++++++---------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java index cc083d7e066..ef935b008d3 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/SocketTube.java @@ -432,7 +432,7 @@ final class SocketTube implements FlowTube { } void signalError(Throwable error) { - debug.log(() -> "write error: " + error); + if (debug.on()) debug.log(() -> "write error: " + error); if (Log.channel()) { Log.logChannel("Failed to write to channel ({0}: {1})", channelDescr(), error); @@ -557,34 +557,15 @@ final class SocketTube implements FlowTube { implements Flow.Publisher> { private final InternalReadSubscription subscriptionImpl = new InternalReadSubscription(); - ConcurrentLinkedQueue pendingSubscriptions = new ConcurrentLinkedQueue<>(); + private final AtomicReference pendingSubscriptions + = new AtomicReference<>(); private volatile ReadSubscription subscription; @Override public void subscribe(Flow.Subscriber> s) { Objects.requireNonNull(s); - - TubeSubscriber sub = FlowTube.asTubeSubscriber(s); - ReadSubscription previous; - while ((previous = pendingSubscriptions.poll()) != null) { - if (debug.on()) - debug.log("read publisher: dropping pending subscriber: " - + previous.subscriber); - previous.errorRef.compareAndSet(null, errorRef.get()); - // make sure no data will be routed to the old subscriber. - previous.stopReading(); - previous.signalOnSubscribe(); - if (subscriptionImpl.completed) { - previous.signalCompletion(); - } else { - previous.subscriber.dropSubscription(); - } - } - ReadSubscription target = new ReadSubscription(subscriptionImpl, sub); - pendingSubscriptions.offer(target); - - if (debug.on()) debug.log("read publisher got new subscriber: " + s); - subscriptionImpl.signalSubscribe(); + if (debug.on()) debug.log("Offering new subscriber: %s", s); + subscriptionImpl.offer(FlowTube.asTubeSubscriber(s)); debugState("leaving read.subscribe: "); } @@ -676,7 +657,6 @@ final class SocketTube implements FlowTube { */ synchronized void stopReading() { stopped = true; - impl.demand.reset(); } synchronized boolean tryDecrementDemand() { @@ -733,14 +713,7 @@ final class SocketTube implements FlowTube { assert client.isSelectorThread(); debug.log("subscribe event raised"); if (Log.channel()) Log.logChannel("Start reading from {0}", channelDescr()); - readScheduler.runOrSchedule(); - if (readScheduler.isStopped() || completed) { - // if already completed or stopped we can handle any - // pending connection directly from here. - if (debug.on()) - debug.log("handling pending subscription when completed"); - handlePending(); - } + handlePending(); } @@ -953,22 +926,46 @@ final class SocketTube implements FlowTube { } } - boolean handlePending() { - ReadSubscription pending; + synchronized void offer(TubeSubscriber sub) { + ReadSubscription target = new ReadSubscription(this, sub); + ReadSubscription previous = pendingSubscriptions.getAndSet(target); + if (previous != null) { + if (debug.on()) + debug.log("read publisher: dropping pending subscriber: " + + previous.subscriber); + previous.errorRef.compareAndSet(null, errorRef.get()); + // make sure no data will be routed to the old subscriber. + previous.stopReading(); + previous.signalOnSubscribe(); + if (completed) { + previous.signalCompletion(); + } else { + previous.subscriber.dropSubscription(); + } + } + if (debug.on()) { + debug.log("read publisher got new subscriber: " + sub); + } + signalSubscribe(); + } + + synchronized boolean handlePending() { boolean subscribed = false; - while ((pending = pendingSubscriptions.poll()) != null) { + ReadSubscription current = subscription; + ReadSubscription pending = pendingSubscriptions.getAndSet(null); + if (pending != null) { subscribed = true; if (debug.on()) debug.log("handling pending subscription for %s", pending.subscriber); - ReadSubscription current = subscription; - if (current != null && current != pending && !completed) { - debug.log("dropping pending subscription for current %s", + if (current != null && !completed) { + debug.log("dropping subscription for current %s", current.subscriber); + current.stopReading(); current.subscriber.dropSubscription(); } if (debug.on()) debug.log("read demand reset to 0"); - subscriptionImpl.demand.reset(); // subscriber will increase demand if it needs to. + demand.reset(); // subscriber will increase demand if it needs to. pending.errorRef.compareAndSet(null, errorRef.get()); if (!readScheduler.isStopped()) { subscription = pending; @@ -1335,7 +1332,6 @@ final class SocketTube implements FlowTube { writePublisher.subscribe(this); } - @Override public String toString() { return dbgString(); From a2f99fd88bd03337e1ba73b413ffe4e39f3584cf Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Tue, 10 Jun 2025 14:19:19 +0000 Subject: [PATCH 213/216] 8354383: C2: enable sinking of Type nodes out of loop Reviewed-by: chagedorn, thartmann --- src/hotspot/share/opto/loopopts.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 912d8452d21..ddeb5f84d49 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1676,6 +1676,10 @@ bool PhaseIdealLoop::safe_for_if_replacement(const Node* dom) const { // like various versions of induction variable+offset. Clone the // computation per usage to allow it to sink out of the loop. void PhaseIdealLoop::try_sink_out_of_loop(Node* n) { + bool is_raw_to_oop_cast = n->is_ConstraintCast() && + n->in(1)->bottom_type()->isa_rawptr() && + !n->bottom_type()->isa_rawptr(); + if (has_ctrl(n) && !n->is_Phi() && !n->is_Bool() && @@ -1685,7 +1689,9 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) { !n->is_OpaqueNotNull() && !n->is_OpaqueInitializedAssertionPredicate() && !n->is_OpaqueTemplateAssertionPredicate() && - !n->is_Type()) { + !is_raw_to_oop_cast && // don't extend live ranges of raw oops + (KillPathsReachableByDeadTypeNode || !n->is_Type()) + ) { Node *n_ctrl = get_ctrl(n); IdealLoopTree *n_loop = get_loop(n_ctrl); From 500a3a2d0af0a3f7cf58b909bbbc2aa25926d8b4 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Tue, 10 Jun 2025 16:20:33 +0000 Subject: [PATCH 214/216] 8358799: Refactor os::jvm_path() Reviewed-by: dholmes, jsjolen --- src/hotspot/os/aix/os_aix.cpp | 63 ---------------------- src/hotspot/os/bsd/os_bsd.cpp | 77 -------------------------- src/hotspot/os/linux/os_linux.cpp | 71 ------------------------ src/hotspot/os/posix/os_posix.cpp | 89 +++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 211 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index e7b401701ac..9c6218aee16 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1261,69 +1261,6 @@ void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { // Nothing to do beyond of what os::print_cpu_info() does. } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm.so. -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - Dl_info dlinfo; - int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); - assert(ret != 0, "cannot locate libjvm"); - char* rp = os::realpath((char *)dlinfo.dli_fname, buf, buflen); - assert(rp != nullptr, "error in realpath(): maybe the 'path' argument is too long?"); - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm.so". - const char* p = strrchr(buf, '/'); - if (p == nullptr) { - return; - } - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer room"); - ss.print("%s/lib", buf); - - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm.so" - ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Go back to path of .so - rp = os::realpath((char *)dlinfo.dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path)); - saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 3535d027dbc..9f77d5a4bde 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -1482,83 +1482,6 @@ void os::print_memory_info(outputStream* st) { st->cr(); } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - char dli_fname[MAXPATHLEN]; - dli_fname[0] = '\0'; - bool ret = dll_address_to_library_name( - CAST_FROM_FN_PTR(address, os::jvm_path), - dli_fname, sizeof(dli_fname), nullptr); - assert(ret, "cannot locate libjvm"); - char *rp = nullptr; - if (ret && dli_fname[0] != '\0') { - rp = os::realpath(dli_fname, buf, buflen); - } - if (rp == nullptr) { - return; - } - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm" - const char* p = strrchr(buf, '/'); - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer space"); - // Add the appropriate library and JVM variant subdirs - ss.print("%s/lib/%s", buf, Abstract_VM_Version::vm_variant()); - - if (0 != access(buf, F_OK)) { - ss.reset(); - ss.print("%s/lib", buf); - } - - // If the path exists within JAVA_HOME, add the JVM library name - // to complete the path to JVM being overridden. Otherwise fallback - // to the path to the current library. - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm" - ss.print("/libjvm%s", JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Fall back to path of current library - rp = os::realpath(dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, MAXPATHLEN); - saved_jvm_path[MAXPATHLEN - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 3aa83895ff1..ff2195d3839 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2746,77 +2746,6 @@ void os::get_summary_cpu_info(char* cpuinfo, size_t length) { #endif } -static char saved_jvm_path[MAXPATHLEN] = {0}; - -// Find the full path to the current module, libjvm.so -void os::jvm_path(char *buf, jint buflen) { - // Error checking. - if (buflen < MAXPATHLEN) { - assert(false, "must use a large-enough buffer"); - buf[0] = '\0'; - return; - } - // Lazy resolve the path to current module. - if (saved_jvm_path[0] != 0) { - strcpy(buf, saved_jvm_path); - return; - } - - char dli_fname[MAXPATHLEN]; - dli_fname[0] = '\0'; - bool ret = dll_address_to_library_name( - CAST_FROM_FN_PTR(address, os::jvm_path), - dli_fname, sizeof(dli_fname), nullptr); - assert(ret, "cannot locate libjvm"); - char *rp = nullptr; - if (ret && dli_fname[0] != '\0') { - rp = os::realpath(dli_fname, buf, buflen); - } - if (rp == nullptr) { - return; - } - - // If executing unit tests we require JAVA_HOME to point to the real JDK. - if (Arguments::executing_unit_tests()) { - // Look for JAVA_HOME in the environment. - char* java_home_var = ::getenv("JAVA_HOME"); - if (java_home_var != nullptr && java_home_var[0] != 0) { - - // Check the current module name "libjvm.so". - const char* p = strrchr(buf, '/'); - if (p == nullptr) { - return; - } - assert(strstr(p, "/libjvm") == p, "invalid library name"); - - stringStream ss(buf, buflen); - rp = os::realpath(java_home_var, buf, buflen); - if (rp == nullptr) { - return; - } - - assert((int)strlen(buf) < buflen, "Ran out of buffer room"); - ss.print("%s/lib", buf); - - if (0 == access(buf, F_OK)) { - // Use current module name "libjvm.so" - ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); - assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, - "buf has been truncated"); - } else { - // Go back to path of .so - rp = os::realpath(dli_fname, buf, buflen); - if (rp == nullptr) { - return; - } - } - } - } - - strncpy(saved_jvm_path, buf, MAXPATHLEN); - saved_jvm_path[MAXPATHLEN - 1] = '\0'; -} - //////////////////////////////////////////////////////////////////////////////// // Virtual Memory diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 448ebce620a..68bdec3875c 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -1060,6 +1060,95 @@ bool os::same_files(const char* file1, const char* file2) { return is_same; } +static char saved_jvm_path[MAXPATHLEN] = {0}; + +// Find the full path to the current module, libjvm.so +void os::jvm_path(char *buf, jint buflen) { + // Error checking. + if (buflen < MAXPATHLEN) { + assert(false, "must use a large-enough buffer"); + buf[0] = '\0'; + return; + } + // Lazy resolve the path to current module. + if (saved_jvm_path[0] != 0) { + strcpy(buf, saved_jvm_path); + return; + } + + char* fname; +#ifdef AIX + Dl_info dlinfo; + int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); + assert(ret != 0, "cannot locate libjvm"); + if (ret == 0) { + return; + } + fname = dlinfo.dli_fname; +#else + char dli_fname[MAXPATHLEN]; + dli_fname[0] = '\0'; + bool ret = dll_address_to_library_name( + CAST_FROM_FN_PTR(address, os::jvm_path), + dli_fname, sizeof(dli_fname), nullptr); + assert(ret, "cannot locate libjvm"); + if (!ret) { + return; + } + fname = dli_fname; +#endif // AIX + char* rp = nullptr; + if (fname[0] != '\0') { + rp = os::realpath(dli_fname, buf, buflen); + } + if (rp == nullptr) { + return; + } + + // If executing unit tests we require JAVA_HOME to point to the real JDK. + if (Arguments::executing_unit_tests()) { + // Look for JAVA_HOME in the environment. + char* java_home_var = ::getenv("JAVA_HOME"); + if (java_home_var != nullptr && java_home_var[0] != 0) { + + // Check the current module name "libjvm.so". + const char* p = strrchr(buf, '/'); + if (p == nullptr) { + return; + } + assert(strstr(p, "/libjvm") == p, "invalid library name"); + + stringStream ss(buf, buflen); + rp = os::realpath(java_home_var, buf, buflen); + if (rp == nullptr) { + return; + } + + assert((int)strlen(buf) < buflen, "Ran out of buffer room"); + ss.print("%s/lib", buf); + + // If the path exists within JAVA_HOME, add the VM variant directory and JVM + // library name to complete the path to JVM being overridden. Otherwise fallback + // to the path to the current library. + if (0 == access(buf, F_OK)) { + // Use current module name "libjvm.so" + ss.print("/%s/libjvm%s", Abstract_VM_Version::vm_variant(), JNI_LIB_SUFFIX); + assert(strcmp(buf + strlen(buf) - strlen(JNI_LIB_SUFFIX), JNI_LIB_SUFFIX) == 0, + "buf has been truncated"); + } else { + // Go back to path of .so + rp = os::realpath(dli_fname, buf, buflen); + if (rp == nullptr) { + return; + } + } + } + } + + strncpy(saved_jvm_path, buf, MAXPATHLEN); + saved_jvm_path[MAXPATHLEN - 1] = '\0'; +} + // Called when creating the thread. The minimum stack sizes have already been calculated size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_size) { size_t stack_size; From 8f487d26c0f219d4df32be48ff1790e6f98d74a0 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Tue, 10 Jun 2025 19:05:08 +0000 Subject: [PATCH 215/216] 8358577: Test serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java failed: unexpexcted monitor object Reviewed-by: cjplummer, syan, sspitsyn --- .../GetCurrentContendedMonitor/contmon01/contmon01.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java b/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java index 5bc4d4fd2b2..a4912c7e6d2 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java +++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -154,9 +154,9 @@ class contmon01Task implements Runnable { System.out.println("check #2 done"); System.out.println("notifying main thread"); + System.out.println("thread is going to loop while is true ..."); contmon01.startingBarrier = false; - System.out.println("thread is going to loop while is true ..."); int i = 0; int n = 1000; while (flag) { From 38b877e941918cc5f0463b256d4672d765d40302 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 10 Jun 2025 20:10:19 +0000 Subject: [PATCH 216/216] 8358294: Remove unnecessary GenAlignment Reviewed-by: iwalulya, tschatzl --- .../share/gc/parallel/parallelArguments.cpp | 11 ++- .../share/gc/parallel/parallelInitLogger.cpp | 2 - .../gc/parallel/parallelScavengeHeap.cpp | 6 +- src/hotspot/share/gc/parallel/psOldGen.cpp | 2 +- src/hotspot/share/gc/parallel/psYoungGen.cpp | 4 +- src/hotspot/share/gc/serial/serialHeap.cpp | 4 +- src/hotspot/share/gc/shared/gcArguments.hpp | 2 +- src/hotspot/share/gc/shared/genArguments.cpp | 77 +++++++++---------- src/hotspot/share/gc/shared/genArguments.hpp | 2 - src/hotspot/share/prims/whitebox.cpp | 26 ------- .../gtest/gc/shared/test_collectorPolicy.cpp | 2 +- .../TestMinAndInitialSurvivorRatioFlags.java | 10 +-- .../jtreg/gc/arguments/TestNewRatioFlag.java | 4 +- .../jtreg/gc/arguments/TestNewSizeFlags.java | 6 +- .../gc/arguments/TestSurvivorRatioFlag.java | 2 +- test/lib/jdk/test/whitebox/WhiteBox.java | 4 - 16 files changed, 59 insertions(+), 105 deletions(-) diff --git a/src/hotspot/share/gc/parallel/parallelArguments.cpp b/src/hotspot/share/gc/parallel/parallelArguments.cpp index 2cddbafd871..cae6f9a93d5 100644 --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp @@ -98,15 +98,15 @@ void ParallelArguments::initialize() { FullGCForwarding::initialize_flags(heap_reserved_size_bytes()); } -// The alignment used for boundary between young gen and old gen -static size_t default_gen_alignment() { +// The alignment used for spaces in young gen and old gen +static size_t default_space_alignment() { return 64 * K * HeapWordSize; } void ParallelArguments::initialize_alignments() { // Initialize card size before initializing alignments CardTable::initialize_card_size(); - SpaceAlignment = GenAlignment = default_gen_alignment(); + SpaceAlignment = default_space_alignment(); HeapAlignment = compute_heap_alignment(); } @@ -123,9 +123,8 @@ void ParallelArguments::initialize_heap_flags_and_sizes() { // Can a page size be something else than a power of two? assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2"); - size_t new_alignment = align_up(page_sz, GenAlignment); - if (new_alignment != GenAlignment) { - GenAlignment = new_alignment; + size_t new_alignment = align_up(page_sz, SpaceAlignment); + if (new_alignment != SpaceAlignment) { SpaceAlignment = new_alignment; // Redo everything from the start initialize_heap_flags_and_sizes_one_pass(); diff --git a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp index 1d9c9f840ba..d7eb265d113 100644 --- a/src/hotspot/share/gc/parallel/parallelInitLogger.cpp +++ b/src/hotspot/share/gc/parallel/parallelInitLogger.cpp @@ -29,10 +29,8 @@ void ParallelInitLogger::print_heap() { log_info_p(gc, init)("Alignments:" " Space " EXACTFMT "," - " Generation " EXACTFMT "," " Heap " EXACTFMT, EXACTFMTARGS(SpaceAlignment), - EXACTFMTARGS(GenAlignment), EXACTFMTARGS(HeapAlignment)); GCInitLogger::print_heap(); } diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 0235864992f..139a5fa52f1 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -69,8 +69,8 @@ jint ParallelScavengeHeap::initialize() { initialize_reserved_region(heap_rs); // Layout the reserved space for the generations. - ReservedSpace old_rs = heap_rs.first_part(MaxOldSize, GenAlignment); - ReservedSpace young_rs = heap_rs.last_part(MaxOldSize, GenAlignment); + ReservedSpace old_rs = heap_rs.first_part(MaxOldSize, SpaceAlignment); + ReservedSpace young_rs = heap_rs.last_part(MaxOldSize, SpaceAlignment); assert(young_rs.size() == MaxNewSize, "Didn't reserve all of the heap"); PSCardTable* card_table = new PSCardTable(_reserved); @@ -107,7 +107,7 @@ jint ParallelScavengeHeap::initialize() { new PSAdaptiveSizePolicy(eden_capacity, initial_promo_size, young_gen()->to_space()->capacity_in_bytes(), - GenAlignment, + SpaceAlignment, max_gc_pause_sec, GCTimeRatio ); diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 0d1c3b60672..bc25683e00f 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -41,7 +41,7 @@ PSOldGen::PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size, _min_gen_size(min_size), _max_gen_size(max_size) { - initialize(rs, initial_size, GenAlignment); + initialize(rs, initial_size, SpaceAlignment); } void PSOldGen::initialize(ReservedSpace rs, size_t initial_size, size_t alignment) { diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp index f9cb067411e..bf77a0dde93 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.cpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp @@ -47,7 +47,7 @@ PSYoungGen::PSYoungGen(ReservedSpace rs, size_t initial_size, size_t min_size, s _from_counters(nullptr), _to_counters(nullptr) { - initialize(rs, initial_size, GenAlignment); + initialize(rs, initial_size, SpaceAlignment); } void PSYoungGen::initialize_virtual_space(ReservedSpace rs, @@ -746,7 +746,7 @@ size_t PSYoungGen::available_to_live() { } size_t delta_in_bytes = unused_committed + delta_in_survivor; - delta_in_bytes = align_down(delta_in_bytes, GenAlignment); + delta_in_bytes = align_down(delta_in_bytes, SpaceAlignment); return delta_in_bytes; } diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 27d94593765..fbbaabf618a 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -188,8 +188,8 @@ jint SerialHeap::initialize() { initialize_reserved_region(heap_rs); - ReservedSpace young_rs = heap_rs.first_part(MaxNewSize, GenAlignment); - ReservedSpace old_rs = heap_rs.last_part(MaxNewSize, GenAlignment); + ReservedSpace young_rs = heap_rs.first_part(MaxNewSize, SpaceAlignment); + ReservedSpace old_rs = heap_rs.last_part(MaxNewSize, SpaceAlignment); _rem_set = new CardTableRS(_reserved); _rem_set->initialize(young_rs.base(), old_rs.base()); diff --git a/src/hotspot/share/gc/shared/gcArguments.hpp b/src/hotspot/share/gc/shared/gcArguments.hpp index 40b612d75a6..fff41e85d8c 100644 --- a/src/hotspot/share/gc/shared/gcArguments.hpp +++ b/src/hotspot/share/gc/shared/gcArguments.hpp @@ -35,7 +35,7 @@ extern size_t SpaceAlignment; class GCArguments { protected: - // Initialize HeapAlignment, SpaceAlignment, and extra alignments (E.g. GenAlignment) + // Initialize HeapAlignment, SpaceAlignment virtual void initialize_alignments() = 0; virtual void initialize_heap_flags_and_sizes(); virtual void initialize_size_info(); diff --git a/src/hotspot/share/gc/shared/genArguments.cpp b/src/hotspot/share/gc/shared/genArguments.cpp index 90617b1675f..9618c515b7d 100644 --- a/src/hotspot/share/gc/shared/genArguments.cpp +++ b/src/hotspot/share/gc/shared/genArguments.cpp @@ -42,17 +42,15 @@ size_t MaxOldSize = 0; // See more in JDK-8346005 size_t OldSize = ScaleForWordSize(4*M); -size_t GenAlignment = 0; - size_t GenArguments::conservative_max_heap_alignment() { return (size_t)Generation::GenGrain; } static size_t young_gen_size_lower_bound() { // The young generation must be aligned and have room for eden + two survivors - return align_up(3 * SpaceAlignment, GenAlignment); + return 3 * SpaceAlignment; } static size_t old_gen_size_lower_bound() { - return align_up(SpaceAlignment, GenAlignment); + return SpaceAlignment; } size_t GenArguments::scale_by_NewRatio_aligned(size_t base_size, size_t alignment) { @@ -69,23 +67,20 @@ static size_t bound_minus_alignment(size_t desired_size, void GenArguments::initialize_alignments() { // Initialize card size before initializing alignments CardTable::initialize_card_size(); - SpaceAlignment = GenAlignment = (size_t)Generation::GenGrain; + SpaceAlignment = (size_t)Generation::GenGrain; HeapAlignment = compute_heap_alignment(); } void GenArguments::initialize_heap_flags_and_sizes() { GCArguments::initialize_heap_flags_and_sizes(); - assert(GenAlignment != 0, "Generation alignment not set up properly"); - assert(HeapAlignment >= GenAlignment, - "HeapAlignment: %zu less than GenAlignment: %zu", - HeapAlignment, GenAlignment); - assert(GenAlignment % SpaceAlignment == 0, - "GenAlignment: %zu not aligned by SpaceAlignment: %zu", - GenAlignment, SpaceAlignment); - assert(HeapAlignment % GenAlignment == 0, - "HeapAlignment: %zu not aligned by GenAlignment: %zu", - HeapAlignment, GenAlignment); + assert(SpaceAlignment != 0, "Generation alignment not set up properly"); + assert(HeapAlignment >= SpaceAlignment, + "HeapAlignment: %zu less than SpaceAlignment: %zu", + HeapAlignment, SpaceAlignment); + assert(HeapAlignment % SpaceAlignment == 0, + "HeapAlignment: %zu not aligned by SpaceAlignment: %zu", + HeapAlignment, SpaceAlignment); // All generational heaps have a young gen; handle those flags here @@ -106,7 +101,7 @@ void GenArguments::initialize_heap_flags_and_sizes() { // Make sure NewSize allows an old generation to fit even if set on the command line if (FLAG_IS_CMDLINE(NewSize) && NewSize >= InitialHeapSize) { - size_t revised_new_size = bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment); + size_t revised_new_size = bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment); log_warning(gc, ergo)("NewSize (%zuk) is equal to or greater than initial heap size (%zuk). A new " "NewSize of %zuk will be used to accomodate an old generation.", NewSize/K, InitialHeapSize/K, revised_new_size/K); @@ -115,8 +110,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { // Now take the actual NewSize into account. We will silently increase NewSize // if the user specified a smaller or unaligned value. - size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize, GenAlignment); - bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, GenAlignment)); + size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize, SpaceAlignment); + bounded_new_size = MAX2(smallest_new_size, align_down(bounded_new_size, SpaceAlignment)); if (bounded_new_size != NewSize) { FLAG_SET_ERGO(NewSize, bounded_new_size); } @@ -125,7 +120,7 @@ void GenArguments::initialize_heap_flags_and_sizes() { if (!FLAG_IS_DEFAULT(MaxNewSize)) { if (MaxNewSize >= MaxHeapSize) { // Make sure there is room for an old generation - size_t smaller_max_new_size = MaxHeapSize - GenAlignment; + size_t smaller_max_new_size = MaxHeapSize - SpaceAlignment; if (FLAG_IS_CMDLINE(MaxNewSize)) { log_warning(gc, ergo)("MaxNewSize (%zuk) is equal to or greater than the entire " "heap (%zuk). A new max generation size of %zuk will be used.", @@ -137,8 +132,8 @@ void GenArguments::initialize_heap_flags_and_sizes() { } } else if (MaxNewSize < NewSize) { FLAG_SET_ERGO(MaxNewSize, NewSize); - } else if (!is_aligned(MaxNewSize, GenAlignment)) { - FLAG_SET_ERGO(MaxNewSize, align_down(MaxNewSize, GenAlignment)); + } else if (!is_aligned(MaxNewSize, SpaceAlignment)) { + FLAG_SET_ERGO(MaxNewSize, align_down(MaxNewSize, SpaceAlignment)); } } @@ -166,13 +161,13 @@ void GenArguments::initialize_heap_flags_and_sizes() { // exceed it. Adjust New/OldSize as necessary. size_t calculated_size = NewSize + OldSize; double shrink_factor = (double) MaxHeapSize / calculated_size; - size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), GenAlignment); + size_t smaller_new_size = align_down((size_t)(NewSize * shrink_factor), SpaceAlignment); FLAG_SET_ERGO(NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); // OldSize is already aligned because above we aligned MaxHeapSize to // HeapAlignment, and we just made sure that NewSize is aligned to - // GenAlignment. In initialize_flags() we verified that HeapAlignment - // is a multiple of GenAlignment. + // SpaceAlignment. In initialize_flags() we verified that HeapAlignment + // is a multiple of SpaceAlignment. OldSize = MaxHeapSize - NewSize; } else { FLAG_SET_ERGO(MaxHeapSize, align_up(NewSize + OldSize, HeapAlignment)); @@ -200,7 +195,7 @@ void GenArguments::initialize_size_info() { // Determine maximum size of the young generation. if (FLAG_IS_DEFAULT(MaxNewSize)) { - max_young_size = scale_by_NewRatio_aligned(MaxHeapSize, GenAlignment); + max_young_size = scale_by_NewRatio_aligned(MaxHeapSize, SpaceAlignment); // Bound the maximum size by NewSize below (since it historically // would have been NewSize and because the NewRatio calculation could // yield a size that is too small) and bound it by MaxNewSize above. @@ -229,18 +224,18 @@ void GenArguments::initialize_size_info() { // If NewSize is set on the command line, we should use it as // the initial size, but make sure it is within the heap bounds. initial_young_size = - MIN2(max_young_size, bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment)); - MinNewSize = bound_minus_alignment(initial_young_size, MinHeapSize, GenAlignment); + MIN2(max_young_size, bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment)); + MinNewSize = bound_minus_alignment(initial_young_size, MinHeapSize, SpaceAlignment); } else { // For the case where NewSize is not set on the command line, use // NewRatio to size the initial generation size. Use the current // NewSize as the floor, because if NewRatio is overly large, the resulting // size can be too small. initial_young_size = - clamp(scale_by_NewRatio_aligned(InitialHeapSize, GenAlignment), NewSize, max_young_size); + clamp(scale_by_NewRatio_aligned(InitialHeapSize, SpaceAlignment), NewSize, max_young_size); // Derive MinNewSize from MinHeapSize - MinNewSize = MIN2(scale_by_NewRatio_aligned(MinHeapSize, GenAlignment), initial_young_size); + MinNewSize = MIN2(scale_by_NewRatio_aligned(MinHeapSize, SpaceAlignment), initial_young_size); } } @@ -252,7 +247,7 @@ void GenArguments::initialize_size_info() { // The maximum old size can be determined from the maximum young // and maximum heap size since no explicit flags exist // for setting the old generation maximum. - MaxOldSize = MAX2(MaxHeapSize - max_young_size, GenAlignment); + MaxOldSize = MAX2(MaxHeapSize - max_young_size, SpaceAlignment); MinOldSize = MIN3(MaxOldSize, InitialHeapSize - initial_young_size, MinHeapSize - MinNewSize); @@ -315,10 +310,10 @@ void GenArguments::assert_flags() { assert(NewSize >= MinNewSize, "Ergonomics decided on a too small young gen size"); assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes"); - assert(NewSize % GenAlignment == 0, "NewSize alignment"); - assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % GenAlignment == 0, "MaxNewSize alignment"); + assert(NewSize % SpaceAlignment == 0, "NewSize alignment"); + assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % SpaceAlignment == 0, "MaxNewSize alignment"); assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes"); - assert(OldSize % GenAlignment == 0, "OldSize alignment"); + assert(OldSize % SpaceAlignment == 0, "OldSize alignment"); } void GenArguments::assert_size_info() { @@ -327,19 +322,19 @@ void GenArguments::assert_size_info() { assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes"); assert(MinNewSize <= NewSize, "Ergonomics decided on incompatible minimum and initial young gen sizes"); assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes"); - assert(MinNewSize % GenAlignment == 0, "_min_young_size alignment"); - assert(NewSize % GenAlignment == 0, "_initial_young_size alignment"); - assert(MaxNewSize % GenAlignment == 0, "MaxNewSize alignment"); - assert(MinNewSize <= bound_minus_alignment(MinNewSize, MinHeapSize, GenAlignment), + assert(MinNewSize % SpaceAlignment == 0, "_min_young_size alignment"); + assert(NewSize % SpaceAlignment == 0, "_initial_young_size alignment"); + assert(MaxNewSize % SpaceAlignment == 0, "MaxNewSize alignment"); + assert(MinNewSize <= bound_minus_alignment(MinNewSize, MinHeapSize, SpaceAlignment), "Ergonomics made minimum young generation larger than minimum heap"); - assert(NewSize <= bound_minus_alignment(NewSize, InitialHeapSize, GenAlignment), + assert(NewSize <= bound_minus_alignment(NewSize, InitialHeapSize, SpaceAlignment), "Ergonomics made initial young generation larger than initial heap"); - assert(MaxNewSize <= bound_minus_alignment(MaxNewSize, MaxHeapSize, GenAlignment), + assert(MaxNewSize <= bound_minus_alignment(MaxNewSize, MaxHeapSize, SpaceAlignment), "Ergonomics made maximum young generation lager than maximum heap"); assert(MinOldSize <= OldSize, "Ergonomics decided on incompatible minimum and initial old gen sizes"); assert(OldSize <= MaxOldSize, "Ergonomics decided on incompatible initial and maximum old gen sizes"); - assert(MaxOldSize % GenAlignment == 0, "MaxOldSize alignment"); - assert(OldSize % GenAlignment == 0, "OldSize alignment"); + assert(MaxOldSize % SpaceAlignment == 0, "MaxOldSize alignment"); + assert(OldSize % SpaceAlignment == 0, "OldSize alignment"); assert(MaxHeapSize <= (MaxNewSize + MaxOldSize), "Total maximum heap sizes must be sum of generation maximum sizes"); assert(MinNewSize + MinOldSize <= MinHeapSize, "Minimum generation sizes exceed minimum heap size"); assert(NewSize + OldSize == InitialHeapSize, "Initial generation sizes should match initial heap size"); diff --git a/src/hotspot/share/gc/shared/genArguments.hpp b/src/hotspot/share/gc/shared/genArguments.hpp index ae20c6126fc..80133bd1ec1 100644 --- a/src/hotspot/share/gc/shared/genArguments.hpp +++ b/src/hotspot/share/gc/shared/genArguments.hpp @@ -35,8 +35,6 @@ extern size_t MaxOldSize; extern size_t OldSize; -extern size_t GenAlignment; - class GenArguments : public GCArguments { friend class TestGenCollectorPolicy; // Testing private: diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index cf3b48c11b5..374e877faa6 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -583,28 +583,6 @@ WB_ENTRY(jboolean, WB_G1HasRegionsToUncommit(JNIEnv* env, jobject o)) THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1HasRegionsToUncommit: G1 GC is not enabled"); WB_END -#endif // INCLUDE_G1GC - -#if INCLUDE_PARALLELGC - -WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o)) - if (UseParallelGC) { - return GenAlignment; - } - THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSVirtualSpaceAlignment: Parallel GC is not enabled"); -WB_END - -WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o)) - if (UseParallelGC) { - return GenAlignment; - } - THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSHeapGenerationAlignment: Parallel GC is not enabled"); -WB_END - -#endif // INCLUDE_PARALLELGC - -#if INCLUDE_G1GC - WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env)) if (UseG1GC) { ResourceMark rm(THREAD); @@ -2773,10 +2751,6 @@ static JNINativeMethod methods[] = { {CC"g1MemoryNodeIds", CC"()[I", (void*)&WB_G1MemoryNodeIds }, {CC"g1GetMixedGCInfo", CC"(I)[J", (void*)&WB_G1GetMixedGCInfo }, #endif // INCLUDE_G1GC -#if INCLUDE_PARALLELGC - {CC"psVirtualSpaceAlignment",CC"()J", (void*)&WB_PSVirtualSpaceAlignment}, - {CC"psHeapGenerationAlignment",CC"()J", (void*)&WB_PSHeapGenerationAlignment}, -#endif {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, {CC"NMTMallocWithPseudoStackAndType", CC"(JII)J", (void*)&WB_NMTMallocWithPseudoStackAndType}, diff --git a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp index e335a25cb50..b5e9c6de6a0 100644 --- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp +++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp @@ -117,7 +117,7 @@ class TestGenCollectorPolicy { initial_heap_size = InitialHeapSize; } - size_t expected = scale_by_NewRatio_aligned(initial_heap_size, GenAlignment); + size_t expected = scale_by_NewRatio_aligned(initial_heap_size, SpaceAlignment); ASSERT_EQ(expected, NewSize); } }; diff --git a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java index 5f585575e7a..6323e5c50cf 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java @@ -162,12 +162,12 @@ public class TestMinAndInitialSurvivorRatioFlags { MemoryUsage survivorUsage = HeapRegionUsageTool.getSurvivorUsage(); long alignedNewSize = edenUsage.getMax() + 2 * survivorUsage.getMax(); - long generationAlignment = wb.psHeapGenerationAlignment(); + long spaceAlignment = wb.getHeapSpaceAlignment(); if (survivorRatio >= 0) { // -XX:SurvivorRatio was passed to JVM, actual ratio should be SurvivorRatio + 2 long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / (survivorRatio + 2), - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedSize) { throw new RuntimeException("Expected survivor size is: " + expectedSize @@ -177,7 +177,7 @@ public class TestMinAndInitialSurvivorRatioFlags { // In case of initial ratio verification or disabled adaptive size policy // ratio should be equal to InitialSurvivorRatio value long expectedSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio, - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedSize) { throw new RuntimeException("Expected survivor size is: " + expectedSize + ", but observed size is: " + survivorUsage.getCommitted()); @@ -186,9 +186,9 @@ public class TestMinAndInitialSurvivorRatioFlags { // In any other case actual survivor ratio should not be lower than MinSurvivorRatio // or is should be equal to InitialSurvivorRatio long expectedMinSize = HeapRegionUsageTool.alignDown(alignedNewSize / minRatio, - generationAlignment); + spaceAlignment); long expectedInitSize = HeapRegionUsageTool.alignDown(alignedNewSize / initRatio, - generationAlignment); + spaceAlignment); if (survivorUsage.getCommitted() != expectedInitSize && survivorUsage.getCommitted() < expectedMinSize) { throw new RuntimeException("Expected survivor size should be " + expectedMinSize diff --git a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java index 86c4c7af8bc..41fa1826799 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java @@ -146,10 +146,8 @@ public class TestNewRatioFlag { long newSize = initEden + 2 * initSurv; // See GenArguments::scale_by_NewRatio_aligned for calculation in the JVM. - long alignedDownNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1), + long expectedNewSize = HeapRegionUsageTool.alignDown(initHeap / (expectedRatio + 1), wb.getHeapSpaceAlignment()); - long expectedNewSize = HeapRegionUsageTool.alignUp(alignedDownNewSize, - wb.psVirtualSpaceAlignment()); if (expectedNewSize != newSize) { throw new RuntimeException("Expected young gen size is: " + expectedNewSize diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java index d3152073c55..2f454940863 100644 --- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java +++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java @@ -182,8 +182,6 @@ public class TestNewSizeFlags { private static final GCTypes.YoungGCType YOUNG_GC_TYPE = GCTypes.YoungGCType.getYoungGCType(); private static final long HEAP_SPACE_ALIGNMENT = WB.getHeapSpaceAlignment(); private static final long HEAP_ALIGNMENT = WB.getHeapAlignment(); - private static final long PS_VIRTUAL_SPACE_ALIGNMENT = - (YOUNG_GC_TYPE == GCTypes.YoungGCType.PSNew) ? WB.psVirtualSpaceAlignment() : 0; public static final int ARRAY_LENGTH = 100; public static final int CHUNK_SIZE = 1024; @@ -303,9 +301,7 @@ public class TestNewSizeFlags { case DefNew: return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT); case PSNew: - return HeapRegionUsageTool.alignUp(HeapRegionUsageTool.alignDown(value, - HEAP_SPACE_ALIGNMENT), - PS_VIRTUAL_SPACE_ALIGNMENT); + return HeapRegionUsageTool.alignDown(value, HEAP_SPACE_ALIGNMENT); case G1: return HeapRegionUsageTool.alignUp(value, WB.g1RegionSize()); default: diff --git a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java index 90a29e78c12..ea2a20b3dc9 100644 --- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java +++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java @@ -154,7 +154,7 @@ public class TestSurvivorRatioFlag { long youngGenSize = edenUsage.getMax() + 2 * survivorUsage.getMax(); // for Paralle GC Min/InitialSurvivorRatio = SurvivorRatio + 2 long expectedSize = HeapRegionUsageTool.alignDown(youngGenSize / (expectedRatio + 2), - wb.psHeapGenerationAlignment()); + wb.getHeapSpaceAlignment()); if (expectedSize != survivorUsage.getCommitted()) { throw new RuntimeException("Expected survivor size is: " + expectedSize diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 10fad866ca3..d1f2c5822af 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -297,10 +297,6 @@ public class WhiteBox { public native int g1ActiveMemoryNodeCount(); public native int[] g1MemoryNodeIds(); - // Parallel GC - public native long psVirtualSpaceAlignment(); - public native long psHeapGenerationAlignment(); - /** * Enumerates old regions with liveness less than specified and produces some statistics * @param liveness percent of region's liveness (live_objects / total_region_size * 100).