From dbd2b5f89f10c6650c302abe2858f1e426c98ae4 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 17 Apr 2023 11:59:11 +0000 Subject: [PATCH 001/288] 8305892: G1: Fix G1MMUTracker::when_sec documentation Reviewed-by: iwalulya, tschatzl --- src/hotspot/share/gc/g1/g1MMUTracker.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1MMUTracker.cpp b/src/hotspot/share/gc/g1/g1MMUTracker.cpp index 77366c0b73c..7fb29eb39f1 100644 --- a/src/hotspot/share/gc/g1/g1MMUTracker.cpp +++ b/src/hotspot/share/gc/g1/g1MMUTracker.cpp @@ -115,13 +115,13 @@ void G1MMUTracker::add_pause(double start, double end) { // GC events / pause_time // / | \ \ | / / // -------------[----]-[---]--[--]---[---]------|[--]-----> Time -// | | | -// | | | -// |<- limit | | -// | |<- balance_timestamp | -// | ^ | -// | | -// |<-------- _time_slice ------>| +// | | | +// | | | +// |<- limit | | +// | |<- balance_timestamp | +// | ^ | +// | | +// |<-------- _time_slice --------->| // // The MMU constraint requires that we can spend up to `max_gc_time()` on GC // pauses inside a window of `_time_slice` length. Therefore, we have a GC @@ -134,7 +134,7 @@ void G1MMUTracker::add_pause(double start, double end) { // time inside [balance_timestamp, current_timestamp] is equal to the budget. // Next, return `balance_timestamp - limit`. // -// When there are no enough GC events, i.e. we have a surplus buget, a new GC +// When there are not enough GC events, i.e. we have a surplus budget, a new GC // pause can start right away, so return 0. double G1MMUTracker::when_sec(double current_timestamp, double pause_time) { assert(pause_time > 0.0, "precondition"); From 1958f0e8bdda3b8aba88f1d3d623ffcf1be31aa8 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 17 Apr 2023 12:00:01 +0000 Subject: [PATCH 002/288] 8305233: G1: Refactor G1ClearCardTableTask Reviewed-by: tschatzl, iwalulya --- src/hotspot/share/gc/g1/g1RemSet.cpp | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 9e25b05935d..d8845880312 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -205,26 +205,20 @@ private: class G1ClearCardTableTask : public G1AbstractSubTask { G1CollectedHeap* _g1h; G1DirtyRegions* _regions; - uint _chunk_length; - uint volatile _cur_dirty_regions; G1RemSetScanState* _scan_state; + static constexpr uint num_cards_per_worker = M; public: G1ClearCardTableTask(G1CollectedHeap* g1h, G1DirtyRegions* regions, - uint chunk_length, G1RemSetScanState* scan_state) : G1AbstractSubTask(G1GCPhaseTimes::ClearCardTable), _g1h(g1h), _regions(regions), - _chunk_length(chunk_length), _cur_dirty_regions(0), - _scan_state(scan_state) { - - assert(chunk_length > 0, "must be"); - } + _scan_state(scan_state) {} double worker_cost() const override { uint num_regions = _regions->size(); @@ -233,9 +227,10 @@ private: // There is no card table clean work, only some cleanup of memory. return AlmostNoWork; } - return ((double)align_up((size_t)num_regions << HeapRegion::LogCardsPerRegion, chunk_size()) / chunk_size()); - } + double num_cards = num_regions << HeapRegion::LogCardsPerRegion; + return ceil(num_cards / num_cards_per_worker); + } virtual ~G1ClearCardTableTask() { _scan_state->cleanup(); @@ -244,12 +239,12 @@ private: #endif } - static uint chunk_size() { return M; } - void do_work(uint worker_id) override { + const uint num_regions_per_worker = num_cards_per_worker / (uint)HeapRegion::CardsPerRegion; + while (_cur_dirty_regions < _regions->size()) { - uint next = Atomic::fetch_and_add(&_cur_dirty_regions, _chunk_length); - uint max = MIN2(next + _chunk_length, _regions->size()); + uint next = Atomic::fetch_and_add(&_cur_dirty_regions, num_regions_per_worker); + uint max = MIN2(next + num_regions_per_worker, _regions->size()); for (uint i = next; i < max; i++) { HeapRegion* r = _g1h->region_at(_regions->at(i)); @@ -368,9 +363,7 @@ public: } G1AbstractSubTask* create_cleanup_after_scan_heap_roots_task() { - uint const chunk_length = G1ClearCardTableTask::chunk_size() / (uint)HeapRegion::CardsPerRegion; - - return new G1ClearCardTableTask(G1CollectedHeap::heap(), _all_dirty_regions, chunk_length, this); + return new G1ClearCardTableTask(G1CollectedHeap::heap(), _all_dirty_regions, this); } void cleanup() { From 2240c7ec2fd87a4fd5670f88b9e7dcb3758294c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Mon, 17 Apr 2023 12:13:12 +0000 Subject: [PATCH 003/288] 8305543: Ensure GC barriers for arraycopy on AArch64 use caller saved neon temp registers Reviewed-by: rcastanedalo, aph --- src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 73423a1bf1c..d7954b2af36 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -791,7 +791,7 @@ class StubGenerator: public StubCodeGenerator { t4 = r7, t5 = r11, t6 = r12, t7 = r13; const Register stride = r14; const Register gct1 = rscratch1, gct2 = rscratch2, gct3 = r10; - const FloatRegister gcvt1 = v6, gcvt2 = v7, gcvt3 = v8; + const FloatRegister gcvt1 = v6, gcvt2 = v7, gcvt3 = v16; // Note that v8-v15 are callee saved ArrayCopyBarrierSetHelper bs(_masm, decorators, type, gct1, gct2, gct3, gcvt1, gcvt2, gcvt3); assert_different_registers(rscratch1, rscratch2, t0, t1, t2, t3, t4, t5, t6, t7); @@ -1185,7 +1185,7 @@ class StubGenerator: public StubCodeGenerator { const Register t6 = r12, t7 = r13, t8 = r14, t9 = r15; const Register send = r17, dend = r16; const Register gct1 = rscratch1, gct2 = rscratch2, gct3 = r10; - const FloatRegister gcvt1 = v6, gcvt2 = v7, gcvt3 = v8; + const FloatRegister gcvt1 = v6, gcvt2 = v7, gcvt3 = v16; // Note that v8-v15 are callee saved ArrayCopyBarrierSetHelper bs(_masm, decorators, type, gct1, gct2, gct3, gcvt1, gcvt2, gcvt3); if (PrefetchCopyIntervalInBytes > 0) From 02347d0cec77212d38aad8d06b6ac0c316be00d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96sterlund?= Date: Mon, 17 Apr 2023 12:14:57 +0000 Subject: [PATCH 004/288] 8305351: C2 setScopedValueCache intrinsic doesn't use access API Reviewed-by: kvn, rcastanedalo, aph, mdoerr --- src/hotspot/share/opto/library_call.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index ce0957fc793..86b1c26d048 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -3508,8 +3508,7 @@ bool LibraryCallKit::inline_native_setScopedValueCache() { Node* cache_obj_handle = scopedValueCache_helper(); const TypePtr *adr_type = _gvn.type(cache_obj_handle)->isa_ptr(); - store_to_memory(control(), cache_obj_handle, arr, T_OBJECT, adr_type, - MemNode::unordered); + access_store_at(nullptr, cache_obj_handle, adr_type, arr, _gvn.type(arr), T_OBJECT, IN_NATIVE | MO_UNORDERED); return true; } From 7551529854b325488b58481e11103b08a211aff4 Mon Sep 17 00:00:00 2001 From: "Kirill A. Korinsky" Date: Mon, 17 Apr 2023 12:22:26 +0000 Subject: [PATCH 005/288] 8305995: Footprint regression from JDK-8224957 Reviewed-by: kvn, thartmann --- src/hotspot/share/opto/node.cpp | 2 +- .../bench/vm/compiler/RBTreeSearch.java | 1236 +++++++++++++++++ 2 files changed, 1237 insertions(+), 1 deletion(-) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/RBTreeSearch.java diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index 20892cfef73..dde202023fd 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -1310,7 +1310,7 @@ bool Node::dominates(Node* sub, Node_List &nlist) { } else if (sub == up && sub->is_Region() && sub->req() == 2) { // Take in(1) path on the way up to 'dom' for regions with only one input up = sub->in(1); - } else if (sub == up && sub->is_Region() && sub->req() == 3) { + } else if (sub == up && sub->is_Region()) { // Try both paths for Regions with 2 input paths (it may be a loop head). // It could give conservative 'false' answer without information // which region's input is the entry path. diff --git a/test/micro/org/openjdk/bench/vm/compiler/RBTreeSearch.java b/test/micro/org/openjdk/bench/vm/compiler/RBTreeSearch.java new file mode 100644 index 00000000000..9b7430ccc13 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/RBTreeSearch.java @@ -0,0 +1,1236 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; + +/* + * This benchmark is used as easy reproducer of JDK-8305995 + * + * This benchmark contains simplified and minimized RB-tree + * which is based on fasutils with iterators that jumps. + * + * At the end it contains a tree serialized as lines, and + * maxPattern which is used to search in this tree. + */ +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 2, timeUnit = TimeUnit.SECONDS) +@Fork(value = 3) +public class RBTreeSearch { + + private final Tree pattern; + + private final Tree[] nodes; + + private final Tree root; + + private final int[] idxStack; + private final Tree[] objStack; + + public RBTreeSearch() { + idxStack = new int[maxPattern]; + + objStack = new Tree[maxPattern]; + + pattern = new Tree(); + for (int i = 0; i <= maxPattern; i++) { + pattern.put(i, i); + } + + nodes = new Tree[directions.length]; + for (int i = 0; i < directions.length; i++) { + if (directions[i] == null) { + continue; + } + Tree kids = new Tree(); + nodes[i] = kids; + for (String pair : directions[i].split(", ")) { + String[] kv = pair.split("=>"); + kids.put(Integer.parseInt(kv[0]), Integer.parseInt(kv[1])); + } + } + + root = nodes[0]; + } + + @Benchmark + public void search() { + Tree.Iterator sliceIt = pattern.keyIterator(); + + int stackSize = 0; + idxStack[stackSize] = pattern.firstIntKey(); + objStack[stackSize++] = root; + + while (stackSize > 0) { + stackSize--; + Tree node = objStack[stackSize]; + + final int startPoint = Math.max(idxStack[stackSize], node.firstIntKey()) - 1; + final Tree.Iterator rootIt = node.keyIterator(startPoint); + + sliceIt.jump(startPoint); + while (sliceIt.hasNext() && rootIt.hasNext()) { + final int sliceElem = sliceIt.nextInt(); + final int rootElem = rootIt.nextInt(); + if (sliceElem < rootElem) { + rootIt.previousInt(); + if (sliceIt.nextInt() >= rootElem) { + sliceIt.previousInt(); + } else { + sliceIt.jump(rootElem - 1); + } + } else if (sliceElem == rootElem) { + final int childrenIdx = node.get(sliceElem); + final Tree children = nodes[childrenIdx]; + + if (children != null) { + idxStack[stackSize] = sliceElem; + objStack[stackSize++] = children; + } + } + } + } + } + + public static class Tree { + + protected transient Entry root; + + protected transient Entry firstEntry; + + protected transient Entry lastEntry; + + private final transient boolean[] dirPath = new boolean[64]; + + private final transient Entry[] nodePath = new Entry[64]; + + public int put(final int k, final int v) { + Entry e = add(k); + final int oldValue = e.value; + e.value = v; + return oldValue; + } + + private Entry add(final int k) { + int maxDepth = 0; + Entry e; + if (root == null) { + e = root = lastEntry = firstEntry = new Entry(k, 0); + } + else { + Entry p = root; + int cmp, i = 0; + while(true) { + if ((cmp = Integer.compare(k, p.key)) == 0) { + while(i-- != 0) nodePath[i] = null; + return p; + } + nodePath[i] = p; + if (dirPath[i++] = cmp > 0) { + if (p.succ()) { + e = new Entry(k, 0); + if (p.right == null) lastEntry = e; + e.left = p; + e.right = p.right; + p.right(e); + break; + } + p = p.right; + } + else { + if (p.pred()) { + e = new Entry(k, 0); + if (p.left == null) firstEntry = e; + e.right = p; + e.left = p.left; + p.left(e); + break; + } + p = p.left; + } + } + maxDepth = i--; + while(i > 0 && ! nodePath[i].black()) { + if (! dirPath[i - 1]) { + Entry y = nodePath[i - 1].right; + if (! nodePath[i - 1].succ() && ! y.black()) { + nodePath[i].black(true); + y.black(true); + nodePath[i - 1].black(false); + i -= 2; + } + else { + Entry x; + if (! dirPath[i]) y = nodePath[i]; + else { + x = nodePath[i]; + y = x.right; + x.right = y.left; + y.left = x; + nodePath[i - 1].left = y; + if (y.pred()) { + y.pred(false); + x.succ(y); + } + } + x = nodePath[i - 1]; + x.black(false); + y.black(true); + x.left = y.right; + y.right = x; + if (i < 2) root = y; + else { + if (dirPath[i - 2]) nodePath[i - 2].right = y; + else nodePath[i - 2].left = y; + } + if (y.succ()) { + y.succ(false); + x.pred(y); + } + break; + } + } + else { + Entry y = nodePath[i - 1].left; + if (! nodePath[i - 1].pred() && ! y.black()) { + nodePath[i].black(true); + y.black(true); + nodePath[i - 1].black(false); + i -= 2; + } + else { + Entry x; + if (dirPath[i]) y = nodePath[i]; + else { + x = nodePath[i]; + y = x.left; + x.left = y.right; + y.right = x; + nodePath[i - 1].right = y; + if (y.succ()) { + y.succ(false); + x.pred(y); + } + } + x = nodePath[i - 1]; + x.black(false); + y.black(true); + x.right = y.left; + y.left = x; + if (i < 2) root = y; + else { + if (dirPath[i - 2]) nodePath[i - 2].right = y; + else nodePath[i - 2].left = y; + } + if (y.pred()){ + y.pred(false); + x.succ(y); + } + break; + } + } + } + } + root.black(true); + while(maxDepth-- != 0) nodePath[maxDepth] = null; + return e; + } + + private static final class Entry { + int key; + int value; + + private static final int BLACK_MASK = 1; + + private static final int SUCC_MASK = 1 << 31; + + private static final int PRED_MASK = 1 << 30; + + Entry left, right; + + int info; + + Entry(final int k, final int v) { + key = k; + value = v; + info = SUCC_MASK | PRED_MASK; + } + + Entry left() { + return (info & PRED_MASK) != 0 ? null : left; + } + + Entry right() { + return (info & SUCC_MASK) != 0 ? null : right; + } + + boolean pred() { + return (info & PRED_MASK) != 0; + } + + boolean succ() { + return (info & SUCC_MASK) != 0; + } + + void pred(final boolean pred) { + if (pred) info |= PRED_MASK; + else info &= ~PRED_MASK; + } + + void succ(final boolean succ) { + if (succ) info |= SUCC_MASK; + else info &= ~SUCC_MASK; + } + + void pred(final Entry pred) { + info |= PRED_MASK; + left = pred; + } + + void succ(final Entry succ) { + info |= SUCC_MASK; + right = succ; + } + + void left(final Entry left) { + info &= ~PRED_MASK; + this.left = left; + } + + void right(final Entry right) { + info &= ~SUCC_MASK; + this.right = right; + } + + boolean black() { + return (info & BLACK_MASK) != 0; + } + + void black(final boolean black) { + if (black) info |= BLACK_MASK; + else info &= ~BLACK_MASK; + } + + Entry next() { + Entry next = this.right; + if ((info & SUCC_MASK) == 0) while ((next.info & PRED_MASK) == 0) next = next.left; + return next; + } + + Entry prev() { + Entry prev = this.left; + if ((info & PRED_MASK) == 0) while ((prev.info & SUCC_MASK) == 0) prev = prev.right; + return prev; + } + } + + public int get(final int k) { + Entry e = root; + int cmp; + while (e != null && (cmp = Integer.compare(k, e.key)) != 0) { + e = cmp < 0 ? e.left() : e.right(); + } + return e == null ? 0 : e.value; + } + + public int firstIntKey() { + return firstEntry.key; + } + + interface Iterator { + boolean hasNext(); + int nextInt(); + int previousInt(); + void jump(final int fromElement); + } + + private class KeyIteratorImpl implements Iterator { + Entry prev; + + Entry next; + + Entry curr; + + int index = 0; + + KeyIteratorImpl() { + next = firstEntry; + } + + KeyIteratorImpl(final int k) { + if ((next = locateKey(k)) != null) { + if (next.key <= k) { + prev = next; + next = next.next(); + } + else prev = next.prev(); + } + } + + private Entry locateKey(final int k) { + Entry e = root, last = root; + int cmp = 0; + while (e != null && (cmp = Integer.compare(k, e.key)) != 0) { + last = e; + e = cmp < 0 ? e.left() : e.right(); + } + return cmp == 0 ? e : last; + } + + public boolean hasNext() { return next != null; } + + Entry nextEntry() { + curr = prev = next; + index++; + next = next.next(); + return curr; + } + + Entry previousEntry() { + curr = next = prev; + index--; + prev = prev.prev(); + return curr; + } + public void jump(final int fromElement) { + if ((next = locateKey(fromElement)) != null) { + if (next.key <= fromElement) { + prev = next; + next = next.next(); + } + else prev = next.prev(); + } + } + + public int nextInt() { return nextEntry().key; } + + public int previousInt() { return previousEntry().key; } + + } + + public Iterator keyIterator() { + return new KeyIteratorImpl(); + } + + public Iterator keyIterator(final int from) { + return new KeyIteratorImpl(from); + } + } + + private static final int maxPattern = 39; + + private static final String[] directions = { + "0=>1, 1=>4, 2=>2, 4=>3, 7=>5", + "13=>628, 14=>627, 15=>626, 17=>629, 18=>630", + "13=>473, 14=>472, 15=>471, 17=>474, 18=>475", + "13=>318, 14=>317, 15=>316, 17=>319, 18=>320", + "13=>163, 14=>162, 15=>161, 17=>164, 18=>165", + "13=>8, 14=>7, 15=>6, 17=>9, 18=>10", + "22=>135, 23=>134, 24=>132, 26=>133, 27=>131", + "22=>105, 23=>104, 24=>102, 26=>103, 27=>101", + "22=>75, 23=>74, 24=>72, 26=>73, 27=>71", + "22=>45, 23=>44, 24=>42, 26=>43, 27=>41", + "22=>15, 23=>14, 24=>12, 26=>13, 27=>11", + "31=>38, 32=>39, 33=>36, 34=>40, 35=>37", + "31=>33, 32=>34, 33=>31, 34=>35, 35=>32", + "31=>28, 32=>29, 33=>26, 34=>30, 35=>27", + "31=>23, 32=>24, 33=>21, 34=>25, 35=>22", + "31=>18, 32=>19, 33=>16, 34=>20, 35=>17", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>68, 32=>69, 33=>66, 34=>70, 35=>67", + "31=>63, 32=>64, 33=>61, 34=>65, 35=>62", + "31=>58, 32=>59, 33=>56, 34=>60, 35=>57", + "31=>53, 32=>54, 33=>51, 34=>55, 35=>52", + "31=>48, 32=>49, 33=>46, 34=>50, 35=>47", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>98, 32=>99, 33=>96, 34=>100, 35=>97", + "31=>93, 32=>94, 33=>91, 34=>95, 35=>92", + "31=>88, 32=>89, 33=>86, 34=>90, 35=>87", + "31=>83, 32=>84, 33=>81, 34=>85, 35=>82", + "31=>78, 32=>79, 33=>76, 34=>80, 35=>77", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>128, 32=>129, 33=>126, 34=>130, 35=>127", + "31=>123, 32=>124, 33=>121, 34=>125, 35=>122", + "31=>118, 32=>119, 33=>116, 34=>120, 35=>117", + "31=>113, 32=>114, 33=>111, 34=>115, 35=>112", + "31=>108, 32=>109, 33=>106, 34=>110, 35=>107", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>158, 32=>159, 33=>156, 34=>160, 35=>157", + "31=>153, 32=>154, 33=>151, 34=>155, 35=>152", + "31=>148, 32=>149, 33=>146, 34=>150, 35=>147", + "31=>143, 32=>144, 33=>141, 34=>145, 35=>142", + "31=>138, 32=>139, 33=>136, 34=>140, 35=>137", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "22=>290, 23=>289, 24=>287, 26=>288, 27=>286", + "22=>260, 23=>259, 24=>257, 26=>258, 27=>256", + "22=>230, 23=>229, 24=>227, 26=>228, 27=>226", + "22=>200, 23=>199, 24=>197, 26=>198, 27=>196", + "22=>170, 23=>169, 24=>167, 26=>168, 27=>166", + "31=>193, 32=>194, 33=>191, 34=>195, 35=>192", + "31=>188, 32=>189, 33=>186, 34=>190, 35=>187", + "31=>183, 32=>184, 33=>181, 34=>185, 35=>182", + "31=>178, 32=>179, 33=>176, 34=>180, 35=>177", + "31=>173, 32=>174, 33=>171, 34=>175, 35=>172", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>223, 32=>224, 33=>221, 34=>225, 35=>222", + "31=>218, 32=>219, 33=>216, 34=>220, 35=>217", + "31=>213, 32=>214, 33=>211, 34=>215, 35=>212", + "31=>208, 32=>209, 33=>206, 34=>210, 35=>207", + "31=>203, 32=>204, 33=>201, 34=>205, 35=>202", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>253, 32=>254, 33=>251, 34=>255, 35=>252", + "31=>248, 32=>249, 33=>246, 34=>250, 35=>247", + "31=>243, 32=>244, 33=>241, 34=>245, 35=>242", + "31=>238, 32=>239, 33=>236, 34=>240, 35=>237", + "31=>233, 32=>234, 33=>231, 34=>235, 35=>232", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>283, 32=>284, 33=>281, 34=>285, 35=>282", + "31=>278, 32=>279, 33=>276, 34=>280, 35=>277", + "31=>273, 32=>274, 33=>271, 34=>275, 35=>272", + "31=>268, 32=>269, 33=>266, 34=>270, 35=>267", + "31=>263, 32=>264, 33=>261, 34=>265, 35=>262", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>313, 32=>314, 33=>311, 34=>315, 35=>312", + "31=>308, 32=>309, 33=>306, 34=>310, 35=>307", + "31=>303, 32=>304, 33=>301, 34=>305, 35=>302", + "31=>298, 32=>299, 33=>296, 34=>300, 35=>297", + "31=>293, 32=>294, 33=>291, 34=>295, 35=>292", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "22=>445, 23=>444, 24=>442, 26=>443, 27=>441", + "22=>415, 23=>414, 24=>412, 26=>413, 27=>411", + "22=>385, 23=>384, 24=>382, 26=>383, 27=>381", + "22=>355, 23=>354, 24=>352, 26=>353, 27=>351", + "22=>325, 23=>324, 24=>322, 26=>323, 27=>321", + "31=>348, 32=>349, 33=>346, 34=>350, 35=>347", + "31=>343, 32=>344, 33=>341, 34=>345, 35=>342", + "31=>338, 32=>339, 33=>336, 34=>340, 35=>337", + "31=>333, 32=>334, 33=>331, 34=>335, 35=>332", + "31=>328, 32=>329, 33=>326, 34=>330, 35=>327", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>378, 32=>379, 33=>376, 34=>380, 35=>377", + "31=>373, 32=>374, 33=>371, 34=>375, 35=>372", + "31=>368, 32=>369, 33=>366, 34=>370, 35=>367", + "31=>363, 32=>364, 33=>361, 34=>365, 35=>362", + "31=>358, 32=>359, 33=>356, 34=>360, 35=>357", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>408, 32=>409, 33=>406, 34=>410, 35=>407", + "31=>403, 32=>404, 33=>401, 34=>405, 35=>402", + "31=>398, 32=>399, 33=>396, 34=>400, 35=>397", + "31=>393, 32=>394, 33=>391, 34=>395, 35=>392", + "31=>388, 32=>389, 33=>386, 34=>390, 35=>387", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>438, 32=>439, 33=>436, 34=>440, 35=>437", + "31=>433, 32=>434, 33=>431, 34=>435, 35=>432", + "31=>428, 32=>429, 33=>426, 34=>430, 35=>427", + "31=>423, 32=>424, 33=>421, 34=>425, 35=>422", + "31=>418, 32=>419, 33=>416, 34=>420, 35=>417", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>468, 32=>469, 33=>466, 34=>470, 35=>467", + "31=>463, 32=>464, 33=>461, 34=>465, 35=>462", + "31=>458, 32=>459, 33=>456, 34=>460, 35=>457", + "31=>453, 32=>454, 33=>451, 34=>455, 35=>452", + "31=>448, 32=>449, 33=>446, 34=>450, 35=>447", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "22=>600, 23=>599, 24=>597, 26=>598, 27=>596", + "22=>570, 23=>569, 24=>567, 26=>568, 27=>566", + "22=>540, 23=>539, 24=>537, 26=>538, 27=>536", + "22=>510, 23=>509, 24=>507, 26=>508, 27=>506", + "22=>480, 23=>479, 24=>477, 26=>478, 27=>476", + "31=>503, 32=>504, 33=>501, 34=>505, 35=>502", + "31=>498, 32=>499, 33=>496, 34=>500, 35=>497", + "31=>493, 32=>494, 33=>491, 34=>495, 35=>492", + "31=>488, 32=>489, 33=>486, 34=>490, 35=>487", + "31=>483, 32=>484, 33=>481, 34=>485, 35=>482", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>533, 32=>534, 33=>531, 34=>535, 35=>532", + "31=>528, 32=>529, 33=>526, 34=>530, 35=>527", + "31=>523, 32=>524, 33=>521, 34=>525, 35=>522", + "31=>518, 32=>519, 33=>516, 34=>520, 35=>517", + "31=>513, 32=>514, 33=>511, 34=>515, 35=>512", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>563, 32=>564, 33=>561, 34=>565, 35=>562", + "31=>558, 32=>559, 33=>556, 34=>560, 35=>557", + "31=>553, 32=>554, 33=>551, 34=>555, 35=>552", + "31=>548, 32=>549, 33=>546, 34=>550, 35=>547", + "31=>543, 32=>544, 33=>541, 34=>545, 35=>542", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>593, 32=>594, 33=>591, 34=>595, 35=>592", + "31=>588, 32=>589, 33=>586, 34=>590, 35=>587", + "31=>583, 32=>584, 33=>581, 34=>585, 35=>582", + "31=>578, 32=>579, 33=>576, 34=>580, 35=>577", + "31=>573, 32=>574, 33=>571, 34=>575, 35=>572", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>623, 32=>624, 33=>621, 34=>625, 35=>622", + "31=>618, 32=>619, 33=>616, 34=>620, 35=>617", + "31=>613, 32=>614, 33=>611, 34=>615, 35=>612", + "31=>608, 32=>609, 33=>606, 34=>610, 35=>607", + "31=>603, 32=>604, 33=>601, 34=>605, 35=>602", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "22=>755, 23=>754, 24=>752, 26=>753, 27=>751", + "22=>725, 23=>724, 24=>722, 26=>723, 27=>721", + "22=>695, 23=>694, 24=>692, 26=>693, 27=>691", + "22=>665, 23=>664, 24=>662, 26=>663, 27=>661", + "22=>635, 23=>634, 24=>632, 26=>633, 27=>631", + "31=>658, 32=>659, 33=>656, 34=>660, 35=>657", + "31=>653, 32=>654, 33=>651, 34=>655, 35=>652", + "31=>648, 32=>649, 33=>646, 34=>650, 35=>647", + "31=>643, 32=>644, 33=>641, 34=>645, 35=>642", + "31=>638, 32=>639, 33=>636, 34=>640, 35=>637", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>688, 32=>689, 33=>686, 34=>690, 35=>687", + "31=>683, 32=>684, 33=>681, 34=>685, 35=>682", + "31=>678, 32=>679, 33=>676, 34=>680, 35=>677", + "31=>673, 32=>674, 33=>671, 34=>675, 35=>672", + "31=>668, 32=>669, 33=>666, 34=>670, 35=>667", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>718, 32=>719, 33=>716, 34=>720, 35=>717", + "31=>713, 32=>714, 33=>711, 34=>715, 35=>712", + "31=>708, 32=>709, 33=>706, 34=>710, 35=>707", + "31=>703, 32=>704, 33=>701, 34=>705, 35=>702", + "31=>698, 32=>699, 33=>696, 34=>700, 35=>697", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>748, 32=>749, 33=>746, 34=>750, 35=>747", + "31=>743, 32=>744, 33=>741, 34=>745, 35=>742", + "31=>738, 32=>739, 33=>736, 34=>740, 35=>737", + "31=>733, 32=>734, 33=>731, 34=>735, 35=>732", + "31=>728, 32=>729, 33=>726, 34=>730, 35=>727", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "31=>778, 32=>779, 33=>776, 34=>780, 35=>777", + "31=>773, 32=>774, 33=>771, 34=>775, 35=>772", + "31=>768, 32=>769, 33=>766, 34=>770, 35=>767", + "31=>763, 32=>764, 33=>761, 34=>765, 35=>762", + "31=>758, 32=>759, 33=>756, 34=>760, 35=>757", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + }; +} From fb58d77e92caf15eada69d32f662d63758927701 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 17 Apr 2023 12:23:17 +0000 Subject: [PATCH 006/288] 8305192: serial GC fails "assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end)) failed: invalid space boundaries" Reviewed-by: iwalulya, tschatzl --- src/hotspot/share/gc/serial/defNewGeneration.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 31ca98f9570..bd256c9c555 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -394,8 +394,12 @@ void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size, uintx survivor_size = compute_survivor_size(size, SpaceAlignment); uintx eden_size = size - (2*survivor_size); if (eden_size > max_eden_size()) { - eden_size = max_eden_size(); - survivor_size = (size - eden_size)/2; + // Need to reduce eden_size to satisfy the max constraint. The delta needs + // to be 2*SpaceAlignment aligned so that both survivors are properly + // aligned. + uintx eden_delta = align_up(eden_size - max_eden_size(), 2*SpaceAlignment); + eden_size -= eden_delta; + survivor_size += eden_delta/2; } assert(eden_size > 0 && survivor_size <= eden_size, "just checking"); From cc60f2ff3f16bdb04917e09cb87f09bd544f1f8b Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 17 Apr 2023 12:27:13 +0000 Subject: [PATCH 007/288] 8305060: G1: Refactor G1ScanHRForRegionClosure::scan_heap_roots Reviewed-by: tschatzl, iwalulya --- src/hotspot/share/gc/g1/g1CardTable.hpp | 2 +- .../share/gc/g1/g1CardTable.inline.hpp | 12 +- src/hotspot/share/gc/g1/g1RemSet.cpp | 260 ++++++++---------- 3 files changed, 126 insertions(+), 148 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CardTable.hpp b/src/hotspot/share/gc/g1/g1CardTable.hpp index 3bf1bd07d04..a1ffe44e499 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.hpp @@ -103,7 +103,7 @@ public: inline void mark_range_dirty(size_t start_card_index, size_t num_cards); // Change the given range of dirty cards to "which". All of these cards must be Dirty. - inline void change_dirty_cards_to(size_t start_card_index, size_t num_cards, CardValue which); + inline void change_dirty_cards_to(CardValue* start_card, CardValue* end_card, CardValue which); inline uint region_idx_for(CardValue* p); diff --git a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp index b8a0e9b5408..5d9742c629a 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp @@ -72,14 +72,12 @@ inline void G1CardTable::mark_range_dirty(size_t start_card_index, size_t num_ca } } -inline void G1CardTable::change_dirty_cards_to(size_t start_card_index, size_t num_cards, CardValue which) { - CardValue* start = &_byte_map[start_card_index]; - CardValue* const end = start + num_cards; - while (start < end) { - CardValue value = *start; +inline void G1CardTable::change_dirty_cards_to(CardValue* start_card, CardValue* end_card, CardValue which) { + for (CardValue* i_card = start_card; i_card < end_card; ++i_card) { + CardValue value = *i_card; assert(value == dirty_card_val(), - "Must have been dirty %d start " PTR_FORMAT " " PTR_FORMAT, value, p2i(start), p2i(end)); - *start++ = which; + "Must have been dirty %d start " PTR_FORMAT " " PTR_FORMAT, value, p2i(start_card), p2i(end_card)); + *i_card = which; } } diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index d8845880312..62cf4a0194c 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -473,107 +473,6 @@ void G1RemSet::initialize(uint max_reserved_regions) { _scan_state->initialize(max_reserved_regions); } -// Helper class to scan and detect ranges of cards that need to be scanned on the -// card table. -class G1CardTableScanner : public StackObj { -public: - typedef CardTable::CardValue CardValue; - -private: - CardValue* const _base_addr; - - CardValue* _cur_addr; - CardValue* const _end_addr; - - static const size_t ToScanMask = G1CardTable::g1_card_already_scanned; - static const size_t ExpandedToScanMask = G1CardTable::WordAlreadyScanned; - - bool cur_addr_aligned() const { - return ((uintptr_t)_cur_addr) % sizeof(size_t) == 0; - } - - bool cur_card_is_dirty() const { - CardValue value = *_cur_addr; - return (value & ToScanMask) == 0; - } - - bool cur_word_of_cards_contains_any_dirty_card() const { - assert(cur_addr_aligned(), "Current address should be aligned"); - size_t const value = *(size_t*)_cur_addr; - return (~value & ExpandedToScanMask) != 0; - } - - bool cur_word_of_cards_all_dirty_cards() const { - size_t const value = *(size_t*)_cur_addr; - return value == G1CardTable::WordAllDirty; - } - - size_t get_and_advance_pos() { - _cur_addr++; - return pointer_delta(_cur_addr, _base_addr, sizeof(CardValue)) - 1; - } - -public: - G1CardTableScanner(CardValue* start_card, size_t size) : - _base_addr(start_card), - _cur_addr(start_card), - _end_addr(start_card + size) { - - assert(is_aligned(start_card, sizeof(size_t)), "Unaligned start addr " PTR_FORMAT, p2i(start_card)); - assert(is_aligned(size, sizeof(size_t)), "Unaligned size " SIZE_FORMAT, size); - } - - size_t find_next_dirty() { - while (!cur_addr_aligned()) { - if (cur_card_is_dirty()) { - return get_and_advance_pos(); - } - _cur_addr++; - } - - assert(cur_addr_aligned(), "Current address should be aligned now."); - while (_cur_addr != _end_addr) { - if (cur_word_of_cards_contains_any_dirty_card()) { - for (size_t i = 0; i < sizeof(size_t); i++) { - if (cur_card_is_dirty()) { - return get_and_advance_pos(); - } - _cur_addr++; - } - assert(false, "Should not reach here given we detected a dirty card in the word."); - } - _cur_addr += sizeof(size_t); - } - return get_and_advance_pos(); - } - - size_t find_next_non_dirty() { - assert(_cur_addr <= _end_addr, "Not allowed to search for marks after area."); - - while (!cur_addr_aligned()) { - if (!cur_card_is_dirty()) { - return get_and_advance_pos(); - } - _cur_addr++; - } - - assert(cur_addr_aligned(), "Current address should be aligned now."); - while (_cur_addr != _end_addr) { - if (!cur_word_of_cards_all_dirty_cards()) { - for (size_t i = 0; i < sizeof(size_t); i++) { - if (!cur_card_is_dirty()) { - return get_and_advance_pos(); - } - _cur_addr++; - } - assert(false, "Should not reach here given we detected a non-dirty card in the word."); - } - _cur_addr += sizeof(size_t); - } - return get_and_advance_pos(); - } -}; - // Helper class to claim dirty chunks within the card table. class G1CardTableChunkClaimer { G1RemSetScanState* _scan_state; @@ -606,9 +505,10 @@ public: // Scans a heap region for dirty cards. class G1ScanHRForRegionClosure : public HeapRegionClosure { + using CardValue = CardTable::CardValue; + G1CollectedHeap* _g1h; G1CardTable* _ct; - G1BlockOffsetTable* _bot; G1ParScanThreadState* _pss; @@ -629,7 +529,7 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { // The address to which this thread already scanned (walked the heap) up to during // card scanning (exclusive). HeapWord* _scanned_to; - G1CardTable::CardValue _scanned_card_value; + CardValue _scanned_card_value; HeapWord* scan_memregion(uint region_idx_for_card, MemRegion mr) { HeapRegion* const card_region = _g1h->region_at(region_idx_for_card); @@ -643,14 +543,18 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { return scanned_to; } - void do_claimed_block(uint const region_idx_for_card, size_t const first_card, size_t const num_cards) { - HeapWord* const card_start = _bot->address_for_index_raw(first_card); + void do_claimed_block(uint const region_idx, CardValue* const dirty_l, CardValue* const dirty_r) { + _ct->change_dirty_cards_to(dirty_l, dirty_r, _scanned_card_value); + size_t num_cards = dirty_r - dirty_l; + _blocks_scanned++; + + HeapWord* const card_start = _ct->addr_for(dirty_l); #ifdef ASSERT - HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card); + HeapRegion* hr = _g1h->region_at_or_null(region_idx); assert(hr == NULL || hr->is_in_reserved(card_start), - "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index()); + "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx)->hrm_index()); #endif - HeapWord* const top = _scan_state->scan_top(region_idx_for_card); + HeapWord* const top = _scan_state->scan_top(region_idx); if (card_start >= top) { return; } @@ -660,16 +564,108 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { return; } MemRegion mr(MAX2(card_start, _scanned_to), scan_end); - _scanned_to = scan_memregion(region_idx_for_card, mr); + _scanned_to = scan_memregion(region_idx, mr); _cards_scanned += num_cards; } - ALWAYSINLINE void do_card_block(uint const region_idx, size_t const first_card, size_t const num_cards) { - _ct->change_dirty_cards_to(first_card, num_cards, _scanned_card_value); - do_claimed_block(region_idx, first_card, num_cards); - _blocks_scanned++; - } + // To locate consecutive dirty cards inside a chunk. + class ChunkScanner { + using Word = size_t; + + CardValue* const _start_card; + CardValue* const _end_card; + + static const size_t ExpandedToScanMask = G1CardTable::WordAlreadyScanned; + static const size_t ToScanMask = G1CardTable::g1_card_already_scanned; + + static bool is_card_dirty(const CardValue* const card) { + return (*card & ToScanMask) == 0; + } + + static bool is_word_aligned(const void* const addr) { + return ((uintptr_t)addr) % sizeof(Word) == 0; + } + + CardValue* find_first_dirty_card(CardValue* i_card) const { + while (!is_word_aligned(i_card)) { + if (is_card_dirty(i_card)) { + return i_card; + } + i_card++; + } + + for (/* empty */; i_card < _end_card; i_card += sizeof(Word)) { + Word word_value = *reinterpret_cast(i_card); + bool has_dirty_cards_in_word = (~word_value & ExpandedToScanMask) != 0; + + if (has_dirty_cards_in_word) { + for (uint i = 0; i < sizeof(Word); ++i) { + if (is_card_dirty(i_card)) { + return i_card; + } + i_card++; + } + assert(false, "should have early-returned"); + } + } + + return _end_card; + } + + CardValue* find_first_non_dirty_card(CardValue* i_card) const { + while (!is_word_aligned(i_card)) { + if (!is_card_dirty(i_card)) { + return i_card; + } + i_card++; + } + + for (/* empty */; i_card < _end_card; i_card += sizeof(Word)) { + Word word_value = *reinterpret_cast(i_card); + bool all_cards_dirty = (word_value == G1CardTable::WordAllDirty); + + if (!all_cards_dirty) { + for (uint i = 0; i < sizeof(Word); ++i) { + if (!is_card_dirty(i_card)) { + return i_card; + } + i_card++; + } + assert(false, "should have early-returned"); + } + } + + return _end_card; + } + + public: + ChunkScanner(CardValue* const start_card, CardValue* const end_card) : + _start_card(start_card), + _end_card(end_card) { + assert(is_word_aligned(start_card), "precondition"); + assert(is_word_aligned(end_card), "precondition"); + } + + template + void on_dirty_cards(Func&& f) { + for (CardValue* cur_card = _start_card; cur_card < _end_card; /* empty */) { + CardValue* dirty_l = find_first_dirty_card(cur_card); + CardValue* dirty_r = find_first_non_dirty_card(dirty_l); + + assert(dirty_l <= dirty_r, "inv"); + + if (dirty_l == dirty_r) { + assert(dirty_r == _end_card, "finished the entire chunk"); + return; + } + + f(dirty_l, dirty_r); + + cur_card = dirty_r + 1; + } + } + }; void scan_heap_roots(HeapRegion* r) { uint const region_idx = r->hrm_index(); @@ -685,32 +681,17 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { _scanned_to = NULL; while (claim.has_next()) { - size_t const region_card_base_idx = ((size_t)region_idx << HeapRegion::LogCardsPerRegion) + claim.value(); - CardTable::CardValue* const base_addr = _ct->byte_for_index(region_card_base_idx); - - G1CardTableScanner scan(base_addr, claim.size()); - - size_t first_scan_idx = scan.find_next_dirty(); - while (first_scan_idx != claim.size()) { -#ifdef ASSERT - { - CardTable::CardValue value = *_ct->byte_for_index(region_card_base_idx + first_scan_idx); - assert(value == CardTable::dirty_card_val(), "is %d at region %u idx " SIZE_FORMAT, value, region_idx, first_scan_idx); - } -#endif - - size_t const last_scan_idx = scan.find_next_non_dirty(); - size_t const len = last_scan_idx - first_scan_idx; - - do_card_block(region_idx, region_card_base_idx + first_scan_idx, len); - - if (last_scan_idx == claim.size()) { - break; - } - - first_scan_idx = scan.find_next_dirty(); - } _chunks_claimed++; + + size_t const region_card_base_idx = ((size_t)region_idx << HeapRegion::LogCardsPerRegion) + claim.value(); + + CardValue* const start_card = _ct->byte_for_index(region_card_base_idx); + CardValue* const end_card = start_card + claim.size(); + + ChunkScanner chunk_scanner{start_card, end_card}; + chunk_scanner.on_dirty_cards([&] (CardValue* dirty_l, CardValue* dirty_r) { + do_claimed_block(region_idx, dirty_l, dirty_r); + }); } } @@ -722,7 +703,6 @@ public: bool remember_already_scanned_cards) : _g1h(G1CollectedHeap::heap()), _ct(_g1h->card_table()), - _bot(_g1h->bot()), _pss(pss), _scan_state(scan_state), _phase(phase), From 7360960454b3116a0724396f25415f2c3bcf8930 Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo Date: Mon, 17 Apr 2023 14:40:29 +0000 Subject: [PATCH 008/288] 8305625: Stress test crashes with SEGV in Deoptimization::deoptimize_frame_internal(JavaThread*, long*, Deoptimization::DeoptReason) Reviewed-by: rrich, rehn --- src/hotspot/share/runtime/escapeBarrier.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/escapeBarrier.cpp b/src/hotspot/share/runtime/escapeBarrier.cpp index 5d80cd8f5e3..bc01d900285 100644 --- a/src/hotspot/share/runtime/escapeBarrier.cpp +++ b/src/hotspot/share/runtime/escapeBarrier.cpp @@ -123,9 +123,8 @@ bool EscapeBarrier::deoptimize_objects_all_threads() { if (!barrier_active()) return true; ResourceMark rm(calling_thread()); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { - oop vt_oop = jt->jvmti_vthread(); - // Skip virtual threads - if (vt_oop != nullptr && java_lang_VirtualThread::is_instance(vt_oop)) { + // Skip thread with mounted continuation + if (jt->last_continuation() != nullptr) { continue; } if (jt->frames_to_pop_failed_realloc() > 0) { From 4ed933cf774f8124b18ae68d0bf8cded9244a2e2 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 17 Apr 2023 16:35:36 +0000 Subject: [PATCH 009/288] 8296248: Update CLDR to Version 43.0 Reviewed-by: joehw --- make/data/cldr/README | 2 +- make/data/cldr/common/bcp47/currency.xml | 36 +- make/data/cldr/common/bcp47/segmentation.xml | 20 +- make/data/cldr/common/bcp47/timezone.xml | 14 +- make/data/cldr/common/bcp47/variant.xml | 10 +- make/data/cldr/common/dtd/ldml.dtd | 31 +- make/data/cldr/common/dtd/ldmlBCP47.dtd | 4 +- .../data/cldr/common/dtd/ldmlSupplemental.dtd | 25 +- make/data/cldr/common/main/aa.xml | 231 + make/data/cldr/common/main/aa_DJ.xml | 45 + make/data/cldr/common/main/aa_ER.xml | 21 + make/data/cldr/common/main/aa_ET.xml | 14 + make/data/cldr/common/main/ab.xml | 4066 ++++++++ make/data/cldr/common/main/ab_GE.xml | 18 + make/data/cldr/common/main/af.xml | 446 +- make/data/cldr/common/main/af_NA.xml | 2 +- make/data/cldr/common/main/af_ZA.xml | 2 +- make/data/cldr/common/main/agq.xml | 2 +- make/data/cldr/common/main/agq_CM.xml | 2 +- make/data/cldr/common/main/ak.xml | 2 +- make/data/cldr/common/main/ak_GH.xml | 2 +- make/data/cldr/common/main/am.xml | 1336 ++- make/data/cldr/common/main/am_ET.xml | 2 +- make/data/cldr/common/main/an.xml | 1730 ++++ make/data/cldr/common/main/an_ES.xml | 14 + make/data/cldr/common/main/ann.xml | 2 +- make/data/cldr/common/main/ann_NG.xml | 2 +- make/data/cldr/common/main/apc.xml | 84 + make/data/cldr/common/main/apc_SY.xml | 14 + make/data/cldr/common/main/ar.xml | 1271 ++- make/data/cldr/common/main/ar_001.xml | 2 +- make/data/cldr/common/main/ar_AE.xml | 10 +- make/data/cldr/common/main/ar_BH.xml | 2 +- make/data/cldr/common/main/ar_DJ.xml | 2 +- make/data/cldr/common/main/ar_DZ.xml | 2 +- make/data/cldr/common/main/ar_EG.xml | 2 +- make/data/cldr/common/main/ar_EH.xml | 2 +- make/data/cldr/common/main/ar_ER.xml | 2 +- make/data/cldr/common/main/ar_IL.xml | 2 +- make/data/cldr/common/main/ar_IQ.xml | 2 +- make/data/cldr/common/main/ar_JO.xml | 2 +- make/data/cldr/common/main/ar_KM.xml | 2 +- make/data/cldr/common/main/ar_KW.xml | 2 +- make/data/cldr/common/main/ar_LB.xml | 2 +- make/data/cldr/common/main/ar_LY.xml | 2 +- make/data/cldr/common/main/ar_MA.xml | 2 +- make/data/cldr/common/main/ar_MR.xml | 2 +- make/data/cldr/common/main/ar_OM.xml | 2 +- make/data/cldr/common/main/ar_PS.xml | 2 +- make/data/cldr/common/main/ar_QA.xml | 2 +- make/data/cldr/common/main/ar_SA.xml | 166 +- make/data/cldr/common/main/ar_SD.xml | 2 +- make/data/cldr/common/main/ar_SO.xml | 2 +- make/data/cldr/common/main/ar_SS.xml | 2 +- make/data/cldr/common/main/ar_SY.xml | 2 +- make/data/cldr/common/main/ar_TD.xml | 2 +- make/data/cldr/common/main/ar_TN.xml | 2 +- make/data/cldr/common/main/ar_YE.xml | 2 +- make/data/cldr/common/main/arn.xml | 29 + make/data/cldr/common/main/arn_CL.xml | 14 + make/data/cldr/common/main/as.xml | 1079 ++- make/data/cldr/common/main/as_IN.xml | 2 +- make/data/cldr/common/main/asa.xml | 2 +- make/data/cldr/common/main/asa_TZ.xml | 2 +- make/data/cldr/common/main/ast.xml | 2 +- make/data/cldr/common/main/ast_ES.xml | 2 +- make/data/cldr/common/main/az.xml | 1247 ++- make/data/cldr/common/main/az_Arab.xml | 193 + make/data/cldr/common/main/az_Arab_IQ.xml | 15 + make/data/cldr/common/main/az_Arab_IR.xml | 15 + make/data/cldr/common/main/az_Arab_TR.xml | 15 + make/data/cldr/common/main/az_Cyrl.xml | 2 +- make/data/cldr/common/main/az_Cyrl_AZ.xml | 2 +- make/data/cldr/common/main/az_Latn.xml | 2 +- make/data/cldr/common/main/az_Latn_AZ.xml | 2 +- make/data/cldr/common/main/ba.xml | 28 + make/data/cldr/common/main/ba_RU.xml | 14 + make/data/cldr/common/main/bal.xml | 636 ++ make/data/cldr/common/main/bal_Arab.xml | 14 + make/data/cldr/common/main/bal_Arab_PK.xml | 15 + make/data/cldr/common/main/bal_Latn.xml | 637 ++ make/data/cldr/common/main/bal_Latn_PK.xml | 15 + make/data/cldr/common/main/bas.xml | 2 +- make/data/cldr/common/main/bas_CM.xml | 2 +- make/data/cldr/common/main/be.xml | 1403 ++- make/data/cldr/common/main/be_BY.xml | 2 +- make/data/cldr/common/main/be_TARASK.xml | 127 +- make/data/cldr/common/main/bem.xml | 2 +- make/data/cldr/common/main/bem_ZM.xml | 2 +- make/data/cldr/common/main/bez.xml | 2 +- make/data/cldr/common/main/bez_TZ.xml | 2 +- make/data/cldr/common/main/bg.xml | 871 +- make/data/cldr/common/main/bg_BG.xml | 2 +- make/data/cldr/common/main/bgc.xml | 2 +- make/data/cldr/common/main/bgc_IN.xml | 2 +- make/data/cldr/common/main/bgn.xml | 1109 +++ make/data/cldr/common/main/bgn_AE.xml | 14 + make/data/cldr/common/main/bgn_AF.xml | 14 + make/data/cldr/common/main/bgn_IR.xml | 14 + make/data/cldr/common/main/bgn_OM.xml | 14 + make/data/cldr/common/main/bgn_PK.xml | 14 + make/data/cldr/common/main/bho.xml | 28 +- make/data/cldr/common/main/bho_IN.xml | 2 +- make/data/cldr/common/main/blt.xml | 22 + make/data/cldr/common/main/blt_VN.xml | 14 + make/data/cldr/common/main/bm.xml | 2 +- make/data/cldr/common/main/bm_ML.xml | 2 +- make/data/cldr/common/main/bm_Nkoo.xml | 175 + make/data/cldr/common/main/bm_Nkoo_ML.xml | 15 + make/data/cldr/common/main/bn.xml | 962 +- make/data/cldr/common/main/bn_BD.xml | 2 +- make/data/cldr/common/main/bn_IN.xml | 2 +- make/data/cldr/common/main/bo.xml | 2 +- make/data/cldr/common/main/bo_CN.xml | 2 +- make/data/cldr/common/main/bo_IN.xml | 2 +- make/data/cldr/common/main/br.xml | 545 +- make/data/cldr/common/main/br_FR.xml | 2 +- make/data/cldr/common/main/brx.xml | 54 +- make/data/cldr/common/main/brx_IN.xml | 2 +- make/data/cldr/common/main/bs.xml | 8587 ++++++++++++++++- make/data/cldr/common/main/bs_Cyrl.xml | 827 +- make/data/cldr/common/main/bs_Cyrl_BA.xml | 2 +- make/data/cldr/common/main/bs_Latn.xml | 2 +- make/data/cldr/common/main/bs_Latn_BA.xml | 2 +- make/data/cldr/common/main/bss.xml | 124 + make/data/cldr/common/main/bss_CM.xml | 14 + make/data/cldr/common/main/byn.xml | 527 + make/data/cldr/common/main/byn_ER.xml | 14 + make/data/cldr/common/main/ca.xml | 946 +- make/data/cldr/common/main/ca_AD.xml | 2 +- make/data/cldr/common/main/ca_ES.xml | 2 +- make/data/cldr/common/main/ca_ES_VALENCIA.xml | 2 +- make/data/cldr/common/main/ca_FR.xml | 2 +- make/data/cldr/common/main/ca_IT.xml | 2 +- make/data/cldr/common/main/cad.xml | 201 + make/data/cldr/common/main/cad_US.xml | 14 + make/data/cldr/common/main/cch.xml | 180 + make/data/cldr/common/main/cch_NG.xml | 14 + make/data/cldr/common/main/ccp.xml | 7 +- make/data/cldr/common/main/ccp_BD.xml | 2 +- make/data/cldr/common/main/ccp_IN.xml | 2 +- make/data/cldr/common/main/ce.xml | 2 +- make/data/cldr/common/main/ce_RU.xml | 2 +- make/data/cldr/common/main/ceb.xml | 622 +- make/data/cldr/common/main/ceb_PH.xml | 2 +- make/data/cldr/common/main/cgg.xml | 2 +- make/data/cldr/common/main/cgg_UG.xml | 2 +- make/data/cldr/common/main/cho.xml | 31 + make/data/cldr/common/main/cho_US.xml | 14 + make/data/cldr/common/main/chr.xml | 421 +- make/data/cldr/common/main/chr_US.xml | 2 +- make/data/cldr/common/main/cic.xml | 213 + make/data/cldr/common/main/cic_US.xml | 14 + make/data/cldr/common/main/ckb.xml | 19 +- make/data/cldr/common/main/ckb_IQ.xml | 2 +- make/data/cldr/common/main/ckb_IR.xml | 2 +- make/data/cldr/common/main/co.xml | 948 ++ make/data/cldr/common/main/co_FR.xml | 14 + make/data/cldr/common/main/cs.xml | 293 +- make/data/cldr/common/main/cs_CZ.xml | 2 +- make/data/cldr/common/main/cu.xml | 1033 ++ make/data/cldr/common/main/cu_RU.xml | 14 + make/data/cldr/common/main/cv.xml | 127 +- make/data/cldr/common/main/cv_RU.xml | 2 +- make/data/cldr/common/main/cy.xml | 1046 +- make/data/cldr/common/main/cy_GB.xml | 2 +- make/data/cldr/common/main/da.xml | 868 +- make/data/cldr/common/main/da_DK.xml | 2 +- make/data/cldr/common/main/da_GL.xml | 2 +- make/data/cldr/common/main/dav.xml | 2 +- make/data/cldr/common/main/dav_KE.xml | 2 +- make/data/cldr/common/main/de.xml | 778 +- make/data/cldr/common/main/de_AT.xml | 2 +- make/data/cldr/common/main/de_BE.xml | 2 +- make/data/cldr/common/main/de_CH.xml | 16 +- make/data/cldr/common/main/de_DE.xml | 2 +- make/data/cldr/common/main/de_IT.xml | 2 +- make/data/cldr/common/main/de_LI.xml | 2 +- make/data/cldr/common/main/de_LU.xml | 2 +- make/data/cldr/common/main/dje.xml | 2 +- make/data/cldr/common/main/dje_NE.xml | 2 +- make/data/cldr/common/main/doi.xml | 3 +- make/data/cldr/common/main/doi_IN.xml | 2 +- make/data/cldr/common/main/dsb.xml | 1013 +- make/data/cldr/common/main/dsb_DE.xml | 2 +- make/data/cldr/common/main/dua.xml | 2 +- make/data/cldr/common/main/dua_CM.xml | 2 +- make/data/cldr/common/main/dv.xml | 154 + make/data/cldr/common/main/dv_MV.xml | 14 + make/data/cldr/common/main/dyo.xml | 2 +- make/data/cldr/common/main/dyo_SN.xml | 2 +- make/data/cldr/common/main/dz.xml | 2 +- make/data/cldr/common/main/dz_BT.xml | 2 +- make/data/cldr/common/main/ebu.xml | 2 +- make/data/cldr/common/main/ebu_KE.xml | 2 +- make/data/cldr/common/main/ee.xml | 2 +- make/data/cldr/common/main/ee_GH.xml | 2 +- make/data/cldr/common/main/ee_TG.xml | 2 +- make/data/cldr/common/main/el.xml | 744 +- make/data/cldr/common/main/el_CY.xml | 2 +- make/data/cldr/common/main/el_GR.xml | 2 +- make/data/cldr/common/main/el_POLYTON.xml | 548 ++ make/data/cldr/common/main/en.xml | 100 +- make/data/cldr/common/main/en_001.xml | 9 +- make/data/cldr/common/main/en_150.xml | 2 +- make/data/cldr/common/main/en_AE.xml | 2 +- make/data/cldr/common/main/en_AG.xml | 2 +- make/data/cldr/common/main/en_AI.xml | 2 +- make/data/cldr/common/main/en_AS.xml | 2 +- make/data/cldr/common/main/en_AT.xml | 2 +- make/data/cldr/common/main/en_AU.xml | 14 +- make/data/cldr/common/main/en_BB.xml | 2 +- make/data/cldr/common/main/en_BE.xml | 2 +- make/data/cldr/common/main/en_BI.xml | 2 +- make/data/cldr/common/main/en_BM.xml | 2 +- make/data/cldr/common/main/en_BS.xml | 2 +- make/data/cldr/common/main/en_BW.xml | 2 +- make/data/cldr/common/main/en_BZ.xml | 2 +- make/data/cldr/common/main/en_CA.xml | 58 +- make/data/cldr/common/main/en_CC.xml | 2 +- make/data/cldr/common/main/en_CH.xml | 2 +- make/data/cldr/common/main/en_CK.xml | 2 +- make/data/cldr/common/main/en_CM.xml | 2 +- make/data/cldr/common/main/en_CX.xml | 2 +- make/data/cldr/common/main/en_CY.xml | 2 +- make/data/cldr/common/main/en_DE.xml | 2 +- make/data/cldr/common/main/en_DG.xml | 2 +- make/data/cldr/common/main/en_DK.xml | 2 +- make/data/cldr/common/main/en_DM.xml | 2 +- make/data/cldr/common/main/en_Dsrt.xml | 936 ++ make/data/cldr/common/main/en_Dsrt_US.xml | 15 + make/data/cldr/common/main/en_ER.xml | 2 +- make/data/cldr/common/main/en_FI.xml | 2 +- make/data/cldr/common/main/en_FJ.xml | 2 +- make/data/cldr/common/main/en_FK.xml | 2 +- make/data/cldr/common/main/en_FM.xml | 2 +- make/data/cldr/common/main/en_GB.xml | 5 +- make/data/cldr/common/main/en_GD.xml | 2 +- make/data/cldr/common/main/en_GG.xml | 2 +- make/data/cldr/common/main/en_GH.xml | 2 +- make/data/cldr/common/main/en_GI.xml | 2 +- make/data/cldr/common/main/en_GM.xml | 2 +- make/data/cldr/common/main/en_GU.xml | 2 +- make/data/cldr/common/main/en_GY.xml | 2 +- make/data/cldr/common/main/en_HK.xml | 2 +- make/data/cldr/common/main/en_IE.xml | 2 +- make/data/cldr/common/main/en_IL.xml | 2 +- make/data/cldr/common/main/en_IM.xml | 2 +- make/data/cldr/common/main/en_IN.xml | 2 +- make/data/cldr/common/main/en_IO.xml | 2 +- make/data/cldr/common/main/en_JE.xml | 2 +- make/data/cldr/common/main/en_JM.xml | 2 +- make/data/cldr/common/main/en_KE.xml | 2 +- make/data/cldr/common/main/en_KI.xml | 2 +- make/data/cldr/common/main/en_KN.xml | 2 +- make/data/cldr/common/main/en_KY.xml | 2 +- make/data/cldr/common/main/en_LC.xml | 2 +- make/data/cldr/common/main/en_LR.xml | 2 +- make/data/cldr/common/main/en_LS.xml | 2 +- make/data/cldr/common/main/en_MG.xml | 2 +- make/data/cldr/common/main/en_MH.xml | 2 +- make/data/cldr/common/main/en_MO.xml | 2 +- make/data/cldr/common/main/en_MP.xml | 2 +- make/data/cldr/common/main/en_MS.xml | 2 +- make/data/cldr/common/main/en_MT.xml | 2 +- make/data/cldr/common/main/en_MU.xml | 2 +- make/data/cldr/common/main/en_MV.xml | 2 +- make/data/cldr/common/main/en_MW.xml | 2 +- make/data/cldr/common/main/en_MY.xml | 2 +- make/data/cldr/common/main/en_NA.xml | 2 +- make/data/cldr/common/main/en_NF.xml | 2 +- make/data/cldr/common/main/en_NG.xml | 2 +- make/data/cldr/common/main/en_NL.xml | 2 +- make/data/cldr/common/main/en_NR.xml | 2 +- make/data/cldr/common/main/en_NU.xml | 2 +- make/data/cldr/common/main/en_NZ.xml | 2 +- make/data/cldr/common/main/en_PG.xml | 2 +- make/data/cldr/common/main/en_PH.xml | 2 +- make/data/cldr/common/main/en_PK.xml | 2 +- make/data/cldr/common/main/en_PN.xml | 2 +- make/data/cldr/common/main/en_PR.xml | 2 +- make/data/cldr/common/main/en_PW.xml | 2 +- make/data/cldr/common/main/en_RW.xml | 2 +- make/data/cldr/common/main/en_SB.xml | 2 +- make/data/cldr/common/main/en_SC.xml | 2 +- make/data/cldr/common/main/en_SD.xml | 2 +- make/data/cldr/common/main/en_SE.xml | 2 +- make/data/cldr/common/main/en_SG.xml | 2 +- make/data/cldr/common/main/en_SH.xml | 2 +- make/data/cldr/common/main/en_SI.xml | 2 +- make/data/cldr/common/main/en_SL.xml | 2 +- make/data/cldr/common/main/en_SS.xml | 2 +- make/data/cldr/common/main/en_SX.xml | 2 +- make/data/cldr/common/main/en_SZ.xml | 2 +- make/data/cldr/common/main/en_Shaw.xml | 212 + make/data/cldr/common/main/en_Shaw_GB.xml | 15 + make/data/cldr/common/main/en_TC.xml | 2 +- make/data/cldr/common/main/en_TK.xml | 2 +- make/data/cldr/common/main/en_TO.xml | 2 +- make/data/cldr/common/main/en_TT.xml | 2 +- make/data/cldr/common/main/en_TV.xml | 2 +- make/data/cldr/common/main/en_TZ.xml | 2 +- make/data/cldr/common/main/en_UG.xml | 2 +- make/data/cldr/common/main/en_UM.xml | 2 +- make/data/cldr/common/main/en_US.xml | 2 +- make/data/cldr/common/main/en_US_POSIX.xml | 2 +- make/data/cldr/common/main/en_VC.xml | 2 +- make/data/cldr/common/main/en_VG.xml | 2 +- make/data/cldr/common/main/en_VI.xml | 2 +- make/data/cldr/common/main/en_VU.xml | 2 +- make/data/cldr/common/main/en_WS.xml | 2 +- make/data/cldr/common/main/en_ZA.xml | 2 +- make/data/cldr/common/main/en_ZM.xml | 2 +- make/data/cldr/common/main/en_ZW.xml | 2 +- make/data/cldr/common/main/eo.xml | 153 +- make/data/cldr/common/main/eo_001.xml | 2 +- make/data/cldr/common/main/es.xml | 352 +- make/data/cldr/common/main/es_419.xml | 78 +- make/data/cldr/common/main/es_AR.xml | 21 +- make/data/cldr/common/main/es_BO.xml | 2 +- make/data/cldr/common/main/es_BR.xml | 2 +- make/data/cldr/common/main/es_BZ.xml | 2 +- make/data/cldr/common/main/es_CL.xml | 10 +- make/data/cldr/common/main/es_CO.xml | 13 +- make/data/cldr/common/main/es_CR.xml | 2 +- make/data/cldr/common/main/es_CU.xml | 2 +- make/data/cldr/common/main/es_DO.xml | 21 +- make/data/cldr/common/main/es_EA.xml | 2 +- make/data/cldr/common/main/es_EC.xml | 2 +- make/data/cldr/common/main/es_ES.xml | 2 +- make/data/cldr/common/main/es_GQ.xml | 2 +- make/data/cldr/common/main/es_GT.xml | 11 +- make/data/cldr/common/main/es_HN.xml | 2 +- make/data/cldr/common/main/es_IC.xml | 2 +- make/data/cldr/common/main/es_MX.xml | 54 +- make/data/cldr/common/main/es_NI.xml | 2 +- make/data/cldr/common/main/es_PA.xml | 2 +- make/data/cldr/common/main/es_PE.xml | 2 +- make/data/cldr/common/main/es_PH.xml | 2 +- make/data/cldr/common/main/es_PR.xml | 2 +- make/data/cldr/common/main/es_PY.xml | 8 +- make/data/cldr/common/main/es_SV.xml | 2 +- make/data/cldr/common/main/es_US.xml | 71 +- make/data/cldr/common/main/es_UY.xml | 2 +- make/data/cldr/common/main/es_VE.xml | 2 +- make/data/cldr/common/main/et.xml | 907 +- make/data/cldr/common/main/et_EE.xml | 2 +- make/data/cldr/common/main/eu.xml | 8097 +++++++++++++++- make/data/cldr/common/main/eu_ES.xml | 2 +- make/data/cldr/common/main/ewo.xml | 2 +- make/data/cldr/common/main/ewo_CM.xml | 2 +- make/data/cldr/common/main/fa.xml | 777 +- make/data/cldr/common/main/fa_AF.xml | 2 +- make/data/cldr/common/main/fa_IR.xml | 2 +- make/data/cldr/common/main/ff.xml | 2 +- make/data/cldr/common/main/ff_Adlm.xml | 5049 +++++++++- make/data/cldr/common/main/ff_Adlm_BF.xml | 2 +- make/data/cldr/common/main/ff_Adlm_CM.xml | 2 +- make/data/cldr/common/main/ff_Adlm_GH.xml | 2 +- make/data/cldr/common/main/ff_Adlm_GM.xml | 2 +- make/data/cldr/common/main/ff_Adlm_GN.xml | 2 +- make/data/cldr/common/main/ff_Adlm_GW.xml | 2 +- make/data/cldr/common/main/ff_Adlm_LR.xml | 2 +- make/data/cldr/common/main/ff_Adlm_MR.xml | 2 +- make/data/cldr/common/main/ff_Adlm_NE.xml | 2 +- make/data/cldr/common/main/ff_Adlm_NG.xml | 2 +- make/data/cldr/common/main/ff_Adlm_SL.xml | 2 +- make/data/cldr/common/main/ff_Adlm_SN.xml | 2 +- make/data/cldr/common/main/ff_Latn.xml | 2 +- make/data/cldr/common/main/ff_Latn_BF.xml | 2 +- make/data/cldr/common/main/ff_Latn_CM.xml | 2 +- make/data/cldr/common/main/ff_Latn_GH.xml | 2 +- make/data/cldr/common/main/ff_Latn_GM.xml | 2 +- make/data/cldr/common/main/ff_Latn_GN.xml | 2 +- make/data/cldr/common/main/ff_Latn_GW.xml | 2 +- make/data/cldr/common/main/ff_Latn_LR.xml | 2 +- make/data/cldr/common/main/ff_Latn_MR.xml | 2 +- make/data/cldr/common/main/ff_Latn_NE.xml | 2 +- make/data/cldr/common/main/ff_Latn_NG.xml | 2 +- make/data/cldr/common/main/ff_Latn_SL.xml | 2 +- make/data/cldr/common/main/ff_Latn_SN.xml | 2 +- make/data/cldr/common/main/fi.xml | 401 +- make/data/cldr/common/main/fi_FI.xml | 2 +- make/data/cldr/common/main/fil.xml | 752 +- make/data/cldr/common/main/fil_PH.xml | 2 +- make/data/cldr/common/main/fo.xml | 264 +- make/data/cldr/common/main/fo_DK.xml | 2 +- make/data/cldr/common/main/fo_FO.xml | 2 +- make/data/cldr/common/main/fr.xml | 354 +- make/data/cldr/common/main/fr_BE.xml | 2 +- make/data/cldr/common/main/fr_BF.xml | 2 +- make/data/cldr/common/main/fr_BI.xml | 2 +- make/data/cldr/common/main/fr_BJ.xml | 2 +- make/data/cldr/common/main/fr_BL.xml | 2 +- make/data/cldr/common/main/fr_CA.xml | 145 +- make/data/cldr/common/main/fr_CD.xml | 2 +- make/data/cldr/common/main/fr_CF.xml | 2 +- make/data/cldr/common/main/fr_CG.xml | 2 +- make/data/cldr/common/main/fr_CH.xml | 2 +- make/data/cldr/common/main/fr_CI.xml | 2 +- make/data/cldr/common/main/fr_CM.xml | 2 +- make/data/cldr/common/main/fr_DJ.xml | 2 +- make/data/cldr/common/main/fr_DZ.xml | 2 +- make/data/cldr/common/main/fr_FR.xml | 2 +- make/data/cldr/common/main/fr_GA.xml | 2 +- make/data/cldr/common/main/fr_GF.xml | 2 +- make/data/cldr/common/main/fr_GN.xml | 2 +- make/data/cldr/common/main/fr_GP.xml | 2 +- make/data/cldr/common/main/fr_GQ.xml | 2 +- make/data/cldr/common/main/fr_HT.xml | 2 +- make/data/cldr/common/main/fr_KM.xml | 2 +- make/data/cldr/common/main/fr_LU.xml | 2 +- make/data/cldr/common/main/fr_MA.xml | 2 +- make/data/cldr/common/main/fr_MC.xml | 2 +- make/data/cldr/common/main/fr_MF.xml | 2 +- make/data/cldr/common/main/fr_MG.xml | 2 +- make/data/cldr/common/main/fr_ML.xml | 5 +- make/data/cldr/common/main/fr_MQ.xml | 2 +- make/data/cldr/common/main/fr_MR.xml | 2 +- make/data/cldr/common/main/fr_MU.xml | 2 +- make/data/cldr/common/main/fr_NC.xml | 2 +- make/data/cldr/common/main/fr_NE.xml | 2 +- make/data/cldr/common/main/fr_PF.xml | 2 +- make/data/cldr/common/main/fr_PM.xml | 2 +- make/data/cldr/common/main/fr_RE.xml | 2 +- make/data/cldr/common/main/fr_RW.xml | 2 +- make/data/cldr/common/main/fr_SC.xml | 2 +- make/data/cldr/common/main/fr_SN.xml | 2 +- make/data/cldr/common/main/fr_SY.xml | 2 +- make/data/cldr/common/main/fr_TD.xml | 2 +- make/data/cldr/common/main/fr_TG.xml | 2 +- make/data/cldr/common/main/fr_TN.xml | 2 +- make/data/cldr/common/main/fr_VU.xml | 2 +- make/data/cldr/common/main/fr_WF.xml | 2 +- make/data/cldr/common/main/fr_YT.xml | 2 +- make/data/cldr/common/main/frr.xml | 128 +- make/data/cldr/common/main/frr_DE.xml | 2 +- make/data/cldr/common/main/fur.xml | 2 +- make/data/cldr/common/main/fur_IT.xml | 2 +- make/data/cldr/common/main/fy.xml | 2 +- make/data/cldr/common/main/fy_NL.xml | 2 +- make/data/cldr/common/main/ga.xml | 610 +- make/data/cldr/common/main/ga_GB.xml | 2 +- make/data/cldr/common/main/ga_IE.xml | 2 +- make/data/cldr/common/main/gaa.xml | 2340 +++++ make/data/cldr/common/main/gaa_GH.xml | 14 + make/data/cldr/common/main/gd.xml | 355 +- make/data/cldr/common/main/gd_GB.xml | 2 +- make/data/cldr/common/main/gez.xml | 525 + make/data/cldr/common/main/gez_ER.xml | 21 + make/data/cldr/common/main/gez_ET.xml | 14 + make/data/cldr/common/main/gl.xml | 860 +- make/data/cldr/common/main/gl_ES.xml | 2 +- make/data/cldr/common/main/gn.xml | 163 + make/data/cldr/common/main/gn_PY.xml | 14 + make/data/cldr/common/main/gsw.xml | 26 +- make/data/cldr/common/main/gsw_CH.xml | 2 +- make/data/cldr/common/main/gsw_FR.xml | 2 +- make/data/cldr/common/main/gsw_LI.xml | 2 +- make/data/cldr/common/main/gu.xml | 866 +- make/data/cldr/common/main/gu_IN.xml | 2 +- make/data/cldr/common/main/guz.xml | 2 +- make/data/cldr/common/main/guz_KE.xml | 2 +- make/data/cldr/common/main/gv.xml | 2 +- make/data/cldr/common/main/gv_IM.xml | 2 +- make/data/cldr/common/main/ha.xml | 723 +- make/data/cldr/common/main/ha_Arab.xml | 116 + make/data/cldr/common/main/ha_Arab_NG.xml | 15 + make/data/cldr/common/main/ha_Arab_SD.xml | 15 + make/data/cldr/common/main/ha_GH.xml | 2 +- make/data/cldr/common/main/ha_NE.xml | 5 +- make/data/cldr/common/main/ha_NG.xml | 2 +- make/data/cldr/common/main/haw.xml | 2 +- make/data/cldr/common/main/haw_US.xml | 2 +- make/data/cldr/common/main/he.xml | 1623 +++- make/data/cldr/common/main/he_IL.xml | 2 +- make/data/cldr/common/main/hi.xml | 1592 ++- make/data/cldr/common/main/hi_IN.xml | 2 +- make/data/cldr/common/main/hi_Latn.xml | 172 +- make/data/cldr/common/main/hi_Latn_IN.xml | 2 +- make/data/cldr/common/main/hnj.xml | 184 + make/data/cldr/common/main/hnj_Hmnp.xml | 14 + make/data/cldr/common/main/hnj_Hmnp_US.xml | 15 + make/data/cldr/common/main/hr.xml | 874 +- make/data/cldr/common/main/hr_BA.xml | 2 +- make/data/cldr/common/main/hr_HR.xml | 2 +- make/data/cldr/common/main/hsb.xml | 892 +- make/data/cldr/common/main/hsb_DE.xml | 2 +- make/data/cldr/common/main/hu.xml | 1008 +- make/data/cldr/common/main/hu_HU.xml | 2 +- make/data/cldr/common/main/hy.xml | 828 +- make/data/cldr/common/main/hy_AM.xml | 2 +- make/data/cldr/common/main/ia.xml | 985 +- make/data/cldr/common/main/ia_001.xml | 2 +- make/data/cldr/common/main/id.xml | 947 +- make/data/cldr/common/main/id_ID.xml | 2 +- make/data/cldr/common/main/ig.xml | 2200 ++++- make/data/cldr/common/main/ig_NG.xml | 2 +- make/data/cldr/common/main/ii.xml | 2 +- make/data/cldr/common/main/ii_CN.xml | 2 +- make/data/cldr/common/main/io.xml | 22 + make/data/cldr/common/main/io_001.xml | 14 + make/data/cldr/common/main/is.xml | 988 +- make/data/cldr/common/main/is_IS.xml | 2 +- make/data/cldr/common/main/it.xml | 546 +- make/data/cldr/common/main/it_CH.xml | 2 +- make/data/cldr/common/main/it_IT.xml | 2 +- make/data/cldr/common/main/it_SM.xml | 2 +- make/data/cldr/common/main/it_VA.xml | 2 +- make/data/cldr/common/main/iu.xml | 213 + make/data/cldr/common/main/iu_CA.xml | 14 + make/data/cldr/common/main/iu_Latn.xml | 25 + make/data/cldr/common/main/iu_Latn_CA.xml | 15 + make/data/cldr/common/main/ja.xml | 331 +- make/data/cldr/common/main/ja_JP.xml | 2 +- make/data/cldr/common/main/jbo.xml | 40 + make/data/cldr/common/main/jbo_001.xml | 14 + make/data/cldr/common/main/jgo.xml | 2 +- make/data/cldr/common/main/jgo_CM.xml | 2 +- make/data/cldr/common/main/jmc.xml | 2 +- make/data/cldr/common/main/jmc_TZ.xml | 2 +- make/data/cldr/common/main/jv.xml | 1013 +- make/data/cldr/common/main/jv_ID.xml | 2 +- make/data/cldr/common/main/ka.xml | 308 +- make/data/cldr/common/main/ka_GE.xml | 2 +- make/data/cldr/common/main/kab.xml | 134 +- make/data/cldr/common/main/kab_DZ.xml | 2 +- make/data/cldr/common/main/kaj.xml | 192 + make/data/cldr/common/main/kaj_NG.xml | 14 + make/data/cldr/common/main/kam.xml | 2 +- make/data/cldr/common/main/kam_KE.xml | 2 +- make/data/cldr/common/main/kcg.xml | 180 + make/data/cldr/common/main/kcg_NG.xml | 14 + make/data/cldr/common/main/kde.xml | 2 +- make/data/cldr/common/main/kde_TZ.xml | 2 +- make/data/cldr/common/main/kea.xml | 190 +- make/data/cldr/common/main/kea_CV.xml | 2 +- make/data/cldr/common/main/ken.xml | 24 + make/data/cldr/common/main/ken_CM.xml | 14 + make/data/cldr/common/main/kgp.xml | 282 +- make/data/cldr/common/main/kgp_BR.xml | 2 +- make/data/cldr/common/main/khq.xml | 2 +- make/data/cldr/common/main/khq_ML.xml | 2 +- make/data/cldr/common/main/ki.xml | 2 +- make/data/cldr/common/main/ki_KE.xml | 2 +- make/data/cldr/common/main/kk.xml | 1043 +- make/data/cldr/common/main/kk_KZ.xml | 2 +- make/data/cldr/common/main/kkj.xml | 2 +- make/data/cldr/common/main/kkj_CM.xml | 2 +- make/data/cldr/common/main/kl.xml | 2 +- make/data/cldr/common/main/kl_GL.xml | 2 +- make/data/cldr/common/main/kln.xml | 2 +- make/data/cldr/common/main/kln_KE.xml | 2 +- make/data/cldr/common/main/km.xml | 920 +- make/data/cldr/common/main/km_KH.xml | 2 +- make/data/cldr/common/main/kn.xml | 1143 ++- make/data/cldr/common/main/kn_IN.xml | 2 +- make/data/cldr/common/main/ko.xml | 911 +- make/data/cldr/common/main/ko_KP.xml | 2 +- make/data/cldr/common/main/ko_KR.xml | 2 +- make/data/cldr/common/main/kok.xml | 238 +- make/data/cldr/common/main/kok_IN.xml | 2 +- make/data/cldr/common/main/kpe.xml | 61 + make/data/cldr/common/main/kpe_GN.xml | 56 + make/data/cldr/common/main/kpe_LR.xml | 14 + make/data/cldr/common/main/ks.xml | 193 +- make/data/cldr/common/main/ks_Arab.xml | 2 +- make/data/cldr/common/main/ks_Arab_IN.xml | 2 +- make/data/cldr/common/main/ks_Deva.xml | 95 +- make/data/cldr/common/main/ks_Deva_IN.xml | 2 +- make/data/cldr/common/main/ksb.xml | 2 +- make/data/cldr/common/main/ksb_TZ.xml | 2 +- make/data/cldr/common/main/ksf.xml | 2 +- make/data/cldr/common/main/ksf_CM.xml | 2 +- make/data/cldr/common/main/ksh.xml | 6 +- make/data/cldr/common/main/ksh_DE.xml | 2 +- make/data/cldr/common/main/ku.xml | 99 +- make/data/cldr/common/main/ku_TR.xml | 2 +- make/data/cldr/common/main/kw.xml | 2 +- make/data/cldr/common/main/kw_GB.xml | 2 +- make/data/cldr/common/main/ky.xml | 1033 +- make/data/cldr/common/main/ky_KG.xml | 2 +- make/data/cldr/common/main/la.xml | 1253 +++ make/data/cldr/common/main/la_VA.xml | 14 + make/data/cldr/common/main/lag.xml | 2 +- make/data/cldr/common/main/lag_TZ.xml | 2 +- make/data/cldr/common/main/lb.xml | 26 +- make/data/cldr/common/main/lb_LU.xml | 2 +- make/data/cldr/common/main/lg.xml | 2 +- make/data/cldr/common/main/lg_UG.xml | 2 +- make/data/cldr/common/main/lij.xml | 7621 +++++++++++++++ make/data/cldr/common/main/lij_IT.xml | 18 + make/data/cldr/common/main/lkt.xml | 2 +- make/data/cldr/common/main/lkt_US.xml | 2 +- make/data/cldr/common/main/lmo.xml | 123 + make/data/cldr/common/main/lmo_IT.xml | 14 + make/data/cldr/common/main/ln.xml | 2 +- make/data/cldr/common/main/ln_AO.xml | 2 +- make/data/cldr/common/main/ln_CD.xml | 2 +- make/data/cldr/common/main/ln_CF.xml | 2 +- make/data/cldr/common/main/ln_CG.xml | 2 +- make/data/cldr/common/main/lo.xml | 885 +- make/data/cldr/common/main/lo_LA.xml | 2 +- make/data/cldr/common/main/lrc.xml | 2 +- make/data/cldr/common/main/lrc_IQ.xml | 2 +- make/data/cldr/common/main/lrc_IR.xml | 2 +- make/data/cldr/common/main/lt.xml | 1260 ++- make/data/cldr/common/main/lt_LT.xml | 2 +- make/data/cldr/common/main/lu.xml | 2 +- make/data/cldr/common/main/lu_CD.xml | 2 +- make/data/cldr/common/main/luo.xml | 2 +- make/data/cldr/common/main/luo_KE.xml | 2 +- make/data/cldr/common/main/luy.xml | 2 +- make/data/cldr/common/main/luy_KE.xml | 2 +- make/data/cldr/common/main/lv.xml | 1149 ++- make/data/cldr/common/main/lv_LV.xml | 2 +- make/data/cldr/common/main/mai.xml | 371 +- make/data/cldr/common/main/mai_IN.xml | 2 +- make/data/cldr/common/main/mas.xml | 2 +- make/data/cldr/common/main/mas_KE.xml | 2 +- make/data/cldr/common/main/mas_TZ.xml | 2 +- make/data/cldr/common/main/mdf.xml | 2 +- make/data/cldr/common/main/mdf_RU.xml | 2 +- make/data/cldr/common/main/mer.xml | 2 +- make/data/cldr/common/main/mer_KE.xml | 2 +- make/data/cldr/common/main/mfe.xml | 2 +- make/data/cldr/common/main/mfe_MU.xml | 2 +- make/data/cldr/common/main/mg.xml | 2 +- make/data/cldr/common/main/mg_MG.xml | 2 +- make/data/cldr/common/main/mgh.xml | 2 +- make/data/cldr/common/main/mgh_MZ.xml | 2 +- make/data/cldr/common/main/mgo.xml | 2 +- make/data/cldr/common/main/mgo_CM.xml | 2 +- make/data/cldr/common/main/mi.xml | 85 +- make/data/cldr/common/main/mi_NZ.xml | 2 +- make/data/cldr/common/main/mk.xml | 858 +- make/data/cldr/common/main/mk_MK.xml | 2 +- make/data/cldr/common/main/ml.xml | 1119 ++- make/data/cldr/common/main/ml_IN.xml | 2 +- make/data/cldr/common/main/mn.xml | 3101 +++++- make/data/cldr/common/main/mn_MN.xml | 2 +- make/data/cldr/common/main/mn_Mong.xml | 90 + make/data/cldr/common/main/mn_Mong_CN.xml | 15 + make/data/cldr/common/main/mn_Mong_MN.xml | 614 ++ make/data/cldr/common/main/mni.xml | 47 +- make/data/cldr/common/main/mni_Beng.xml | 2 +- make/data/cldr/common/main/mni_Beng_IN.xml | 2 +- make/data/cldr/common/main/mni_Mtei.xml | 94 + make/data/cldr/common/main/mni_Mtei_IN.xml | 15 + make/data/cldr/common/main/moh.xml | 61 + make/data/cldr/common/main/moh_CA.xml | 14 + make/data/cldr/common/main/mr.xml | 802 +- make/data/cldr/common/main/mr_IN.xml | 2 +- make/data/cldr/common/main/ms.xml | 1150 ++- make/data/cldr/common/main/ms_Arab.xml | 1007 ++ make/data/cldr/common/main/ms_Arab_BN.xml | 57 + make/data/cldr/common/main/ms_Arab_MY.xml | 15 + make/data/cldr/common/main/ms_BN.xml | 25 +- make/data/cldr/common/main/ms_ID.xml | 48 +- make/data/cldr/common/main/ms_MY.xml | 2 +- make/data/cldr/common/main/ms_SG.xml | 2 +- make/data/cldr/common/main/mt.xml | 28 +- make/data/cldr/common/main/mt_MT.xml | 2 +- make/data/cldr/common/main/mua.xml | 2 +- make/data/cldr/common/main/mua_CM.xml | 2 +- make/data/cldr/common/main/mus.xml | 242 + make/data/cldr/common/main/mus_US.xml | 14 + make/data/cldr/common/main/my.xml | 837 +- make/data/cldr/common/main/my_MM.xml | 2 +- make/data/cldr/common/main/myv.xml | 768 ++ make/data/cldr/common/main/myv_RU.xml | 14 + make/data/cldr/common/main/mzn.xml | 2 +- make/data/cldr/common/main/mzn_IR.xml | 2 +- make/data/cldr/common/main/naq.xml | 2 +- make/data/cldr/common/main/naq_NA.xml | 2 +- make/data/cldr/common/main/nb.xml | 2 +- make/data/cldr/common/main/nb_NO.xml | 2 +- make/data/cldr/common/main/nb_SJ.xml | 2 +- make/data/cldr/common/main/nd.xml | 2 +- make/data/cldr/common/main/nd_ZW.xml | 2 +- make/data/cldr/common/main/nds.xml | 26 +- make/data/cldr/common/main/nds_DE.xml | 2 +- make/data/cldr/common/main/nds_NL.xml | 2 +- make/data/cldr/common/main/ne.xml | 349 +- make/data/cldr/common/main/ne_IN.xml | 2 +- make/data/cldr/common/main/ne_NP.xml | 2 +- make/data/cldr/common/main/nl.xml | 1287 ++- make/data/cldr/common/main/nl_AW.xml | 2 +- make/data/cldr/common/main/nl_BE.xml | 27 +- make/data/cldr/common/main/nl_BQ.xml | 2 +- make/data/cldr/common/main/nl_CW.xml | 2 +- make/data/cldr/common/main/nl_NL.xml | 2 +- make/data/cldr/common/main/nl_SR.xml | 2 +- make/data/cldr/common/main/nl_SX.xml | 2 +- make/data/cldr/common/main/nmg.xml | 2 +- make/data/cldr/common/main/nmg_CM.xml | 2 +- make/data/cldr/common/main/nn.xml | 91 +- make/data/cldr/common/main/nn_NO.xml | 2 +- make/data/cldr/common/main/nnh.xml | 2 +- make/data/cldr/common/main/nnh_CM.xml | 2 +- make/data/cldr/common/main/no.xml | 560 +- make/data/cldr/common/main/nqo.xml | 1833 ++++ make/data/cldr/common/main/nqo_GN.xml | 14 + make/data/cldr/common/main/nr.xml | 134 + make/data/cldr/common/main/nr_ZA.xml | 14 + make/data/cldr/common/main/nso.xml | 561 ++ make/data/cldr/common/main/nso_ZA.xml | 14 + make/data/cldr/common/main/nus.xml | 2 +- make/data/cldr/common/main/nus_SS.xml | 2 +- make/data/cldr/common/main/nv.xml | 29 + make/data/cldr/common/main/nv_US.xml | 14 + make/data/cldr/common/main/ny.xml | 116 + make/data/cldr/common/main/ny_MW.xml | 14 + make/data/cldr/common/main/nyn.xml | 2 +- make/data/cldr/common/main/nyn_UG.xml | 2 +- make/data/cldr/common/main/oc.xml | 3549 ++++++- make/data/cldr/common/main/oc_ES.xml | 799 +- make/data/cldr/common/main/oc_FR.xml | 2 +- make/data/cldr/common/main/om.xml | 2 +- make/data/cldr/common/main/om_ET.xml | 2 +- make/data/cldr/common/main/om_KE.xml | 2 +- make/data/cldr/common/main/or.xml | 596 +- make/data/cldr/common/main/or_IN.xml | 2 +- make/data/cldr/common/main/os.xml | 2 +- make/data/cldr/common/main/os_GE.xml | 2 +- make/data/cldr/common/main/os_RU.xml | 2 +- make/data/cldr/common/main/osa.xml | 282 + make/data/cldr/common/main/osa_US.xml | 14 + make/data/cldr/common/main/pa.xml | 635 +- make/data/cldr/common/main/pa_Arab.xml | 2 +- make/data/cldr/common/main/pa_Arab_PK.xml | 2 +- make/data/cldr/common/main/pa_Guru.xml | 2 +- make/data/cldr/common/main/pa_Guru_IN.xml | 2 +- make/data/cldr/common/main/pap.xml | 133 + make/data/cldr/common/main/pap_AW.xml | 14 + make/data/cldr/common/main/pap_CW.xml | 14 + make/data/cldr/common/main/pcm.xml | 824 +- make/data/cldr/common/main/pcm_NG.xml | 2 +- make/data/cldr/common/main/pis.xml | 2 +- make/data/cldr/common/main/pis_SB.xml | 2 +- make/data/cldr/common/main/pl.xml | 2209 ++++- make/data/cldr/common/main/pl_PL.xml | 2 +- make/data/cldr/common/main/prg.xml | 969 ++ make/data/cldr/common/main/prg_001.xml | 14 + make/data/cldr/common/main/ps.xml | 719 +- make/data/cldr/common/main/ps_AF.xml | 2 +- make/data/cldr/common/main/ps_PK.xml | 7 +- make/data/cldr/common/main/pt.xml | 1171 ++- make/data/cldr/common/main/pt_AO.xml | 2 +- make/data/cldr/common/main/pt_BR.xml | 2 +- make/data/cldr/common/main/pt_CH.xml | 2 +- make/data/cldr/common/main/pt_CV.xml | 2 +- make/data/cldr/common/main/pt_GQ.xml | 2 +- make/data/cldr/common/main/pt_GW.xml | 2 +- make/data/cldr/common/main/pt_LU.xml | 2 +- make/data/cldr/common/main/pt_MO.xml | 2 +- make/data/cldr/common/main/pt_MZ.xml | 2 +- make/data/cldr/common/main/pt_PT.xml | 221 +- make/data/cldr/common/main/pt_ST.xml | 2 +- make/data/cldr/common/main/pt_TL.xml | 2 +- make/data/cldr/common/main/qu.xml | 642 +- make/data/cldr/common/main/qu_BO.xml | 2 +- make/data/cldr/common/main/qu_EC.xml | 2 +- make/data/cldr/common/main/qu_PE.xml | 2 +- make/data/cldr/common/main/quc.xml | 39 + make/data/cldr/common/main/quc_GT.xml | 14 + make/data/cldr/common/main/raj.xml | 2 +- make/data/cldr/common/main/raj_IN.xml | 2 +- make/data/cldr/common/main/rhg.xml | 621 ++ make/data/cldr/common/main/rhg_Rohg.xml | 14 + make/data/cldr/common/main/rhg_Rohg_BD.xml | 47 + make/data/cldr/common/main/rhg_Rohg_MM.xml | 15 + make/data/cldr/common/main/rif.xml | 146 + make/data/cldr/common/main/rif_MA.xml | 14 + make/data/cldr/common/main/rm.xml | 79 +- make/data/cldr/common/main/rm_CH.xml | 2 +- make/data/cldr/common/main/rn.xml | 2 +- make/data/cldr/common/main/rn_BI.xml | 2 +- make/data/cldr/common/main/ro.xml | 991 +- make/data/cldr/common/main/ro_MD.xml | 2 +- make/data/cldr/common/main/ro_RO.xml | 2 +- make/data/cldr/common/main/rof.xml | 2 +- make/data/cldr/common/main/rof_TZ.xml | 2 +- make/data/cldr/common/main/root.xml | 467 +- make/data/cldr/common/main/ru.xml | 1196 ++- make/data/cldr/common/main/ru_BY.xml | 3 +- make/data/cldr/common/main/ru_KG.xml | 2 +- make/data/cldr/common/main/ru_KZ.xml | 2 +- make/data/cldr/common/main/ru_MD.xml | 2 +- make/data/cldr/common/main/ru_RU.xml | 2 +- make/data/cldr/common/main/ru_UA.xml | 2 +- make/data/cldr/common/main/rw.xml | 2 +- make/data/cldr/common/main/rw_RW.xml | 2 +- make/data/cldr/common/main/rwk.xml | 2 +- make/data/cldr/common/main/rwk_TZ.xml | 2 +- make/data/cldr/common/main/sa.xml | 3 +- make/data/cldr/common/main/sa_IN.xml | 2 +- make/data/cldr/common/main/sah.xml | 2 +- make/data/cldr/common/main/sah_RU.xml | 2 +- make/data/cldr/common/main/saq.xml | 2 +- make/data/cldr/common/main/saq_KE.xml | 2 +- make/data/cldr/common/main/sat.xml | 181 +- make/data/cldr/common/main/sat_Deva.xml | 94 + make/data/cldr/common/main/sat_Deva_IN.xml | 15 + make/data/cldr/common/main/sat_Olck.xml | 2 +- make/data/cldr/common/main/sat_Olck_IN.xml | 2 +- make/data/cldr/common/main/sbp.xml | 2 +- make/data/cldr/common/main/sbp_TZ.xml | 2 +- make/data/cldr/common/main/sc.xml | 7552 ++++++++++++++- make/data/cldr/common/main/sc_IT.xml | 2 +- make/data/cldr/common/main/scn.xml | 728 ++ make/data/cldr/common/main/scn_IT.xml | 14 + make/data/cldr/common/main/sd.xml | 1213 ++- make/data/cldr/common/main/sd_Arab.xml | 2 +- make/data/cldr/common/main/sd_Arab_PK.xml | 2 +- make/data/cldr/common/main/sd_Deva.xml | 39 +- make/data/cldr/common/main/sd_Deva_IN.xml | 2 +- make/data/cldr/common/main/sdh.xml | 50 + make/data/cldr/common/main/sdh_IQ.xml | 14 + make/data/cldr/common/main/sdh_IR.xml | 14 + make/data/cldr/common/main/se.xml | 2 +- make/data/cldr/common/main/se_FI.xml | 2 +- make/data/cldr/common/main/se_NO.xml | 2 +- make/data/cldr/common/main/se_SE.xml | 2 +- make/data/cldr/common/main/seh.xml | 2 +- make/data/cldr/common/main/seh_MZ.xml | 2 +- make/data/cldr/common/main/ses.xml | 2 +- make/data/cldr/common/main/ses_ML.xml | 2 +- make/data/cldr/common/main/sg.xml | 2 +- make/data/cldr/common/main/sg_CF.xml | 2 +- make/data/cldr/common/main/shi.xml | 2 +- make/data/cldr/common/main/shi_Latn.xml | 2 +- make/data/cldr/common/main/shi_Latn_MA.xml | 2 +- make/data/cldr/common/main/shi_Tfng.xml | 2 +- make/data/cldr/common/main/shi_Tfng_MA.xml | 2 +- make/data/cldr/common/main/shn.xml | 32 + make/data/cldr/common/main/shn_MM.xml | 14 + make/data/cldr/common/main/shn_TH.xml | 14 + make/data/cldr/common/main/si.xml | 1014 +- make/data/cldr/common/main/si_LK.xml | 2 +- make/data/cldr/common/main/sid.xml | 205 + make/data/cldr/common/main/sid_ET.xml | 14 + make/data/cldr/common/main/sk.xml | 999 +- make/data/cldr/common/main/sk_SK.xml | 2 +- make/data/cldr/common/main/sl.xml | 1190 ++- make/data/cldr/common/main/sl_SI.xml | 2 +- make/data/cldr/common/main/sma.xml | 29 + make/data/cldr/common/main/sma_NO.xml | 18 + make/data/cldr/common/main/sma_SE.xml | 14 + make/data/cldr/common/main/smj.xml | 29 + make/data/cldr/common/main/smj_NO.xml | 14 + make/data/cldr/common/main/smj_SE.xml | 14 + make/data/cldr/common/main/smn.xml | 36 +- make/data/cldr/common/main/smn_FI.xml | 2 +- make/data/cldr/common/main/sms.xml | 4 +- make/data/cldr/common/main/sms_FI.xml | 2 +- make/data/cldr/common/main/sn.xml | 2 +- make/data/cldr/common/main/sn_ZW.xml | 2 +- make/data/cldr/common/main/so.xml | 6971 ++++++++++++- make/data/cldr/common/main/so_DJ.xml | 2 +- make/data/cldr/common/main/so_ET.xml | 2 +- make/data/cldr/common/main/so_KE.xml | 2 +- make/data/cldr/common/main/so_SO.xml | 2 +- make/data/cldr/common/main/sq.xml | 474 +- make/data/cldr/common/main/sq_AL.xml | 2 +- make/data/cldr/common/main/sq_MK.xml | 2 +- make/data/cldr/common/main/sq_XK.xml | 2 +- make/data/cldr/common/main/sr.xml | 1294 ++- make/data/cldr/common/main/sr_Cyrl.xml | 2 +- make/data/cldr/common/main/sr_Cyrl_BA.xml | 32 +- make/data/cldr/common/main/sr_Cyrl_ME.xml | 2 +- make/data/cldr/common/main/sr_Cyrl_RS.xml | 2 +- make/data/cldr/common/main/sr_Cyrl_XK.xml | 2 +- make/data/cldr/common/main/sr_Latn.xml | 1559 ++- make/data/cldr/common/main/sr_Latn_BA.xml | 32 +- make/data/cldr/common/main/sr_Latn_ME.xml | 2 +- make/data/cldr/common/main/sr_Latn_RS.xml | 2 +- make/data/cldr/common/main/sr_Latn_XK.xml | 2 +- make/data/cldr/common/main/ss.xml | 133 + make/data/cldr/common/main/ss_SZ.xml | 46 + make/data/cldr/common/main/ss_ZA.xml | 14 + make/data/cldr/common/main/ssy.xml | 235 + make/data/cldr/common/main/ssy_ER.xml | 14 + make/data/cldr/common/main/st.xml | 650 ++ make/data/cldr/common/main/st_LS.xml | 53 + make/data/cldr/common/main/st_ZA.xml | 14 + make/data/cldr/common/main/su.xml | 36 +- make/data/cldr/common/main/su_Latn.xml | 2 +- make/data/cldr/common/main/su_Latn_ID.xml | 2 +- make/data/cldr/common/main/sv.xml | 633 +- make/data/cldr/common/main/sv_AX.xml | 2 +- make/data/cldr/common/main/sv_FI.xml | 6 +- make/data/cldr/common/main/sv_SE.xml | 2 +- make/data/cldr/common/main/sw.xml | 806 +- make/data/cldr/common/main/sw_CD.xml | 2 +- make/data/cldr/common/main/sw_KE.xml | 41 +- make/data/cldr/common/main/sw_TZ.xml | 2 +- make/data/cldr/common/main/sw_UG.xml | 2 +- make/data/cldr/common/main/syr.xml | 7222 ++++++++++++++ make/data/cldr/common/main/syr_IQ.xml | 14 + make/data/cldr/common/main/syr_SY.xml | 14 + make/data/cldr/common/main/szl.xml | 5412 +++++++++++ make/data/cldr/common/main/szl_PL.xml | 14 + make/data/cldr/common/main/ta.xml | 398 +- make/data/cldr/common/main/ta_IN.xml | 2 +- make/data/cldr/common/main/ta_LK.xml | 2 +- make/data/cldr/common/main/ta_MY.xml | 2 +- make/data/cldr/common/main/ta_SG.xml | 2 +- make/data/cldr/common/main/te.xml | 749 +- make/data/cldr/common/main/te_IN.xml | 2 +- make/data/cldr/common/main/teo.xml | 2 +- make/data/cldr/common/main/teo_KE.xml | 2 +- make/data/cldr/common/main/teo_UG.xml | 2 +- make/data/cldr/common/main/tg.xml | 65 +- make/data/cldr/common/main/tg_TJ.xml | 2 +- make/data/cldr/common/main/th.xml | 350 +- make/data/cldr/common/main/th_TH.xml | 2 +- make/data/cldr/common/main/ti.xml | 1295 ++- make/data/cldr/common/main/ti_ER.xml | 49 +- make/data/cldr/common/main/ti_ET.xml | 2 +- make/data/cldr/common/main/tig.xml | 526 + make/data/cldr/common/main/tig_ER.xml | 14 + make/data/cldr/common/main/tk.xml | 1095 ++- make/data/cldr/common/main/tk_TM.xml | 2 +- make/data/cldr/common/main/tn.xml | 647 ++ make/data/cldr/common/main/tn_BW.xml | 21 + make/data/cldr/common/main/tn_ZA.xml | 14 + make/data/cldr/common/main/to.xml | 577 +- make/data/cldr/common/main/to_TO.xml | 2 +- make/data/cldr/common/main/tok.xml | 2 +- make/data/cldr/common/main/tok_001.xml | 2 +- make/data/cldr/common/main/tpi.xml | 246 + make/data/cldr/common/main/tpi_PG.xml | 14 + make/data/cldr/common/main/tr.xml | 700 +- make/data/cldr/common/main/tr_CY.xml | 2 +- make/data/cldr/common/main/tr_TR.xml | 2 +- make/data/cldr/common/main/trv.xml | 635 ++ make/data/cldr/common/main/trv_TW.xml | 14 + make/data/cldr/common/main/trw.xml | 6145 ++++++++++++ make/data/cldr/common/main/trw_PK.xml | 14 + make/data/cldr/common/main/ts.xml | 579 ++ make/data/cldr/common/main/ts_ZA.xml | 14 + make/data/cldr/common/main/tt.xml | 107 +- make/data/cldr/common/main/tt_RU.xml | 2 +- make/data/cldr/common/main/twq.xml | 2 +- make/data/cldr/common/main/twq_NE.xml | 2 +- make/data/cldr/common/main/tzm.xml | 2 +- make/data/cldr/common/main/tzm_MA.xml | 2 +- make/data/cldr/common/main/ug.xml | 2 +- make/data/cldr/common/main/ug_CN.xml | 2 +- make/data/cldr/common/main/uk.xml | 618 +- make/data/cldr/common/main/uk_UA.xml | 2 +- make/data/cldr/common/main/ur.xml | 798 +- make/data/cldr/common/main/ur_IN.xml | 4 +- make/data/cldr/common/main/ur_PK.xml | 2 +- make/data/cldr/common/main/uz.xml | 938 +- make/data/cldr/common/main/uz_Arab.xml | 2 +- make/data/cldr/common/main/uz_Arab_AF.xml | 2 +- make/data/cldr/common/main/uz_Cyrl.xml | 2 +- make/data/cldr/common/main/uz_Cyrl_UZ.xml | 2 +- make/data/cldr/common/main/uz_Latn.xml | 2 +- make/data/cldr/common/main/uz_Latn_UZ.xml | 2 +- make/data/cldr/common/main/vai.xml | 2 +- make/data/cldr/common/main/vai_Latn.xml | 2 +- make/data/cldr/common/main/vai_Latn_LR.xml | 2 +- make/data/cldr/common/main/vai_Vaii.xml | 2 +- make/data/cldr/common/main/vai_Vaii_LR.xml | 2 +- make/data/cldr/common/main/ve.xml | 144 + make/data/cldr/common/main/ve_ZA.xml | 14 + make/data/cldr/common/main/vec.xml | 44 + make/data/cldr/common/main/vec_IT.xml | 14 + make/data/cldr/common/main/vi.xml | 1808 +++- make/data/cldr/common/main/vi_VN.xml | 2 +- make/data/cldr/common/main/vo.xml | 400 + make/data/cldr/common/main/vo_001.xml | 14 + make/data/cldr/common/main/vun.xml | 2 +- make/data/cldr/common/main/vun_TZ.xml | 2 +- make/data/cldr/common/main/wa.xml | 24 + make/data/cldr/common/main/wa_BE.xml | 14 + make/data/cldr/common/main/wae.xml | 22 +- make/data/cldr/common/main/wae_CH.xml | 2 +- make/data/cldr/common/main/wal.xml | 389 + make/data/cldr/common/main/wal_ET.xml | 14 + make/data/cldr/common/main/wbp.xml | 30 + make/data/cldr/common/main/wbp_AU.xml | 14 + make/data/cldr/common/main/wo.xml | 38 +- make/data/cldr/common/main/wo_SN.xml | 2 +- make/data/cldr/common/main/xh.xml | 156 +- make/data/cldr/common/main/xh_ZA.xml | 2 +- make/data/cldr/common/main/xog.xml | 2 +- make/data/cldr/common/main/xog_UG.xml | 2 +- make/data/cldr/common/main/yav.xml | 2 +- make/data/cldr/common/main/yav_CM.xml | 2 +- make/data/cldr/common/main/yi.xml | 4 +- make/data/cldr/common/main/yi_001.xml | 2 +- make/data/cldr/common/main/yo.xml | 1907 +++- make/data/cldr/common/main/yo_BJ.xml | 206 +- make/data/cldr/common/main/yo_NG.xml | 2 +- make/data/cldr/common/main/yrl.xml | 313 +- make/data/cldr/common/main/yrl_BR.xml | 2 +- make/data/cldr/common/main/yrl_CO.xml | 2 +- make/data/cldr/common/main/yrl_VE.xml | 2 +- make/data/cldr/common/main/yue.xml | 829 +- make/data/cldr/common/main/yue_Hans.xml | 796 +- make/data/cldr/common/main/yue_Hans_CN.xml | 2 +- make/data/cldr/common/main/yue_Hant.xml | 2 +- make/data/cldr/common/main/yue_Hant_HK.xml | 2 +- make/data/cldr/common/main/zgh.xml | 2 +- make/data/cldr/common/main/zgh_MA.xml | 2 +- make/data/cldr/common/main/zh.xml | 831 +- make/data/cldr/common/main/zh_Hans.xml | 2 +- make/data/cldr/common/main/zh_Hans_CN.xml | 2 +- make/data/cldr/common/main/zh_Hans_HK.xml | 18 +- make/data/cldr/common/main/zh_Hans_MO.xml | 21 +- make/data/cldr/common/main/zh_Hans_SG.xml | 19 +- make/data/cldr/common/main/zh_Hant.xml | 324 +- make/data/cldr/common/main/zh_Hant_HK.xml | 102 +- make/data/cldr/common/main/zh_Hant_MO.xml | 10 +- make/data/cldr/common/main/zh_Hant_TW.xml | 2 +- make/data/cldr/common/main/zu.xml | 2048 +++- make/data/cldr/common/main/zu_ZA.xml | 2 +- .../cldr/common/properties/coverageLevels.txt | 284 +- .../supplemental/attributeValueValidity.xml | 10 +- .../common/supplemental/languageGroup.xml | 58 +- .../common/supplemental/likelySubtags.xml | 6254 +++++++++++- .../common/supplemental/supplementalData.xml | 98 +- .../supplemental/supplementalMetadata.xml | 30 +- make/data/cldr/common/supplemental/units.xml | 13 + .../cldr/common/supplemental/windowsZones.xml | 10 +- .../OtherCommonLocales.properties | 3 - .../SupplementDataParseHandler.java | 19 +- src/java.base/share/legal/cldr.md | 2 +- .../plugins/IncludeLocalesPlugin.java | 3 +- src/jdk.localedata/share/legal/cldr.md | 2 +- .../time/format/TestUnicodeExtension.java | 5 +- test/jdk/sun/text/resources/LocaleData.cldr | 4 +- .../plugins/IncludeLocalesPluginTest.java | 7 +- 1037 files changed, 201710 insertions(+), 5063 deletions(-) create mode 100644 make/data/cldr/common/main/aa.xml create mode 100644 make/data/cldr/common/main/aa_DJ.xml create mode 100644 make/data/cldr/common/main/aa_ER.xml create mode 100644 make/data/cldr/common/main/aa_ET.xml create mode 100644 make/data/cldr/common/main/ab.xml create mode 100644 make/data/cldr/common/main/ab_GE.xml create mode 100644 make/data/cldr/common/main/an.xml create mode 100644 make/data/cldr/common/main/an_ES.xml create mode 100644 make/data/cldr/common/main/apc.xml create mode 100644 make/data/cldr/common/main/apc_SY.xml create mode 100644 make/data/cldr/common/main/arn.xml create mode 100644 make/data/cldr/common/main/arn_CL.xml create mode 100644 make/data/cldr/common/main/az_Arab.xml create mode 100644 make/data/cldr/common/main/az_Arab_IQ.xml create mode 100644 make/data/cldr/common/main/az_Arab_IR.xml create mode 100644 make/data/cldr/common/main/az_Arab_TR.xml create mode 100644 make/data/cldr/common/main/ba.xml create mode 100644 make/data/cldr/common/main/ba_RU.xml create mode 100644 make/data/cldr/common/main/bal.xml create mode 100644 make/data/cldr/common/main/bal_Arab.xml create mode 100644 make/data/cldr/common/main/bal_Arab_PK.xml create mode 100644 make/data/cldr/common/main/bal_Latn.xml create mode 100644 make/data/cldr/common/main/bal_Latn_PK.xml create mode 100644 make/data/cldr/common/main/bgn.xml create mode 100644 make/data/cldr/common/main/bgn_AE.xml create mode 100644 make/data/cldr/common/main/bgn_AF.xml create mode 100644 make/data/cldr/common/main/bgn_IR.xml create mode 100644 make/data/cldr/common/main/bgn_OM.xml create mode 100644 make/data/cldr/common/main/bgn_PK.xml create mode 100644 make/data/cldr/common/main/blt.xml create mode 100644 make/data/cldr/common/main/blt_VN.xml create mode 100644 make/data/cldr/common/main/bm_Nkoo.xml create mode 100644 make/data/cldr/common/main/bm_Nkoo_ML.xml create mode 100644 make/data/cldr/common/main/bss.xml create mode 100644 make/data/cldr/common/main/bss_CM.xml create mode 100644 make/data/cldr/common/main/byn.xml create mode 100644 make/data/cldr/common/main/byn_ER.xml create mode 100644 make/data/cldr/common/main/cad.xml create mode 100644 make/data/cldr/common/main/cad_US.xml create mode 100644 make/data/cldr/common/main/cch.xml create mode 100644 make/data/cldr/common/main/cch_NG.xml create mode 100644 make/data/cldr/common/main/cho.xml create mode 100644 make/data/cldr/common/main/cho_US.xml create mode 100644 make/data/cldr/common/main/cic.xml create mode 100644 make/data/cldr/common/main/cic_US.xml create mode 100644 make/data/cldr/common/main/co.xml create mode 100644 make/data/cldr/common/main/co_FR.xml create mode 100644 make/data/cldr/common/main/cu.xml create mode 100644 make/data/cldr/common/main/cu_RU.xml create mode 100644 make/data/cldr/common/main/dv.xml create mode 100644 make/data/cldr/common/main/dv_MV.xml create mode 100644 make/data/cldr/common/main/el_POLYTON.xml create mode 100644 make/data/cldr/common/main/en_Dsrt.xml create mode 100644 make/data/cldr/common/main/en_Dsrt_US.xml create mode 100644 make/data/cldr/common/main/en_Shaw.xml create mode 100644 make/data/cldr/common/main/en_Shaw_GB.xml create mode 100644 make/data/cldr/common/main/gaa.xml create mode 100644 make/data/cldr/common/main/gaa_GH.xml create mode 100644 make/data/cldr/common/main/gez.xml create mode 100644 make/data/cldr/common/main/gez_ER.xml create mode 100644 make/data/cldr/common/main/gez_ET.xml create mode 100644 make/data/cldr/common/main/gn.xml create mode 100644 make/data/cldr/common/main/gn_PY.xml create mode 100644 make/data/cldr/common/main/ha_Arab.xml create mode 100644 make/data/cldr/common/main/ha_Arab_NG.xml create mode 100644 make/data/cldr/common/main/ha_Arab_SD.xml create mode 100644 make/data/cldr/common/main/hnj.xml create mode 100644 make/data/cldr/common/main/hnj_Hmnp.xml create mode 100644 make/data/cldr/common/main/hnj_Hmnp_US.xml create mode 100644 make/data/cldr/common/main/io.xml create mode 100644 make/data/cldr/common/main/io_001.xml create mode 100644 make/data/cldr/common/main/iu.xml create mode 100644 make/data/cldr/common/main/iu_CA.xml create mode 100644 make/data/cldr/common/main/iu_Latn.xml create mode 100644 make/data/cldr/common/main/iu_Latn_CA.xml create mode 100644 make/data/cldr/common/main/jbo.xml create mode 100644 make/data/cldr/common/main/jbo_001.xml create mode 100644 make/data/cldr/common/main/kaj.xml create mode 100644 make/data/cldr/common/main/kaj_NG.xml create mode 100644 make/data/cldr/common/main/kcg.xml create mode 100644 make/data/cldr/common/main/kcg_NG.xml create mode 100644 make/data/cldr/common/main/ken.xml create mode 100644 make/data/cldr/common/main/ken_CM.xml create mode 100644 make/data/cldr/common/main/kpe.xml create mode 100644 make/data/cldr/common/main/kpe_GN.xml create mode 100644 make/data/cldr/common/main/kpe_LR.xml create mode 100644 make/data/cldr/common/main/la.xml create mode 100644 make/data/cldr/common/main/la_VA.xml create mode 100644 make/data/cldr/common/main/lij.xml create mode 100644 make/data/cldr/common/main/lij_IT.xml create mode 100644 make/data/cldr/common/main/lmo.xml create mode 100644 make/data/cldr/common/main/lmo_IT.xml create mode 100644 make/data/cldr/common/main/mn_Mong.xml create mode 100644 make/data/cldr/common/main/mn_Mong_CN.xml create mode 100644 make/data/cldr/common/main/mn_Mong_MN.xml create mode 100644 make/data/cldr/common/main/mni_Mtei.xml create mode 100644 make/data/cldr/common/main/mni_Mtei_IN.xml create mode 100644 make/data/cldr/common/main/moh.xml create mode 100644 make/data/cldr/common/main/moh_CA.xml create mode 100644 make/data/cldr/common/main/ms_Arab.xml create mode 100644 make/data/cldr/common/main/ms_Arab_BN.xml create mode 100644 make/data/cldr/common/main/ms_Arab_MY.xml create mode 100644 make/data/cldr/common/main/mus.xml create mode 100644 make/data/cldr/common/main/mus_US.xml create mode 100644 make/data/cldr/common/main/myv.xml create mode 100644 make/data/cldr/common/main/myv_RU.xml create mode 100644 make/data/cldr/common/main/nqo.xml create mode 100644 make/data/cldr/common/main/nqo_GN.xml create mode 100644 make/data/cldr/common/main/nr.xml create mode 100644 make/data/cldr/common/main/nr_ZA.xml create mode 100644 make/data/cldr/common/main/nso.xml create mode 100644 make/data/cldr/common/main/nso_ZA.xml create mode 100644 make/data/cldr/common/main/nv.xml create mode 100644 make/data/cldr/common/main/nv_US.xml create mode 100644 make/data/cldr/common/main/ny.xml create mode 100644 make/data/cldr/common/main/ny_MW.xml create mode 100644 make/data/cldr/common/main/osa.xml create mode 100644 make/data/cldr/common/main/osa_US.xml create mode 100644 make/data/cldr/common/main/pap.xml create mode 100644 make/data/cldr/common/main/pap_AW.xml create mode 100644 make/data/cldr/common/main/pap_CW.xml create mode 100644 make/data/cldr/common/main/prg.xml create mode 100644 make/data/cldr/common/main/prg_001.xml create mode 100644 make/data/cldr/common/main/quc.xml create mode 100644 make/data/cldr/common/main/quc_GT.xml create mode 100644 make/data/cldr/common/main/rhg.xml create mode 100644 make/data/cldr/common/main/rhg_Rohg.xml create mode 100644 make/data/cldr/common/main/rhg_Rohg_BD.xml create mode 100644 make/data/cldr/common/main/rhg_Rohg_MM.xml create mode 100644 make/data/cldr/common/main/rif.xml create mode 100644 make/data/cldr/common/main/rif_MA.xml create mode 100644 make/data/cldr/common/main/sat_Deva.xml create mode 100644 make/data/cldr/common/main/sat_Deva_IN.xml create mode 100644 make/data/cldr/common/main/scn.xml create mode 100644 make/data/cldr/common/main/scn_IT.xml create mode 100644 make/data/cldr/common/main/sdh.xml create mode 100644 make/data/cldr/common/main/sdh_IQ.xml create mode 100644 make/data/cldr/common/main/sdh_IR.xml create mode 100644 make/data/cldr/common/main/shn.xml create mode 100644 make/data/cldr/common/main/shn_MM.xml create mode 100644 make/data/cldr/common/main/shn_TH.xml create mode 100644 make/data/cldr/common/main/sid.xml create mode 100644 make/data/cldr/common/main/sid_ET.xml create mode 100644 make/data/cldr/common/main/sma.xml create mode 100644 make/data/cldr/common/main/sma_NO.xml create mode 100644 make/data/cldr/common/main/sma_SE.xml create mode 100644 make/data/cldr/common/main/smj.xml create mode 100644 make/data/cldr/common/main/smj_NO.xml create mode 100644 make/data/cldr/common/main/smj_SE.xml create mode 100644 make/data/cldr/common/main/ss.xml create mode 100644 make/data/cldr/common/main/ss_SZ.xml create mode 100644 make/data/cldr/common/main/ss_ZA.xml create mode 100644 make/data/cldr/common/main/ssy.xml create mode 100644 make/data/cldr/common/main/ssy_ER.xml create mode 100644 make/data/cldr/common/main/st.xml create mode 100644 make/data/cldr/common/main/st_LS.xml create mode 100644 make/data/cldr/common/main/st_ZA.xml create mode 100644 make/data/cldr/common/main/syr.xml create mode 100644 make/data/cldr/common/main/syr_IQ.xml create mode 100644 make/data/cldr/common/main/syr_SY.xml create mode 100644 make/data/cldr/common/main/szl.xml create mode 100644 make/data/cldr/common/main/szl_PL.xml create mode 100644 make/data/cldr/common/main/tig.xml create mode 100644 make/data/cldr/common/main/tig_ER.xml create mode 100644 make/data/cldr/common/main/tn.xml create mode 100644 make/data/cldr/common/main/tn_BW.xml create mode 100644 make/data/cldr/common/main/tn_ZA.xml create mode 100644 make/data/cldr/common/main/tpi.xml create mode 100644 make/data/cldr/common/main/tpi_PG.xml create mode 100644 make/data/cldr/common/main/trv.xml create mode 100644 make/data/cldr/common/main/trv_TW.xml create mode 100644 make/data/cldr/common/main/trw.xml create mode 100644 make/data/cldr/common/main/trw_PK.xml create mode 100644 make/data/cldr/common/main/ts.xml create mode 100644 make/data/cldr/common/main/ts_ZA.xml create mode 100644 make/data/cldr/common/main/ve.xml create mode 100644 make/data/cldr/common/main/ve_ZA.xml create mode 100644 make/data/cldr/common/main/vec.xml create mode 100644 make/data/cldr/common/main/vec_IT.xml create mode 100644 make/data/cldr/common/main/vo.xml create mode 100644 make/data/cldr/common/main/vo_001.xml create mode 100644 make/data/cldr/common/main/wa.xml create mode 100644 make/data/cldr/common/main/wa_BE.xml create mode 100644 make/data/cldr/common/main/wal.xml create mode 100644 make/data/cldr/common/main/wal_ET.xml create mode 100644 make/data/cldr/common/main/wbp.xml create mode 100644 make/data/cldr/common/main/wbp_AU.xml diff --git a/make/data/cldr/README b/make/data/cldr/README index b75492f15a4..cca0921da83 100644 --- a/make/data/cldr/README +++ b/make/data/cldr/README @@ -1,4 +1,4 @@ CLDR - Unicode Common Locale Data Repository http://cldr.unicode.org -CLDR version installed: 42 +CLDR version installed: 43 diff --git a/make/data/cldr/common/bcp47/currency.xml b/make/data/cldr/common/bcp47/currency.xml index 49fddfc7e6b..f357a38dd2f 100644 --- a/make/data/cldr/common/bcp47/currency.xml +++ b/make/data/cldr/common/bcp47/currency.xml @@ -67,9 +67,9 @@ For terms of use, see http://www.unicode.org/copyright.html - + - + @@ -112,7 +112,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -136,8 +136,8 @@ For terms of use, see http://www.unicode.org/copyright.html - - + + @@ -181,7 +181,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -189,7 +189,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -210,7 +210,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -219,7 +219,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -235,11 +235,11 @@ For terms of use, see http://www.unicode.org/copyright.html - + - - + + @@ -274,28 +274,28 @@ For terms of use, see http://www.unicode.org/copyright.html - + + - - + - - + + - + diff --git a/make/data/cldr/common/bcp47/segmentation.xml b/make/data/cldr/common/bcp47/segmentation.xml index 3f54cd8567a..427a3adcbd1 100644 --- a/make/data/cldr/common/bcp47/segmentation.xml +++ b/make/data/cldr/common/bcp47/segmentation.xml @@ -10,25 +10,25 @@ For terms of use, see http://www.unicode.org/copyright.html - + - - - + + + - - - - + + + + - - + + diff --git a/make/data/cldr/common/bcp47/timezone.xml b/make/data/cldr/common/bcp47/timezone.xml index 57d81ed48ec..20ec0c1f9da 100644 --- a/make/data/cldr/common/bcp47/timezone.xml +++ b/make/data/cldr/common/bcp47/timezone.xml @@ -96,20 +96,20 @@ For terms of use, see http://www.unicode.org/copyright.html - + - + - + @@ -177,7 +177,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -190,7 +190,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -280,7 +280,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -390,7 +390,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + diff --git a/make/data/cldr/common/bcp47/variant.xml b/make/data/cldr/common/bcp47/variant.xml index 9940379315c..0517a9b923c 100644 --- a/make/data/cldr/common/bcp47/variant.xml +++ b/make/data/cldr/common/bcp47/variant.xml @@ -7,18 +7,18 @@ - - - + + + - + + description="Valid unicode_subdivision_subtag for the region subtag as specified in LDML, based on subdivisionContainment data in supplementalData, prefixed by the associated unicode_region_subtag" since="28"/> diff --git a/make/data/cldr/common/dtd/ldml.dtd b/make/data/cldr/common/dtd/ldml.dtd index 76c0176780b..ade0de9e581 100644 --- a/make/data/cldr/common/dtd/ldml.dtd +++ b/make/data/cldr/common/dtd/ldml.dtd @@ -1,5 +1,5 @@ - + @@ -68,6 +68,7 @@ CLDR data files are interpreted according to the LDML specification (http://unic + @@ -465,6 +466,7 @@ CLDR data files are interpreted according to the LDML specification (http://unic + @@ -2825,10 +2827,11 @@ CLDR data files are interpreted according to the LDML specification (http://unic - + + @@ -3123,7 +3126,7 @@ CLDR data files are interpreted according to the LDML specification (http://unic - + @@ -3159,10 +3162,8 @@ CLDR data files are interpreted according to the LDML specification (http://unic - - @@ -3172,7 +3173,6 @@ CLDR data files are interpreted according to the LDML specification (http://unic - @@ -3183,7 +3183,6 @@ CLDR data files are interpreted according to the LDML specification (http://unic - @@ -3193,18 +3192,16 @@ CLDR data files are interpreted according to the LDML specification (http://unic - - + - + - + - + - @@ -3212,14 +3209,12 @@ CLDR data files are interpreted according to the LDML specification (http://unic - - + - - + diff --git a/make/data/cldr/common/dtd/ldmlBCP47.dtd b/make/data/cldr/common/dtd/ldmlBCP47.dtd index b82183c1825..ce302dc6990 100644 --- a/make/data/cldr/common/dtd/ldmlBCP47.dtd +++ b/make/data/cldr/common/dtd/ldmlBCP47.dtd @@ -1,5 +1,5 @@ - + diff --git a/make/data/cldr/common/dtd/ldmlSupplemental.dtd b/make/data/cldr/common/dtd/ldmlSupplemental.dtd index 9545872ddbc..9855a1ce7a6 100644 --- a/make/data/cldr/common/dtd/ldmlSupplemental.dtd +++ b/make/data/cldr/common/dtd/ldmlSupplemental.dtd @@ -1,18 +1,18 @@ - + - + @@ -216,7 +216,7 @@ CLDR data files are interpreted according to the LDML specification (http://unic - + @@ -237,6 +237,11 @@ CLDR data files are interpreted according to the LDML specification (http://unic + + + + + @@ -250,6 +255,12 @@ CLDR data files are interpreted according to the LDML specification (http://unic + + + + + + @@ -439,7 +450,6 @@ CLDR data files are interpreted according to the LDML specification (http://unic - @@ -900,6 +910,8 @@ CLDR data files are interpreted according to the LDML specification (http://unic + + @@ -923,6 +935,9 @@ CLDR data files are interpreted according to the LDML specification (http://unic + + + diff --git a/make/data/cldr/common/main/aa.xml b/make/data/cldr/common/main/aa.xml new file mode 100644 index 00000000000..0c36f7e0435 --- /dev/null +++ b/make/data/cldr/common/main/aa.xml @@ -0,0 +1,231 @@ + + + + + + + + + + + Qafar + + + Yabuuti + Eretria + Otobbia + + + + [a b t s e c k x i d q r f g o l m n u w h y] + [j p v z] + [A B T S E C K X I D Q R F G O L M N U W H Y] + + + + + + + + EEEE, MMMM dd, y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + + + Qun + Nah + Cig + Agd + Cax + Qas + Qad + Leq + Way + Dit + Xim + Kax + + + Qunxa Garablu + Kudo + Ciggilta Kudo + Agda Baxis + Caxah Alsa + Qasa Dirri + Qado Dirri + Liiqen + Waysu + Diteli + Ximoli + Kaxxa Garablu + + + + + Q + N + C + A + C + Q + Q + L + W + D + X + K + + + + + + + Aca + Etl + Tal + Arb + Kam + Gum + Sab + + + Acaada + Etleeni + Talaata + Arbaqa + Kamiisi + Gumqata + Sabti + + + + + A + E + T + A + K + G + S + + + + + + + saaku + carra + + + saaku + carra + + + + + + Yaasuusuk Duma + Yaasuusuk Wadir + + + YD + YW + + + + + + EEEE, MMMM dd, y + yMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + + ¤#,##0.00 + + + + + + Br + + + + diff --git a/make/data/cldr/common/main/aa_DJ.xml b/make/data/cldr/common/main/aa_DJ.xml new file mode 100644 index 00000000000..f8f3194a14f --- /dev/null +++ b/make/data/cldr/common/main/aa_DJ.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + Qunxa Garablu + Kudo + Ciggilta Kudo + Agda Baxis + Caxah Alsa + Qasa Dirri + Qado Dirri + Leqeeni + Waysu + Diteli + Ximoli + Kaxxa Garablu + + + + + + + + + + Fdj + + + + diff --git a/make/data/cldr/common/main/aa_ER.xml b/make/data/cldr/common/main/aa_ER.xml new file mode 100644 index 00000000000..ea1daef97dc --- /dev/null +++ b/make/data/cldr/common/main/aa_ER.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + Nfk + + + + diff --git a/make/data/cldr/common/main/aa_ET.xml b/make/data/cldr/common/main/aa_ET.xml new file mode 100644 index 00000000000..6ccfb6dad6b --- /dev/null +++ b/make/data/cldr/common/main/aa_ET.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ab.xml b/make/data/cldr/common/main/ab.xml new file mode 100644 index 00000000000..78f7728b0a7 --- /dev/null +++ b/make/data/cldr/common/main/ab.xml @@ -0,0 +1,4066 @@ + + + + + + + + + + + {0} ({1}) + {0}, {1} + {0}: {1} + + + Аԥсшәа + ачех + адангме + аедыгь + африкаанс + агем + аин + акан + алеут + аладалтаи + амхар + арагон + ангика + араб + амапуче + арапахо + анедџитә араб + ассам + асу + астури + авар + авадхи + аимара + азербаиџьан + абашкир + абали + абаса + абелорус + абемба + абена + аболгар + абхоџпури + абислама + абини + асиксика + абамбара + абенгал + атибет + абретон + абодо + абосни + абуги + абилин + акаталан + акаиуга + ачакма + ачечен + асебуано + акига + ачаморро + ачукот + амари + ачоктав + ачипевиан + ачероки + ашаиен + агәҭантәи ақәырд + ақәырд (асорани) + акорсикан + ачеш + ауахәама-славиан + ачуваш + авалли + адат + адакота + адаргин + атаита + агерман + австриа агерман + алитературатә ашвеицар агерман + адогриб + аџерма + адогри + ҵаҟатәи лужик + адуала + амалдив + адиола-фони + аӡонг-ка + адаза + аембу + аеве + аефик + аекаџук + абырзен + англыз + австралиатәи англыз + канадатәи англыз + абритан англыз + америкатәи англыз + аесперанто + аиспан + алаҭын-америкатәи аиспан + европатәи аиспан + мексикатәи аиспан + аестон + абаск + аевондо + аџьам + адари + афулах + афин + афилиппин + афиџи + афарер + афон + афранцыз + канадатәи афранцыз + швеицариатәи афранцыз + каџунтәи афранцыз + африул + мраҭашәаратәи африз + аирланд + ага + агел + агеез + агилберт + агалиси + агуарани + агоронтало + швеицариатәи агерман + агуџарати + агуси + амен + агвичин + ахауса + ахаида + агаваи + аиврит + ахинди + ахынглыз + ахилигаинон + ахмонг + ахорват + хыхьтәи-алужик + агаитиан + авенгер + ахупа + аерман + агереро + аинтерлингва + аибан + аибибио + аиндонез + аигбо + аносу + аилоко + аингәыш + аидо + аисланд + аиталиа + аинуктитут + аиапон + аложбан + ангомба + амачаме + аиаван + ақырҭ + акабил + акачин + акаџи + акамба + аҟабарда + атиап + амаконде + акабувердиану + акоро + акхаси + акоира чиини + акикәиу + акәнама + аҟазах + акако + агренланд + акаленџин + акхмер + акимбунду + аканнада + акореи + аконкани + акпелле + аканури + аҟарач-абалҟар + акарел + акурух + акашмири + ашамбала + абафиа + акиолн + ақәырд + акәымык + акоми + акорн + акиргиз + алаҭын + аладино + аланго + алиуксембург + алезгьын + аганда + алимбург + алакота + алингала + алаос + алуизиантәи акреол + алози + аҩадалур + алитов + алуба-акатанга + алуба-алулуа + алунда + алуо + амизо + алухьиа + алатыш + амадур + амагахи + амаитхили + амакассар + амасаи + амокшан + аменде + амеру + амаврикитә креол + амалагаси + амакуа-амеетто + амета + амаршал + амаори + амикмак + аминангкабау + амакедон + амалаиалам + амонгол + аманипур + амохаук + амоси + амаратхи + амалаи + амалти + амунданг + еиуеиԥшым аҭаацәаратә бызшәақәа + акрик + амиранд + абирман + аерзиан + амазандеран + анауру + анеаполитан + анама + анорвегтәи абукмол + нхыҵ андебеле + ҵаҟатәи агерман + ҵаҟатәи асаксон + анепал + аневар + андонга + аниас + аниуе + анидерланд + афламанд + аквасио + аниунорск + ангиембунд + анорвег + аногаи + анко + аладатәи андебеле + аҩадатәи асото + ануер + анавахо + анианџа + анианколе + аокситан + аоромо + аориа + ауаԥс + апанџаби + апангасинан + апампанга + апапиаменто + апалау + анигери-креол + апол + апрус + апушту + апортугал + бразилиатәи апортугал + европатәи апортугал + акечуа + арапануи + араротонга + арохинџа + ароманш + арунди + арумын + молдав + аромбо + аурыс + аромун + акиниаруанда + аруанда + асанскрит + асандаве + асаха + асамбуру + асантали + ангамбаи + асангу + асардин + асицили + ашотланд + асиндхи + аҩадасаам + асена + акоираборо асенни + асанго + аташелхит + ашан + асингал + асловак + асловен + асамоан + аинари-асаам + аколтта-асаам + ашона + асонинке + асомали + арнауҭ + асерб + асранан-атонго + асвази + аладатәи асото + асундан + асукәыма + ашвед + асуахили + конголезтәи асуахили + акомор + ашьам + атамил + ателугу + атемне + атесо + атетум + аҭаџьык + атаи + атигриниа + атигре + атуркмен + аклингон + атлингит + атсвана + атонган + аток-аписин + аҭырқә + аседек + атсонга + аҭаҭар + атумбука + атувалу + атасавак + атаитиан + атувин + абжьара-атластәи атамазигхт + аудмурт + ауигур + аукраин + аумбунду + еилкаам абызшәа + аурду + аузбек + аваи + авенда + авиетнам + аволапиук + авунџо + аваллон + аваллис + аволамо + авараи + аволоф + аву + аҟалмыҟ + акоса + асога + аиангбен + аиемба + аидиш + аиоруба + акантон + атамазигхт + акитаи + аҩадакитаи + акитаи, имариоу аҩыра + аҩадакитаи, имариоу аҩыра + акитаи, атрадициатә ҩыра + аҩадакитаи, атрадициатә ҩыра + азулу + азуни + абызшәатә хыҵхырҭақәа ыҟаӡам + азаза + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + адунеи зегьы + Африка + Аҩадатәи Америка + Аладатәи Америка + Океаниа + Мраҭашәаратәи Африка + Агәҭантәи Америка + Мрагыларатәи Африка + Аҩадатәи Африка + Агәҭантәи Африка + Аладатәи Африка + Америка + Аҩада-Америкатәи арегион + Кариб + Мрагыларатәи Азиа + Аладатәи Азиа + Алада-Мрагыларатәи Азиа + Аладатәи Европа + Австралазиа + Меланезиа + Микронезиа + Полинезиа + Азиа + Агәҭантәи Азиа + Мраҭашәаратәи Азиа + Европа + Мрагыларатәи Европа + Аҩадатәи Европа + Мраҭашәаратәи Европа + Атроптә Африка + Алаҭынтәи Америка + ад-ха Вознесениа + Андорра + ЕАЕ + Афганистан + Антигуеи Барбудеи + Ангилиа + Албаниа + Ермантәыла + Ангола + Антарктида + Аргентина + Америкатәи Самоа + Австриа + Австралиа + Аруба + Аландтәи ад-хақәа + Азербаиџьан + Босниеи Герцеговинеи + Барбадос + Бангладеш + Бельгиа + Буркина-Фасо + Болгариа + Бахреин + Бурунди + Бенин + Сен-Бартелеми + Бермудтәи ад-хақәа + Брунеи-Даруссалам + Боливиа + Бонеир, Синт-Естатиуси Сабеи + Бразилиа + Баӷама + Бутан + ад-ха Буве + Ботсвана + Беларус + Белиз + Канада + Кокостәи ад-қәа + Конго-Киншаса + Конго (АРК) + Агәҭантәи-Африкатәи Ареспублика + Конго-Браззавиль + Ареспублика Конго + Швеицариа + Кот-д’Ивуар + Кук идгьылбжьахақәа + Чили + Камерун + Китаи + Колумбиа + ад-ха Клиппертон + Коста-Рика + Куба + Кабо-Верде + Киурасао + ад-ха Қьырса + Кипр + Чехиа + Чештәи ареспублика + Германиа + Диего-Гарсиа + Џибути + Даниа + Доминика + Доминиканатәи Ареспублика + Алжир + Сеутеи Мелилиеи + Еквадор + Естониа + Египет + Мраҭашәаратәи Сахара + Еритреиа + Испаниа + Ефиопиа + Европатәи аидгыла + евроцәаҳәа + Финлиандиа + Фиџи + Фолклендтәи ад-хақәа + Фолклендтәи (Мальвинтәи) ад-хақәа + Еилоу Микронезиатәи Аштатқәа + Фарертәи ад-хақәа + Франциа + Габон + Британиа ду + Британиа + Гренада + Қырҭтәыла + Францызтәи Гвиана + Гернси + Гана + Гибралтар + Гренландиа + Гамбиа + Гвинеиа + Гваделупа + Екваториалтәи Гвинеиа + Бырзентәыла + Аладатәи Георгиеи Аладатәи Сандвичқәеи ад-қәа + Гватемала + Гуам + Гвинеиа-Бисау + Гаиана + Гонконг (ҶАР) + Гонконг + ад-хақәа Херди Макдональди + Гондурас + Хорватиа + Гаити + Венгриа + Канартәи ад-хақәа + Индонезиа + Ирландиа + Израиль + ад-ха Мен + Индиа + Британиатәи аҵакырадгьыл Индиатәи аокеан аҟны + Ирак + Иран + Исландиа + Италиа + Џерси + Иамаика + Иорданиа + Иапониа + Кениа + Киргизиа + Камбоџа + Кирибати + Комор + Сент-Китси Невиси + КЖӘДР + Кореиа Ареспублика + Кувеит + Адгьылбжьахақәа Каиман + Ҟазахсҭан + Лаос + Ливан + Сент-Люсиа + Лихтенштеин + Шри-Ланка + Либериа + Лесото + Литва + Лиуксембург + Латвиа + Ливиа + Марокко + Монако + Молдова + Ашьхеиқәаҵәа + Сен-Мартен + Мадагаскар + Маршаллтәи Адгьылбжьахақәа + Аҩадатәи Македониа + Мали + Мианма (Бирма) + Монголиа + Макао (ҶАР) + Макао + Аҩадатәи Мариантәи ад-хақәа + Мартиника + Мавританиа + Монтсеррат + Мальта + Маврики + Мальдив + Малави + Мексика + Малаизиа + Мозамбик + Намибиа + Каледониа ҿыц + Нигер + Ад-ха Норфолк + Нигериа + Никарагуа + Нидерланд + Норвегиа + Непал + Науру + Ниуе + Зеландиа ҿыц + Аотеароа (Зеландиа ҿыц) + Оман + Панама + Перу + Францызтәи Полинезиа + Папуа — Гвинеиа ҿыц + Филиппин + Пакистан + Польша + Сен-Пиери Микелони + Питкерн ад-хақәа + Пуерто-Рико + Палестинатәи аҵакырадгьылқәа + Палестина + Португалиа + Палау + Парагваи + Катар + Нҭыҵтәи Океаниа + Реиунон + Румыниа + Сербиа + Урыстәыла + Руанда + Саудтәи Арабсҭан + Соломонтәи адгьылбжьахақәа + Сеишелтәи адгьылбжьахақәа + Судан + Швециа + Сингапур + Иԥшьоу Елена ладгьылбжьаха + Словениа + Шпицбергени Иан-Маиени + Словакиа + Сиерра-Леоне + Сан-Марино + Сенегал + Сомали + Суринам + Аладатәи Судан + Сан-Томеи Принсипиеи + Сальвадор + Синт-Мартен + Шьамтәыла + Есватини + Свазиленд + Тристан-да-Куниа + ад-хақәа Тиоркси Каикоси + Чад + Францызтәи Аладатәи аҵакырадгьылқәа + Того + Таиланд + Таџьықсҭан + Токелау + Мрагыларатәи Тимор + Тимор-Лесте + Ҭурқменисҭан + Тунис + Тонга + Ҭырқәтәыла + Тринидади Тобагои + Тувалу + Таиван + Танзаниа + Украина + Уганда + Нҭыҵтәи малыетәи ад-қәа (ЕАШ) + Еиду Амилаҭқәа Реиҿкаара + Еиду Аштатқәа + ЕАШ + Уругваи + Узбеқьисҭан + Ватикан + Сент-Винсенти Гренадини + Венесуела + Виргинтәи ад-хақәа (Британиаду) + Виргинтәи ад-хақәа (ЕАШ) + Виетнам + Вануату + Уоллиси Футунеи + Самоа + амццәажәашьақәа + амц-Bidi + Косово + Иемен + Маиотта + Алада-Африкатәи ареспублика + Замбиа + Зимбабве + еилкаам арегион + + + агригориантә мзар + амзар ISO-8601 + астандартә сортла аилыхра + иахьатәи араб ацифра + + + Аметрикатә + Англиатәи + Америкатә + + + Абызшәа: {0} + Аҩыра: {0} + Арегион: {0} + + + + [а ә б в г {гә} {гь} ӷ {ӷә} {ӷь} д {дә} е ж {жә} {жь} з ӡ {ӡә} и к {кә} {кь} қ {қә} {қь} ҟ {ҟә} {ҟь} л м н о п ԥ р с т {тә} ҭ {ҭә} у ф х {хә} {хь} ҳ {ҳә} ц {цә} ҵ {ҵә} ч ҷ ҽ ҿ џ {џь} ш {шә} {шь} ы ь ҩ] + [{а\u0301} ҕ {ҕә} {ҕь} {е\u0301} {и\u0301} {о\u0301} ҧ {у\u0301} {ы\u0301}] + [А Б В Г {ГӘ} {ГЬ} Ӷ {ӶӘ} {ӶЬ} Д {ДӘ} Е Ж {ЖӘ} {ЖЬ} З Ӡ {ӠӘ} И К {КӘ} {КЬ} Қ {ҚӘ} {ҚЬ} Ҟ {ҞӘ} {ҞЬ} Л М Н О П Ԥ Р С Т {ТӘ} Ҭ {ҬӘ} У Ф Х {ХӘ} {ХЬ} Ҳ {ҲӘ} Ц {ЦӘ} Ҵ {ҴӘ} Ч Ҷ Ҽ Ҿ Џ {ЏЬ} Ш {ШӘ} {ШЬ} Ы Ҩ] + [\- ‑ , % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ‚ " “ „ « » ( ) \[ \] \{ \} § @ * / \& #] + {0}… + …{0} + {0}…{1} + {0} … + … {0} + {0} … {1} + ? + + [\--/] + [\:∶] + + + [.․。︒﹒.。] + ['ʼ՚᾽᾿’'] + [%٪﹪%] + [؉‰] + [\$﹩$$] + [£₤] + [¥¥] + [₩₩] + [₨₹{Rp}{Rs}] + + + [\-‒⁻₋−➖﹣-] + [,،٫、︐︑﹐﹑,、] + [+⁺₊➕﬩﹢+] + + + [,٫︐﹐,] + [.․﹒.。] + + + + « + » + + + + + + + + + + EEEE, d MMMM y 'ш'. G + + + + + d MMMM y 'ш'. G + + + + + d MMM y 'ш'. G + + + + + dd.MM.y G + + + + + + + {1}, {0} + + + {1}, {0} 'аҿы' + + + + + {1}, {0} + + + {1}, {0} 'аҿы' + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + E, d + ccc, h:mm a + ccc HH:mm + ccc, h:mm:ss a + ccc HH:mm:ss + y 'ш'. G + dd.MM.y G + LLL y 'ш'. G + d MMM y 'ш'. G + E, d MMM y 'ш'. G + dd.MM + E, dd.MM + d MMM + ccc, d MMM + d MMMM + y 'ш'. G + y 'ш'. G + MM.y G + dd.MM.y G + E, dd.MM.y G + LLL y 'ш'. G + d MMM y 'ш'. G + E, d MMM y 'ш'. G + LLLL y 'ш'. G + QQQ y 'ш'. G + QQQQ y 'ш'. G + + + + y 'ш'. G – y 'ш'. G + y–y 'шш'. G + + + MM.y G – MM.y G + MM.y – MM.y G + MM.y – MM.y G + + + dd.MM.y – dd.MM.y G + dd.MM.y G – dd.MM.y G + dd.MM.y – dd.MM.y G + dd.MM.y – dd.MM.y G + + + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y G – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + + + LLL y 'ш'. G – LLL y 'ш'. G + LLL – LLL y 'ш'. G + LLL y – LLL y 'шш'. G + + + d–d MMM y 'ш'. G + d MMM y 'ш'. G – d MMM y 'ш'. G + d MMM – d MMM y 'ш'. G + d MMM y – d MMM y 'шш'. G + + + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM y 'ш'. G – ccc, d MMM y 'ш'. G + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM y – ccc, d MMM y 'шш'. G + + + M–M + + + E, dd.MM – E, dd.MM + E, dd.MM – E, dd.MM + + + LLL – LLL + + + d–d MMM + d MMM – d MMM + + + ccc, d MMM – ccc, d MMM + ccc, d MMM – ccc, d MMM + + + y–y 'шш'. G + + + MM.y – MM.y G + MM.y – MM.y G + + + dd.MM.y – dd.MM.y G + dd.MM.y – dd.MM.y G + dd.MM.y – dd.MM.y G + + + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + + + LLL – LLL y 'ш'. G + LLL y 'ш'. – LLL y 'ш'. G + + + d–d MMM y 'ш'. G + d MMM – d MMM y 'ш'. G + d MMM y 'ш'. – d MMM y 'ш'. G + + + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM y 'ш'. – ccc, d MMM y 'ш'. G + + + LLLL – LLLL y 'ш'. G + LLLL y 'ш'. – LLLL y 'ш'. G + + + + + + + + + Ажь + Жəаб + Хəажә + Мш + Лаҵ + Рашә + Ԥхынгә + Нанҳә + Цəыб + Жьҭ + Абҵ + Ԥхынҷ + + + Жь + Жə + Хə + М + Л + Р + Гә + Н + Цə + Ҭ + Б + Ҷ + + + Ажьырныҳəа + Жəабран + Хəажəкыра + Мшаԥы + Лаҵара + Рашəара + Ԥхынгəы + Нанҳəа + Цəыббра + Жьҭаара + Абҵара + Ԥхынҷкәын + + + + + Ажь + Жəаб + Хəажә + Мш + Лаҵ + Рашә + Ԥхынгә + Нанҳә + Цəыб + Жьҭ + Абҵ + Ԥхынҷ + + + Жь + Жə + Хə + М + Л + Р + Гә + Н + Цә + Ҭ + Б + Ҷ + + + Ажьырныҳəа + Жəабран + Хəажəкыра + Мшаԥы + Лаҵара + Рашəара + Ԥхынгəы + Нанҳəа + Цəыббра + Жьҭаара + Абҵара + Ԥхынҷкәын + + + + + + + Ам + Ашә + Аҩ + Ах + Аԥ + Ахә + Ас + + + М + Шә + Ҩ + Х + Ԥ + Хә + С + + + Ам + Ашә + Аҩ + Ах + Аԥ + Ахә + Ас + + + Амҽыша + Ашәахьа + Аҩаша + Ахаша + Аԥшьаша + Ахәаша + Асабша + + + + + Ам + Ашә + Аҩ + Ах + Аԥ + Ахә + Ас + + + М + Шә + Ҩ + Х + Ԥ + Хә + С + + + Ам + Ашә + Аҩ + Ах + Аԥ + Ахә + Ас + + + Амҽыша + Ашәахьа + Аҩаша + Ахаша + Аԥшьаша + Ахәаша + Асабша + + + + + + + 1-тәи акв. + 2-тәи акв. + 3-тәи акв. + 4-тәи акв. + + + 1 + 2 + 3 + 4 + + + 1-тәи аквартал + 2-тәи аквартал + 3-тәи аквартал + 4-тәи аквартал + + + + + 1-тәи акв. + 2-тәи акв. + 3-тәи акв. + 4-тәи акв. + + + 1-тәи аквартал + 2-тәи аквартал + 3-тәи аквартал + 4-тәи аквартал + + + + + + + AM + PM + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + + EEEE, d MMMM y 'ш'. + + + + + d MMMM y 'ш'. + + + + + d MMM y 'ш'. + + + + + dd.MM.y + + + + + + + HH:mm:ss zzzz + + + + + HH:mm:ss z + + + + + HH:mm:ss + + + + + HH:mm + + + + + + + {1}, {0} + + + {1}, {0} 'аҿы' + + + + + {1}, {0} + + + {1}, {0} 'аҿы' + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + ccc, h:mm B + ccc, h:mm:ss B + ccc, d + y 'ш'. G + dd.MM.y GGGGG + LLL y 'ш'. G + d MMM y 'ш'. G + E, d MMM y 'ш'. G + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + dd.MM + E, dd.MM + d MMM + ccc, d MMM + d MMMM + W-'тәи' 'амчыбжь' MMMM + MM.y + dd.MM.y + ccc, dd.MM.y 'ш'. + LLL y 'ш'. + d MMM y 'ш'. + E, d MMM y 'ш'. + LLLL y 'ш'. + QQQ y 'ш'. + QQQQ y 'ш'. + w-'тәи' 'амчыбжь' Y 'ш'. + + + {0} – {1} + + d–d + + + y 'ш'. G – y 'ш'. G + y–y 'шш'. G + + + MM.y G – MM.y G + MM.y – MM.y G + MM.y – MM.y G + + + dd.MM.y – dd.MM.y G + dd.MM.y G – dd.MM.y G + dd.MM.y – dd.MM.y G + dd.MM.y – dd.MM.y G + + + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y G – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + ccc, dd.MM.y – ccc, dd.MM.y G + + + LLL y 'ш'. G – LLL y 'ш'. G + LLL – LLL y 'ш'. G + LLL y – LLL y 'шш'. G + + + d–d MMM y 'ш'. G + d MMM y 'ш'. G – d MMM y 'ш'. G + d MMM – d MMM y 'ш'. G + d MMM y – d MMM y 'шш'. G + + + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM y 'ш'. G – ccc, d MMM y 'ш'. G + ccc, d MMM – ccc, d MMM y 'ш'. G + ccc, d MMM y – ccc, d MMM y 'шш'. G + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + h a – h a v + h–h a v + + + M–M + + + dd.MM – dd.MM + dd.MM – dd.MM + + + E, dd.MM – E, dd.MM + E, dd.MM – E, dd.MM + + + LLL – LLL + + + d–d MMM + d MMM – d MMM + + + E, d MMM – E, d MMM + E, d MMM – E, d MMM + + + y–y + + + MM.y – MM.y + MM.y – MM.y + + + dd.MM.y – dd.MM.y + dd.MM.y – dd.MM.y + dd.MM.y – dd.MM.y + + + ccc, dd.MM.y – ccc, dd.MM.y + ccc, dd.MM.y – ccc, dd.MM.y + ccc, dd.MM.y – ccc, dd.MM.y + + + LLL – LLL y 'ш'. + LLL y 'ш'. – LLL y 'ш'. + + + d–d MMM y 'ш'. + d MMM – d MMM y 'ш'. + d MMM y 'ш'. – d MMM y 'ш'. + + + ccc, d – ccc, d MMM y 'ш'. + ccc, d MMM – ccc, d MMM y 'ш'. + ccc, d MMM y 'ш'. – ccc, d MMM y 'ш'. + + + LLLL – LLLL y 'ш'. + LLLL y 'ш'. – LLLL y 'ш'. + + + + + + + + аера + + + ашықәс + + + ш. + + + ш + + + аквартал + + + акв. + + + акв + + + амза + + + амз. + + + амз + + + амчыбжь + + + амч. + + + амч + + + амш + иацы + иахьа + уаҵәы + + + амш + иацы + иахьа + уаҵәы + + + амш + иацы + иахьа + уаҵәы + + + + {0} Аамҭа + {0} Аԥхынтәи Аамҭа + {0} Астандартә Аамҭа + + Еилкаам ақалақь + + + Андорра + + + Дубаи + + + Кабул + + + Антигуа + + + Ангилиа + + + Тирана + + + Ереван + + + Луанда + + + Ротера + + + Палмер + + + Тролл + + + Сиова + + + Моусон + + + Деивис + + + Амрагылара + + + Кеиси + + + Диумон-д’Иурвил + + + Мак-Мердо + + + Рио-Галегос + + + Мендоса + + + Сан-Хуан + + + Ушуаиа + + + Ла-Риоха + + + Сан-Луис + + + Катамарка + + + Салта + + + Жужуи + + + Тукуман + + + Кордова + + + Буенос-Аирес + + + Паго-Паго + + + Вена + + + Перт + + + Иукла + + + Дарвин + + + Аделаида + + + Брокен-Хилл + + + Мелбурн + + + Хобарт + + + Линдеман + + + Сиднеи + + + Брисбен + + + Маккуори + + + Лорд-Хау + + + Аруба + + + Мариехамн + + + Баку + + + Сараево + + + Барбадос + + + Дакка + + + Бриуссел + + + Уагадугу + + + Софиа + + + Бахреин + + + Бужумбура + + + Порто-Ново + + + Сен-Бартелеми + + + Бермудтәи ад-хақәа + + + Брунеи + + + Ла-Пас + + + Кралендеик + + + Еирунепе + + + Риу-Бранку + + + Порту-Велиу + + + Боа-Виста + + + Манаус + + + Куиаба + + + Сантарен + + + Кампу-Гранди + + + Белен + + + Арагуаина + + + Сан-Паулу + + + Баиа + + + Форталеза + + + Масеио + + + Ресифи + + + Норониа + + + Нассау + + + Тхимпху + + + Габороне + + + Минск + + + Белиз + + + Доусон + + + Уаитхорс + + + Инувик + + + Ванкувер + + + Форт Нелсон + + + Доусон-Крик + + + Крестон + + + Иеллоунаиф + + + Едмонтон + + + Свифт-Керрент + + + Кеимбриџ-Беи + + + Реџаина + + + Виннипег + + + Резолиут + + + Реини-Ривер + + + Ранкин-Инлет + + + Корал-Харбор + + + Тандер-Беи + + + Нипигон + + + Торонто + + + Икалуит + + + Пангниртанг + + + Монктон + + + Ҳалифакс + + + Гус-Беи + + + Глеис-Беи + + + Бланк-Саблон + + + Сент-Џонс + + + Кокостәи ад-хақәа + + + Киншаса + + + Лубумбаши + + + Банги + + + Браззавил + + + Циурих + + + Абиџан + + + Раротонга + + + ад-ха Пасхи + + + Пунта-Аренас + + + Сантиаго + + + Дуала + + + Урумчи + + + Шанхаи + + + Богота + + + Коста-Рика + + + Гавана + + + Кабо-Верде + + + Киурасао + + + ад-ха Қьырса + + + Никосиа + + + Фамагуста + + + Прага + + + Биузинген-Хыхьтәи-Реине + + + Берлин + + + Џибути + + + Копенҳаген + + + Доминика + + + Санто-Доминго + + + Алжир + + + Галапагостәи ад-хақәа + + + Гуаиакил + + + Таллин + + + Каир + + + Ел-Аиун + + + Асмера + + + Канартәи ад-хақәа + + + Сеута + + + Мадрид + + + Аддис-Абеба + + + Хелсинки + + + Фиџи + + + Стенли + + + Трук + + + Понпеи + + + Косрае + + + Фарертәи ад-хақәа + + + Париж + + + Либревил + + + + Англиа Аԥхынтәи Аамҭа + + Лондон + + + Гренада + + + Қарҭ + + + Каиенна + + + Гернси + + + Аккра + + + Гибралтар + + + Туле + + + Нуук + + + Скорсбисунн + + + Денмарксхавн + + + Банжул + + + Конакри + + + Гваделупа + + + Малабо + + + Афин + + + Аладатәи Георгиа + + + Гватемала + + + Гуам + + + Бисау + + + Гаиана + + + Ҳонконг + + + Тегусигалпа + + + Загреб + + + Порт-о-Пренс + + + Будапешт + + + Џакарта + + + Понтианак + + + Макасар + + + Џаиапура + + + + Аирланд Астандартә Аамҭа + + Дублин + + + Иерусалим + + + ад-ха Мен + + + Калкутта + + + Чагос + + + Багдад + + + Тегеран + + + Реикиавик + + + Рим + + + Џерси + + + Иамаика + + + Амман + + + Токио + + + Наироби + + + Бишкек + + + Пномпен + + + Кантон + + + Киритимати + + + Тарава + + + Комор + + + Сент-Китс + + + Пхениан + + + Сеул + + + Кувеит + + + Адгьылбжьахақәа Каиман + + + Актау + + + Уралск + + + Атырау + + + Актобе + + + Костанаи + + + Кызылорда + + + Алматы + + + Вентиан + + + Беирут + + + Сент-Лиусиа + + + Вадуц + + + Коломбо + + + Монровиа + + + Масеру + + + Вилниус + + + Лиуксембург + + + Рига + + + Триполи + + + Касабланка + + + Монако + + + Кишинев + + + Подгорица + + + Мариго + + + Антананариву + + + Кваџалеин + + + Маџуро + + + Скопе + + + Бамако + + + Иангон + + + Ховд + + + Улан-Батор + + + Чоибалсан + + + Макао + + + Саипан + + + Мартиника + + + Нуакшот + + + Монтсеррат + + + Малта + + + Маврики + + + Малдив + + + Блантаир + + + Тихуана + + + Ермосило + + + Масатлан + + + Чиуауа + + + Баиа-де-Бандерас + + + Охинага + + + Монтерреи + + + Мехико + + + Матаморос + + + Мерида + + + Канкун + + + Куала-Лумпур + + + Кучинг + + + Мапуту + + + Виндхук + + + Нумеа + + + Ниамеи + + + Норфолк + + + Лагос + + + Манагуа + + + Амстердам + + + Осло + + + Катманду + + + Науру + + + Ниуе + + + Чатем + + + Окленд + + + Маскат + + + Панама + + + Лима + + + Таити + + + Маркизтәи ад-хақәа + + + ад-хақәа Гамбе + + + Порт-Морсби + + + Бугенвил + + + Манила + + + Карачи + + + Варшава + + + Микелон + + + Питкерн + + + Пуерто-Рико + + + Газа + + + Хеврон + + + Азортәи ад-хақәа + + + Мадеира + + + Лиссабон + + + Палау + + + Асунсон + + + Катар + + + Реиунон + + + Бухарест + + + Белград + + + Калининград + + + Москва + + + Волгоград + + + Саратов + + + Астрахан + + + Улиановск + + + Киров + + + Самара + + + Екатеринбург + + + Омск + + + Новосибирск + + + Барнаул + + + Томск + + + Новокузнецк + + + Красноиарск + + + Иркутск + + + Чита + + + Иакутск + + + Владивосток + + + Хандыга + + + ад-ха Сахалин + + + Уст-Нера + + + Магадан + + + Среднеколымск + + + Петропавловск-Камчаткатәи + + + Анадыр + + + Кигали + + + Ер-Риад + + + Гуадалканал + + + Мае + + + Хартум + + + Стокҳолм + + + Сингапур + + + Иԥшьоу Елена ладгьылбжьаха + + + Лиублиана + + + Лонгир + + + Братислава + + + Фритаун + + + Сан-Марино + + + Дакар + + + Могадишо + + + Парамарибо + + + Џуба + + + Сан-Томе + + + Салвадор + + + Лоуер-Принс-Куотер + + + Дамаск + + + Мбабане + + + Гранд-Терк + + + Нџамена + + + Кергелен + + + Ломе + + + Бангкок + + + Душанбе + + + Факаофо + + + Дили + + + Ашхабад + + + Тунис + + + Тонгатапу + + + Стамбул + + + Порт-оф-Спеин + + + Фунафути + + + Таибеи + + + Дар-ес-Салам + + + Ужҳород + + + Киев + + + Симферопол + + + Запороже + + + Кампала + + + ад-хақәа Мидуеи + + + Уеик + + + Адак + + + Ном + + + Џонстон + + + Анкориџ + + + Иакутат + + + Ситка + + + Џуно + + + Метлакатла + + + Лос-Анџелес + + + Боисе + + + Финикс + + + Денвер + + + Боила, Аҩадатәи Дакота + + + Ниу-Сеилем, Аҩадатәи Дакота + + + Агәҭа, Аҩадатәи Дакота + + + Чикаго + + + Меномини + + + Винсеннес + + + Питерсберг, Индиана + + + Телл-Сити + + + Нокс, Индиана + + + Уинамак + + + Маренго, Индиана + + + Индианаполис + + + Луисвилл + + + Вевеи, Индиана + + + Монтиселло, Кентукки + + + Детроит + + + Ниу-Иорк + + + Монтевидео + + + Самарканд + + + Ташкент + + + Ватикан + + + Сент-Винсент + + + Каракас + + + Тортола + + + Сент-Томас + + + Хошимин + + + Ефате + + + Уоллис + + + Апиа + + + Аден + + + Маиотта + + + Иоҳаннесбург + + + Лусака + + + Ҳараре + + + + Акри аамҭа + Акри астандартә аамҭа + Акри аԥхынтәи аамҭа + + + + + Афганистан + + + + + Агәҭантәи Африка + + + + + Мрагыларатәи Африка + + + + + Аладатәи Африка + + + + + Мраҭашәаратәи Африка + Мраҭашәаратәи Африка, астандартә аамҭа + Мраҭашәаратәи Африка, аԥхынтәи аамҭа + + + + + Алиаска + Алиаска, астандартә аамҭа + Алиаска, аԥхынтәи аамҭа + + + + + Алма-Ата аамҭа + Алма-Ата астандартә аамҭа + Алма-Ата аԥхынтәи аамҭа + + + + + Амазонка + Амазонка, астандартә аамҭа + Амазонка, аԥхынтәи аамҭа + + + + + Агәҭантәи Америка + Агәҭантәи Америка, астандартә аамҭа + Агәҭантәи Америка, аԥхынтәи аамҭа + + + + + Мрагыларатәи Америка + Мрагыларатәи Америка, астандартә аамҭа + Мрагыларатәи Америка, аԥхынтәи аамҭа + + + + + Ашьхатә аамҭа (Аҩадатәи Америка) + Астандартә ашьхатә аамҭа (Аҩадатәи Америка) + Аԥхынтәи ашьхатә аамҭа (Аҩадатәи Америка) + + + + + Аокеанҭынчтәи аамҭа + Аокеанҭынчтәи астандартә аамҭа + Аокеанҭынчтәи аԥхынтәи аамҭа + + + + + аамҭа Анадыр аҿы + Анадыр астандартә аамҭа + Анадыр аԥхынтәи аамҭа + + + + + Апиа + Апиа, астандартә аамҭа + Апиа, аԥхынтәи аамҭа + + + + + Актау аамҭа + Актау, астандартә аамҭа + Актау аԥхынтәи аамҭа + + + + + Актобе аамҭа + Актобе астандартә аамҭа + Актобе аԥхынтәи аамҭа + + + + + Саудтәи Арабсҭан + Саудтәи Арабсҭан, астандартә аамҭа + Саудтәи Арабсҭан, аԥхынтәи аамҭа + + + + + Аргентина + Аргентина, астандартә аамҭа + Аргентина, аԥхынтәи аамҭа + + + + + Мраҭашәаратәи Аргентина + Мраҭашәаратәи Аргентина, астандартә аамҭа + Мраҭашәаратәи Аргентина, аԥхынтәи аамҭа + + + + + Ермантәыла + Ермантәыла, астандартә аамҭа + Ермантәыла, аԥхынтәи аамҭа + + + + + Атлантикатәи аамҭа + Атлантикатәи астандартә аамҭа + Атлантикатәи аԥхынтәи аамҭа + + + + + Агәҭантәи Австралиа + Агәҭантәи Австралиа, астандартә аамҭа + Агәҭантәи Австралиа, аԥхынтәи аамҭа + + + + + Агәҭантәи Австралиа, мраҭашәаратәи аамҭа + Агәҭантәи Австралиа, мраҭашәаратәи астандартә аамҭа + Агәҭантәи Австралиа, мраҭашәаратәи аԥхынтәи аамҭа + + + + + Мрагыларатәи Австралиа + Мрагыларатәи Австралиа, астандартә аамҭа + Мрагыларатәи Австралиа, аԥхынтәи аамҭа + + + + + Мраҭашәаратәи Австралиа + Мраҭашәаратәи Австралиа, астандартә аамҭа + Мраҭашәаратәи Австралиа, аԥхынтәи аамҭа + + + + + Азербаиџьан + Азербаиџьан, астандартә аамҭа + Азербаиџьан, аԥхынтәи аамҭа + + + + + Азортәи ад-хақәа + Азортәи ад-хақәа, астандартә аамҭа + Азортәи ад-хақәа, аԥхынтәи аамҭа + + + + + Бангладеш + Бангладеш, астандартә аамҭа + Бангладеш, аԥхынтәи аамҭа + + + + + Бутан + + + + + Боливиа + + + + + Бразилиа + Бразилиа, астандартә аамҭа + Бразилиа, аԥхынтәи аамҭа + + + + + Брунеи-Даруссалам + + + + + Кабо-Верде + Кабо-Верде, астандартә аамҭа + Кабо-Верде, аԥхынтәи аамҭа + + + + + Кеиси + + + + + Чаморро + + + + + Чатем + Чатем, астандартә аамҭа + Чатем, аԥхынтәи аамҭа + + + + + Чили + Чили, астандартә аамҭа + Чили, аԥхынтәи аамҭа + + + + + Китаи + Китаи, астандартә аамҭа + Китаи, аԥхынтәи аамҭа + + + + + Чоибалсан + Чоибалсан, астандартә аамҭа + Чоибалсан, аԥхынтәи аамҭа + + + + + ад-ха Қьырса + + + + + Кокостәи ад-хақәа + + + + + Колумбиа + Колумбиа, астандартә аамҭа + Колумбиа, аԥхынтәи аамҭа + + + + + Кук идгьылбжьахақәа + Кук идгьылбжьахақәа, астандартә аамҭа + Кук идгьылбжьахақәа, полуаԥхынтәи аамҭа + + + + + Куба + Куба, астандартә аамҭа + Куба, аԥхынтәи аамҭа + + + + + Деивис + + + + + Диумон-д’Иурвил + + + + + Мрагыларатәи Тимор + + + + + ад-ха Пасхи + ад-ха Пасхи, астандартә аамҭа + ад-ха Пасхи, аԥхынтәи аамҭа + + + + + Еквадор + + + + + Агәҭантәи Европа + Агәҭантәи Европа, астандартә аамҭа + Агәҭантәи Европа, аԥхынтәи аамҭа + + + + + Мрагыларатәи Европа + Мрагыларатәи Европа, астандартә аамҭа + Мрагыларатәи Европа, аԥхынтәи аамҭа + + + + + Московатәи аамҭа + + + + + Мраҭашәаратәи Европа + Мраҭашәаратәи Европа, астандартә аамҭа + Мраҭашәаратәи Европа, аԥхынтәи аамҭа + + + + + Фолклендтәи ад-хақәа + Фолклендтәи ад-хақәа, астандартә аамҭа + Фолклендтәи ад-хақәа, аԥхынтәи аамҭа + + + + + Фиџи + Фиџи, астандартә аамҭа + Фиџи, аԥхынтәи аамҭа + + + + + Францызтәи Гвиана + + + + + Францызтәи Аладатәеи Антарктикатәи рҵакырадгьылқәа + + + + + Галапагостәи ад-хақәа + + + + + Гамбе + + + + + Қырҭтәыла + Қырҭтәыла, астандартә аамҭа + Қырҭтәыла, аԥхынтәи аамҭа + + + + + ад-хақәа Гилберта + + + + + Агринвич Ибжьаратәу Аамҭа + + + + + Мрагыларатәи Гренландиа + Мрагыларатәи Гренландиа, стандарное времиа + Мрагыларатәи Гренландиа, аԥхынтәи аамҭа + + + + + Мраҭашәаратәи Гренландиа + Мраҭашәаратәи Гренландиа, астандартә аамҭа + Мраҭашәаратәи Гренландиа, аԥхынтәи аамҭа + + + + + Гуам + + + + + Аџьамтә аӡыбжьахала + + + + + Гаиана + + + + + Ҳаваи-алеуттәи аамҭа + Ҳаваи-алеуттәи астандартә аамҭа + Ҳаваи-алеуттәи аԥхынтәи аамҭа + + + + + Ҳонконг + Ҳонконг, астандартә аамҭа + Ҳонконг, аԥхынтәи аамҭа + + + + + Ховд + Ховд, астандартә аамҭа + Ховд, аԥхынтәи аамҭа + + + + + Индиа + + + + + Индиатәи аокеан + + + + + Индокитаи + + + + + Агәҭантәи Индонезиа + + + + + Мрагыларатәи Индонезиа + + + + + Мраҭашәаратәи Индонезиа + + + + + Иран + Иран, астандартә аамҭа + Иран, аԥхынтәи аамҭа + + + + + Иркутск + Иркутск, астандартә аамҭа + Иркутск, аԥхынтәи аамҭа + + + + + Израиль + Израиль, астандартә аамҭа + Израиль, аԥхынтәи аамҭа + + + + + Иапониа + Иапониа, астандартә аамҭа + Иапониа, аԥхынтәи аамҭа + + + + + Петропавловск-Камчаткатәи + Петропавловск-Камчаткатәи, астандартә аамҭа + Петропавловск-Камчаткатәи, аԥхынтәи аамҭа + + + + + Мрагыларатәи Ҟазахсҭан + + + + + Мраҭашәаратәи Ҟазахсҭан + + + + + Кореиа + Кореиа, астандартә аамҭа + Кореиа, аԥхынтәи аамҭа + + + + + Косрае + + + + + Красноиарск + Красноиарск, астандартә аамҭа + Красноиарск, аԥхынтәи аамҭа + + + + + Киргизиа + + + + + Шри-Ланка + + + + + ад-хақәа Лаин + + + + + Лорд-Ҳау + Лорд-Ҳау, астандартә аамҭа + Лорд-Ҳау, аԥхынтәи аамҭа + + + + + Макао + Макао, астандартә аамҭа + Макао, аԥхынтәи аамҭа + + + + + Маккуори + + + + + Магадан + Магадан, астандартә аамҭа + Магадан, аԥхынтәи аамҭа + + + + + Малаизиа + + + + + Мальдив + + + + + Маркизтәи ад-хақәа + + + + + Маршаллтәи Адгьылбжьахақәа + + + + + Маврики + Маврики, астандартә аамҭа + Маврики, аԥхынтәи аамҭа + + + + + Моусон + + + + + Аҩадамра-Ҭашәаратәи амексикатә аамҭа + Аҩадамра-Ҭашәаратәи амексикатә астандартә аамҭа + Аҩадамра-Ҭашәаратәи амексикатә аԥхынтәи аамҭа + + + + + Аокеанҭынчтәи амексикатә аамҭа + Аокеанҭынчтәи амексикатә астандартә аамҭа + Аокеанҭынчтәи амексикатә аԥхынтәи аамҭа + + + + + Улан-Батор + Улан-Батор, астандартә аамҭа + Улан-Батор, аԥхынтәи аамҭа + + + + + Москва + Москва, астандартә аамҭа + Москва, аԥхынтәи аамҭа + + + + + Мианма + + + + + Науру + + + + + Непал + + + + + Каледониа ҿыц + Каледониа ҿыц, астандартә аамҭа + Каледониа ҿыц, аԥхынтәи аамҭа + + + + + Зеландиа ҿыц + Зеландиа ҿыц, астандартә аамҭа + Зеландиа ҿыц, аԥхынтәи аамҭа + + + + + Ниуфаундленд + Ниуфаундленд, астандартә аамҭа + Ниуфаундленд, аԥхынтәи аамҭа + + + + + Ниуе + + + + + Норфолк + Норфолк, астандартә аамҭа + Норфолк, аԥхынтәи аамҭа + + + + + Фернанду-ди-Норониа + Фернанду-ди-Норониа, астандартә аамҭа + Фернанду-ди-Норониа, аԥхынтәи аамҭа + + + + + Аҩадатәи Мариантәи ад-хақәа + + + + + Новосибирск + Новосибирск, астандартә аамҭа + Новосибирск, аԥхынтәи аамҭа + + + + + Омск + Омск, астандартә аамҭа + Омск, аԥхынтәи аамҭа + + + + + Пакистан + Пакистан, астандартә аамҭа + Пакистан, аԥхынтәи аамҭа + + + + + Палау + + + + + Папуа — Гвинеиа ҿыц + + + + + Парагваи + Парагваи, астандартә аамҭа + Парагваи, аԥхынтәи аамҭа + + + + + Перу + Перу, астандартә аамҭа + Перу, аԥхынтәи аамҭа + + + + + Филиппин + Филиппин, астандартә аамҭа + Филиппин, аԥхынтәи аамҭа + + + + + ад-хақәа Феникс + + + + + Сен-Пиери Микелони + Сен-Пиери Микелони, астандартә аамҭа + Сен-Пиери Микелони, аԥхынтәи аамҭа + + + + + Питкерн + + + + + Понпеи + + + + + Пхениан + + + + + Кызылорда* + Кызылорда, астандартә аамҭа* + Кызылорда, аԥхынтәи аамҭа* + + + + + Реиунон + + + + + Ротера + + + + + Сахалин + Сахалин, астандартә аамҭа + Сахалин, аԥхынтәи аамҭа + + + + + аамҭа Самараҿы + Самартәи астандартә аамҭа + Самартәи аԥхынтәи аамҭа + + + + + Самоа + Самоа, астандартә аамҭа + Самоа, аԥхынтәи аамҭа + + + + + Сеишелтәи адгьылбжьахақәа + + + + + Сингапур + + + + + Соломонтәи адгьылбжьахақәа + + + + + Аладатәи Георгиа + + + + + Суринам + + + + + Сиова + + + + + Таити + + + + + Таиван + Таиван, астандартә аамҭа + Таиван, аԥхынтәи аамҭа + + + + + Таџьықсҭан + + + + + Токелау + + + + + Тонга + Тонга, астандартә аамҭа + Тонга, аԥхынтәи аамҭа + + + + + Трук + + + + + Туркменистан + Туркменистан, астандартә аамҭа + Туркменистан, аԥхынтәи аамҭа + + + + + Тувалу + + + + + Уругваи + Уругваи, астандартә аамҭа + Уругваи, аԥхынтәи аамҭа + + + + + Узбеқьисҭан + Узбеқьисҭан, астандартә аамҭа + Узбеқьисҭан, аԥхынтәи аамҭа + + + + + Вануату + Вануату, астандартә аамҭа + Вануату, аԥхынтәи аамҭа + + + + + Венесуела + + + + + Владивосток + Владивосток, астандартә аамҭа + Владивосток, аԥхынтәи аамҭа + + + + + Волгоград + Волгоград, астандартә аамҭа + Волгоград, аԥхынтәи аамҭа + + + + + Амрагылара + + + + + Уеик + + + + + Уоллиси Футунеи + + + + + Иакутск + Иакутск, астандартә аамҭа + Иакутск, аԥхынтәи аамҭа + + + + + Екатеринбург + Екатеринбург, астандартә аамҭа + Екатеринбург, аԥхынтәи аамҭа + + + + + Иукон + + + + + + latn + + latn + + + , +   + + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0 % + + + + + + + #,##0.00 ¤ + + + #,##0.00 ¤ + #,##0.00 + + + + + + бермудтәи адоллар + бермудтәи адоллар + + + евро + евро + + + + + + ¥ + + + PHP + + + L + + + + + + леоне + леоне + + + ฿ + + + NT$ + + + + + + $ + + + Еилкаам Авалиута + (еилкаам авалиута) + + + + ≈{0} + + + {0} мшы + + + + + + {0}/{1} + + + {0}⋅{1} + + + + + {0}/{1} + + + {0}⋅{1} + + + + + + {0}-и {1}-и + {0}-и {1}-и + + + {0} ма {1} + {0} ма {1} + + + {0}, {1} + {0}, {1} + {0} ма {1} + {0} ма {1} + + + {0}, {1} + {0}, {1} + {0} ма {1} + {0} ма {1} + + + {0}, {1} + {0}, {1} + {0}, {1} + {0}, {1} + + + {0}, {1} + {0}, {1} + {0}-и {1}-и + {0}-и {1}-и + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + + + ааи:а + мап:м + + + diff --git a/make/data/cldr/common/main/ab_GE.xml b/make/data/cldr/common/main/ab_GE.xml new file mode 100644 index 00000000000..60180381674 --- /dev/null +++ b/make/data/cldr/common/main/ab_GE.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/af.xml b/make/data/cldr/common/main/af.xml index 5cd23719d22..b0b8a1ef44a 100644 --- a/make/data/cldr/common/main/af.xml +++ b/make/data/cldr/common/main/af.xml @@ -1,6 +1,6 @@ - + + + + + + + + aragonés + arabe + arabe standard moderno + bengalí + alemán + alemán austriaco + alemán standard suizo + anglés + anglés australiano + anglés canadiense + anglés britanico + anglés (RU) + anglés americano + anglés (EUA) + espanyol + espanyol latino-americano + espanyol europeu + espanyol mexicano + francés + francés canadiense + francés suizo + hindi + indonesio + italiano + chaponés + coreano + neerlandés + flamenco + polaco + portugués + portugués brasilenyo + portugués europeu + ruso + tai + turco + idioma desconoixiu + chino + chino mandarín + chino simplificau + chino mandarín (simplificau) + chino tradicional + chino mandarín (tradicional) + + + + + + + + + + + + + + + + Mundo + Africa + America d’o Norte + Sudamerica + Oceanía + Africa occidental + America Central + Africa oriental + Africa septentrional + Africa central + Africa meridional + America + Norteamerica + Caribe + Asia oriental + Asia meridional + Asia sudoriental + Europa meridional + Australasia + Melanesia + Rechión d’a Micronesia + Polinesia + Asia + Asia central + Asia occidental + Europa + Europa oriental + Europa septentrional + Europa occidental + Africa subsahariana + Latino-america + Isla Ascensión + Andorra + Emiratos Arabes Unius + Afganistán + Antigua y Barbuda + Anguilla + Albania + Armenia + Angola + Antartida + Archentina + Samoa Americana + Austria + Australia + Aruba + Islas Åland + Azerbaichán + Bosnia y Herzegovina + Barbados + Bangladesh + Belchica + Burkina Faso + Bulgaria + Bahrain + Burundi + Benín + St. Barthélemy + Bermuda + Brunei + Bolivia + Caribe neerlandés + Brasil + Bahamas + Bhután + Isla Bouvet + Botswana + Belarrusia + Belize + Canadá + Islas Cocos + Republica Democratica d’o Congo + Congo Kinshasa + Republica Centro-africana + Republica d’o Congo + Congo Brazzaville + Suiza + Côte d’Ivoire + Costa de Vori + Islas Cook + Chile + Camerún + ¨China + Colombia + Isla Clipperton + Costa Rica + Cuba + Cabo Verde + Curaçao + Isla Chirstmas + Chipre + Chequia + Republica checa + Alemanya + Diego García + Chibuti + Dinamarca + Dominica + Republica Dominicana + Alcheria + Ceuta y Melilla + Ecuador + Estonia + Echipto + Sahara occidental + Eritrea + Espanya + Ethiopia + Unión Europea + Eurozona + Finlandia + Fichi + Islas Malvinas + Islas Malvinas (Islas Falkland) + Micronesia + Islas Feroe + Francia + Gabón + Reino Uniu + RU + Grenada + Cheorchia + Guayana francesa + Guernsey + Ghana + Chibraltar + Gronlandia + Gambia + Guinea + Guadeloupe + Guinea equatorial + Grecia + Islas Cheorchia d’o Sud y Sandwich d’o Sud + Guatemala + Guam + Guinea-Bissau + Guyana + Hong Kong, RAS China + Hong Kong + Islas Heard y McDonald + Honduras + Croacia + Haití + Hongría + Islas Canarias + Indonesia + Irlanda + Israel + Isla de Man + India + Territorio Britanico de l’Oceano Indico + Iraq + Irán + Islandia + Italia + Jersey + Chamaica + Chordania + Chapón + Kenya + Kirguistán + Cambocha + Kiribati + Comoros + Sant Cristofo y Nieus + Corea d’o Norte + Corea d’o Sud + Kuwait + Islas Caimán + Cazaquistán + Laos + Libano + Santa Lucía + Liechtenstein + Sri Lanka + Liberia + Lesotho + Lituania + Luxemburgo + Letonia + Libia + Marruecos + Monaco + Moldavia + Montenegro + Sant Martín + Madagascar + Islas Marshall + Macedonia d’o norte + Mali + Myanmar (Burma) + Mongolia + Macau, RAS China + Macau + Islas Marianas d’o Norte + Martinica + Mauritania + Montserrat + Malta + Mauricio + Maldivas + Malawi + Mexico + Malasia + Mozambique + Namibia + Nueva Caledonia + Nicher + Isla Norfolk + Nicheria + Nicaragua + Países Baixos + Noruega + Nepal + Nauru + Niue + Nueva Zelanda + Omán + Panamá + Perú + Polinesa Francesa + Papúa Nueva Guinea + Filipinas + Paquistán + Polonia + Saint-Pierre y Miquelon + Islas Pitcairn + Puerto Rico + Territorios Palestinos + Palestina + Portugal + Palau + Paraguay + Qatar + Territorios aleixaus d’Oceanía + Isla d’a Reunión + Rumanía + Serbia + Rusia + Ruanda + Arabia Saudí + Islas Salomón + Seychelles + Sudán + Suecia + Singapur + Santa Helena + Eslovenia + Svalbard y Jan Mayen + Eslovaquia + Sierra Leona + San Marino + Senegal + Somalia + Surinam + Sudán d’o Sud + Sant Tomé y Principe + El Salvador + Sint Maarten + Siria + Eswatini + Swazilandia + Tristán da Cunha + Islas Turcas y Caicos + Chad + Territorios australs franceses + Togo + Tailandia + Tayikistán + Tokelau + Timor-Leste + Timor Oriental + Turkmenistán + Tunicia + Tonga + Turquía + Trinidad y Tobago + Tuvalu + Taiwán + Tanzania + Ucrainia + Uganda + Islas perifericas d’os EUA + Nacions Unidas + Estaus Unius + EUA + Uruguay + Uzbequistán + Ciudat d’o Vaticano + Sant Vicent y las Granadinas + Venezuela + Islas Virchens Britanicas + Islas Virchens Norte-americanas + Vietnam + Vanuatu + Wallis y Fortuna + Samoa + Pseudoaccentos + Pseudobidi + Kosovo + Yemen + Mayotte + Republica de Sudafrica + Zambia + Zimbabue + Rechión desconoixida + + + calendario gregoriano + calendario ISO-8601 + ordenación standard + dichitos occidentals + + + metrico + RU + EUA + + + Idioma: {0} + Escritura: {0} + Rechión: {0} + + + + [a á b c d e é f g h i í j k l m n o ó p q r s t u ú ü v w x y z] + [· à â ä ç è ê ë ì î ï ñ ò ô ö ù û] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ¡ ? ¿ . … ' ‘ ’ " “ ” « » ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + « + » + + + + + + + + + + EEEE, d MMMM 'de' y G + GyMMMMEEEEd + + + + + d MMMM 'de' y G + GyMMMMd + + + + + d MMM 'de' y G + GyMMMd + + + + + dd-MM-y GGGGG + GGGGGyMMdd + + + + + + + {1} 'a' 'las' {0} + + + + + {1} 'a' 'las' {0} + + + + + {1}, {0} + + + + + {1} {0} + + + + E, d + y G + MMM y G + d MMM y G + E, d MMM y G + d/M + E, d/M + d MMM + E, d MMM + d 'de' MMMM + y G + y G + M/y GGGGG + d/M/y GGGGG + E, d/M/y GGGGG + MMM y G + d MMM y G + E, d MMM y G + MMMM y G + QQQ y G + QQQQ y G + + + + y G – y G + y – y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + d/M/y – d/M/y GGGGG + d/M/y GGGGG – d/M/y GGGGG + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + + + E, d/M/y – E, d/M/y GGGGG + E, d/M/y GGGGG – E, d/M/y GGGGG + E, d/M/y – E, d/M/y GGGGG + E, d/M/y – E, d/M/y GGGGG + + + LLL y G – LLL y G + LLL–LLL y G + LLL y – LLL y G + + + d–d MMM y G + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + M–M + + + d/M – d/M + d/M – d/M + + + E, d/M – E, d/M + E, d/M – E, d/M + + + LLL–LLL + + + d–d MMM + d MMM – d MMM + + + E, d MMM – E, d MMM + E, d MMM – E, d MMM + + + y–y G + + + M/y – M/y GGGGG + M/y – M/y GGGGG + + + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + + + E, d/M/y – E, d/M/y GGGGG + E, d/M/y – E, d/M/y GGGGG + E, d/M/y – E, d/M/y GGGGG + + + LLL–LLL y G + LLL y – LLL y G + + + d–d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + E, d MMM y – E, d MMM y G + + + LLLL – LLLL y G + LLLL y – LLLL y G + + + + + + + + + chi. + feb. + mar. + abr. + may. + chn. + chl. + ago. + set. + oct. + nov. + avi. + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + de chinero + de febrero + de marzo + d’abril + de mayo + de chunyo + de chuliol + d’agosto + de setiembre + d’octubre + de noviembre + d’aviento + + + + + chi. + feb. + mar. + abr. + may. + chn. + chl. + ago. + set. + oct. + nov. + avi. + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + chinero + febrero + marzo + abril + mayo + chunyo + chuliol + agosto + setiembre + octubre + noviembre + aviento + + + + + + + dom + lun + mar + mie + chu + vie + sab + + + D + L + Ma + Mi + Ch + V + S + + + dom + lun + mar + mie + chu + vie + sab + + + dominche + luns + martz + miercres + chueves + viernes + sabado + + + + + dom + lun + mar + mie + chu + vie + sab + + + D + L + Ma + Mi + Ch + V + S + + + dom + lun + mar + mie + chu + vie + sab + + + dominche + luns + martz + miercres + chueves + viernes + sabado + + + + + + + 1T + 2T + 3T + 4T + + + 1 + 2 + 3 + 4 + + + 1r trimestre + 2o trimestre + 3r trimestre + 4o trimestre + + + + + 1T + 2T + 3T + 4T + + + 1r trimestre + 2o trimestre + 3r trimestre + 4o trimestre + + + + + + + a.m. + p.m. + + + a.m. + p.m. + + + a.m. + p.m. + + + + + a.m. + p.m. + + + a.m. + p.m. + + + a.m. + p.m. + + + + + + a.C. + AEC + d.C. + EC + + + a.C. + AEC + d.C. + EC + + + + + + EEEE, d MMMM 'de' y + yMMMMEEEEd + + + + + d MMMM 'de' y + yMMMMd + + + + + d MMM y + yMMMd + + + + + d/M/yy + yyMd + + + + + + + H:mm:ss zzzz + Hmmsszzzz + + + + + H:mm:ss z + Hmmssz + + + + + H:mm:ss + Hmmss + + + + + H:mm + Hmm + + + + + + + {1} 'a' 'las' {0} + + + + + {1} 'a' 'las' {0} + + + + + {1}, {0} + + + + + {1} {0} + + + + d + ccc + E d + y G + MMM y G + d MMM y G + E, d MMM y G + d/M + E, d/M + d MMM + E, d MMM + d MMMM + 'semana' W 'de' MMMM + 'semana' W 'de' MMMM + y + M/y + d/M/y + E, d/M/y + y MMM + d MMM y + E, d MMM y + MMMM y + QQQ 'de' y + QQQQ y + 'semana' w 'de' Y + 'semana' w 'de' Y + + + + y G – y G + y–y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + d/M/y – d/M/y GGGGG + d/M/y GGGGG – d/M/y GGGGG + d/M/y – d/M/y GGGGG + M/d/y – M/d/y GGGGG + + + E, d/M/y – E, d/M/y GGGGG + E, dd/MM/y GGGGG – E, dd/MM/y GGGGG + E, dd/MM/y GGGGG – E, dd/MM/y GGGGG + E, dd/MM/y GGGGG – E, dd/MM/y GGGGG + + + LLL y G – LLL y G + LLL – LLL y G + LLL y – LLL y G + + + d–d LLL y G + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + h a – h a + h – h a + + + HH – HH + + + h:mm a – h:mm a + h:mm – h:mm a + h:mm – h:mm a + + + HH:mm – HH:mm + HH:mm – HH:mm + + + h:mm a – h:mm a v + h:mm – h:mm a v + h:mm – h:mm a v + + + HH:mm – HH:mm v + HH:mm – HH:mm v + + + h a – h a v + h – h a v + + + HH – HH v + + + M–M + + + d/M – d/M + d/M – d/M + + + E, d/M – E, d/M + E, d/M – E, d/M + + + LLL–LLL + + + d–d MMM + d MMM – d MMM + + + E, d MMM – E, d MMM + E, d MMM – E, d MMM + + + y–y + + + M/y – M/y + M/y – M/y + + + d/M/y – d/M/y + d/M/y – d/M/y + d/M/y – d/M/y + + + E, d/M/y – E, d/M/y + E, d/M/y + E, d/M/Y – E, d/M/Y + + + LLL–LLL y + LLL y – LLL y + + + d–d MMM y + d MMM – d MMM y + d MMM y – d MMM y + + + E, d MMM y – E, d MMM y + E, d MMM – E, d MMM y + E, d MMM y – E, d MMM y + + + LLLL–LLLL y + LLLL y – LLLL y + + + + + + + + era + + + anyo + l’anyo pasau + estianyo + l’anyo que viene + + + a. + l’anyo pasau + estianyo + l’anyo que viene + + + a. + l’anyo pasau + estianyo + l’anyo que viene + + + trimestre + + + trim. + + + trim. + + + mes + lo mes pasau + este mes + lo mes que viene + + + m. + lo mes pasau + este mes + lo mes que viene + + + m. + lo mes pasau + este mes + lo mes que viene + + + semana + la semana pasada + esta semana + la semana que viene + la semana de {0} + + + s. + la semana pasada + esta semana + la semana que viene + la semana de {0} + + + s. + la semana pasada + esta semana + la semana que viene + la semana de ´{0} + + + día + ahiere + hue + manyana + + + día + ahiere + hue + manyana + + + día + ahiere + hue + manyana + + + día d’a semana + + + a.m./p.m. + + + hora + + + h. + + + h. + + + minuto + + + min. + + + min. + + + segundo + + + s. + + + s. + + + zona horaria + + + + GMT{0} + Hora de {0} + Hora de verano de {0} + Hora standard de {0} + + + tiempo universal coordenado + + + + Ciudat desconoixida + + + Macau + + + + hora central d’America d’o Norte + hora standard central d’America d’o Norte + hora de verano central d’America d’o Norte + + + + + hora oriental d’America d’o Norte + hora standard oriental d’America d’o Norte + hora de verano oriental d’America d’o Norte + + + + + hora de montanya d’America d’o Norte + hora standard de montanya d’America d’o Norte + hora de verano de montanya d’America d’o Norte + + + + + hora d’o Pacifico d’America d’o Norte + hora standard d’o Pacifico d’America d’o Norte + hora de verano d’o Pacifico d’America d’o Norte + + + + + hora de l’Atlantico + hora standard de l’Atlantico + hora de verano de l’Atlantico + + + + + hora d’o centro d’Europa + hora standard d’o centro d’Europa + hora de verano d’o centro d’Europa + + + + + hora de l’este d’Europa + hora standard de l’este d’Europa + hora de verano de l’este d’Europa + + + + + hora de l’ueste d’Europa + hora standard de l’ueste d’Europa + hora de verano de l’ueste d’Europa + + + + + hora d’o meridiano de Greenwich + + + + + + + , + . + % + + + - + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + #,##0.00 ¤ + + + ¤#,##0.00;(¤#,##0.00) + + + {0} {1} + {0} {1} + + + + real brasilenyo + real brasilenyo + reals brasilenyos + R$ + R$ + + + yuan chino + yuan chino + yuans chinos + CN¥ + ¥ + + + euro + euro + euros + + r + + + libra britanica + libra britanica + libras britanicas + £ + £ + + + rupia india + rupia india + rupias indias + + + + + yen chaponés + yen chaponés + yens chaponeses + ¥ + ¥ + + + ringgit de Malasia + ringgit de Malasia + ringgit de Malasia + + + piso filipino + piso filipino + pisos filipinos + + + rublo ruso + rublo ruso + rublos rusos + RUB + + + + dólar de Singapur + dolar de Singapur + dolars de Singapur + + + baht tailandés + baht tailandés + baht tailandés + + + dolar d’os Estaus Unius + dolar d’os Estaus Unius + dolars d’os Estaus Unius + US$ + $ + + + moneda desconoixida + (moneda desconoixida) + (moneda desconoixida) + + + + {0} día + {0} días + Pilla lo {0}o a la dreita + + + + + + {0} per {1} + + + {0}⋅{1} + + + revolución + {0} revolución + {0} revolucions + + + radians + {0} radián + {0} radians + + + graus + {0} grau + {0} graus + + + minutos d’arco + {0} minutos d’arco + {0} minutos d’arco + + + segundos d’arco + {0} segundo d’arco + {0} segundos d’arco + + + quiratz + {0} quirat + {0} quiratz + + + per cient + {0} per cient + {0} per cient + + + per mil + {0} per mil + {0} per mil + + + per miriada + {0} per miriada + {0} per miriada + + + joules + {0} joule + {0} joules + + + centimetros + {0} centimetro + {0} centimetros + {0} per centimetro + + + tonas metricas + {0} tona metrica + {0} tonas metricas + + + kilogramos + {0} kilogramo + {0} kilogramos + {0} per kilogramo + + + gramos + {0} gramo + {0} gramos + {0} per gramo + + + tonas + {0} tona + {0} tonas + + + quiratz + {0} quirat + {0} quiratz + + + masas d’a Tierra + {0} masa d’a Tierra + {0} masas d’a Tierra + + + masas solars + {0} masa solar + {0} masas solars + + + watts + {0} watt + {0} watts + + + caballos de vapor + {0} caballo de vapor + {0} caballos de vapor + + + graus Celsius + {0} grau Celsius + {0} graus Celsius + + + graus Farenheit + {0} grau Farenheit + {0} graus Farenheit + + + punto cardinal + {0} este + {0} norte + {0} sud + {0} ueste + + + + + {0} rev + {0} rev + + + {0} rad + {0} rad + + + º + {0}° + {0}° + + + {0} arcmin + {0} arcmin + + + {0} arcsec + {0} arcsec + + + {0} kt + {0} kt + + + {0}% + {0}% + + + {0}‰ + {0}‰ + + + {0}‱ + {0}‱ + + + J + {0} J + {0} J + + + cm + {0} cm + {0} cm + {0}/cm + + + tm + {0} tm + {0} tm + + + {0} kg + {0} kg + + + g + {0} g + {0} g + + + {0} tn + {0} tn + + + {0} M⊕ + {0} M⊕ + + + {0} M☉ + {0} M☉ + + + W + {0} W + {0} W + + + {0} hp + {0} hp + + + {0}°C + {0}°C + + + punto + {0}U + + + + + {0}/{1} + + + {0}⋅{1} + + + % + {0}% + {0}% + + + cm + {0} cm + {0} cm + + + kg + {0} kg + {0} kg + + + g + {0} g + {0} g + + + °C + {0}°C + {0}°C + + + punto + {0}N + {0}S + {0}U + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0}, {1} + {0}, {1} + {0} y {1} + {0} y {1} + + + {0}, {1} + {0}, {1} + {0} u {1} + {0} u {1} + + + {0}, {1} + {0}, {1} + {0} u {1} + {0} u {1} + + + {0}, {1} + {0}, {1} + {0} u {1} + {0} u {1} + + + {0}, {1} + {0}, {1} + {0} y {1} + {0} y {1} + + + {0}, {1} + {0}, {1} + {0} y {1} + {0} y {1} + + + {0}, {1} + {0}, {1} + {0} y {1} + {0} y {1} + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + {0}, {1} + {0}, {1} + {0} y {1} + {0} y {1} + + + + + sí:s + no:n + + + diff --git a/make/data/cldr/common/main/an_ES.xml b/make/data/cldr/common/main/an_ES.xml new file mode 100644 index 00000000000..03e10f9bda6 --- /dev/null +++ b/make/data/cldr/common/main/an_ES.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ann.xml b/make/data/cldr/common/main/ann.xml index 67b4f4f9828..8fd5510aea7 100644 --- a/make/data/cldr/common/main/ann.xml +++ b/make/data/cldr/common/main/ann.xml @@ -1,6 +1,6 @@ - + + + + + + + + العامية + + + + + right-to-left + + + + [\u064B \u064C \u064D \u064E \u064F \u0650 \u0651 \u0652 \u0670 ء آ أ ؤ إ ئ ا ب ة ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ى ي] + [ـ\u200C\u200D\u200E\u200F پ چ ژ ڜ ڢ ڤ ڥ ٯ ڧ ڨ ک گ ی] + [ا ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي] + [\u061C\u200E \- ‑ , ٫ ٬ . % ٪ ‰ ؉ + 0٠ 1١ 2٢ 3٣ 4٤ 5٥ 6٦ 7٧ 8٨ 9٩] + [\- ‐ ‑ – — ، ؛ \: ! ؟ . … ' " « » ( ) \[ \] \&] + + + + + + + + كانون التاني + شباط + أذار + نيسان + أيار + حزيران + تموز + آب + أيلول + تشرين الأول + تشرين التاني + كانون الأول + + + + + + + الأحد + التنين + التلاتا + الأربعا + الخميس + الجمعة + السبت + + + + + + + صباحا + مساء + + + + + + + + + + د.أ.‏ + + + + diff --git a/make/data/cldr/common/main/apc_SY.xml b/make/data/cldr/common/main/apc_SY.xml new file mode 100644 index 00000000000..b6113b39be2 --- /dev/null +++ b/make/data/cldr/common/main/apc_SY.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ar.xml b/make/data/cldr/common/main/ar.xml index e4be099c4de..c151869ea47 100644 --- a/make/data/cldr/common/main/ar.xml +++ b/make/data/cldr/common/main/ar.xml @@ -1,6 +1,6 @@ - {given-monogram-allCaps}.{given2-monogram-allCaps}.{surname-monogram-allCaps} {given-informal-monogram-allCaps}.{surname-monogram-allCaps} - {prefix} {given} {given2-initial} {surname} + {title} {given} {given2-initial} {surname} {given-informal} {surname} - {prefix} {surname} + {title} {surname} {given-informal} @@ -13221,17 +14411,20 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {given-monogram-allCaps}.{surname-monogram-allCaps} - {prefix} {given-initial} {surname} + {title} {given-initial} {surname} {given-informal-initial}. {surname} - {prefix} {surname} + {title} {surname} {given-informal} + + {surname-monogram-allCaps} + {given-monogram-allCaps}.{surname-monogram-allCaps} @@ -13242,7 +14435,7 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {surname} {given-informal} - {prefix} {surname} + {title} {surname} {given-informal} @@ -13260,34 +14453,34 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {surname} {given-informal} - {prefix} {surname} + {title} {surname} {given-informal} - {surname-monogram-allCaps}. + {surname-monogram-allCaps} - {given-informal-monogram-allCaps}. + {given-informal-monogram-allCaps} - {surname}، {given-initial} + {surname}، {given-initial} {given2-initial} {surname} {given-initial} - {prefix} {surname} + {title} {surname} {given-informal} - {surname-monogram-allCaps}. + {surname-monogram-allCaps} - {given-informal-monogram-allCaps}. + {given-informal-monogram-allCaps} {surname-prefix} {surname-core}، {given} {given2} @@ -13307,27 +14500,51 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {surname}، {given-informal} - + منير - + سميرة النجار - + كمال مجدي العامر - - الدكتور - علاء الدين - ربيع - رامي كامل + + السيد + أحمد رامي + وسام + نجيب محفوظ أبو - شقرا + الأغا علم الدين - ماجستير، دكتوراه + الابن + النائب + + + سندباد + + + كاثرين + مولر + + + زيزينيا + هاميش + ستوبر + + + الدكتور + عايدة كورنيليا + نيللي + سيزار مارتن + فون + برول + غونزاليس دومينغو + الإبن + طبيب وجراح diff --git a/make/data/cldr/common/main/ar_001.xml b/make/data/cldr/common/main/ar_001.xml index ace8e36d5d3..c388fbdd243 100644 --- a/make/data/cldr/common/main/ar_001.xml +++ b/make/data/cldr/common/main/ar_001.xml @@ -1,6 +1,6 @@ - + + + + + + + + Mapudungun + + + + + left-to-right + top-to-bottom + + + + [a {ch} d e f g i k l ḻ {ll} m n ñ ṉ {ng} o p r s {sh} t ṯ {tr} u ü w y] + [b c h j q x z] + [A {CH} D E F G I K L Ḻ {LL} M N Ñ Ṉ {NG} O P R S {SH} T Ṯ {TR} U Ü W Y] + + diff --git a/make/data/cldr/common/main/arn_CL.xml b/make/data/cldr/common/main/arn_CL.xml new file mode 100644 index 00000000000..105e0609de8 --- /dev/null +++ b/make/data/cldr/common/main/arn_CL.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/as.xml b/make/data/cldr/common/main/as.xml index f3ac4afd749..1158c7fb2e3 100644 --- a/make/data/cldr/common/main/as.xml +++ b/make/data/cldr/common/main/as.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + دۆنیا + + + دیل: {0} + یازی: {0} + بؤلگه: {0} + + + + + right-to-left + top-to-bottom + + + + [آ ؤ ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن ه و ۆ ۇ ی ؽ] + [\u200C\u200D\u200E\u200F \u064E \u064F \u0650 \u0652 إ ك ڭ ى ي] + [آ ا ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش ص ض ط ظ ع غ ف ق ک گ ل م ن ه و ی] + [\- ‐ ‑ ، ٫ ٬ ؛ \: ! ؟ . … ‹ › « » ( ) \[ \] * / \\] + {0}… + …{0} + {0}…{1} + {0} … + … {0} + {0} … {1} + ؟ + + + « + » + + + + + arabext + + arabext + + + : + + + diff --git a/make/data/cldr/common/main/az_Arab_IQ.xml b/make/data/cldr/common/main/az_Arab_IQ.xml new file mode 100644 index 00000000000..27d806cf2a0 --- /dev/null +++ b/make/data/cldr/common/main/az_Arab_IQ.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + + + برازیل + چین + جرمنی + پرانس + برتانیا + هندستان + ایتالیا + جاپان + پاکستان + روس + امریکی هئوارێن ملک + نگیشّتگێن دمگ + + + بُدّایی سالدر + چینی سالدر + کپتی سالدر + دانگی سالدر + ایتیوپیایی سالدر + ایتیوپیایی آمیت آلم سالدر + گرێگۆری سالدر + ابرانی سالدر + هندی کئومی سالدر + اسلامی سالدر + اسلامی شهری سالدر + اسلامی سئوودی اربی سالدر + اسلامی نجومی سالدر + اسلامی ام الکراهی سالدر + سالدر ISO-8601 + جاپانی سالدر + پارسی سالدر + مینگۆ چینی سالدر + زرّئے گیشّتگێن کالب + گیشّتگێن ترتیب + اربی-هندی نمبر + روسی نمبر + دێوناگری نمبر + مگربی نمبر + + + میتَری + برتانی + امریکی + + + زبان: {0} + سیاهگ: {0} + دمگ: {0} + + + + + right-to-left + top-to-bottom + + + + [\u064E \u064F \u0650 \u0651 \u0652 آ ا ئ ب پ ت ٹ ج چ د ڈ ر ڑ ز ژ س ش ک گ ل م ن و ۆ ه ی ێ ے] + [\u200C\u200D \u064B \u0654 ء أ ؤ إ ة ث ح خ ذ ص ض ط ظ ع غ ف ق ں ھ ہ] + [آ ا {ای} {اێ} {ائی} ب پ ت ٹ ج چ د ڈ ر ڑ ز ژ س ش ف ک گ ل م ن و ه ی] + [، ؛ \: ! ؟ . ' ‹ › " « »] + + + + + + + + جن + پر + مار + اپر + مئیی + جون + جۆل + اگست + ستم + اکت + نئوم + دسم + + + جنوری + پروری + مارچ + اپرێل + مئیی + جون + جۆلایی + اگست + ستمبر + اکتوبر + نئومبر + دسمبر + + + + + + + یک + دو + سئے + چار + پنچ + جمه + شم + + + یکشمبه + دوشمبه + سئیشمبه + چارشمبه + پنچشمبه + جمه + شمبه + + + + + + + 1/4 + 2/4 + 3/4 + 4/4 + + + 1 + 2 + 3 + 4 + + + ائوَلی چارِک + دومی چارِک + سئیمی چارِک + چارُمی چارِک + + + + + 1/4 + 2/4 + 3/4 + 4/4 + + + 1 + 2 + 3 + 4 + + + ائوَلی چارِک + دومی چارِک + سئیمی چارِک + چارُمی چارِک + + + + + + + EEEE, d MMMM, y + + + + + d MMMM, y + + + + + d MMM, y + + + + + d/M/yy + + + + + + + hh:mm:ss a zzzz + + + + + hh:mm:ss a zzz + + + + + hh:mm:ss a + + + + + hh:mm a + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + + + + + اَلاسکائے ساهت + اَلاسکائے گیشّتگێن ساهت + اَلاسکائے گرماگی ساهت + + + + + امازۆنئے ساهت + امازۆنئے گیشّتگێن ساهت + امازۆنئے گرماگی ساهت + + + + + نیامی امریکائے ساهت + نیامی امریکائے گیشّتگێن ساهت + نیامی امریکائے گرماگی ساهت + + + + + رۆدراتکی امریکائے ساهت + رۆدراتکی امریکائے گیشّتگێن ساهت + رۆدراتکی امریکائے گرماگی ساهت + + + + + کۆهستگێن امریکائے ساهت + کۆهستگێن امریکائے گیشّتگێن ساهت + کۆهستگێن امریکائے گرماگی ساهت + + + + + آرامزِری امریکائے ساهت + آرامزِری امریکائے گیشّتگێن ساهت + آرامزِری امریکائے گرماگی ساهت + + + + + ارجنتینائے ساهت + ارجنتینائے گیشّتگێن ساهت + ارجنتینائے گرماگی ساهت + + + + + رۆنندی ارجنتینائے ساهت + رۆنندی ارجنتینائے گیشّتگێن ساهت + رۆنندی ارجنتینائے گرماگی ساهت + + + + + نیامی اُسترالیائے ساهت + نیامی اُسترالیائے گیشّتگێن ساهت + نیامی اُسترالیائے گرماگی ساهت + + + + + نیام‌رۆنندی اُسترالیائے ساهت + نیام‌رۆنندی اُسترالیائے گیشّتگێن ساهت + نیام‌رۆنندی اُسترالیائے گرماگی ساهت + + + + + رۆدراتکی اُسترالیائے ساهت + رۆدراتکی اُسترالیائے گیشّتگێن ساهت + رۆدراتکی اُسترالیائے گرماگی ساهت + + + + + رۆنندی اُسترالیائے ساهت + رۆنندی اُسترالیائے گیشّتگێن ساهت + رۆنندی اُسترالیائے گرماگی ساهت + + + + + برازیلئے ساهت + برازیلئے گیشّتگێن ساهت + برازیلئے گرماگی ساهت + + + + + نیامی یورپئے ساهت + نیامی یورپئے گیشّتگێن ساهت + نیامی یورپئے گرماگی ساهت + + + + + رۆدراتکی یورپئے ساهت + رۆدراتکی یورپئے گیشّتگێن ساهت + رۆدراتکی یورپئے گرماگی ساهت + + + + + دێمتری رۆدراتکی یورپئے گیشّتگێن ساهت + + + + + رۆنندی یورپئے ساهت + رۆنندی یورپئے گیشّتگێن ساهت + رۆنندی یورپئے گرماگی ساهت + + + + + هئواییئے ساهت + هئواییئے گیشّتگێن ساهت + هئواییئے گرماگی ساهت + + + + + نیامی اندۆنیزیائے گیشّتگێن ساهت + + + + + رۆدراتکی اندۆنیزیائے گیشّتگێن ساهت + + + + + رۆنندی اندۆنیزیائے گیشّتگێن ساهت + + + + + ایرکوتسکئے ساهت + ایرکوتسکئے گیشّتگێن ساهت + ایرکوتسکئے گرماگی ساهت + + + + + رۆدراتکی کازکستانئے گیشّتگێن ساهت + + + + + رۆنندی کازکستانئے گیشّتگێن ساهت + + + + + کرانسنُیارسکئے ساهت + کرانسنُیارسکئے گیشّتگێن ساهت + کرانسنُیارسکئے گرماگی ساهت + + + + + لۆرڈ هئو اُسترالیائے ساهت + لۆرڈ هئو اُسترالیائے گیشّتگێن ساهت + لۆرڈ هئو اُسترالیائے گرماگی ساهت + + + + + ماکواریئے گیشّتگێن ساهت + + + + + مَگَدَنئے ساهت + مَگَدَنئے گیشّتگێن ساهت + مَگَدَنئے گرماگی ساهت + + + + + شمالی مِکسیکۆئے ساهت + شمالی مِکسیکۆئے گیشّتگێن ساهت + شمالی مِکسیکۆئے گرماگی ساهت + + + + + آرامزِری مِکسیکۆئے ساهت + آرامزِری مِکسیکۆئے گیشّتگێن ساهت + آرامزِری مِکسیکۆئے گرماگی ساهت + + + + + ماسکۆئے ساهت + ماسکۆئے گیشّتگێن ساهت + ماسکۆئے گرماگی ساهت + + + + + نیوفاوونڈلئینڈئے ساهت + نیوفاوونڈلئینڈئے گیشّتگێن ساهت + نیوفاوونڈلئینڈئے گرماگی ساهت + + + + + نُرُنهائے ساهت + نُرُنهائے گیشّتگێن ساهت + نُرُنهائے گرماگی ساهت + + + + + نۆوۆسیبیرسکئے ساهت + نۆوۆسیبیرسکئے گیشّتگێن ساهت + نۆوۆسیبیرسکئے گرماگی ساهت + + + + + اۆمسکئے ساهت + اۆمسکئے گیشّتگێن ساهت + اۆمسکئے گرماگی ساهت + + + + + ولادیوُستُکئے ساهت + ولادیوُستُکئے گیشّتگێن ساهت + ولادیوُستُکئے گرماگی ساهت + + + + + یاکوتسکئے ساهت + یاکوتسکئے گیشّتگێن ساهت + یاکوتسکئے گرماگی ساهت + + + + + یێکاترینبورگئے ساهت + یێکاترینبورگئے گیشّتگێن ساهت + یێکاترینبورگئے گرماگی ساهت + + + + + + latn + + . + , + % + + + - + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + + + + برازیلی ریال + R$ + R$ + + + یورۆ + + + + + برتانی پئوند + £ + £ + + + هندُستانی روپّئیی + + + + + اێرانی ریال + ریال + + + جاپانی یَن + ¥ + ¥ + + + پاکستانی روپی + Rs + Rs + + + روسی روبل + + + + + امریکی دالر + $ + $ + + + نگیشّتگێن زَرّ + XXX + + + + + + هئو:ه + نه:ن + + + diff --git a/make/data/cldr/common/main/bal_Arab.xml b/make/data/cldr/common/main/bal_Arab.xml new file mode 100644 index 00000000000..a6fb072f7ef --- /dev/null +++ b/make/data/cldr/common/main/bal_Arab.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + + + + Brázil + Chin + Jarmani + Paráns + Bartániá + Hendostán + Itáliá + Jápán + Pákestán + Rus + Amrikáay Tepákén Están + Nagisshetagén damag + + + Buddái sáldar + Chini sáldar + Kobti sáldar + Dángi sáldar + Etupiái sáldar + Etupiái Ámet Álem sáldar + Miládi sáldar + Ebráni sáldar + Hendi Kawmi sáldar + Eslámi sáldar + Eslámi shahri sáldar + Eslámi Saudi-Arabi sáldar + Eslámi Nojumi sáldar + Eslámi Omm al-Korrahi sáldar + ISO-8601 sáldar + Jápáni sáldar + Pársi sáldar + Mingu-Chini sáldar + Zarray anjárén káleb + Gisshetagén red o band + Arabi-Hendi mórdán + Rusi mórdán + Dénágari mórdán + Rónendi mórdán + + + mitari + Bartáni + Amriki + + + zobán: {0} + syáhag: {0} + damag: {0} + + + + + left-to-right + top-to-bottom + + + + [á a b c d é e g h i j k l m n ó o p r s t u v w y z] + [f ń q x] + [Á A B {Ch} D {Dh} É E F G H I J K L M N Ó O P R {Rh} S {Sh} T {Th} U V W Y Z {Zh}] + [, ; \: ? . ‘ ’ “ ”] + + + + + + + + Jan + Par + Már + Apr + Mai + Jun + Jól + Aga + Sat + Akt + Naw + Das + + + Janwari + Parwari + Márch + Aprél + Mai + Jun + Jólái + Agast + Satambar + Aktubar + Nawambar + Dasambar + + + + + + + Yak + Do + Say + Chá + Pan + Jom + Sha + + + Yakshambeh + Doshambeh + Sayshambeh + Chárshambeh + Panchshambeh + Jomah + Shambeh + + + + + + + 1/4 + 2/4 + 3/4 + 4/4 + + + 1 + 2 + 3 + 4 + + + awali chárek + domi chárek + sayomi chárek + cháromi chárek + + + + + 1/4 + 2/4 + 3/4 + 4/4 + + + 1 + 2 + 3 + 4 + + + awali chárek + domi chárek + sayomi chárek + cháromi chárek + + + + + + + EEEE, d MMMM, y + + + + + d MMMM, y + + + + + d MMM, y + + + + + d/M/yy + + + + + + + hh:mm:ss a zzzz + + + + + hh:mm:ss a zzz + + + + + hh:mm:ss a + + + + + hh:mm a + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + + + + + Aláskáay wahd + Aláskáay anjári wahd + Aláskáay garmági wahd + + + + + Amázónay wahd + Amázónay anjári wahd + Amázónay garmági wahd + + + + + Delgáhi Amrikáay wahd + Delgáhi Amrikáay anjári wahd + Delgáhi Amrikáay garmági wahd + + + + + Ródarátki Amrikáay wahd + Ródarátki Amrikáay anjári wahd + Ródarátki Amrikáay garmági wahd + + + + + Kóhestagi Amrikáay wahd + Kóhestagi Amrikáay anjári wahd + Kóhestagi Amrikáay garmági wahd + + + + + Árámzeri Amrikáay wahd + Árámzeri Amrikáay anjári wahd + Árámzeri Amrikáay garmági wahd + + + + + Arjentináay wahd + Arjentináay anjári wahd + Arjentináay garmági wahd + + + + + Rónendi Arjentináay wahd + Rónendi Arjentináay anjári wahd + Rónendi Arjentináay gramági wahd + + + + + Delgáhi Ástréliáay wahd + Delgáhi Ástréliáay anjári wahd + Delgáhi Ástréliáay garmági wahd + + + + + Delgáhirónendi Ástréliáay wahd + Delgáhirónendi Ástréliáay anjári wahd + Delgáhirónendi Ástréliáay garmági wahd + + + + + Ródarátki Ástréliáay wahd + Ródarátki Ástréliáay anjári wahd + Ródarátki Ástréliáay garmági wahd + + + + + Rónendi Ástréliáay wahd + Rónendi Ástréliáay anjári wahd + Rónendi Ástréliáay garmági wahd + + + + + Brázilay wahd + Brázilay anjári wahd + Brázilay garmági wahd + + + + + Delgáhi Yuropay wahd + Delgáhi Yuropay anjári wahd + Delgáhi Yuropay garmági wahd + + + + + Ródarátki Yuropay wahd + Ródarátki Yuropay anjári wahd + Ródarátki Yuropay garmági wahd + + + + + Démterén Ródarátki Yuropay anjári wahd + + + + + Rónendi Yuropay wahd + Rónendi Yuropay anjári wahd + Rónendi Yuropay garmági wahd + + + + + Hawái/Alushiay wahd + Hawái/Alushiay anjári wahd + Hawái/Alushiay garmági wahd + + + + + Delgáhi Endhonishiáay anjári wahd + + + + + Ródarátki Endhonishiáay anjári wahd + + + + + Rónendi Endhonishiáay anjári wahd + + + + + Erkuskay wahd + Erkuskay anjári wahd + Erkuskay garmági wahd + + + + + Ródarátki Kázekestánay anjári wahd + + + + + Rónendi Kázekestánay anjári wahd + + + + + Krasnóyáskay wahd + Krasnóyáskay anjári wahd + Krasnóyáskay garmági wahd + + + + + Ástréliáay, Ládhaway wahd + Ástréliáay, Ládhaway anjári wahd + Ástréliáay, Ládhaway garmági wahd + + + + + Makwáriay anjári wahd + + + + + Mágadánay wahd + Mágadánay anjári wahd + Mágadánay garmági wahd + + + + + Shemálrónendi Meksikóay wahd + Górichánrónendi Meksikóay anjári wahd + Shemálrónendi Meksikóay garmági wahd + + + + + Árámzeri Meksikóay wahd + Árámzeri Meksikóay anjári wahd + Árámzeri Meksikóay garmági wahd + + + + + Máskóay wahd + Máskóay anjári wahd + Máskóay garmági wahd + + + + + Nipándlaynday wahd + Nipándlaynday anjári wahd + Nipándlaynday garmági wahd + + + + + Noronáay wahd + Noronáay anjári wahd + Noronáay garmági wahd + + + + + Nawásibiskay wahd + Nawásibiskay anjári wahd + Nawásibiskay garmági wahd + + + + + Ómskay wahd + Ómskay anjári wahd + Ómskay garmági wahd + + + + + Waládiwástókay wahd + Waládiwástókay anjári wahd + Waládiwástókay garmági wahd + + + + + Yákuskay wahd + Yákuskay anjári wahd + Yákuskay garmági wahd + + + + + Yakátrinborgay wahd + Yakátrinborgay anjári wahd + Yakátrinborgay garmági wahd + + + + + + latn + + . + , + % + + + - + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + + + + Brázili riál + R$ + R$ + + + yuró + + + + + Bartáni pawndh + £ + £ + + + Hendostáni rupi + + + + + Éráni ryál + ریال + + + Jápáni yen + ¥ + ¥ + + + Pákestáni rupi + Rs + Rs + + + Rusi rubel + + + + + Amriki dhálar + $ + $ + + + Nazántagén zarr + XXX + + + + + + haw:h + na:n + + + diff --git a/make/data/cldr/common/main/bal_Latn_PK.xml b/make/data/cldr/common/main/bal_Latn_PK.xml new file mode 100644 index 00000000000..9bfffa1f977 --- /dev/null +++ b/make/data/cldr/common/main/bal_Latn_PK.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + دونیا/جهان + افریقا + اوقیانوسیه + امریکای براعظم + استرالیا + اسیا + اورورپا + متحدین عربین امارات + انگویلا + انگولا + ارجنٹاین + اسٹرالیا + آزربایجان + بیلجیم + بولغاریه + بحرین + بروندی + بیرمودا + برونی + بولیویه + برازیل + بهاماس + بوتان + کاناڈا + چیلی + کامیرون + چین + کولومبیا + کوبا + قبرس + جرمنی + جیبوتی + الجزایر + اکوادور + مصر + روچ‌کپتین سحرا + اریتره + هسپانیه + ایتوپیه + اورورپایی یکویی + فیجی + فرانسه + گابون + گرجستان + گانا + گرینلاند + گامبیا + گوینیا + یونان + گویانا + هانگ کانگ + هنگری + ایندونیزیا + اسرائیل + عراق + ایتالیه + اردن + کینیا + قیرغیزستان + کمبودیا + کومورس + کویٹ + قزاقستان + لاوس + لیبنان + لیبیا + مراکو + مالداویا + ماداگاسکار + مالی + مالته + موریتانیا + مکسیکو + مالیزیا + نیجیر + نایجیریا + نیوزلنڈ + ئومان + پانامه + پیرو + فلیپین + پورتگال + پاراگوی + قطر + رومانیه + سیربستان + روندا + سیشیل + سوڈان + سینگاپور + سینیگال + سومالیا + سورینامی + سوریه + چاد + ٹایلنڈ + تاجیکستان + تورکمنستان + ٹونیس + تانزانیا + اوگاندا + متحدین ایالات + اوراگوی + اوزبکیستان + وینزوویلا + ویتنام + یمن + زامبیا + زیمبابوی + نازانتین سیمسر + + + میٹریک + بریتانوی + امریکایی + + + + + right-to-left + top-to-bottom + + + + [آ ئ ا ب پ ت ث ٹ ج چ ح خ د ڈ ر ز ڑ ژ س ش ص ض ط ظ غ ف ق ک گ ل م ن ھ و ۆ ی ێ] + [\u200C ؤ] + [آ ئ ا ب پ ت ث ٹ ج چ ح خ د ڈ ر ز ڑ ژ س ش ص ض ط ظ غ ف ق ک گ ل م ن ھ و ۆ ی ێ] + [‐ – — ، ؛ \: ! ؟ . … ‘ ’ " “ ” « » ( ) \[ \] § @ * \\ \& # † ‡ ′ ″] + + + + + سال + + + سال + + + سال + + + ماه + + + ماه + + + ماه + + + هفته‌گ + + + هفته‌گ + + + هفته‌گ + + + روچ + زي + مروچی + باندا + + +{0} روچ + + + + روچ + + + روچ + + + هفته‌گئ روچان + + + ساعت + + + سائت + + + ساعت + + + + {0} + + نازانتین شاران + + + دوبی + + + کابل + + + باکو + + + ڈاکا + + + بحرین + + + ٹیمپو + + + اورمچی + + + تیبلیسی + + + یورشلیم + + + کلکته + + + بغداد + + + تهران + + + امان + + + توکیو + + + بیشکیک + + + سیول + + + کویٹ + + + اقتاو + + + اورال + + + اقتوبه + + + قیزیلوردا + + + الماته + + + کولومبو + + + اولان‌باتور + + + مالدیف + + + کٹمنڈو + + + مسقط + + + کراچی + + + غزه + + + قطر + + + کیروف + + + سامارا + + + تومسک + + + ریاض + + + دمشق + + + دوشنبه + + + عشق آبات + + + استانبول + + + سمرقند + + + تاشکینت + + + عدن + + + + اوگانستانی وخت + + + + + روچ‌دراتین قزاقستانی وخت + + + + + روچ‌کپتین قزاقستانی وخت + + + + + قیرغیزستانی وخت + + + + + تاجیکستانی وخت + + + + + + arabext + + arabext + + + : + + + ٫ + ، + ٪ + + + - + × + + ناعدد + : + + + + + ¤ #,##0.00 + + + + + 0 هزار ¤ + ¤00هزار + ¤ 000هزار + ¤ 0میلیون + ¤ 00میلیون + ¤000میلیون + ¤0میلیارد + ¤00میلیارد + + + {0} {1} + + + + اوگانستانئ اوگانی + اوگانستانئ اوگانی + ؋ + + + بنگلادیشئ ٹاکه + بنگلادیشئ ٹاکه + BDT + + + + بوتانئ انگولٹروم + بوتانئ انگولٹروم + BTN + + + هندوستانئ روپی + هندوستانئ روپی + + + + + ایرانئ ریال + ایرانئ ریال + ریال + + + سریلانکایی روپی + سریلانکایی روپی + LKR + Rs + + + مالدیوی روپی + مالدیوی روپی + MVR + + + نیپالین روپی + نیپالین روپی + NPR + Rs + + + پاکستانئ روپی + پاکستانئ روپی + PKR + Rs + + + روسین روبل + + + + ≥{0} + {0}–{1} + + + + + + سده‌گ + {0} سده‌گ + + + سال + {0} سال + {0} سالئ تا + + + ماه + {0} ماه + {0} به ماه‌ای تا + + + هفته‌گ + {0} هفته‌گ + {0} هفته‌گئ تا + + + روچ + {0} روچ + {0} روچئ تا + + + ساعت + {0} ساعت + {0} ساعتئ تا + + + دقیقه + {0} دقیقه + {0} دقیقه‌ای تا + + + ثانیه + {0} ثانیه + {0} ثانیه‌ای تا + + + میلی‌ثانیه + {0} میلی‌ثانیه + + + مایکروثانیه + {0} مایکروثانیه + + + نانوثانیه + {0} نانوثانیه + + + کیلومیتر + {0} کیلومیتر + {0} کیلومیترئ تا + + + میتر + {0} میتر + {0} میترئ تا + + + روچ‌دراتین {0} + بُرزسرین {0} + + + + + سده‌گ + {0} سده‌گ + + + سال + {0} سال + {0}/سال + + + ماه + {0} ماه + {0}/ماه + + + هفته‌گ + {0} هفته‌گ + {0}/هفته‌گ + + + روچ + {0} روچ + {0}/روچ + + + ساعت + {0} ساعت + {0}/ساعت + + + دقیقه + {0} دقیقه + {0}/دقیقه + + + ثانیه + {0} ثانیه + {0}/ث + + + میلی‌ثانیه + {0} میلی‌ثانیه + + + مایکروثانیه + {0} مایکروثانیه + + + نانوثانیه + {0} نانوثانیه + + + کیلومیتر + {0} کیلومیتر + {0}/کیلومیتر + + + میتر + {0} میتر + {0}/میتر + + + روچ‌دراتین {0} + بُرزسرین {0} + + + + + سال + {0} سال + + + ماه + {0}ماه + + + هفته‌گ + {0}هفته‌گ + + + روچ + {0}روچ + + + ساعت + {0}ساعت + + + دقیقه + {0}دقیقه + + + ثانیه + {0}ث + + + میلی‌ثانیه + {0}میلی‌ثانیه + + + کیلومیتر + {0}کیلومیتر + + + میتر + {0}میتر + + + روچ‌دراتین {0} + بُرزسرین {0} + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0}، {1} + {0}، {1} + {0}، و {1} + {0} و {1} + + + {0}، {1} + {0}، {1} + {0}، و {1} + {0} و {1} + + + {0}، {1} + {0}، {1} + {0}، {1} + {0}، {1} + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + {0}، {1} + {0}، {1} + {0}، {1} + {0}، {1} + + + + + هان:هاو + نه:ن + + + + {0} — موچ + {0}: {1} + {0} — تاریخی + {0} ضربه + + diff --git a/make/data/cldr/common/main/bgn_AE.xml b/make/data/cldr/common/main/bgn_AE.xml new file mode 100644 index 00000000000..773bfd72b56 --- /dev/null +++ b/make/data/cldr/common/main/bgn_AE.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bgn_AF.xml b/make/data/cldr/common/main/bgn_AF.xml new file mode 100644 index 00000000000..53cc222ffaa --- /dev/null +++ b/make/data/cldr/common/main/bgn_AF.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bgn_IR.xml b/make/data/cldr/common/main/bgn_IR.xml new file mode 100644 index 00000000000..e4eea64176d --- /dev/null +++ b/make/data/cldr/common/main/bgn_IR.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bgn_OM.xml b/make/data/cldr/common/main/bgn_OM.xml new file mode 100644 index 00000000000..0155f7d6fb1 --- /dev/null +++ b/make/data/cldr/common/main/bgn_OM.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bgn_PK.xml b/make/data/cldr/common/main/bgn_PK.xml new file mode 100644 index 00000000000..456d8df2f1f --- /dev/null +++ b/make/data/cldr/common/main/bgn_PK.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bho.xml b/make/data/cldr/common/main/bho.xml index 9b916393fd6..724cb84915f 100644 --- a/make/data/cldr/common/main/bho.xml +++ b/make/data/cldr/common/main/bho.xml @@ -1,6 +1,6 @@ - + + + + + + + + ꪼꪕꪒꪾ + + + + [\uAABF \uAAC1 ꫝ ꪀ ꪁ ꪄ ꪅ ꪆ ꪇ ꪈ ꪉ ꪊ ꪋ ꪎ ꪏ ꪐ ꪑ ꪒ ꪓ ꪔ ꪕ ꪖ ꪗ ꪘ ꪙ ꪚ ꪛ ꪜ ꪝ ꪠ ꪡ ꪢ ꪣ ꪤ ꪥ ꪦ ꪧ ꪨ ꪩ ꪪ ꪫ ꪬ ꪭ ꪮ ꪯ \uAAB0 ꪱ \uAAB2 \uAAB3 \uAAB4 ꪵ ꪶ \uAAB7 \uAAB8 ꪹ ꪺ ꪻ ꪼ ꪽ \uAABE ꫀ ꫂ ꫛ ꫜ] + [. ꫞ ꫟] + + diff --git a/make/data/cldr/common/main/blt_VN.xml b/make/data/cldr/common/main/blt_VN.xml new file mode 100644 index 00000000000..1746f69fb20 --- /dev/null +++ b/make/data/cldr/common/main/blt_VN.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/bm.xml b/make/data/cldr/common/main/bm.xml index c91898bfa33..4b9ccee4e7a 100644 --- a/make/data/cldr/common/main/bm.xml +++ b/make/data/cldr/common/main/bm.xml @@ -1,6 +1,6 @@ - + + + + + + + + Kamerûn + + + mɔné + + + Metric + + + + [a á â ǎ ā b c d e é ê ě ē ə {ə\u0301} {ə\u0302} {ə\u030C} {ə\u0304} ɛ {ɛ\u0301} {ɛ\u0302} {ɛ\u030C} {ɛ\u0304} g h i í î ǐ ī j k l m ḿ n ń ŋ o ó ô ǒ ō ɔ {ɔ\u0301} {ɔ\u0302} {ɔ\u030C} {ɔ\u0304} p s t u ú û ǔ ū w y z ʼ] + [f q r v x] + [A B C D E Ə Ɛ G H I J K L M N Ŋ O Ɔ P S T U W Y Z] + [, ; \: ! ? . ' "] + {0}… + …{0} + {0}…{1} + + + + + + + + + + + mwɛ̌ + + + ngɔn + + + sɔ̂ndé + + + mbwɛ + súúbɛ + chǎn ábe éʼtómé + chii + chǎn ábe éʼhúɛʼ + + + háwa + + + menúte + + + + + GMT+1 + + + + + + . + , + % + + + - + + + + + + + #,##0.### + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + + + + Frânke CFA + FCFA + + + + + + {0}, {1} + {0}, {1} + {0} {1} + {0}, {1} + + + diff --git a/make/data/cldr/common/main/bss_CM.xml b/make/data/cldr/common/main/bss_CM.xml new file mode 100644 index 00000000000..be5edffb7d1 --- /dev/null +++ b/make/data/cldr/common/main/bss_CM.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/byn.xml b/make/data/cldr/common/main/byn.xml new file mode 100644 index 00000000000..eae47fb6c2b --- /dev/null +++ b/make/data/cldr/common/main/byn.xml @@ -0,0 +1,527 @@ + + + + + + + + + + + አፋርኛ + አብሐዚኛ + አፍሪቃንስኛ + አማርኛ + ዐርቢኛ + አሳሜዛዊ + አያማርኛ + አዜርባይጃንኛ + ባስኪርኛ + ቤላራሻኛ + ቡልጋሪኛ + ቢስላምኛ + በንጋሊኛ + ትበትንኛ + ብሬቶንኛ + ብሊን + ካታላንኛ + ኮርሲካኛ + ቼክኛ + ወልሽ + ዴኒሽ + ጀርመን + ድዞንግኻኛ + ግሪክኛ + እንግሊዝኛ + ኤስፐራንቶ + ስፓኒሽ + ኤስቶኒአን + ባስክኛ + ፐርሲያኛ + ፊኒሽ + ፊጂኛ + ፋሮኛ + ፈረንሳይኛ + ፍሪስኛ + አይሪሽ + እስኮትስ ጌልክኛ + ግዕዝኛ + ጋለጋኛ + ጓራኒኛ + ጉጃርቲኛ + ሃውሳኛ + ዕብራስጥ + ሐንድኛ + ክሮሽያንኛ + ሀንጋሪኛ + አርመናዊ + ኢንቴርሊንጓ + እንዶኒሲኛ + እንተርሊንግወ + እኑፒያቅኛ + አይስላንድኛ + ጣሊያንኛ + እኑክቲቱትኛ + ጃፓንኛ + ጃቫንኛ + ጊዮርጊያን + ካዛክኛ + ካላሊሱትኛ + ክመርኛ + ካናዳኛ + ኮሪያኛ + ካሽሚርኛ + ኩርድሽኛ + ኪርጊዝኛ + ላቲንኛ + ሊንጋላኛ + ላውስኛ + ሊቱአኒያን + ላትቪያን + ማላጋስኛ + ማዮሪኛ + ማከዶኒኛ + ማላያላምኛ + ሞንጎላዊኛ + ማራዚኛ + ማላይኛ + ማልቲስኛ + ቡርማኛ + ናኡሩ + ኔፓሊኛ + ደች + ኖርዌጂያን + ኦኪታንኛ + ኦሮምኛ + ኦሪያኛ + ፓንጃቢኛ + ፖሊሽ + ፑሽቶኛ + ፖርቱጋሊኛ + ኵቿኛ + ሮማንስ + ሩንዲኛ + ሮማኒያን + ሞልዳቫዊና + ራሽኛ + ኪንያርዋንድኛ + ሳንስክሪትኛ + ሲንድሂኛ + ሳንጎኛ + ስንሃልኛ + ሲዳምኛ + ስሎቫክኛ + ስሎቪኛ + ሳሞአኛ + ሾናኛ + ሱማልኛ + ልቤኒኛ + ሰርቢኛ + ስዋቲኛ + ሶዞኛ + ሱዳንኛ + ስዊድንኛ + ስዋሂሊኛ + ታሚልኛ + ተሉጉኛ + ታጂኪኛ + ታይኛ + ትግርኛ + ትግረ + ቱርክመንኛ + ታጋሎገኛ + ጽዋናዊኛ + ቶንጋ + ቱርክኛ + ጾንጋኛ + ታታርኛ + ትዊኛ + ኡዊግሁርኛ + ዩክረኒኛ + ኡርዱኛ + ኡዝበክኛ + ቪትናምኛ + ቮላፑክኛ + ዎሎፍኛ + ዞሳኛ + ይዲሻዊኛ + ዮሩባዊኛ + ዡዋንግኛ + ቻይንኛ + ዙሉኛ + + + + + + አንዶራ + የተባበሩት አረብ ኤምሬትስ + አልባኒያ + አርሜኒያ + አርጀንቲና + ኦስትሪያ + አውስትሬሊያ + አዘርባጃን + ቦስኒያ እና ሄርዞጎቪኒያ + ባርቤዶስ + ቤልጄም + ቡልጌሪያ + ባህሬን + ቤርሙዳ + ቦሊቪያ + ብራዚል + ቡህታን + ቤላሩስ + ቤሊዘ + ኮንጎ + የመካከለኛው አፍሪካ ሪፐብሊክ + ስዊዘርላንድ + ቺሊ + ካሜሩን + ቻይና + ኮሎምቢያ + ኬፕ ቬርዴ + ሳይፕረስ + ቼክ ሪፑብሊክ + ጀርመን + ዴንማርክ + ዶሚኒካ + ዶሚኒክ ሪፑብሊክ + አልጄሪያ + ኢኳዶር + ኤስቶኒያ + ግብጽ + ምዕራባዊ ሳህራ + ኤርትራ + ስፔን + ኢትዮጵያ + ፊንላንድ + ፊጂ + ሚክሮኔዢያ + ፈረንሳይ + እንግሊዝ + ጆርጂያ + የፈረንሳይ ጉዊአና + ጋምቢያ + ጊኒ + ኢኳቶሪያል ጊኒ + ግሪክ + ቢሳዎ + ጉያና + ሆንግ ኮንግ + ክሮኤሽያ + ሀይቲ + ሀንጋሪ + ኢንዶኔዢያ + አየርላንድ + እስራኤል + ህንድ + ኢራቅ + አይስላንድ + ጣሊያን + ጃማይካ + ጆርዳን + ጃፓን + ካምቦዲያ + ኮሞሮስ + ሰሜን ኮሪያ + ደቡብ ኮሪያ + ክዌት + ሊባኖስ + ሊቱዌኒያ + ላትቪያ + ሊቢያ + ሞሮኮ + ሞልዶቫ + ማከዶኒያ + ሞንጎሊያ + ማካዎ + ሞሪቴኒያ + ማልታ + ማሩሸስ + ሜክሲኮ + ማሌዢያ + ናሚቢያ + ኒው ካሌዶኒያ + ናይጄሪያ + ኔዘርላንድ + ኖርዌ + ኔፓል + ኒው ዚላንድ + ፔሩ + የፈረንሳይ ፖሊኔዢያ + ፓፑዋ ኒው ጊኒ + ፖላንድ + ፖርታ ሪኮ + ሮሜኒያ + ራሺያ + ሳውድአረቢያ + ሱዳን + ስዊድን + ሲንጋፖር + ስሎቬኒያ + ስሎቫኪያ + ሴኔጋል + ሱማሌ + ሲሪያ + ቻድ + የፈረንሳይ ደቡባዊ ግዛቶች + ታይላንድ + ታጃኪስታን + ምስራቅ ቲሞር + ቱኒዚያ + ቱርክ + ትሪኒዳድ እና ቶባጎ + ታንዛኒያ + ዩጋንዳ + አሜሪካ + ዩዝበኪስታን + ቬንዙዌላ + የእንግሊዝ ድንግል ደሴቶች + የአሜሪካ ቨርጂን ደሴቶች + የመን + ደቡብ አፍሪካ + ዛምቢያ + + + + [\u135F ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ሉ ሊ ላ ሌ ል ሎ ሏ ሐ ሑ ሒ ሓ ሔ ሕ ሖ ሗ መ ሙ ሚ ማ ሜ ም ሞ ሟ ረ ሩ ሪ ራ ሬ ር ሮ ሯ ሰ ሱ ሲ ሳ ሴ ስ ሶ ሷ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቋ ቌ ቍ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቛ ቜ ቝ በ ቡ ቢ ባ ቤ ብ ቦ ቧ ቨ ቩ ቪ ቫ ቬ ቭ ቮ ቯ ተ ቱ ቲ ታ ቴ ት ቶ ቷ ቸ ቹ ቺ ቻ ቼ ች ቾ ቿ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኋ ኌ ኍ ነ ኑ ኒ ና ኔ ን ኖ ኗ ኘ ኙ ኚ ኛ ኜ ኝ ኞ ኟ አ ኡ ኢ ኣ ኤ እ ኦ ኧ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኳ ኴ ኵ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዃ ዄ ዅ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዙ ዚ ዛ ዜ ዝ ዞ ዟ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ የ ዩ ዪ ያ ዬ ይ ዮ ደ ዱ ዲ ዳ ዴ ድ ዶ ዷ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጓ ጔ ጕ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶔ ⶕ ⶖ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጧ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ጿ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፏ ፐ ፑ ፒ ፓ ፔ ፕ ፖ ፗ] + [᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሇ ⶀ ᎀ ᎁ ᎂ ᎃ ⶁ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ሧ ⶂ ⶃ ⶄ ቇ ᎄ ᎅ ᎆ ᎇ ⶅ ⶆ ⶇ ኇ ⶈ ⶉ ⶊ ኯ ዏ ⶋ ዯ ⶌ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ⶎ ጏ ⶏ ⶐ ⶑ ፇ ᎈ ᎉ ᎊ ᎋ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ ፙ ፚ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶱ ⶲ ⶳ ⶴ ⶵ ⶶ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷁ ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷙ ⷚ ⷛ ⷜ ⷝ ⷞ] + [ሀ ለ ሐ መ ረ ሰ ሸ ቀ ቈ ቐ ቘ በ ቨ ተ ቸ ኀ ኈ ነ ኘ አ ከ ኰ ኸ ዀ ወ ዐ ዘ ዠ የ ደ ጀ ገ ጐ ጘ ⶓ ⶔ ⶕ ⶖ ጠ ጨ ጸ ፈ ፐ] + + + + + + + + EEEE፡ dd MMMM ግርጋ y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + + + ልደት + ካብኽ + ክብላ + ፋጅኺ + ክቢቅ + ም/ት + ኰር + ማርያ + ያኸኒ + መተሉ + ም/ም + ተሕሳ + + + ልደትሪ + ካብኽብቲ + ክብላ + ፋጅኺሪ + ክቢቅሪ + ምኪኤል ትጟኒሪ + ኰርኩ + ማርያም ትሪ + ያኸኒ መሳቅለሪ + መተሉ + ምኪኤል መሽወሪ + ተሕሳስሪ + + + + + + + + + + + + + + + + + + + + + + + ሰ/ቅ + ሰኑ + ሰሊጝ + ለጓ + ኣምድ + ኣርብ + ሰ/ሽ + + + ሰንበር ቅዳዅ + ሰኑ + ሰሊጝ + ለጓ ወሪ ለብዋ + ኣምድ + ኣርብ + ሰንበር ሽጓዅ + + + + + + + + + + + + + + + + + + ፋዱስ ጃብ + ፋዱስ ደምቢ + + + ፋዱስ ጃብ + ፋዱስ ደምቢ + + + + + + ይጅ + ኣድ + + + + + + EEEE፡ dd MMMM ግርጋ y G + GyMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + latn + + latn + ethi + + + + + ¤#,##0.00 + + + + + + የብራዚል ሪል + + + የቻይና ዩአን ረንሚንቢ + + + Nfk + + + የኢትዮጵያ ብር + + + አውሮ + + + የእንግሊዝ ፓውንድ ስተርሊንግ + + + የሕንድ ሩፒ + + + የጃፓን የን + + + የራሻ ሩብል + + + የአሜሪካን ዶላር + + + + diff --git a/make/data/cldr/common/main/byn_ER.xml b/make/data/cldr/common/main/byn_ER.xml new file mode 100644 index 00000000000..508caef4825 --- /dev/null +++ b/make/data/cldr/common/main/byn_ER.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ca.xml b/make/data/cldr/common/main/ca.xml index dc3dbe1b39d..3168fcdcb9e 100644 --- a/make/data/cldr/common/main/ca.xml +++ b/make/data/cldr/common/main/ca.xml @@ -1,6 +1,6 @@ - + + + + + + + + Caddo + + + United States + + + US + + + + [a á à {aː} {áː} {àː} b {ch} {chʼ} d e é è {eː} {éː} {èː} h i í ì {iː} {íː} {ìː} k {kʼ} m n o ó ò {oː} {óː} {òː} p s t {tsʼ} {tʼ} u ú ù {uː} {úː} {ùː} w y ˀ ʼ] + [c f g j l q r v x z] + [A B {CH} D E H I K M N O P S {SH} T {TS} U W Y] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + EEEE, MMMM d, y G + GyMMMMEEEEd + + + + + MMMM d, y G + GyMMMMd + + + + + MMM d, y G + GyMMMd + + + + + M/d/y GGGGG + GGGGGyMd + + + + + + + + + Cháykáhday Haˀimay + Tsahkápbiˀ + Wánit + Háshnihtiˀtiˀ + Háshnih Haˀimay + Háshnihtsiˀ + Násˀahˀatsus + Dahósikah nish + Híisikah nish + Nípbaatiˀtiˀ + Nípbaa Haˀimay + Cháykáhdaytiˀtiˀ + + + + + + + Inikuˀ + Wísts’i hayashuh + Bít hayashuh + Dahó hayashuh + Hiwí hayashuh + Dissik’an hayashuh + Inikuˀtiˀtiˀ + + + + + + + EEEE, MMMM d, y + yMMMMEEEEd + + + + + MMMM d, y + yMMMMd + + + + + MMM d, y + yMMMd + + + + + M/d/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + . + , + ; + % + + + - + E + + + NaN + + + + + ¤ 0K + ¤ 00K + ¤ 000K + ¤ 0M + ¤ 00M + ¤ 000M + ¤ 0G + ¤ 00G + ¤ 000G + ¤ 0T + ¤ 00T + ¤ 000T + + + + + + $ + + + + + + + Nish + Nish {0} + + + Wísts’iˀ inikuˀ + Wísts’iˀ inikuˀ {0} + + + Kaˀisch’áyˀah + {0} Kaˀisch’áyˀah + + + + diff --git a/make/data/cldr/common/main/cad_US.xml b/make/data/cldr/common/main/cad_US.xml new file mode 100644 index 00000000000..1ca1eff9b5a --- /dev/null +++ b/make/data/cldr/common/main/cad_US.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/cch.xml b/make/data/cldr/common/main/cch.xml new file mode 100644 index 00000000000..353e649ae35 --- /dev/null +++ b/make/data/cldr/common/main/cch.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + Atsam + + + + [a {a\u0331} b c {ch} d {dy} e f g {g\u0331} {gb} {gw} {gy} h {hy} i j k ḵ {kp} {kw} l {ly} m n ṉ {ny} o p {ph} {py} r {ry} s {sh} t u v w {wh} y {y\u0331} z ʼ] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ʼ] + + + + + + + + EEEE, G y MMMM dd + GyMMMMEEEEdd + + + + + G y MMMM d + GyMMMMd + + + + + G y MMM d + GyMMMd + + + + + GGGGG yy/MM/dd + GGGGGyyMMdd + + + + + + + + + Dyon + Baa + Atat + Anas + Atyo + Achi + Atar + Awur + Shad + Shak + Naba + Nata + + + Pen Dyon + Pen Baʼa + Pen Atat + Pen Anas + Pen Atyon + Pen Achirim + Pen Atariba + Pen Awurr + Pen Shadon + Pen Shakur + Pen Kur Naba + Pen Kur Natat + + + + + + + Yok + Tung + Gitung + Tsan + Nas + Nat + Chir + + + Wai Yoka Bawai + Wai Tunga + Toki Gitung + Tsam Kasuwa + Wai Na Nas + Wai Na Tiyon + Wai Na Chirim + + + + + + Gabanin Miladi + Miladi + + + GM + M + + + + + + EEEE, y MMMM dd + yMMMMEEEEdd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + yy/MM/dd + yyMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + + + + Aman + + + + + diff --git a/make/data/cldr/common/main/cch_NG.xml b/make/data/cldr/common/main/cch_NG.xml new file mode 100644 index 00000000000..9f11c337973 --- /dev/null +++ b/make/data/cldr/common/main/cch_NG.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ccp.xml b/make/data/cldr/common/main/ccp.xml index dc39fe4d46d..29abe237696 100644 --- a/make/data/cldr/common/main/ccp.xml +++ b/make/data/cldr/common/main/ccp.xml @@ -1,6 +1,6 @@ - + + + + + + + + Chahta + + + + + + United States + + + + [a {a\u0331} b {ch} e f h {hl} i {i\u0331} k l m n o {o\u0331} p s {sh} t u v ʋ w y] + [c č d g j q r š x z] + [A {A\u0331} B {CH} E F H {HL} I {I\u0331} K L M N O {O\u0331} P S {SH} T U V Ʋ W Z] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + diff --git a/make/data/cldr/common/main/cho_US.xml b/make/data/cldr/common/main/cho_US.xml new file mode 100644 index 00000000000..7d860d2bed7 --- /dev/null +++ b/make/data/cldr/common/main/cho_US.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/chr.xml b/make/data/cldr/common/main/chr.xml index 159a91cd495..1d6274a3c4f 100644 --- a/make/data/cldr/common/main/chr.xml +++ b/make/data/cldr/common/main/chr.xml @@ -1,6 +1,6 @@ - + + + + + + + + Chikashshanompaʼ + + + United States + + + US + + + + [a {a\u0331} b {ch} f h i {i\u0331} k l {lh} m n {ng} o {o\u0331} p s {sh} t w y ʼ] + [á {á\u0331} c d e g í {í\u0331} j ó {ó\u0331} q r u v x z] + [A {A\u0331} B {CH} D E F H I {I\u0331} K L {LH} M N O {O\u0331} P S {SH} T V W Y] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + EEEE, MMMM d, y G + GyMMMMEEEEd + + + + + MMMM d, y G + GyMMMMd + + + + + MMM d, y G + GyMMMd + + + + + M/d/y GGGGG + GGGGGyMd + + + + + + + + + Hashiʼ Ammoʼnaʼ + Hashiʼ Atokloʼ + Hashiʼ Atochchíʼnaʼ + Iiplal + Mih + Choon + Choola + Akaas + Siptimpaʼ + Aaktopaʼ + Nofimpaʼ + Tiisimpaʼ + + + + + + + Nittak Holloʼ + Mantiʼ + Chostiʼ + Winstiʼ + Soistiʼ + Nannalhchifaʼ Nittak + Nittak Holloʼ Nakfish + + + + + + + EEEE, MMMM d, y + yMMMMEEEEd + + + + + MMMM d, y + yMMMMd + + + + + MMM d, y + yMMMd + + + + + M/d/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + . + , + ; + % + + + - + E + + + NaN + + + + + ¤ 0K + ¤ 00K + ¤ 000K + ¤ 0M + ¤ 00M + ¤ 000M + ¤ 0G + ¤ 00G + ¤ 000G + ¤ 0T + ¤ 00T + ¤ 000T + + + + + + $ + + + + + + + Afammi + Afammi {0} + + + Hashiʼ alhpisaʼ + Hashiʼ alhpisaʼ {0} + + + Nittak hollo ittataklaʼ + Nittak hollo ittataklaʼ {0} + + + Nittak + {0} Nittak + + + Hashiʼ kanalli chaffaʼ + Hashiʼ kanalli chaffaʼ {0} + + + Hashiʼ kanallloshiʼ + Hashiʼ kanallloshiʼ {0} + + + + diff --git a/make/data/cldr/common/main/cic_US.xml b/make/data/cldr/common/main/cic_US.xml new file mode 100644 index 00000000000..3eaf1b33792 --- /dev/null +++ b/make/data/cldr/common/main/cic_US.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ckb.xml b/make/data/cldr/common/main/ckb.xml index 87f70f1b56e..59c0ecee42f 100644 --- a/make/data/cldr/common/main/ckb.xml +++ b/make/data/cldr/common/main/ckb.xml @@ -1,6 +1,6 @@ - + + + + + + + + {0} : {1} + + + arabu + arabu mudernu + corsu + tedescu + tedescu austriacu + tedescu sguizzeru + inglese + inglese australianu + inglese canadianu + inglese americanu + inglese (S.U.) + spagnolu + francese + francese canadianu + francese sguizzeru + talianu + giappunese + cureanu + neerlandese + fiammingu + pulunese + purtughese + purtughese brasilianu + purtughese europeanu + russiu + tailandese + turcu + lingua scunnisciuta + chinese + chinese mandarinu + chinese simplificatu + mandarinu simplificatu + chinese tradiziunale + mandarinu tradiziunale + + + + + + + + + + + Mondu + Africa + Oceania + Americhe + Asia + Europa + America latina + Antarticu + Austria + Australia + Belgica + Canada + Svizzera + China + Costa Rica + Cuba + Republica cecca + Alemagna + Danimarca + Republica Duminicana + Spagna + Unione europea + Finlandia + Francia + Reame Unitu + R.U. + Grecia + Guatemala + Ungheria + Irlanda + Israele + India + Iran + Islanda + Italia + Giappone + Libanu + Santa Lucia + San Martinu + Mungulia + Martinica + Messicu + Malesia + Nicaragua + Nederlanda + Nurvegia + Nova Zelanda + Panama + Perù + Filippine + Palestina + Portugallu + Serbia + Russia + Sluvacchia + Siria + Turchia + Nazioni Unite + Stati Uniti + S.U. + regione scunnisciuta + + + calendariu gregurianu + calendariu ISO 8601 + ordine di classificazione standardizatu + cifri occidentale + + + metricu + imperiale + americanu + + + lingua : {0} + scrittura : {0} + regione : {0} + + + + + left-to-right + top-to-bottom + + + + [a à b c {chj} d e è f g {ghj} h i ì ï j l m n o ò p q r s {sc} {sg} t u ù ü v z] + [â æ ç é ê ë î k ñ ô œ ú û w x y ÿ] + [A B C {CHJ} D E F G {GHJ} H I J L M N O P Q R S {SC} {SG} T U V Z] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + {0}… + + + « + » + « + » + + + + + + + + EEEE d MMMM 'di' 'u' y G + GyMMMMEEEEd + + + + + d MMMM 'di' 'u' y G + GyMMMMd + + + + + d MMM y G + GyMMMd + + + + + dd/MM/y GGGGG + GGGGGyMMdd + + + + + + + {1} 'à' {0} + + + + + {1} 'à' {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + + + + + ghj. + fer. + mar. + apr. + mag. + ghju. + lug. + aos. + sit. + ott. + nuv. + dic. + + + G + F + M + A + M + G + L + A + S + O + N + D + + + di ghjennaghju + di ferraghju + di marzu + d’aprile + di maghju + di ghjugnu + di lugliu + d’aostu + di sittembre + d’ottobre + di nuvembre + di dicembre + + + + + ghj. + fer. + mar. + apr. + mag. + ghju. + lug. + aos. + sit. + ott. + nuv. + dic. + + + G + F + M + A + M + G + L + A + S + O + N + D + + + ghjennaghju + ferraghju + marzu + aprile + maghju + ghjugnu + lugliu + aostu + sittembre + ottobre + nuvembre + dicembre + + + + + + + dum. + lun. + mar. + mer. + ghj. + ven. + sab. + + + D + L + M + M + G + V + S + + + du + lu + ma + me + gh + ve + sa + + + dumenica + luni + marti + mercuri + ghjovi + venneri + sabbatu + + + + + dum. + lun. + mar. + mer. + ghj. + ven. + sab. + + + D + L + M + M + G + V + S + + + du + lu + ma + me + gh + ve + sa + + + dumenica + luni + marti + mercuri + ghjovi + venneri + sabbatu + + + + + + + T1 + T2 + T3 + T4 + + + 1 + 2 + 3 + 4 + + + 1u trimestru + 2u trimestru + 3u trimestru + 4u trimestru + + + + + T1 + T2 + T3 + T4 + + + 1u trimestru + 2u trimestru + 3u trimestru + 4u trimestru + + + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + nanzu à Cristu + nanzu l’era cumuna + dopu à Cristu + di l’era cumuna + + + nz à C. + NEC + dp à C. + EC + + + nz à C. + NEC + dp à C. + EC + + + + + + EEEE d MMMM 'di' 'u' y + yMMMMEEEEd + + + + + d MMMM 'di' 'u' y + yMMMMd + + + + + d MMM y + yMMMd + + + + + dd/MM/y + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1} 'à' {0} + + + {1} 'à' {0} + + + + + {1} {0} + + + {1} {0} + + + + h B + h:mm B + h:mm:ss B + d + E + E h:mm B + E h:mm:ss B + E d + E h:mm a + E HH:mm + E h:mm:ss a + E HH:mm:ss + y G + dd/MM/y G + MMM y G + d MMM y G + E d MMM y G + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + L + dd/MM + E dd/MM + LLL + d MMM + E d MMM + d MMMM + 'settimana' W MMMM + mm:ss + y + MM/y + dd/MM/y + E dd/MM/y + MMM y + d MMM y + E d MMM y + LLLL 'di' 'u' y + QQQ y + QQQQ 'di' 'u' y + 'settimana' w 'di' 'u' Y + + + {0} {1} + + + {0} – {1} + + h a – h a + h – h a + + + HH – HH + + + h:mm a – h:mm a + h:mm – h:mm a + h:mm – h:mm a + + + HH:mm – HH:mm + HH:mm – HH:mm + + + h:mm a – h:mm a v + h:mm – h:mm a v + h:mm – h:mm a v + + + HH:mm – HH:mm v + HH:mm – HH:mm v + + + h a – h a v + h – h a v + + + HH – HH v + + + MM–MM + + + dd/MM – dd/MM + dd/MM – dd/MM + + + E dd/MM – dd/MM + E dd/MM – dd/MM + + + MMM – MMM + + + y–y + + + MMM–MMM y + + + d – d MMM y + d MMM y – d MMM y + + + LLLL–LLLL y + LLLL y – LLLL y + + + + + + + + era + + + annu + l’annu scorsu + quist’annu + l’annu chì vene + + + an. + l’annu scorsu + quist’annu + l’annu chì vene + + + a. + l’annu scorsu + quist’annu + l’annu chì vene + + + trimestru + + + trim. + + + tr. + + + mese + u mese scorsu + stu mese + u mese chì vene + + + m. + u mese scorsu + stu mese + u mese chì vene + + + m. + u mese scorsu + stu mese + u mese chì vene + + + settimana + a settimana scorsa + sta settimana + a settimana chì vene + a settimana di u {0} + + + sett. + a settimana scorsa + sta settimana + a settimana chì vene + a settimana di u {0} + + + st. + a settimana scorsa + sta settimana + a settimana chì vene + a settimana di u {0} + + + ghjornu + eri + oghje + dumane + + + ghj. + eri + oghje + dumane + + + g + eri + oghje + dumane + + + ghjornu di a settimana + + + ora + + + ora + + + o. + + + minutu + + + min. + + + m. + + + seconda + + + sec. + + + s. + + + fusu orariu + + + + +HH:mm;-HH:mm + UTC{0} + UTC + ora : {0} + {0} (ora d’estate) + {0} (ora usuale) + + + Tempu universale cuurdinatu + + + + + ora mediana di Greenwich + + + + + + latn + + latn + + 1 + + , +   + % + + + - + + E + × + + + NaN + + + + + #,##0.### + + + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #E0 + + + + + + + #,##0 % + + + + + + + #,##0 % + + + + + + + #,##0.00 ¤ + #,##0.00 + + + #,##0.00 ¤;(#,##0.00) ¤ + #,##0.00;(#,##0.00) + + + + + + + #,##0.00 ¤ + + + #,##0.00 ¤;(#,##0.00) ¤ + #,##0.00;(#,##0.00) + + + {0} {1} + + + + yuan chinese + + + euro + EUR + + + libra sterlina + libre sterline + £GB + + + rupia indiana + rupie indiane + INR + + + yen giappunese + + + rublu russiu + rubli russii + + + $US + + + muneta scunnisciuta + munete scunnisciute + + + + ≈{0} + ≥{0} + ≤{0} + {0}–{1} + + + + + {0} è {1} + {0} è {1} + + + + + iè:i + innò:n + + + diff --git a/make/data/cldr/common/main/co_FR.xml b/make/data/cldr/common/main/co_FR.xml new file mode 100644 index 00000000000..b70e6839dce --- /dev/null +++ b/make/data/cldr/common/main/co_FR.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/cs.xml b/make/data/cldr/common/main/cs.xml index 9b57f54591b..5355745f299 100644 --- a/make/data/cldr/common/main/cs.xml +++ b/make/data/cldr/common/main/cs.xml @@ -1,6 +1,6 @@ - + + + + + + + + а҆бха́зскїй + а҆ра́вскїй + а҆зербайджа́нскїй + бѣлорꙋ́сскїй + бо́лгарскїй + церковнослове́нскїй + нѣме́цкїй + а҆ѵстрі́йскїй нѣме́цкїй + є҆лветі́йскїй нѣме́цкїй + є҆́ллинскїй + а҆нглі́йскїй + а҆ѵстралі́йскїй а҆нглі́йскїй + кана́дскїй а҆нглі́йскїй + брїта́нскїй а҆нглі́йскїй + а҆нглі́йскїй (вели́каѧ брїта́нїа) + а҆мерїка́нскїй а҆нглі́йскїй + а҆нглі́йскїй (асд) + і҆спа́нскїй + латїноамерїка́нскїй і҆спа́нскїй + є҆ѵрѡпе́йскїй і҆спа́нскїй + і҆спанскїй (ме́ѯїка) + є҆сто́нскїй + фі́нскїй + францꙋ́зскїй + кана́дскїй францꙋ́зскїй + є҆лветі́йскїй францꙋ́зскїй + є҆вре́йскїй + а҆рме́нскїй + і҆талїа́нскїй + ꙗ҆пѡ́нскїй + і҆́верскїй + каза́хскїй + латі́нскїй + лїто́вскїй + латві́йскїй + портога́льскїй + бразі́льскїй портога́льскїй + є҆ѵрѡпе́йскїй портога́льскїй + дакорꙋмы́нскїй + молда́вскїй + рꙋ́сскїй + се́рбскїй + ᲂу҆краи́нскїй + невѣ́домый ѧ҆зы́къ + хи́нскїй + ᲂу҆проще́нный хи́нскїй + традїцїо́нный хи́нскїй + + + + + + + + + + + + + А҆ѵстралі́ѧ + бразі́лїа + бѣ́лаѧ рꙋ́сь + Кана́да + хи́нскаѧ страна̀ + герма́нїа + Дані́ѧ + га́ллїа + Вели́каѧ брїта́нїа + і҆́ндїа + і҆та́лїа + ꙗ҆пѡ́нїа + кирги́зїа + казахста́нъ + Ме́ѯїко + рѡссі́а + ᲂу҆краи́на + а҆мерїка̑нскїѧ соединє́нныѧ держа̑вы + невѣ́домаѧ страна̀ + + + григорїа́нскїй мѣсѧцесло́въ + канѡни́ческое ᲂу҆порѧ́доченїе + а҆раві́йстїи числові́и зна́цы + + + метрі́ческаѧ + а҆нглі́йскаѧ + а҆мерїка́нскаѧ + + + + + left-to-right + top-to-bottom + + + + [\u0487\uA67D \u0483 ҂ а б \u2DE0 в \u2DE1 г \u2DE2 д \u2DE3 е є ж \u2DE4 \u2DE5 ѕ з ꙁ и й і ї к \u2DE6 л \u2DE7 м \u2DE8 н \u2DE9 ѻ о \u2DEA п р \u2DEC с \u2DED т у ꙋ ф х \u2DEF ѡ ѿ ꙍ ѽ ц ч \u2DF1 ш щ ⸯ ꙿ ъ ы ь ѣ ю ѫ ꙗ ѧ ѯ ѱ ѳ ѵ ѷ \u2DF4] + [\u0488\u0489\u200C\u200D\uA670\uA671\uA672\uFE2F \u0484 \uFE2E \uA66F \u2DF6 ꙣ \u2DF7 \uA674 ꙃ ꙅ \uA675 \uA676 ꙇ ꙉ \u2DF8 ꙥ ꙧ ҥ ꙩꙫꙭꙮꚙꚛ \u2DEB ҁ \u2DF5 \u2DEE \uA677 \u2DF9 \uA69E \uA67B \u2DF0 ꙡ џ \u2DF2 \u2DF3 ꙏ \uA678 ꙑ \uA679 \uA67A \u2DFA ꙓ \u2DFB ꙕ \u2DFC ѥ \uA69F \u2DFD ꙙ \u2DFE ꙛ ѩ ꙝ ѭ \u2DFF ꙟ] + [А Б В Г Д Є Ж Ѕ З И І К Л М Н Ѻ О П Р С Т Ꙋ Ф Х Ѡ Ѿ Ц Ч Ш Щ Ъ Ы Ь Ѣ Ю Ѫ Ꙗ Ѧ Ѯ Ѱ Ѳ Ѵ] + [  \- ‑ , % ‰ + 0 1 2 3 4 5 6 7 8 9] + [_ \- ‐ ‑ – — ⹃ , ; \: ! ? . ( ) ꙳ / ꙾] + + + « + » + + + + + + + + + + G y MMMM d, EEEE + GyMMMMEEEEd + + + + + G y MMMM d + GyMMMMd + + + + + G y MMM d + GyMMMd + + + + + GGGGG y-MM-dd + GGGGGyMMdd + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + {0} – {1} + + + + + + + + і҆аⷩ҇ + феⷡ҇ + маⷬ҇ + а҆пⷬ҇ + маꙵ + і҆ꙋⷩ҇ + і҆ꙋⷧ҇ + а҆́ѵⷢ҇ + сеⷫ҇ + ѻ҆кⷮ + ноеⷨ + деⷦ҇ + + + І҆ + Ф + М + А҆ + М + І҆ + І҆ + А҆ + С + Ѻ҆ + Н + Д + + + і҆аннꙋа́рїа + феврꙋа́рїа + ма́рта + а҆прі́ллїа + ма́їа + і҆ꙋ́нїа + і҆ꙋ́лїа + а҆́ѵгꙋста + септе́мврїа + ѻ҆ктѡ́врїа + ное́мврїа + деке́мврїа + + + + + і҆аⷩ҇ + феⷡ҇ + маⷬ҇ + а҆пⷬ҇ + маꙵ + і҆ꙋⷩ҇ + і҆ꙋⷧ҇ + а҆́ѵⷢ҇ + сеⷫ҇ + ѻ҆кⷮ + ноеⷨ + деⷦ҇ + + + І҆ + Ф + М + А҆ + М + І҆ + І҆ + А҆ + С + Ѻ҆ + Н + Д + + + і҆аннꙋа́рїй + феврꙋа́рїй + ма́ртъ + а҆прі́ллїй + ма́їй + і҆ꙋ́нїй + і҆ꙋ́лїй + а҆́ѵгꙋстъ + септе́мврїй + ѻ҆ктѡ́врїй + ное́мврїй + деке́мврїй + + + + + + + ндⷧ҇ѧ + пнⷣе + втоⷬ҇ + срⷣе + чеⷦ҇ + пѧⷦ҇ + сꙋⷠ҇ + + + Н + П + В + С + Ч + П + С + + + ндⷧ҇ѧ + пнⷣе + втоⷬ҇ + срⷣе + чеⷦ҇ + пѧⷦ҇ + сꙋⷠ҇ + + + недѣ́лѧ + понедѣ́льникъ + вто́рникъ + среда̀ + четверто́къ + пѧто́къ + сꙋббѡ́та + + + + + ндⷧ҇ѧ + пнⷣе + втоⷬ҇ + срⷣе + чеⷦ҇ + пѧⷦ҇ + сꙋⷠ҇ + + + Н + П + В + С + Ч + П + С + + + ндⷧ҇ѧ + пнⷣе + втоⷬ҇ + срⷣе + чеⷦ҇ + пѧⷦ҇ + сꙋⷠ҇ + + + недѣ́лѧ + понедѣ́льникъ + вто́рникъ + среда̀ + четверто́къ + пѧто́къ + сꙋббѡ́та + + + + + + + а҃_ѧ че́тверть + в҃_ѧ че́тверть + г҃_ѧ че́тверть + д҃_ѧ че́тверть + + + а҃ + в҃ + г҃ + д҃ + + + а҃_ѧ че́тверть + в҃_ѧ че́тверть + г҃_ѧ че́тверть + д҃_ѧ че́тверть + + + + + а҃ + в҃ + г҃ + д҃ + + + а҃ + в҃ + г҃ + д҃ + + + а҃_ѧ че́тверть + в҃_ѧ че́тверть + г҃_ѧ че́тверть + д҃_ѧ че́тверть + + + + + + + ДП + ПП + + + ДП + ПП + + + + + ДП + ПП + + + ДП + ПП + + + ДП + ПП + + + + + + пре́дъ р. х. + по р. х. + + + пре́дъ р. х. + пре́дъ р. х. + ѿ р. х. + ѿ р. х. + + + + + + EEEE, d MMMM 'л'. y. + yMMMMEEEEd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + y.MM.dd + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + {0} – {1} + + + + + + + вѣ́къ + + + лѣ́то + + + л. + + + л. + + + че́тверть + + + чеⷡ҇ + + + чеⷡ҇ + + + мѣ́сѧцъ + + + мцⷭ҇ъ + + + мцⷭ҇ъ + + + седми́ца + + + сеⷣ + + + сеⷣ + + + де́нь + вчера̀ + дне́сь + наꙋ́трїе + + + деⷩ҇ + + + деⷩ҇ + + + де́нь седми́цы + + + ДП/ПП + + + ча́съ + + + чаⷭ҇ + + + чаⷭ҇ + + + минꙋ́та + + + миⷩ҇ + + + миⷩ҇ + + + секꙋ́нда + + + сеⷦ҇ + + + сеⷦ҇ + + + по́ѧсъ часовѡ́мъ + + + + +HH:mm;-HH:mm + GMT{0} + GMT + {0} (вре́мѧ) + {0} (лѣ́тнее вре́мѧ) + {0} (зи́мнее вре́мѧ) + {1} ({0}) + + + всемі́рное сѷгхронїзи́рованное вре́мѧ + + + + невѣ́домый гра́дъ + + + ми́нскъ + + + бишке́къ + + + а҆кта́ꙋ + + + ᲂу҆ра́льскъ + + + а҆ктю́бинскъ + + + кызылѻрда̀ + + + а҆лматы̀ + + + калинингра́дъ + + + москва̀ + + + волгогра́дъ + + + сама́ра + + + є҆катерїнбꙋ́ргъ + + + ѻ҆́мскъ + + + новосиби́рскъ + + + новокꙋзне́цкъ + + + красноѧ́рскъ + + + и҆ркꙋ́тскъ + + + чита̀ + + + ꙗ҆кꙋ́тскъ + + + владивосто́къ + + + ха́ндыга + + + сахали́нъ + + + ᲂу҆́сть_не́ра + + + магада́нъ + + + среднеколы́мскъ + + + петропа́ѵловскъ_камча́тскїй + + + а҆на́дырь + + + ᲂу҆́жградъ + + + кі́евъ + + + сѷмферꙋ́поль + + + запра́жїе + + + + среднеамерїка́нское вре́мѧ + среднеамерїка́нское зи́мнее вре́мѧ + среднеамерїка́нское лѣ́тнее вре́мѧ + + + + + восточноамерїка́нское вре́мѧ + восточноамерїка́нское зи́мнее вре́мѧ + восточноамерїка́нское лѣ́тнее вре́мѧ + + + + + а҆мерїка́нское наго́рнее вре́мѧ + а҆мерїка́нское наго́рнее зи́мнее вре́мѧ + а҆мерїка́нское наго́рнее лѣ́тнее вре́мѧ + + + + + тихоѻкеа́нское вре́мѧ + тихоѻкеа́нское зи́мнее вре́мѧ + тихоѻкеа́нское лѣ́тнее вре́мѧ + + + + + а҆тланті́ческое вре́мѧ + а҆тланті́ческое зи́мнее вре́мѧ + а҆тланті́ческое лѣ́тнее вре́мѧ + + + + + среднеєѵрѡпе́йское вре́мѧ + среднеєѵрѡпе́йское зи́мнее вре́мѧ + среднеєѵрѡпе́йское лѣ́тнее вре́мѧ + + + + + восточноєѵрѡпе́йское вре́мѧ + восточноєѵрѡпе́йское зи́мнее вре́мѧ + восточноєѵрѡпе́йское лѣ́тнее вре́мѧ + + + + + вре́мѧ въ калинингра́дѣ и҆ ми́нскѣ + + + + + западноєѵрѡпе́йское вре́мѧ + западноєѵрѡпе́йское зи́мнее вре́мѧ + западноєѵрѡпе́йское лѣ́тнее вре́мѧ + + + + + сре́днее вре́мѧ по грі́нꙋичꙋ + + + + + и҆ркꙋ́тское вре́мѧ + и҆ркꙋ́тское зи́мнее вре́мѧ + и҆ркꙋ́тское лѣ́тнее вре́мѧ + + + + + восто́чный казахста́нъ + + + + + за́падный казахста́нъ + + + + + красноѧ́рское вре́мѧ + красноѧ́рское зи́мнее вре́мѧ + красноѧ́рское лѣ́тнее вре́мѧ + + + + + кирги́зїа + + + + + магада́нское вре́мѧ + магада́нское зи́мнее вре́мѧ + магада́нское лѣ́тнее вре́мѧ + + + + + моско́вское вре́мѧ + моско́вское зи́мнее вре́мѧ + моско́вское лѣ́тнее вре́мѧ + + + + + новосиби́рское вре́мѧ + новосиби́рское зи́мнее вре́мѧ + новосиби́рское лѣ́тнее вре́мѧ + + + + + ѻ҆́мское вре́мѧ + ѻ҆́мское зи́мнее вре́мѧ + ѻ҆́мское лѣ́тнее вре́мѧ + + + + + вре́мѧ на сахали́нѣ + зи́мнее вре́мѧ на сахали́нѣ + лѣ́тнее вре́мѧ на сахали́нѣ + + + + + владивосто́цкое вре́мѧ + владивосто́цкое зи́мнее вре́мѧ + владивосто́цкое лѣ́тнее вре́мѧ + + + + + волгогра́дское вре́мѧ + волгогра́дское зи́мнее вре́мѧ + волгогра́дское лѣ́тнее вре́мѧ + + + + + ꙗ҆кꙋ́тское вре́мѧ + ꙗ҆кꙋ́тское зи́мнее вре́мѧ + ꙗ҆кꙋ́тское лѣ́тнее вре́мѧ + + + + + є҆катерїнбꙋ́ржское вре́мѧ + є҆катерїнбꙋ́ржское зи́мнее вре́мѧ + є҆катерїнбꙋ́ржское лѣ́тнее вре́мѧ + + + + + + latn + + cyrl + + + , +   + % + + + - + + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0 % + + + + + + + #,##0.00 ¤ + + + {0} {1} + + + + бразі́льскїй реа́лъ + бразі́льскагѡ реа́ла + R$ + R$ + + + бѣлорꙋ́сскїй рꙋ́бль + бѣлорꙋ́сскагѡ рꙋблѧ̀ + BYN + р. + + + бѣлорꙋ́сскїй рꙋ́бль (2000–2016) + бѣлорꙋ́сскагѡ рꙋблѧ̀ (2000–2016) + BYR + + + хи́нскїй ю҆а́нь + хи́нскагѡ ю҆а́нѧ + CN¥ + ¥ + + + є҆́ѵрѡ + є҆́ѵра + + + + + а҆нглі́йскїй фꙋ́нтъ сте́рлингѡвъ + а҆нглі́йскагѡ фꙋ́нта сте́рлингѡвъ + £ + £ + + + і҆нді́йскаѧ рꙋ́пїѧ + і҆нді́йскїѧ рꙋ́пїи + + + + + ꙗ҆пѡ́нскаѧ і҆е́на + ꙗ҆пѡ́нскїѧ і҆е́ны + JP¥ + ¥ + + + кирги́зскїй сꙋ́мъ + кирги́зскагѡ сꙋ́ма + KGS + + + каза́хскаѧ деньга̀ + каза́хскїѧ деньгѝ + + + + + рѡссі́йскїй рꙋ́бль + рѡссі́йскагѡ рꙋблѧ̀ + + + + + ᲂу҆краи́нскаѧ гри́вна + ᲂу҆краи́нскїѧ гри́вны + + + + + а҆мерїка́нскїй до́лларъ + а҆мерїка́нскагѡ до́ллара + $ + $ + + + невѣ́домое пла́тное сре́дство + невѣ́домагѡ пла́тнагѡ сре́дства + + + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0}, {1} + {0}, {1} + {0} и҆ {1} + {0} и҆ {1} + + + {0}, {1} + {0}, {1} + {0}, {1} + {0}, {1} + + + {0}, {1} + {0}, {1} + {0}, {1} + {0}, {1} + + + {0}, {1} + {0}, {1} + {0}, {1} + {0}, {1} + + + + + є҆́й:є + нѝ:н + + + diff --git a/make/data/cldr/common/main/cu_RU.xml b/make/data/cldr/common/main/cu_RU.xml new file mode 100644 index 00000000000..120c8710823 --- /dev/null +++ b/make/data/cldr/common/main/cu_RU.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/cv.xml b/make/data/cldr/common/main/cv.xml index 07a49b6c516..a6422ca0f3d 100644 --- a/make/data/cldr/common/main/cv.xml +++ b/make/data/cldr/common/main/cv.xml @@ -1,6 +1,6 @@ - + + + + + + + + ދިވެހިބަސް + + + ދިވެހި ރާއްޖެ + + + + + right-to-left + + + + [ހ ށ ނ ރ ބ ޅ ކ އ ވ މ ފ ދ ތ ލ ގ ޏ ސ ޑ ޒ ޓ ޔ ޕ ޖ ޗ \u07A6 \u07A7 \u07A8 \u07A9 \u07AA \u07AB \u07AC \u07AD \u07AE \u07AF \u07B0] + [\u200C\u200D ޙ ޚ ޜ ޢ ޣ ޥ ޛ ޘ ޠ ޡ ޤ ޝ ޞ ޟ ޱ] + [ހ ށ ނ ރ ބ ޅ ކ އ ވ މ ފ ދ ތ ލ ގ ޏ ސ ޑ ޒ ޓ ޔ ޕ ޖ ޗ] + + + + + + + + EEEE d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + dd-MM-y G + GyMMdd + + + + + d-M-yy GGGGG + GGGGGyyMd + + + + + + + + + EEEE d MMMM y + yMMMMEEEEd + + + + + d MMMM y + yMMMMd + + + + + dd-MM-y + yMMdd + + + + + d-M-yy + yyMd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + + + arab + + + ، + + + , + + + + + #,##,##0.### + + + + + + + #,##,##0% + + + + + + + ¤ #,##,##0.00 + + + + + + ރ. + + + + diff --git a/make/data/cldr/common/main/dv_MV.xml b/make/data/cldr/common/main/dv_MV.xml new file mode 100644 index 00000000000..7d07ed90b72 --- /dev/null +++ b/make/data/cldr/common/main/dv_MV.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/dyo.xml b/make/data/cldr/common/main/dyo.xml index 46cc8d4d63e..4d83bbf6400 100644 --- a/make/data/cldr/common/main/dyo.xml +++ b/make/data/cldr/common/main/dyo.xml @@ -1,6 +1,6 @@ - + + + + + + + + + Ἀραβικά + Ἀραμαϊκά + Οὐαλικά + Αἰγυπτιακὰ (ἀρχαῖα) + Ἑλληνικά + Ἀγγλικά + Ἱσπανικά + Ἐσθονικά + Ἰρλανδικά + Σκωτικὰ κελτικά + Ἀρχαῖα Ἑλληνικά + Ἑβραϊκά + Οὑγγρικά + Ἀρμενικά + Ἰνδονησιακά + Ἰσλανδικά + Ἰταλικά + Ἰαπωνικά + Πολλαπλές γλῶσσες + Ὁλλανδικά + Τουρκικά, ὀθωμανικὰ + Ἀρχαῖα περσικὰ + Ἀλβανικά + Οὐκρανικά + Ἰουδαϊκά + + + + + + + + + + Ἀνδόρα + Ἠνωμένα Ἀραβικὰ Ἐμιράτα + Ἀφγανιστάν + Ἀντίγκουα καὶ Μπαρμπούντα + Ἀνγκουίλα + Ἀλβανία + Ἀρμενία + Ἀνγκόλα + Ἀνταρκτική + Ἀργεντινή + Ἀμερικανικὴ Σαμόα + Αὐστρία + Αὐστραλία + Ἀρούμπα + Ἀζερμπαϊτζάν + Βοσνία - Ἐρζεγοβίνη + Βερμοῦδες + Νῆσος Μπουβέ + Νῆσοι Κόκος (Κήλινγκ) + Κονγκό, Λαϊκὴ Δημοκρατία τοῦ + Κεντροαφρικανικὴ Δημοκρατία + Ἑλβετία + Ἀκτὴ Ἐλεφαντοστού + Ακτή Ελεφαντοστού + Νῆσοι Κούκ + Πράσινο Ἀκρωτήριο + Νῆσος Χριστουγέννων + Δομινικανὴ Δημοκρατία + Ἀλγερία + Ἰσημερινός + Ἐσθονία + Αἴγυπτος + Δυτικὴ Σαχάρα + Ἐρυθραία + Ἱσπανία + Αἰθιοπία + Εὐρωπαϊκὴ ᾿Ένωση + Μικρονησία, Ὁμόσπονδες Πολιτεῖες τῆς + Νῆσοι Φερόες + Ἡνωμένο Βασίλειο + Γαλλικὴ Γουιάνα + Ἰσημερινὴ Γουινέα + Ἑλλάδα + Νότια Γεωργία καὶ Νότιες Νήσοι Σάντουιτς + Χὸνγκ Κόνγκ, Εἰδικὴ Διοικητικὴ Περιφέρεια τῆς Κίνας + Νῆσοι Χὲρντ καὶ Μακντόναλντ + Ὁνδούρα + Ἁϊτή + Οὑγγαρία + Ἰνδονησία + Ἰρλανδία + Ἰσραήλ + Ἰνδία + Βρετανικὰ Ἐδάφη Ἰνδικοῦ Ὠκεανοῦ + Ἰράκ + Ἰράν, Ἰσλαμικὴ Δημοκρατία τοῦ + Ἰσλανδία + Ἰταλία + Ἰορδανία + Ἰαπωνία + Σαὶντ Κὶτς καὶ Νέβις + Νῆσοι Κέιμαν + Λατινικὴ Ἀμερική + Ἁγία Λουκία + Σρὶ Λάνκα + Λουξεμβοῦργο + Μολδαβία, Δημοκρατία τῆς + Νῆσοι Μάρσαλ + Μαλί + Μακάο, Εἰδικὴ Διοικητικὴ Περιφέρεια τῆς Κίνας + Νῆσοι Βόρειες Μαριάνες + Νῆσος Νόρφολκ + Ὁλλανδία + Ὀμάν + Γαλλικὴ Πολυνησία + Σαὶντ Πιὲρ καὶ Μικελόν + Παλαιστινιακὰ Ἐδάφη + Σαουδικὴ Ἀραβία + Νῆσοι Σολομῶντος + Ἁγία Ἑλένη + Νῆσοι Σβάλμπαρ καὶ Γιὰν Μαγιέν + Ἅγιος Μαρίνος + Σάο Τομὲ καὶ Πρίνσιπε + Ἒλ Σαλβαδόρ + Συρία, Ἀραβικὴ Δημοκρατία τῆς + Νῆσοι Τὲρκς καὶ Κάικος + Τσάντ + Γαλλικὰ Νότια Ἐδάφη + Ἀνατολικὸ Τιμόρ + Τρινιδὰδ καὶ Τομπάγκο + Οὐκρανία + Οὐγκάντα + Ἀπομακρυσμένες Νησίδες τῶν Ἡνωμένων Πολιτειῶν + Ἡνωμένες Πολιτεῖες + Οὐρουγουάη + Οὐζμπεκιστάν + Ἁγία Ἕδρα (Βατικανό) + Ἅγιος Βικέντιος καὶ Γρεναδίνες + Βρετανικὲς Παρθένοι Νῆσοι + Ἀμερικανικὲς Παρθένοι Νῆσοι + Νῆσοι Οὐάλλις καὶ Φουτουνά + Ὑεμένη + Νότια Ἀφρική + + + Ἡμερολόγιο + + + Βουδιστικὸ ἡμερολόγιο + Κινεζικὸ ἡμερολόγιο + Γρηγοριανὸ ἡμερολόγιο + Ἑβραϊκὸ ἡμερολόγιο + Ἰσλαμικὸ ἡμερολόγιο + Ἰσλαμικὸ ἀστικὸ ἡμερολόγιο + Ἰαπωνικὸ ἡμερολόγιο + Σειρὰ τηλεφωνικοῦ καταλόγου + Σειρὰ Πίνγιν + Σειρὰ Stroke + + + + [α ἀ ἄ ἂ ἆ ἁ ἅ ἃ ἇ ά ὰ ᾶ β γ δ ε ἐ ἔ ἒ ἑ ἕ ἓ έ ὲ ζ η ἠ ἤ ἢ ἦ ἡ ἥ ἣ ἧ ή ὴ ῆ θ ι ἰ ἴ ἲ ἶ ἱ ἵ ἳ ἷ ί ὶ ῖ ϊ ΐ ῒ ῗ κ λ μ ν ξ ο ὄ ὂ ὃ ό ὸ π ρ σ ς τ υ ὐ ὔ ὒ ὖ ὑ ὕ ὓ ὗ ύ ὺ ῦ ϋ ΰ ῢ ῧ φ χ ψ ω ὤ ὢ ὦ ὥ ὣ ὧ ώ ὼ ῶ] + [] + + + + + + + + + + + + Ιαν + Φεβ + Μαρ + Απρ + Μαΐ + Ιουν + Ιουλ + Αὐγ + Σεπ + Ὀκτ + Νοε + Δεκ + + + Ιανουαρίου + Φεβρουαρίου + Μαρτίου + Απριλίου + Μαΐου + Ιουνίου + Ιουλίου + Αὐγούστου + Σεπτεμβρίου + Ὀκτωβρίου + Νοεμβρίου + Δεκεμβρίου + + + + + Ιανουάριος + Φεβρουάριος + Μάρτιος + Απρίλιος + Μάιος + Ιούνιος + Ιούλιος + Αὔγουστος + Σεπτέμβριος + Ὀκτώβριος + Νοέμβριος + Δεκέμβριος + + + + + + + + + + Πεσέτα Ἀνδόρας + + + Ντιρὰμ Ἡνωμένων Ἀραβικῶν Ἐμιράτων + + + Λὲκ Ἀλβανίας + + + Dram Ἀρμενίας + + + Γκίλντα Ὁλλανδικῶν Ἀντιλλῶν + + + Kwanza Ἀνγκόλας + + + Kwanza Ἀνγκόλας (1977–1990) + + + Νέα Kwanza Ἀνγκόλας (1990–2000) + + + Kwanza Reajustado Ἀνγκόλας (1995–1999) + + + Austral Ἀργεντινῆς + + + Πέσο Ἀργεντινῆς (1983–1985) + + + Πέσο Ἀργεντινῆς + + + Σελίνι Αὐστρίας + + + Δολάριο Αὐστραλίας + + + Γκίλντα Ἀρούμπα + + + Μανὰτ Ἀζερμπαϊτζάν + + + Δηνάριο Βοσνίας-Ἑρζεγοβίνης + + + Μάρκο Βοσνίας-Ἑρζεγοβίνης + + + Φράγκο Βελγίου (οἰκονομικό) + + + Μεταλλικὸ Λὲβ Βουλγαρίας + + + Νέο Λὲβ Βουλγαρίας + + + Δολάριο Καναδᾶ + + + Φράγκο Ἑλβετίας + + + Unidades de Fomento Χιλῆς + + + Πέσο Χιλῆς + + + Σκληρὴ Κορόνα Τσεχοσλοβακίας + + + Ἐσκούδο Πράσινου Ἀκρωτηρίου + + + Ostmark Ἀνατολικῆς Γερμανίας + + + Δηνάριο Ἀλγερίας + + + Sucre Ἰσημερινοῦ + + + Unidad de Valor Constante (UVC) Ἰσημερινοῦ + + + Κορόνα Ἐστονίας + + + Λίρα Αἰγύπτου + + + Nakfa Ἐρυθραίας + + + Πεσέτα Ἱσπανίας + + + Birr Αἰθιοπίας + + + Εὐρώ + + + Λίρα Νήσων Φώλκλαντ + + + Dalasi Γκάμπιας + + + Ekwele Guineana Ἰσημερινῆς Γουινέας + + + Quetzal Γουατεμάλας + + + Γκινέα Ἐσκούδο Πορτογαλίας + + + Δολάριο Χὸνγκ Κόνγκ + + + Gourde Ἁϊτῆς + + + Φιορίνι Οὑγγαρίας + + + Ρούπια Ἰνδονησίας + + + Λίρα Ἰρλανδίας + + + Λίρα Ἰσραήλ + + + Νέο Sheqel Ἰσραήλ + + + Ρούπια Ἰνδίας + + + Δηνάριο Ἰράκ + + + Rial Ἰράκ + + + Κορόνα Ἰσλανδίας + + + Λιρέτα Ἰταλίας + + + Δηνάριο Ἰορδανίας + + + Γιὲν Ἰαπωνίας + + + Ρούπια Σρὶ Λάνκας + + + Pataca Μακάου + + + Πέσο Μεξικοῦ + + + Ἀσημένιο Πέσο Μεξικοῦ (1861–1992) + + + Unidad de Inversion (UDI) Μεξικοῦ + + + Ἐσκούδο Μοζαμβίκης + + + Χρυσὴ Κόρδοβα Νικαράγουας + + + Γκίλντα Ὁλλανδίας + + + Μπαλμπόα Παναμᾶ + + + Kina Παπούα Νέα Γουινέας + + + Ἐσκούδο Πορτογαλίας + + + Γκουαρανὶ Παραγουάης + + + Δολάριο Νήσων Σολομῶντος + + + Ρούπια Σεϋχελῶν + + + Λίρα Ἀγίας Ἑλένης + + + Σοβιετικὸ Ρούβλι + + + Colon Ἒλ Σαλβαδόρ + + + Lilangeni Ζουαζιλάνδης + + + Μπὰτ Ταϊλάνδης + + + Μανὰτ Τουρκμενιστάν + + + Ἐσκούδο Τιμόρ + + + Δολάριο Τρινιδὰδ καὶ Τομπάγκο + + + Hryvnia Οὐκρανίας + + + Karbovanetz Οὐκρανίας + + + Σελίνι Οὐγκάντας (1966–1987) + + + Σελίνι Οὐγκάντας + + + Δολάριο ΗΠΑ (Ἑπόμενη ἡμέρα) + + + Δολάριο ΗΠΑ (Ἴδια ἡμέρα) + + + Πέσο Οὐρουγουάης (1975–1993) + + + Πέσο Uruguayo Οὐρουγουάης + + + Sum Οὐζμπεκιστάν + + + Μπολιβὰλ Βενεζουέλας + + + Tala Δυτικῆς Σαμόας + + + Εὐρωπαϊκὴ Σύνθετη Μονάδα + + + Εὐρωπαϊκὴ Νομισματικὴ Μονάδα + + + Εὐρωπαϊκὴ Μονάδα Λογαριασμοῦ (XBC) + + + Εὐρωπαϊκὴ Μονάδα Λογαριασμοῦ (XBD) + + + Δολάριο Ἀνατολικῆς Καραϊβικῆς + + + Εἰδικὰ Δικαιώματα Ἀνάληψης + + + Εὐρωπαϊκὴ Συναλλαγματικὴ Μονάδα + + + Χρυσὸ Φράγκο Γαλλίας + + + Δηνάριο Ὑεμένης + + + Rial Ὑεμένης + + + Μεταλλικὸ Δηνάριο Γιουγκοσλαβίας + + + Ραντ Νότιας Ἀφρικῆς (οἰκονομικό) + + + Ρὰντ Νότιας Ἀφρικῆς + + + + + + Ναί + Ὄχι + + + diff --git a/make/data/cldr/common/main/en.xml b/make/data/cldr/common/main/en.xml index a6c7c0e7ae5..32abf37721f 100644 --- a/make/data/cldr/common/main/en.xml +++ b/make/data/cldr/common/main/en.xml @@ -1,6 +1,6 @@ - - - Sinbad + + Zendaya - + Irene Adler - - John + + Mary Sue Hamish Watson - - Prof. Dr. + + Mr. + Bertram Wilberforce + Bertie + Henry Robert + ∅∅∅ + Wooster + ∅∅∅ + Jr + MP + + + Sinbad + + + Käthe + Müller + + + Zäzilia + Hamish + Stöber + + + Prof. Dr. Ada Cornelia Neele - Eva Sophia - van den - Wolf - Becker Schmidt - M.D. Ph.D. + César Martín + von + Brühl + González Domingo + Jr + MD DDS diff --git a/make/data/cldr/common/main/en_001.xml b/make/data/cldr/common/main/en_001.xml index 62ca51a8325..d3b2346c27a 100644 --- a/make/data/cldr/common/main/en_001.xml +++ b/make/data/cldr/common/main/en_001.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 𐐎𐐲𐑉𐑊𐐼 + 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐤𐐱𐑉𐑃 𐐊𐑋𐐯𐑉𐐲𐐿𐐲 + 𐐝𐐵𐑃 𐐊𐑋𐐯𐑉𐐲𐐿𐐲 + 𐐄𐑇𐐨𐐰𐑌𐐨𐐲 + 𐐎𐐯𐑅𐐻𐐲𐑉𐑌 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐊𐑋𐐯𐑉𐐲𐐿𐐲 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐤𐐱𐑉𐑄𐐲𐑉𐑌 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐣𐐮𐐼𐑊 𐐈𐑁𐑉𐐮𐐿𐐲 + 𐐝𐐲𐑄𐐲𐑉𐑌 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐊𐑋𐐯𐑉𐐲𐐿𐐲𐑆 + 𐐤𐐱𐑉𐑄𐐲𐑉𐑌 𐐊𐑋𐐯𐑉𐐲𐐿𐐲 + 𐐗𐐯𐑉𐐲𐐺𐐨𐐲𐑌 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐁𐑈𐐲 + 𐐝𐐲𐑄𐐲𐑉𐑌 𐐁𐑈𐐲 + 𐐝𐐵𐑃-𐐀𐑅𐐻𐐲𐑉𐑌 𐐁𐑈𐐲 + 𐐝𐐲𐑄𐐲𐑉𐑌 𐐏𐐲𐑉𐐲𐐹 + 𐐉𐑅𐐻𐑉𐐩𐑊𐐨𐐲 𐐰𐑌𐐼 𐐤𐐭 𐐞𐐨𐑊𐐲𐑌𐐼 + 𐐣𐐯𐑊𐐲𐑌𐐨𐑈𐐲 + 𐐣𐐴𐐿𐑉𐐲𐑌𐐨𐑈𐐲𐑌 𐐡𐐨𐐾𐐲𐑌 + 𐐑𐐪𐑊𐐲𐑌𐐨𐑈𐐲 + 𐐁𐑈𐐲 + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐁𐑈𐐲 + 𐐎𐐯𐑅𐐻𐐲𐑉𐑌 𐐁𐑈𐐲 + 𐐏𐐲𐑉𐐲𐐹 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐏𐐲𐑉𐐲𐐹 + 𐐤𐐱𐑉𐑄𐐲𐑉𐑌 𐐏𐐲𐑉𐐲𐐹 + 𐐎𐐯𐑅𐐻𐐲𐑉𐑌 𐐏𐐲𐑉𐐲𐐹 + 𐐢𐐰𐐻𐑌 𐐊𐑋𐐯𐑉𐐲𐐿𐐲 𐐰𐑌𐐼 𐑄 𐐗𐐯𐑉𐐲𐐺𐐨𐐲𐑌 + 𐐈𐑌𐐼𐐱𐑉𐐲 + 𐐏𐐭𐑌𐐴𐐼𐐮𐐼 𐐇𐑉𐐲𐐺 𐐇𐑋𐐲𐑉𐐩𐐻𐑅 + 𐐈𐑁𐑀𐐰𐑌𐐲𐑅𐐻𐐰𐑌 + 𐐈𐑌𐐻𐐨𐑀𐐶𐐲 𐐰𐑌𐐼 𐐒𐐪𐑉𐐺𐐷𐐭𐐼𐐲 + 𐐈𐑍𐑀𐐶𐐮𐑊𐐲 + 𐐈𐑊𐐺𐐩𐑌𐐨𐐲 + 𐐂𐑉𐑋𐐨𐑌𐐨𐐲 + 𐐈𐑌𐑀𐐬𐑊𐐲 + 𐐈𐑌𐐻𐐪𐑉𐐿𐐻𐐮𐐿𐐲 + 𐐂𐑉𐐾𐐲𐑌𐐻𐐨𐑌𐐲 + 𐐊𐑋𐐯𐑉𐐲𐐿𐐲𐑌 𐐝𐐲𐑋𐐬𐐲 + 𐐉𐑅𐐻𐑉𐐨𐐲 + 𐐉𐑅𐐻𐑉𐐩𐑊𐐨𐐲 + 𐐊𐑉𐐭𐐺𐐲 + 𐐈𐑊𐐰𐑌𐐼 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐈𐑆𐐲𐑉𐐺𐐴𐑈𐐪𐑌 + 𐐒𐐱𐑆𐑌𐐨𐐲 𐐰𐑌𐐼 𐐐𐐲𐑉𐐻𐑅𐐲𐑀𐐬𐑂𐐨𐑌𐐲 + 𐐒𐐪𐑉𐐺𐐩𐐼𐐬𐑅 + 𐐒𐐪𐑍𐑀𐑊𐐲𐐼𐐯𐑇 + 𐐒𐐯𐑊𐐾𐐲𐑋 + 𐐒𐐲𐑉𐐿𐐩𐑌𐐲 𐐙𐐰𐑅𐐬 + 𐐒𐐲𐑊𐑀𐐯𐑉𐐨𐐲 + 𐐒𐐪𐑉𐐩𐑌 + 𐐒𐐲𐑉𐐳𐑌𐐼𐐨 + 𐐒𐐲𐑌𐐨𐑌 + 𐐝𐐩𐑌𐐻 𐐒𐐪𐑉𐐻𐐩𐑊𐐲𐑋𐐨 + 𐐒𐐲𐑉𐑋𐐷𐐭𐐼𐐲 + 𐐒𐑉𐐭𐑌𐐴 + 𐐒𐐬𐑊𐐮𐑂𐐨𐐲 + 𐐒𐑉𐐲𐑆𐐮𐑊 + 𐐒𐐲𐐸𐐪𐑋𐐲𐑅 + 𐐒𐐭𐐻𐐪𐑌 + 𐐒𐐭𐑂𐐩 𐐌𐑊𐐲𐑌𐐼 + 𐐒𐐪𐐻𐑅𐐶𐐪𐑌𐐲 + 𐐒𐐯𐑊𐐲𐑉𐐭𐑅 + 𐐒𐐲𐑊𐐨𐑆 + 𐐗𐐰𐑌𐐲𐐼𐐲 + 𐐗𐐬𐐿𐐬𐑆 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐗𐐪𐑍𐑀𐐬 - 𐐗𐐲𐑌𐑇𐐪𐑅𐐲 + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐈𐑁𐑉𐐲𐐿𐐲𐑌 𐐡𐐨𐐹𐐲𐐺𐑊𐐮𐐿 + 𐐗𐐪𐑍𐑀𐐬 - 𐐒𐑉𐐪𐑆𐐲𐑂𐐮𐑊 + 𐐝𐐶𐐮𐐻𐑅𐐲𐑉𐑊𐐲𐑌𐐼 + 𐐌𐑂𐑉𐐨 𐐗𐐬𐑅𐐻 + 𐐗𐐳𐐿 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐕𐐨𐑊𐐩 + 𐐗𐐰𐑋𐐲𐑉𐐭𐑌 + 𐐕𐐴𐑌𐐲 + 𐐗𐐲𐑊𐐲𐑋𐐺𐐨𐐲 + 𐐗𐐱𐑅𐐻𐐲 𐐡𐐨𐐿𐐲 + 𐐗𐐷𐐭𐐺𐐲 + 𐐗𐐩𐐹 𐐚𐐯𐑉𐐼𐐨 + 𐐗𐑉𐐮𐑅𐑋𐐲𐑅 𐐌𐑊𐐲𐑌𐐼 + 𐐝𐐴𐐹𐑉𐐲𐑅 + 𐐕𐐯𐐿 𐐡𐐨𐐹𐐲𐐺𐑊𐐮𐐿 + 𐐖𐐲𐑉𐑋𐐲𐑌𐐨 + 𐐖𐐲𐐺𐐭𐐼𐐨 + 𐐔𐐯𐑌𐑋𐐪𐑉𐐿 + 𐐔𐐪𐑋𐐲𐑌𐐨𐐿𐐲 + 𐐔𐐲𐑋𐐮𐑌𐐲𐐿𐐲𐑌 𐐡𐐨𐐹𐐲𐐺𐑊𐐮𐐿 + 𐐈𐑊𐐾𐐮𐑉𐐨𐐲 + 𐐇𐐿𐐶𐐲𐐼𐐱𐑉 + 𐐇𐑅𐐻𐐬𐑌𐐨𐐲 + 𐐀𐐾𐐲𐐹𐐻 + 𐐎𐐯𐑅𐐻𐐲𐑉𐑌 𐐝𐐲𐐸𐐱𐑉𐐲 + 𐐇𐑉𐐮𐐻𐑉𐐨𐐲 + 𐐝𐐹𐐩𐑌 + 𐐀𐑃𐐨𐐬𐐹𐐨𐐲 + 𐐏𐐲𐑉𐐲𐐹𐐨𐐲𐑌 𐐏𐐭𐑌𐐷𐐲𐑌 + 𐐙𐐮𐑌𐑊𐐲𐑌𐐼 + 𐐙𐐨𐐾𐐨 + 𐐙𐐪𐑊𐐿𐑊𐐲𐑌𐐼 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐣𐐴𐐿𐑉𐐲𐑌𐐨𐑈𐐲 + 𐐙𐐯𐑉𐐬 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐙𐑉𐐰𐑌𐑅 + 𐐘𐐲𐐺𐐪𐑌 + 𐐏𐐭𐑌𐐴𐐻𐐲𐐼 𐐗𐐨𐑍𐐼𐐲𐑋 + 𐐘𐑉𐐲𐑌𐐩𐐼𐐲 + 𐐖𐐱𐑉𐐾𐐲 + 𐐙𐑉𐐯𐑌𐐽 𐐘𐐨𐐪𐑌𐐲 + 𐐘𐐲𐑉𐑌𐑆𐐨 + 𐐘𐐪𐑌𐐲 + 𐐖𐐲𐐺𐑉𐐱𐑊𐐻𐐲𐑉 + 𐐘𐑉𐐨𐑌𐑊𐐲𐑌𐐼 + 𐐘𐐰𐑋𐐺𐐨𐐲 + 𐐘𐐮𐑌𐐨 + 𐐘𐐶𐐪𐐼𐐲𐑊𐐭𐐹 + 𐐇𐐿𐐶𐐲𐐻𐐱𐑉𐐨𐐲𐑊 𐐘𐐮𐑌𐐨 + 𐐘𐑉𐐨𐑅 + 𐐝𐐵𐑃 𐐖𐐱𐑉𐐾𐐲 𐐰𐑌𐐼 𐑄 𐐝𐐵𐑃 𐐝𐐰𐑌𐐼𐐶𐐮𐐽 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐘𐐶𐐪𐐼𐐲𐑋𐐪𐑊𐐲 + 𐐘𐐶𐐪𐑋 + 𐐘𐐮𐑌𐐨-𐐒𐐮𐑅𐐵 + 𐐘𐐴𐐰𐑌𐐲 + 𐐐𐐬𐑍 𐐗𐐬𐑍 𐐝𐐈𐐡 𐐕𐐴𐑌𐐲 + 𐐐𐐬𐑍 𐐗𐐬𐑍 + 𐐐𐐲𐑉𐐼 𐐌𐑊𐐲𐑌𐐼 𐐰𐑌𐐼 𐐣𐐿𐐔𐐱𐑌𐐲𐑊𐐼 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐐𐐪𐑌𐐼𐐭𐑉𐐲𐑅 + 𐐗𐑉𐐬𐐩𐑇𐐲 + 𐐐𐐩𐐻𐐨 + 𐐐𐐲𐑍𐑀𐐲𐑉𐐨 + 𐐆𐑌𐐼𐐲𐑌𐐨𐑈𐐲 + 𐐌𐑉𐑊𐐲𐑌𐐼 + 𐐆𐑆𐑉𐐨𐐲𐑊 + 𐐌𐐲𐑊 𐐲𐑁 𐐣𐐰𐑌 + 𐐆𐑌𐐼𐐨𐐲 + 𐐒𐑉𐐮𐐼𐐮𐑇 𐐆𐑌𐐼𐐨𐐲𐑌 𐐄𐑇𐐲𐑌 𐐓𐐯𐑉𐐲𐐻𐐱𐑉𐐨 + 𐐆𐑉𐐰𐐿 + 𐐆𐑉𐐪𐑌 + 𐐌𐑅𐑊𐐲𐑌𐐼 + 𐐆𐐻𐐲𐑊𐐨 + 𐐖𐐲𐑉𐑆𐐨 + 𐐖𐐲𐑋𐐩𐐿𐐲 + 𐐖𐐱𐑉𐐼𐐲𐑌 + 𐐖𐐲𐐹𐐰𐑌 + 𐐗𐐯𐑌𐐷𐐲 + 𐐗𐐮𐑉𐑀𐐲𐑅𐐻𐐰𐑌 + 𐐗𐐰𐑋𐐺𐐬𐐼𐐨𐐲 + 𐐗𐐮𐑉𐐲𐐺𐐪𐐻𐐨 + 𐐗𐐪𐑋𐐲𐑉𐐬𐑆 + 𐐝𐐩𐑌𐐻 𐐗𐐮𐐻𐑅 𐐰𐑌𐐼 𐐤𐐨𐑂𐐮𐑅 + 𐐤𐐱𐑉𐑃 𐐗𐐲𐑉𐐨𐐲 + 𐐝𐐵𐑃 𐐗𐐲𐑉𐐨𐐲 + 𐐗𐐲𐐶𐐩𐐻 + 𐐗𐐩𐑋𐐲𐑌 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐗𐐲𐑆𐐪𐐿𐑅𐐻𐐪𐑌 + 𐐢𐐪𐐬𐑅 + 𐐢𐐯𐐺𐐲𐑌𐐪𐑌 + 𐐢𐐮𐐿𐐻𐐲𐑌𐑅𐐻𐐴𐑌 + 𐐟𐑉𐐨 𐐢𐐰𐑍𐐿𐐲 + 𐐢𐐴𐐺𐐮𐑉𐐨𐐲 + 𐐢𐐲𐑅𐐬𐑃𐐬 + 𐐢𐐮𐑃𐐲𐐶𐐩𐑌𐐨𐐲 + 𐐢𐐲𐐿𐑅𐐲𐑋𐐺𐐲𐑉𐑀 + 𐐢𐐰𐐻𐑂𐐨𐐲 + 𐐢𐐮𐐺𐐨𐐲 + 𐐣𐐲𐑉𐐪𐐿𐐬 + 𐐣𐐪𐑌𐐲𐐿𐐬 + 𐐣𐐱𐑊𐐼𐐬𐑂𐐲 + 𐐣𐐪𐑌𐐲𐑌𐐨𐑀𐑉𐐬 + 𐐝𐐩𐑌𐐻 𐐣𐐪𐑉𐐻𐑌 + 𐐣𐐰𐐼𐐲𐑀𐐰𐑅𐐿𐐲𐑉 + 𐐣𐐪𐑉𐑇𐐲𐑊 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐣𐐰𐑅𐐲𐐼𐐬𐑌𐐨𐐲 + 𐐣𐐪𐑊𐐨 + 𐐣𐐨𐐲𐑌𐑋𐐪𐑉 + 𐐣𐐪𐑍𐑀𐐬𐑊𐐨𐐲 + 𐐣𐐲𐐿𐐵 𐐝𐐈𐐡 𐐕𐐴𐑌𐐲 + 𐐣𐐲𐐿𐐵 + 𐐤𐐱𐑉𐑄𐐲𐑉𐑌 𐐣𐐰𐑉𐐨𐐱𐑌𐐲 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐣𐐪𐑉𐐻𐑌𐐨𐐿 + 𐐣𐐱𐑉𐐲𐐻𐐩𐑌𐐨𐐲 + 𐐣𐐪𐑌𐐻𐑅𐐲𐑉𐐪𐐻 + 𐐣𐐱𐑊𐐻𐐲 + 𐐣𐐱𐑉𐐮𐑇𐐲𐑅 + 𐐣𐐪𐑊𐐼𐐨𐑂𐑆 + 𐐣𐐲𐑊𐐪𐐶𐐨 + 𐐣𐐯𐐿𐑅𐐲𐐿𐐬 + 𐐣𐐲𐑊𐐩𐑈𐐲 + 𐐣𐐬𐑆𐐰𐑋𐐺𐐨𐐿 + 𐐤𐐲𐑋𐐮𐐺𐐨𐐲 + 𐐤𐐭 𐐗𐐰𐑊𐐲𐐼𐐬𐑌𐐷𐐲 + 𐐤𐐴𐐾𐐲𐑉 + 𐐤𐐱𐑉𐑁𐐲𐐿 𐐌𐑊𐐲𐑌𐐼 + 𐐤𐐴𐐾𐐮𐑉𐐨𐐲 + 𐐤𐐮𐐿𐐲𐑉𐐪𐑀𐐶𐐲 + 𐐤𐐯𐑄𐐲𐑉𐑊𐐲𐑌𐐼𐑆 + 𐐤𐐱𐑉𐐶𐐩 + 𐐤𐐩𐐹𐐪𐑊 + 𐐤𐐪𐐭𐑉𐐭 + 𐐤𐐷𐐭𐐩 + 𐐤𐐭 𐐞𐐨𐑊𐐲𐑌𐐼 + 𐐄𐑋𐐲𐑌 + 𐐑𐐰𐑌𐐲𐑋𐐪 + 𐐑𐐲𐑉𐐭 + 𐐙𐑉𐐯𐑌𐐽 𐐑𐐪𐑊𐐲𐑌𐐨𐑈𐐲 + 𐐑𐐰𐐹𐐷𐐳𐐲 𐐤𐐭 𐐘𐐮𐑌𐐨 + 𐐙𐐮𐑊𐐲𐐹𐐨𐑌𐑆 + 𐐑𐐰𐐿𐐲𐑅𐐻𐐰𐑌 + 𐐑𐐬𐑊𐐲𐑌𐐼 + 𐐝𐐩𐑌𐐻 𐐑𐐨𐐯𐑉 𐐰𐑌𐐼 𐐣𐐨𐐿𐐲𐑊𐐪𐑌 + 𐐑𐐮𐐻𐐿𐐯𐑉𐑌 + 𐐑𐐶𐐯𐑉𐐻𐐬 𐐡𐐨𐐿𐐬 + 𐐑𐐰𐑊𐐲𐑅𐐻𐐮𐑌𐐨𐐲𐑌 𐐓𐐯𐑉𐐲𐐻𐐱𐑉𐐨 + 𐐑𐐱𐑉𐐽𐐲𐑀𐐲𐑊 + 𐐑𐐲𐑊𐐵 + 𐐑𐐯𐑉𐐲𐑀𐐶𐐴 + 𐐗𐐲𐐻𐐪𐑉 + 𐐍𐐻𐑊𐐴𐐮𐑍 𐐄𐑇𐐨𐐰𐑌𐐨𐐲 + 𐐡𐐨𐐷𐐭𐑌𐐷𐐲𐑌 + 𐐡𐐬𐑋𐐩𐑌𐐨𐐲 + 𐐝𐐲𐑉𐐺𐐨𐐲 + 𐐡𐐲𐑇𐐲 + 𐐡𐐲𐐶𐐪𐑌𐐼𐐲 + 𐐝𐐵𐐼𐐨 𐐊𐑉𐐩𐐺𐐨𐐲 + 𐐝𐐪𐑊𐐲𐑋𐐲𐑌 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐝𐐩𐑇𐐯𐑊𐑆 + 𐐝𐐭𐐼𐐰𐑌 + 𐐝𐐶𐐨𐐼𐑌 + 𐐝𐐮𐑍𐐲𐐹𐐱𐑉 + 𐐝𐐩𐑌𐐻 𐐐𐐯𐑊𐐲𐑌𐐲 + 𐐝𐑊𐐬𐑂𐐨𐑌𐐨𐐲 + 𐐝𐑂𐐪𐑊𐐺𐐪𐑉𐐼 𐐰𐑌𐐼 𐐖𐐰𐑌 𐐣𐐴𐐲𐑌 + 𐐝𐑊𐐬𐑂𐐪𐐿𐐨𐐲 + 𐐝𐐨𐐯𐑉𐐲 𐐢𐐨𐐬𐑌 + 𐐝𐐪𐑌 𐐣𐐲𐑉𐐨𐑌𐐬 + 𐐝𐐯𐑌𐐲𐑀𐐱𐑊 + 𐐝𐐲𐑋𐐪𐑊𐐨𐐲 + 𐐝𐐭𐑉𐐲𐑌𐐪𐑋 + 𐐝𐐵 𐐓𐐬𐑋 𐐰𐑌𐐼 𐐑𐑉𐐮𐑌𐐽𐐮𐐹𐐩 + 𐐇𐑊 𐐝𐐰𐑊𐑂𐐲𐐼𐐱𐑉 + 𐐝𐐮𐑉𐐨𐐲 + 𐐝𐐶𐐪𐑆𐐨𐑊𐐰𐑌𐐼 + 𐐓𐐲𐑉𐐿𐑅 𐐰𐑌𐐼 𐐗𐐴𐐿𐐬𐑆 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐕𐐰𐐼 + 𐐙𐑉𐐯𐑌𐐽 𐐝𐐲𐑄𐐲𐑉𐑌 𐐓𐐯𐑉𐐲𐐻𐐱𐑉𐐨𐑆 + 𐐓𐐬𐑀𐐬 + 𐐓𐐴𐑊𐐰𐑌𐐼 + 𐐓𐐲𐐾𐐨𐐿𐐲𐑅𐐻𐐰𐑌 + 𐐓𐐬𐐿𐐯𐑊𐐵 + 𐐀𐑅𐐻 𐐓𐐨𐑋𐐱𐑉 + 𐐓𐐲𐑉𐐿𐑋𐐯𐑌𐐲𐑅𐐻𐐰𐑌 + 𐐓𐐪𐑍𐑀𐐲 + 𐐓𐐲𐑉𐐿𐐨 + 𐐓𐑉𐐮𐑌𐐮𐐼𐐰𐐼 𐐰𐑌𐐼 𐐓𐐲𐐺𐐩𐑀𐐬 + 𐐓𐐲𐑂𐐪𐑊𐐭 + 𐐓𐐴𐐶𐐪𐑌 + 𐐓𐐰𐑌𐑆𐐲𐑌𐐨𐐲 + 𐐏𐐭𐑀𐐰𐑌𐐼𐐲 + 𐐏𐐭𐑌𐐰𐐮𐐻𐐲𐐼 𐐝𐐻𐐩𐐻𐑅 𐐣𐐴𐑌𐐬𐑉 𐐍𐐻𐑊𐐴𐐨𐑍 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐏𐐭𐑌𐐴𐐻𐐲𐐼 𐐝𐐻𐐩𐐻𐑅 + 𐐏𐐳𐑉𐐲𐑀𐐶𐐴 + 𐐅𐑆𐐺𐐯𐐿𐐲𐑅𐐻𐐰𐑌 + 𐐚𐐰𐐼𐐲𐐿𐐲𐑌 + 𐐝𐐩𐑌𐐻 𐐚𐐮𐑌𐑅𐐲𐑌𐐻 𐐰𐑌𐐼 𐑄 𐐘𐑉𐐯𐑌𐐲𐐼𐐨𐑌𐑆 + 𐐒𐑉𐐮𐐼𐐮𐑇 𐐚𐐲𐑉𐐾𐐲𐑌 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐏.𐐝. 𐐚𐐲𐑉𐐾𐐲𐑌 𐐌𐑊𐐲𐑌𐐼𐑆 + 𐐚𐐨𐐯𐐻𐑌𐐪𐑋 + 𐐚𐐪𐑌𐐳𐐪𐐼𐐭 + 𐐎𐐪𐑊𐐮𐑅 𐐰𐑌𐐼 𐐙𐐭𐐻𐐭𐑌𐐲 + 𐐝𐐲𐑋𐐬𐐲 + 𐐏𐐯𐑋𐐲𐑌 + 𐐣𐐪𐐷𐐱𐐻 + 𐐝𐐵𐑃 𐐈𐑁𐑉𐐲𐐿𐐲 + 𐐞𐐰𐑋𐐺𐐨𐐲 + 𐐞𐐮𐑋𐐺𐐪𐐺𐐶𐐩 + 𐐊𐑌𐐬𐑌 𐐬𐑉 𐐆𐑌𐑂𐐰𐑊𐐮𐐼 𐐡𐐨𐐾𐐲𐑌 + + + 𐐓𐑉𐐲𐐼𐐮𐑇𐐲𐑌𐑊 𐐖𐐲𐑉𐑋𐐲𐑌 𐐱𐑉𐑃𐐪𐑀𐑉𐐲𐑁𐐨 + 𐐖𐐲𐑉𐑋𐐲𐑌 𐐱𐑉𐑃𐐪𐑀𐑉𐐲𐑁𐐨 𐐲𐑂 1996 + 𐐢𐐩𐐻 𐐣𐐮𐐼𐑊 𐐙𐑉𐐯𐑌𐐽 𐐻𐐭 1606 + 𐐊𐑉𐑊𐐨 𐐣𐐪𐐼𐐲𐑉𐑌 𐐙𐑉𐐯𐑌𐐽 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐂𐑉𐑋𐐨𐑌𐐨𐐲𐑌 + 𐐎𐐯𐑅𐐻𐐲𐑉𐑌 𐐂𐑉𐑋𐐨𐑌𐐨𐐲𐑌 + 𐐏𐐭𐑌𐐲𐑁𐐴𐐼 𐐓𐐲𐑉𐐿𐐮𐐿 𐐢𐐰𐐻𐑌 𐐈𐑊𐑁𐐲𐐺𐐲𐐻 + 𐐆𐐙𐐈 𐐙𐐬𐑌𐐯𐐻𐐮𐐿𐑅 + 𐐣𐐪𐑌𐐲𐐻𐐪𐑌𐐮𐐿 + 𐐑𐐱𐑊𐐨𐐻𐐱𐑌𐐮𐐿 + 𐐗𐐲𐑋𐐹𐐷𐐭𐐻𐐯𐑉 + 𐐡𐐲𐑂𐐴𐑆𐐼 𐐉𐑉𐑃𐐪𐑀𐑉𐐲𐑁𐐨 + 𐐝𐐿𐐪𐐼𐐮𐑇 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐆𐑍𐑊𐐮𐑇 + + + 𐑋𐐯𐐻𐑉𐐮𐐿 + 𐐏𐐝 + + + + [𐐨 𐐩 𐐪 𐐫 𐐬 𐐭 𐐮 𐐯 𐐰 𐐱 𐐲 𐐳 𐐴 𐐵 𐐶 𐐷 𐐸 𐐹 𐐺 𐐻 𐐼 𐐽 𐐾 𐐿 𐑀 𐑁 𐑂 𐑃 𐑄 𐑅 𐑆 𐑇 𐑈 𐑉 𐑊 𐑋 𐑌 𐑍 𐑎 𐑏] + [] + [𐐀 𐐁 𐐂 𐐃 𐐄 𐐅 𐐆 𐐇 𐐈 𐐉 𐐊 𐐋 𐐌 𐐍 𐐎 𐐏 𐐐 𐐑 𐐒 𐐓 𐐔 𐐕 𐐖 𐐗 𐐘 𐐙 𐐚 𐐛 𐐜 𐐝 𐐞 𐐟 𐐠 𐐡 𐐢 𐐣 𐐤 𐐥 𐐦 𐐧] + + + + + + + + 𐐖𐐰𐑌 + 𐐙𐐯𐐺 + 𐐣𐐪𐑉 + 𐐁𐐹𐑉 + 𐐣𐐩 + 𐐖𐐭𐑌 + 𐐖𐐭𐑊 + 𐐂𐑀 + 𐐝𐐯𐐹 + 𐐉𐐿𐐻 + 𐐤𐐬𐑂 + 𐐔𐐨𐑅 + + + 𐐖 + 𐐙 + 𐐣 + 𐐁 + 𐐣 + 𐐖 + 𐐖 + 𐐂 + 𐐝 + 𐐉 + 𐐤 + 𐐔 + + + 𐐖𐐰𐑌𐐷𐐭𐐯𐑉𐐨 + 𐐙𐐯𐐺𐑉𐐭𐐯𐑉𐐨 + 𐐣𐐪𐑉𐐽 + 𐐁𐐹𐑉𐐮𐑊 + 𐐣𐐩 + 𐐖𐐭𐑌 + 𐐖𐐭𐑊𐐴 + 𐐂𐑀𐐲𐑅𐐻 + 𐐝𐐯𐐹𐐻𐐯𐑋𐐺𐐲𐑉 + 𐐉𐐿𐐻𐐬𐐺𐐲𐑉 + 𐐤𐐬𐑂𐐯𐑋𐐺𐐲𐑉 + 𐐔𐐨𐑅𐐯𐑋𐐺𐐲𐑉 + + + + + 𐐖𐐰𐑌 + 𐐙𐐯𐐺 + 𐐣𐐪𐑉 + 𐐁𐐹𐑉 + 𐐣𐐩 + 𐐖𐐭𐑌 + 𐐖𐐭𐑊 + 𐐂𐑀 + 𐐝𐐯𐐹 + 𐐉𐐿𐐻 + 𐐤𐐬𐑂 + 𐐔𐐨𐑅 + + + 𐐖 + 𐐙 + 𐐣 + 𐐁 + 𐐣 + 𐐖 + 𐐖 + 𐐂 + 𐐝 + 𐐉 + 𐐤 + 𐐔 + + + 𐐖𐐰𐑌𐐷𐐭𐐯𐑉𐐨 + 𐐙𐐯𐐺𐑉𐐭𐐯𐑉𐐨 + 𐐣𐐪𐑉𐐽 + 𐐁𐐹𐑉𐐮𐑊 + 𐐣𐐩 + 𐐖𐐭𐑌 + 𐐖𐐭𐑊𐐴 + 𐐂𐑀𐐲𐑅𐐻 + 𐐝𐐯𐐹𐐻𐐯𐑋𐐺𐐲𐑉 + 𐐉𐐿𐐻𐐬𐐺𐐲𐑉 + 𐐤𐐬𐑂𐐯𐑋𐐺𐐲𐑉 + 𐐔𐐨𐑅𐐯𐑋𐐺𐐲𐑉 + + + + + + + 𐐝𐐲𐑌 + 𐐣𐐲𐑌 + 𐐓𐐭𐑆 + 𐐎𐐯𐑌 + 𐐛𐐲𐑉 + 𐐙𐑉𐐴 + 𐐝𐐰𐐻 + + + 𐐝𐐲𐑌𐐼𐐩 + 𐐣𐐲𐑌𐐼𐐩 + 𐐓𐐭𐑆𐐼𐐩 + 𐐎𐐯𐑌𐑆𐐼𐐩 + 𐐛𐐲𐑉𐑆𐐼𐐩 + 𐐙𐑉𐐴𐐼𐐩 + 𐐝𐐰𐐻𐐲𐑉𐐼𐐩 + + + + + 𐐝 + 𐐣 + 𐐓 + 𐐎 + 𐐛 + 𐐙 + 𐐝 + + + + + + + 𐐗1 + 𐐗2 + 𐐗3 + 𐐗4 + + + 1𐑅𐐻 𐐿𐐶𐐪𐑉𐐻𐐲𐑉 + 2𐑌𐐼 𐐿𐐶𐐪𐑉𐐻𐐲𐑉 + 3𐑉𐐼 𐐿𐐶𐐪𐑉𐐻𐐲𐑉 + 4𐑉𐑃 𐐿𐐶𐐪𐑉𐐻𐐲𐑉 + + + + + + + 𐐈𐐣 + 𐐰𐑋 + 𐐑𐐣 + 𐐹𐑋 + + + 𐐈𐐣 + 𐐰𐑋 + 𐐑𐐣 + 𐐹𐑋 + + + + + + 𐐒𐐲𐑁𐐬𐑉 𐐗𐑉𐐴𐑅𐐻 + 𐐈𐑌𐐬 𐐔𐐱𐑋𐐮𐑌𐐨 + + + 𐐒𐐗 + 𐐈𐐔 + + + 𐐒 + 𐐈 + + + + + + + 𐐇𐑉𐐲 + + + 𐐏𐐨𐑉 + + + 𐐣𐐲𐑌𐑃 + + + 𐐎𐐨𐐿 + + + 𐐔𐐩 + 𐐜 𐐼𐐩 𐐺𐐲𐑁𐐬𐑉 𐐷𐐯𐑅𐐻𐐲𐑉𐐼𐐩 + 𐐏𐐯𐑅𐐻𐐲𐑉𐐼𐐩 + 𐐓𐐲𐐼𐐩 + 𐐓𐐲𐑋𐐱𐑉𐐬 + 𐐜 𐐼𐐩 𐐰𐑁𐐻𐐲𐑉 𐐻𐐲𐑋𐐱𐑉𐐬 + + + 𐐔𐐩 𐐲𐑂 𐑄 𐐎𐐨𐐿 + + + 𐐈𐐣/𐐑𐐣 + + + 𐐍𐑉 + + + 𐐣𐐮𐑌𐐲𐐻 + + + 𐐝𐐯𐐿𐐲𐑌𐐼 + + + 𐐞𐐬𐑌 + + + + 𐐘𐐣𐐓 {0} + 𐐘𐐣𐐓 + {0} 𐐓𐐴𐑋 + + 𐐊𐑌𐑌𐐬𐑌 + + + 𐐣𐐮𐐼𐐶𐐩 + + + 𐐎𐐩𐐿 + + + 𐐈𐐼𐐰𐐿 + + + 𐐤𐐬𐑋 + + + 𐐐𐐪𐑌𐐲𐑊𐐭𐑊𐐭 + + + 𐐖𐐪𐑌𐑅𐐻𐐲𐑌 + + + 𐐁𐑍𐐿𐐲𐑉𐐮𐐾 + + + 𐐏𐐰𐐿𐐭𐐻𐐰𐐻 + + + 𐐖𐐭𐑌𐐬 + + + 𐐢𐐱𐑅 𐐈𐑌𐐾𐐲𐑊𐑅 + + + 𐐒𐐱𐐮𐑆𐐨 + + + 𐐙𐐨𐑌𐐮𐐿𐑅 + + + 𐐔𐐯𐑌𐑂𐐲𐑉 + + + 𐐤𐐭 𐐝𐐩𐑊𐐲𐑋, 𐐤𐐱𐑉𐑃 𐐔𐐲𐐿𐐬𐐼𐐲 + + + 𐐝𐐯𐑌𐐻𐐲𐑉, 𐐤𐐱𐑉𐑃 𐐔𐐲𐐿𐐬𐐼𐐲 + + + 𐐟𐐮𐐿𐐪𐑀𐐬 + + + 𐐣𐐲𐑌𐐪𐑋𐐲𐑌𐐨 + + + 𐐚𐐮𐑌𐑅𐐯𐑌𐑆, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐑𐐨𐐻𐐲𐑉𐑆𐐺𐐲𐑉𐑀, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐓𐐯𐑊 𐐝𐐮𐐼𐐨, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐤𐐪𐐿𐑅, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐎𐐮𐑌𐐲𐑋𐐰𐐿, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐣𐐲𐑉𐐯𐑍𐑀𐐬, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐆𐑌𐐼𐐨𐐲𐑌𐐰𐐹𐐬𐑊𐐲𐑅 + + + 𐐢𐐭𐐶𐐨𐑂𐐮𐑊 + + + 𐐚𐐯𐑂𐐩, 𐐆𐑌𐐼𐐨𐐰𐑌𐐲 + + + 𐐣𐐪𐑌𐐻𐐲𐑅𐐯𐑊𐐬, 𐐗𐐲𐑌𐐻𐐲𐐿𐐨 + + + 𐐔𐐲𐐻𐑉𐐱𐐮𐐻 + + + 𐐤𐐭 𐐏𐐱𐑉𐐿 + + + + 𐐊𐑊𐐰𐑅𐐿𐐲 𐐓𐐴𐑋 + 𐐊𐑊𐐰𐑅𐐿𐐲 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐊𐑊𐐰𐑅𐐿𐐲 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐓𐐴𐑋 + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐝𐐯𐑌𐐻𐑉𐐲𐑊 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐓𐐴𐑋 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐀𐑅𐐻𐐲𐑉𐑌 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐣𐐵𐑌𐐻𐐲𐑌 𐐓𐐴𐑋 + 𐐣𐐵𐑌𐐻𐐲𐑌 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐣𐐵𐑌𐐻𐐲𐑌 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐑𐐲𐑅𐐮𐑁𐐮𐐿 𐐓𐐴𐑋 + 𐐑𐐲𐑅𐐮𐑁𐐮𐐿 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐑𐐲𐑅𐐮𐑁𐐮𐐿 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐈𐐻𐑊𐐰𐑌𐐻𐐮𐐿 𐐓𐐴𐑋 + 𐐈𐐻𐑊𐐰𐑌𐐻𐐮𐐿 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐈𐐻𐑊𐐰𐑌𐐻𐐮𐐿 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐐𐐱𐑍 𐐗𐐱𐑍 𐐓𐐴𐑋 + 𐐐𐐱𐑍 𐐗𐐱𐑍 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐐𐐱𐑍 𐐗𐐱𐑍 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + 𐐤𐐭𐑁𐐲𐑌𐐼𐑊𐐲𐑌𐐼 𐐓𐐴𐑋 + 𐐤𐐭𐑁𐐲𐑌𐐼𐑊𐐲𐑌𐐼 𐐝𐐻𐐰𐑌𐐼𐐲𐑉𐐼 𐐓𐐴𐑋 + 𐐤𐐭𐑁𐐲𐑌𐐼𐑊𐐲𐑌𐐼 𐐔𐐩𐑊𐐴𐐻 𐐓𐐴𐑋 + + + + + + + + $ + + + + + + + {0} 𐐷𐐮𐑉 + {0} 𐐷𐐮𐑉𐑆 + + + {0} 𐑋𐐲𐑌𐑃𐑅 + {0} 𐑋𐐲𐑌𐑃 + + + {0} 𐐶𐐨𐐿 + {0} 𐐶𐐨𐐿𐑅 + + + {0} 𐐼𐐩 + {0} 𐐼𐐩𐑆 + + + {0} 𐐵𐑉 + {0} 𐐵𐑉𐑆 + + + {0} 𐑋𐐮𐑌𐐲𐐻 + {0} 𐑋𐐮𐑌𐐲𐐻𐑅 + + + {0} 𐑅𐐯𐐿𐐲𐑌𐐼 + {0} 𐑅𐐯𐐿𐐲𐑌𐐼𐑆 + + + + + + 𐐷𐐯𐑅:𐐷 + 𐑌𐐬:𐑌 + + + diff --git a/make/data/cldr/common/main/en_Dsrt_US.xml b/make/data/cldr/common/main/en_Dsrt_US.xml new file mode 100644 index 00000000000..f5d45057f16 --- /dev/null +++ b/make/data/cldr/common/main/en_Dsrt_US.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + + + + + + + Jeŋ Fɛɛ + Afrika + Kooyigbɛ Amerika + Wuoyigbɛ Amerika + Ŋshɔkpɔi + Afrika Anaigbɛ + Teŋgbɛ Amerika + Afrika Bokagbɛ + Afrika Kooyigbɛ + Afrika Teŋgbɛ + Afrika Wuoyigbɛ + Amerika Niiaŋ + Kooyigbɛ Shɔŋŋ Amerika + Karibean + Asia Bokagbɛ + Asia Wuoyigbɛ + Asia Wuoyi-Bokagbɛ + Yuropa Wuoyigbɛ + Australasia + Melanesia + Ŋshɔkpɔi Bibii + Ŋshɔkpɔi Bibii Pii + Asia + Asia Teŋgbɛ + Asia Anaigbɛ + Yuropa + Yuropa Bokagbɛ + Yuropa Kooyigbɛ + Yuropa Anaigbɛ + Afrika Fã Ni Yɔɔ Sahara Lɛ Shishi + Romanse Amerika + Antigua Kɛ Barbuda + Anguilla + Angola + Argentina + Aruba + Barbados + Burkina Faso + Burundi + Benin + St. Barthélemy + Bermuda + Bolivia + Netherlands Ni Yɔɔ Karibean + Brazil + Bahamas + Bouvet Ŋshɔkpɔ + Botswana + Belize + Kanada + Kongo - Kinshasa + Kongo (DR) + Teŋgbɛ Afrika Jeŋmaŋ + Kongo - Brazzaville + Kongo (Jeŋmaŋ) + Ko Divua + Tsili + Kameroon + Tsaina + Kolombia + Kosta Rika + Kuba + Kape Verde + Kurasao + Djibouti + Dominika + Dominika Republik + Algeria + Keuta Kɛ Melilla + Ekuador + Ejipt + Sahara Wuoyigbɛ + Eritrea + Etiopia + Yuropa Maji Ekomefeemɔ + Yuropaniiaŋ + Falkland Ŋshɔkpɔi + Falkland Ŋshɔkpɔi Lɛ + Gabon + Grenada + Frentsibii Guiana + Ghana + Greenland + Gambia + Guinea + Guadeloupe + Ekuatorial Guinea + Georgia Wuoyi Kɛ Sandwitsi Ŋshɔkpɔi Ni Yɔɔ Wuoyi + Guatemala + Guinea-Bissau + Guyana + Honduras + Haiti + Kanary Ŋshɔkpɔi + India + Britain Shikpɔji Ni Yɔɔ Indian Ŋshɔ Lɛ Mli + Jamaika + Japan + Kenya + Komoros + St. Kitts Kɛ Nevis + Kayman Ŋshɔkpɔi + St. Lusia + Liberia + Lesotho + Libia + Moroko + St. Martin + Madagaskar + Mali + Makao SAR Tsaina + Makao + Martinik + Mauritania + Montserrat + Mauritius + Malawi + Meziko + Mozambik + Namibia + Niger + Anago + Nikaragua + Panama + Peru + St. Pierre Kɛ Mikelon + Puerto Riko + Paraguay + Ŋshɔkpɔi Ni Yɔɔ Shɔŋŋ + Réunion + Rwanda + Seyshelles + Sudan + St. Helena + Sierra Leone + Senegal + Somalia + Suriname + Sudan Wuoyi + São Tomé Kɛ Prínsipe + El Salvador + Sint Maarten + Eswatini + Swaziland + Turks Kɛ Kaikos Ŋshɔkpɔi + Tsad + Frentsibii Ashikpɔji Ni Yɔɔ Wuoyi + Togo + Tunisia + Trinidad Kɛ Tobago + Tanzania + Uganda + Jeŋmaji Ekomefeemɔ + United States + US + Uruguay + St. Vinsent Kɛ Grenadines + Venezuela + Britain Ŋshɔkpɔi Ni Atarako Amɛhe + US Ŋshɔkpɔi Ni Atarako Amɛhe + Eyaa Ŋwɛi Kɛ Shikpɔŋ Fɛɛ + Eyaa Biɛ Kɛ Biɛ Fɛɛ + Mayotte + South Afrika + Zambia + Zimbabwe + He Ko Ni Gbɛ́i Bɛ Mli + + + Gregory Kalanda + ISO-8601 Kalanda + Bɔ Ni Atoɔ Naa Daa + Blɔfomɛi Anɔmbai + + + Susumɔnii + + + Language: {0} + Script: {0} + Region: {0} + + + + [a b d e ɛ f g h i j k l m n ŋ o ɔ p q r s t u v w y z] + [á ã é í ĩ ó ũ] + [A B D E Ɛ F G H I J K L M N Ŋ O Ɔ P Q R S T U V W Y Z] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + {0}… + …{0} + {0}…{1} + {0} … + … {0} + {0} … {1} + ? + + [\--/] + [\:∶︓﹕:] + + + [.․。︒﹒.。] + ['ʼ՚᾽᾿’'] + [%٪﹪%] + [؉‰] + [\$﹩$] + [£₤£] + [¥¥] + [₩₩] + [₨₹{Rp}{Rs}] + + + [\-‐‒–⁻₋−➖﹣-] + [,،٫⹁、︐︑﹐﹑,、] + [+⁺₊➕﬩﹢+] + + + [,٫⹁︐﹐,] + [.․﹒.。] + + + + + + + + + + + + + + + EEEE, MMMM d, y G + GyMMMMEEEEd + + + + + MMMM d, y G + GyMMMMd + + + + + MMM d, y G + GyMMMd + + + + + M/d/y GGGGG + GGGGGyMd + + + + + + + {1} 'be' 'ni' 'atswa' {0} + + + + + {1} 'be' 'ni' 'atswa' {0} + + + + + {1}, {0} + + + + + {1}, {0} + + + + E d + y G + MMM y G + MMM d, y G + E, MMM d, y G + M/d + E, M/d + E, MMM d + y G + y G + M/y GGGGG + M/d/y GGGGG + E, M/d/y GGGGG + MMM y G + MMM d, y G + E, MMM d, y G + MMMM y G + QQQ y G + QQQQ y G + + + + y G – y G + y – y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + M/d/y – M/d/y GGGGG + M/d/y GGGGG – M/d/y GGGGG + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + + + E, M/d/y – E, M/d/y GGGGG + E, M/d/y GGGGG – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + MMM d – d, y G + MMM d, y G – MMM d, y G + MMM d – MMM d, y G + MMM d, y – MMM d, y G + + + E, MMM d – E, MMM d, y G + E, MMM d, y G – E, MMM d, y G + E, MMM d – E, MMM d, y G + E, MMM d, y – E, MMM d, y G + + + M – M + + + M/d – M/d + M/d – M/d + + + E, M/d – E, M/d + E, M/d – E, M/d + + + MMM – MMM + + + E, MMM d – E, MMM d + E, MMM d – E, MMM d + + + y – y G + + + M/y – M/y GGGGG + M/y – M/y GGGGG + + + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + + + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + + + MMM – MMM y G + MMM y – MMM y G + + + MMM d – d, y G + MMM d – MMM d, y G + MMM d, y – MMM d, y G + + + E, MMM d – E, MMM d, y G + E, MMM d – E, MMM d, y G + E, MMM d, y – E, MMM d, y G + + + MMMM – MMMM y G + MMMM y – MMMM y G + + + + + + + + + Aha + Ofl + Ots + Abe + Agb + Otu + Maa + Man + Gbo + Ant + Ale + Afu + + + A + O + O + A + A + O + M + M + G + A + A + A + + + Aharabata + Oflɔ + Otsokrikri + Abeibe + Agbiɛnaa + Otukwajaŋ + Maawɛ + Manyawale + Gbo + Antɔŋ + Alemle + Afuabe + + + + + Aha + Ofl + Ots + Abe + Agb + Otu + Maa + Man + Gbo + Ant + Ale + Afu + + + A + O + O + A + A + O + M + M + G + A + A + A + + + Aharabata + Oflɔ + Otsokrikri + Abeibe + Agbiɛnaa + Otukwajan + Maawɛ + Manyawale + Gbo + Antɔŋ + Alemle + Afuabe + + + + + + + Hɔg + Ju + Juf + Shɔ + Soo + Soh + Hɔɔ + + + H + J + J + S + S + S + H + + + Hɔg + Ju + Juf + Shɔ + Soo + Soh + Hɔɔ + + + Hɔgbaa + Ju + Jufɔ + Shɔ + Soo + Sohaa + Hɔɔ + + + + + Hɔg + Ju + Juf + Shɔ + Soo + Soh + Hɔɔ + + + H + J + J + S + S + S + H + + + Hɔg + Ju + Juf + Shɔ + Soo + Soh + Hɔɔ + + + Hɔgbaa + Ju + Jufɔ + Shɔ + Soo + Sohaa + Hɔɔ + + + + + + + N1 + N2 + N3 + N4 + + + 1 + 2 + 3 + 4 + + + nyɔji etɛ 1 + nyɔji etɛ 2 + nyɔji etɛ 3 + nyɔji etɛ 4 + + + + + N1 + N2 + N3 + N4 + + + nyɔji etɛ 1 + nyɔji etɛ 2 + nyɔji etɛ 3 + nyɔji etɛ 4 + + + + + + + LB + SN + + + LB + SN + + + LEEBI + SHWANE + + + + + LB + SN + + + LB + SN + + + LEEBI + SHWANE + + + + + + Dani Yesu + Dani Ŋmɛnɛŋmɛnɛ Beiaŋ + Yesu Gbele Sɛɛ + Ŋmɛnɛŋmɛnɛ Beiaŋ + + + DY + DŊB + YGS + ŊB + + + + + + EEEE, MMMM d, y + yMMMMEEEEd + + + + + MMMM d, y + yMMMMd + + + + + MMM d, y + yMMMd + + + + + M/d/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + {1} 'be' 'ni' 'atswa' {0} + + + + + {1} 'be' 'ni' 'atswa' {0} + + + + + {1}, {0} + + + + + {1}, {0} + + + + E d + y G + MMM y G + MMM d, y G + E, MMM d, y G + M/d + E, M/d + E, MMM d + MMMM 'otsi' W + M/y + M/d/y + E, M/d/y + MMM y + MMM d, y + E, MMM d, y + MMMM y + QQQ y + QQQQ y + Y 'otsi' w + + + + y G – y G + y – y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + M/d/y – M/d/y GGGGG + M/d/y GGGGG – M/d/y GGGGG + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + + + E, M/d/y – E, M/d/y GGGGG + E, M/d/y GGGGG – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + MMM d – d, y G + MMM d, y G – MMM d, y G + MMM d – MMM d, y G + MMM d, y – MMM d, y G + + + E, MMM d – E, MMM d, y G + E, MMM d, y G – E, MMM d, y G + E, MMM d – E, MMM d, y G + E, MMM d, y – E, MMM d, y G + + + M – M + + + M/d – M/d + M/d – M/d + + + E, M/d – E, M/d + E, M/d – E, M/d + + + MMM – MMM + + + E, MMM d – E, MMM d + E, MMM d – E, MMM d + + + M/y – M/y + M/y – M/y + + + M/d/y – M/d/y + M/d/y – M/d/y + M/d/y – M/d/y + + + E, M/d/y – E, M/d/y + E, M/d/y – E, M/d/y + E, M/d/y – E, M/d/y + + + MMM – MMM y + MMM y – MMM y + + + MMM d – d, y + MMM d – MMM d, y + MMM d, y – MMM d, y + + + E, MMM d – E, MMM d, y + E, MMM d – E, MMM d, y + E, MMM d, y – E, MMM d, y + + + MMMM – MMMM y + MMMM y – MMMM y + + + + + + + + yinɔ + + + afi + nyɛsɛɛ afi + afi nɛɛ + wɔsɛɛ afi + + + afi + nyɛsɛɛ afi + afi nɛɛ + wɔsɛɛ afi + + + afi + nyɛsɛɛ afi + afi nɛɛ + wɔsɛɛ afi + + + nyɔji etɛ + + + ny. etɛ + + + ny. etɛ + + + nyɔɔŋ + nyɔɔŋ ni ho lɛ + nyɔɔŋ nɛɛ + nyɔɔŋ ni baa lɛ + + + ny. + ny. ni ho lɛ + ny. nɛɛ + ny. ni baa lɛ + + + ny. + ny. ni ho lɛ + ny. nɛɛ + ny. ni baa lɛ + + + otsi + nyɛsɛɛ otsi + otsi nɛɛ + wɔsɛɛ otsi + {0} otsi lɛ mli + + + ot. + nyɛsɛɛ ot. + ot. nɛɛ + wɔsɛɛ ot. + {0} otsi lɛ mli + + + ot. + nyɛsɛɛ ot. + ot. nɛɛ + wɔsɛɛ ot. + {0} otsi lɛ mli + + + gbi + nyɛ + ŋmɛnɛ + wɔ́ + + + gbi + nyɛ + ŋmɛnɛ + wɔ́ + + + gbi + nyɛ + ŋmɛnɛ + wɔ́ + + + otsi lɛ mli gbi + + + LEEBI/SHWANE + + + ŋmɛlɛtswaa + + + ŋm. + + + ŋm. + + + miniti + + + min. + + + min. + + + sɛkɛnsi + + + sɛk. + + + sɛk. + + + maji ni akɛ amɛbe buɔ akɔntaa + + + + {0} Be + {0} Be Yɛ Latsa Beiaŋ + {0} Be Yɛ Fɛi Beiaŋ + + + Be Ni Maji Ni Yɔɔ Jeŋ Fɛɛ Kɛtsuɔ Nii + + + + Maŋtiase Ko Ni Gbɛ́i Bɛ Mli + + + Kasey + + + MakMurdo + + + Yukla + + + Ŋmeŋme Ni Ekumɔ + + + Kurrie + + + Makwarie + + + Nuŋtsɔ Howe + + + St. Barthélemy + + + Okpɔŋɔ Yɛŋ + + + Vankouver + + + Nelson Mɔɔ + + + Dawson Kpaakpo Bibioo + + + Kreston + + + Kakla Wuɔfɔ + + + Swift Karɛnt + + + Kambridge Ŋshɔnine Bibioo + + + Faa Ni Nɛɔ + + + Rankin Ŋshɔnine + + + Sarawa Ŋshɔnine Bibioo + + + Ikaluit + + + Monkton + + + Halifas + + + Goose Ŋshɔnine Bibioo + + + Glase Ŋshɔnine Bibioo + + + Blank-Sablon + + + Kokos + + + Urumki + + + Kosta Rika + + + Kape Verde + + + Kurasao + + + Krismas + + + Nikosia + + + Dominika + + + Kairo + + + Tsuuk + + + + Be Ni Britainbii Kɛtsuɔ Nii Yɛ Latsa Beiaŋ + + + + Ga + + + Ittokortoormiit + + + Konakry + + + Tegusigalpa + + + Abladei Alɛjiadaamɔhe + + + + Be Ni Irelandbii Kɛtsuɔ Nii + + + + Yerusalem + + + Tsagos + + + Jamaika + + + Komoro + + + Kayman + + + Aktau + + + Aktobe + + + Kostanay + + + Kyzylorda + + + St. Lusia + + + Kolombo + + + Kasablanka + + + Tsoibalsan + + + Makao + + + Martinik + + + Nouakshott + + + Tsihuahua + + + Meziko Maŋ + + + Kankun + + + Kutsing + + + Tsatham + + + Ɔkland + + + Muskat + + + Markwesas + + + Karatsi + + + Mikelon + + + Pitkairn + + + Puerto Riko + + + Kata + + + Guadalkanal + + + Ablade Shĩa Ni Yɔɔ Jɔɔ Mli + + + Damasko + + + Turke Wulu + + + Spain Lɛjiadaamɔhe + + + Ankorage + + + New Salem, Dakota Kooyigbɛ + + + Maŋteŋ, Dakota Kooyigbɛ + + + Tsikago + + + Vinsennes, Indiana + + + Osheku Maŋ, Indiana + + + Knos, Indiana + + + Winamak, Indiana + + + Montisello, Kentuky + + + St. Vinsent + + + Ho Tsi Minh Maŋtiase + + + + Afrika Teŋgbɛ Be + + + + + Afrika Bokagbɛ Be + + + + + South Afrika Be + + + + + Afrika Anaigbɛ Be + Afrika Anaigbɛ Be Yɛ Fɛi Beiaŋ + Afrika Anaigbɛ Be Yɛ Latsa Beiaŋ + + + + + Alaska Be + Alaska Be Yɛ Fɛi Beiaŋ + Alaska Be Yɛ Latsa Beiaŋ + + + + + Amerika Teŋgbɛbii Abe + Amerika Teŋgbɛbii Abe Yɛ Fɛi Beiaŋ + Amerika Teŋgbɛbii Abe Yɛ Latsa Beiaŋ + + + + + Amerika Bokãgbɛbii Abe + Amerika Bokãgbɛbii Abe Yɛ Fɛi Beiaŋ + Amerika Bokãgbɛbii Abe Yɛ Latsa Beiaŋ + + + + + Amerika Gɔjianɔbii Abe + Amerika Gɔjianɔbii Abe Yɛ Fɛi Beiaŋ + Amerika Gɔjianɔbii Abe Yɛ Latsa Beiaŋ + + + + + Pasifik Be + Pasifik Be Yɛ Fɛi Beiaŋ + Pasifik Be Yɛ Latsa Beiaŋ + + + + + Atlantik Be + Atlantik Be Yɛ Fɛi Beiaŋ + Atlantik Be Yɛ Latsa Beiaŋ + + + + + Azores Be + Azores Be Yɛ Fɛi Beiaŋ + Azores Be Yɛ Latsa Beiaŋ + + + + + Kape Verde Be + Kape Verde Be Yɛ Fɛi Beiaŋ + Kape Verde Be Yɛ Latsa Beiaŋ + + + + + Kuba Be + Kuba Be Yɛ Fɛi Beiaŋ + Kuba Be Yɛ Latsa Beiaŋ + + + + + Antarktik Kɛ Wuoyigbɛbii Ni Wieɔ Frɛntsi Be + + + + + Greenland Bokãgbɛ Be + Greenland Bokãgbɛ Be Yɛ Fɛi Beiaŋ + Greenland Bokãgbɛ Be Yɛ Latsa Beiaŋ + + + + + Greenland Anaigbɛ Be + Greenland Anaigbɛ Be Yɛ Fɛi Beiaŋ + Greenland Anaigbɛ Be Yɛ Latsa Beiaŋ + + + + + Hawaii-Aleutia Be + Hawaii-Aleutia Be Yɛ Fɛi Beiaŋ + Hawaii-Aleutia Be Yɛ Latsa Beiaŋ + + + + + Indian Ŋshɔ Lɛ Be + + + + + Mauritius Be + Mauritius Be Yɛ Fɛi Beiaŋ + Mauritius Be Yɛ Latsa Beiaŋ + + + + + Meziko Kooyi-Anaigbɛ Be + Meziko Kooyi-Anaigbɛ Be Yɛ Fɛi Beiaŋ + Meziko Kooyi-Anaigbɛ Be Yɛ Latsa Beiaŋ + + + + + Meziko Pasifik Be + Meziko Pasifik Be Yɛ Fɛi Beiaŋ + Meziko Pasifik Be Yɛ Latsa Beiaŋ + + + + + Newfoundland Be + Newfoundland Be Yɛ Fɛi Beiaŋ + Newfoundland Be Yɛ Latsa Beiaŋ + + + + + St. Pierre Kɛ Mikelon Be + St. Pierre Kɛ Mikelon Be Yɛ Fɛi Beiaŋ + St. Pierre Kɛ Mikelon Be Yɛ Latsa Beiaŋ + + + + + Réunion Be + + + + + Seyshelles Be + + + + + + latn + + latn + + + + + #,##0% + + + + + + + ¤#,##0.00;(¤#,##0.00) + + + + + + Albania Leki + Albania lekii + + + Netherlands Antillea Guilda + Netherlands Antillea guildai + + + Angola Kwanza + Angola kwanzai + + + Argentina Peso + Argentina pesoi + + + Aruba Florin + Aruba florinii + + + Bosnia-Herzegovina Marki Ni Hiɔ Tsakemɔ + Bosnia-Herzegovina markii ni hiɔ tsakemɔ + + + Barbados Dɔla + Barbados dɔlai + + + Bulgaria Levi + Bulgaria levii + + + Burundi Franki + Burundi frankii + + + Bermuda Dɔla + Bermuda dɔlai + + + Bolivia Boliviano + Bolivia bolivianoi + + + Brazil Real + Brazil realii + + + Bahamas Dɔla + Bahamas dɔlai + + + Botswana Pula + Botswana pulai + + + Belarus Rubol + Belarus rubolii + BYN + + + Belize Dɔla + Belize dɔlai + + + Kanada Dɔla + Kanada dɔlai + KA$ + + + Kongo Franki + Kongo frankii + KDF + + + Switzerland Frank + Switzerland frankii + SZF + + + Tsili Peso + Tsili pesoi + + + Kolombia Peso + Kolombia pesoi + KOP + + + Kosta Rika Kolón + Kosta Rika kolónii + KRK + + + Kuba Peso Ni Hiɔ Tsakemɔ + Kuba pesoi ni hiɔ tsakemɔ + KUK + + + Kuba Peso + Kuba pesoi + KUP + + + Tsek Koruna + Tsek korunai + TSK + + + Djibouti Franki + Djibouti frankii + + + Denmark Krone + Denmark kronei + + + Dominika Peso + Dominika pesoi + + + Algeria Dinar + Algeria dinarii + + + Ejipt Pound + Ejipt pounds + + + Eritrea Nakfa + Eritrea nakfai + + + Ethiopia Birr + Ethiopia birri + + + Yuro + yuro + + + Falkland Ŋshɔkpɔi Pound + Falkland Ŋshɔkpɔi pounds + + + Britain Pound + Britain pounds + + + Sidi + + + Ghana Sidi + Ghana sidii + + + Gibraltar Pound + Gibraltar pounds + + + Gambia Dalasi + Gambia dalasii + + + Guinea Franki + Guinea frankii + GNF + + + Guatemala Kuetzal + Guatemala kuetzalii + GTK + K + + + Guyana Dɔla + Guyan dɔlai + + + Hondura Lempira + Hondura lempirai + + + Kroatia Kuna + Kroatia kunai + + + Haiti Gourde + Haiti gourdei + + + Hungary Forinti + Hungary forintii + + + Aisland Króna + Aisland krónai + + + Jamaika Dɔla + Jamaika dɔlai + + + Kenya Sheleŋ + Kenya sheleŋ + + + Komoros Franki + Komoros frankii + KF + + + Kayman Ŋshɔkpɔi Dɔla + Kayman Ŋshɔkpɔi dɔlai + + + Liberia Dɔla + Liberia dɔlai + LRD + + + Libia Dinar + Libia dinarii + + + Moroko Dirham + Moroko dirhamii + + + Moldova Leu + Moldova leuii + + + Madagaska Ariari + Madagaska ariarii + + + Makedonia Denari + Makedonia denarii + + + Mauritania Ouguiya + Mauritania ouguiyai + + + Mauritius Rupi + Mauritius rupii + + + Malawi Kwatsa + Malawi kwatsai + + + Meziko Peso + Meziko pesoi + MZ$ + + + Mozambik Metikal + Mozambik metikalii + + + Namibia Dɔla + Namibia dɔlai + + + Anago Naira + Anago nairai + + + Nikaragua Kórdoba + Nikaragua kórdobai + K$ + + + Norway Krone + Norway kronei + + + Panama Balboa + Panama balboai + + + Peru Sol + Peru solii + + + Poland Zloti + Poland zlotii + + + Paraguay Guarani + Paraguay guaranii + + + Romania Leu + Romania leuii + + + Serbia Dinari + Serbia dinarii + + + Russia Rubol + Russia rubolii + + + Rwanda Franki + Rwanda frankii + + + Seyshɛl Rupi + Seyshɛl rupii + SSR + + + Sudan Pound + Sudan pounds + + + Sweden Krona + Sweden kronai + + + St. Helena Pound + St. Helena pounds + + + Sierra Leone Leone + Sierra Leone leonei + + + Somali Sheleŋ + Somali sheleŋ + + + Surinam Dɔla + Surinam dɔlai + + + Sudan Anai Pound + Sudan Anai pounds + + + Swazi Lilangeni + Swazi lilangenii + + + Tunisia Dinar + Tunisia dinarii + + + Trinidad Kɛ Tobago Dɔla + Trinidad Kɛ Tobago dɔlai + + + Tanzania Sheleŋ + Tanzania sheleŋ + + + Ukrainia Hryvnia + Ukrainia hryvniai + + + Uganda Sjeleŋ + Uganda sheleŋ + UGS + + + US Dɔla + US dɔlai + $ + + + Uruguay Peso + Uruguay pesoi + + + Venezuela Bolívar + Venezuela bolívarii + + + Karibbean Bokã Dɔla + Karibbean Bokã dɔlai + KB$ + + + Afrika Anai Sefa Franki + Afrika Anai Sefa Frankii + SFA + + + Shika Ko Ni Gbɛ́i Bɛ Mli + (shika ko ni gbɛ́i bɛ mli) + + + South Afrika Randi + South Afrika randii + + + Zambia Kwatsa + Zambia kwatsai + ZMW + + + + gbii {0} + ni ji {0} + + + + + + deg + {0}° + + + % + {0}% + + + afii ohai + afii ohai {0} + + + afii nyɔŋma + afi nyɔŋmai {0} + + + afii + afii {0} + {0} daa afi + + + nyɔji + nyɔji {0} + {0} daa nyɔɔŋ + + + otsii + otsii {0} + {0} daa otsi + + + gbii + gbii {0} + {0} daa gbi + + + ŋmɛlɛtswai + ŋmɛlɛtswai {0} + {0} ŋmɛlɛtswaa fɛɛ ŋmɛlɛtswaa + + + minitii + minitii {0} + {0} miniti fɛɛ miniti + + + sɛkɛnsi + sɛkɛnsii {0} + {0} sɛkɛnsi fɛɛ sɛkɛnsi + + + sɛkɛnsi mlijaa 100 + sɛkɛnsi {0} mlijaa 100 + + + sɛkɛnsi mlijaa 1000 + sɛkɛnsi {0} mlijaa 1000 + + + sɛkɛnsi frim + sɛkɛnsi frim {0} + + + kilomita + kilomitai {0} + {0} kilomita fɛɛ kilomita + + + mitai + mitai {0} + {0} mita fɛɛ mita + + + dɛsimita + dɛsimitai {0} + + + sɛntimitai + sɛntimitai {0} + {0} sɛntimita fɛɛ sɛntimita + + + milimitai + milimitai {0} + + + jeŋ koji ejwɛ + {0} bokã + {0} kooyi + {0} wuoyi + {0} anai + + + + + ao + {0}ao + + + an + {0}an + + + afii + {0} afii + {0}/afi + + + nyɔji + nyɔji {0} + {0}/nyɔɔŋ + + + otsii + {0} otsii + {0}/otsi + + + gbii + gbii {0} + {0}/gbi + + + ŋmɛlɛtswai + ŋm {0} + {0}/ŋm + + + min + min {0} + {0}/min + + + sɛk + sɛk {0} + {0}/s + + + sɛk mlij + sm {0} + + + μsɛk + {0}μs + + + sɛkɛnsifrim + {0}sf + + + km + {0} km + {0}/km + + + m + + + sɛm + {0} sɛm + {0}/sɛm + + + koji + {0} B + {0} K + {0} W + {0} A + + + + + % + {0}% + + + afi + a{0} + + + nyɔɔŋ + {0}n + + + otsi + {0}o + + + gbi + {0}g + + + ŋmɛlɛtswaa + {0}ŋm + + + min + {0}m + + + sɛk + {0}s + + + sɛkmlij + {0}sm + + + km + {0}km + + + m + {0} m + + + mm + {0}mm + + + koji + {0}B + {0}K + {0}W + {0}A + + + + + + {0}, kɛ {1} + {0} kɛ {1} + + + + + hɛɛ:h + dabi:d + + + + und gaa + + + {0}. + {0} {1} + + {given} {given2} {surname} {credentials} + + + {given-informal} {surname} + + + {title} {surname} + + + {given-informal} + + + {given-monogram-allCaps}{given2-monogram-allCaps}{surname-monogram-allCaps} + + + {given-informal-monogram-allCaps}{surname-monogram-allCaps} + + + {given} {given2-initial} {surname} {credentials} + + + {given-informal} {surname} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {given-initial} {given2-initial} {surname} + + + {given-informal} {surname-initial} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname} {given} {given2} {credentials} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps}{given-monogram-allCaps}{given2-monogram-allCaps} + + + {surname-monogram-allCaps}{given-informal-monogram-allCaps} + + + {surname} {given} {given2-initial} {credentials} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname} {given-initial} {given2-initial} + + + {surname} {given-initial} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname-core}, {given} {given2} {surname-prefix} + + + {surname}, {given-informal} + + + {surname-core}, {given} {given2-initial} {surname-prefix} + + + {surname}, {given-informal} + + + {surname-core}, {given-initial} {given2-initial} {surname-prefix} + + + {surname}, {given-informal} + + + Prof. Dr. + Ada Kornelia + Neele + Eva Sofia + van den + Wolf + Beker Shmidt + M.D. Ph.D. + + + diff --git a/make/data/cldr/common/main/gaa_GH.xml b/make/data/cldr/common/main/gaa_GH.xml new file mode 100644 index 00000000000..94f9d0dd6d5 --- /dev/null +++ b/make/data/cldr/common/main/gaa_GH.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/gd.xml b/make/data/cldr/common/main/gd.xml index bc2f488a7b5..f57731275a3 100644 --- a/make/data/cldr/common/main/gd.xml +++ b/make/data/cldr/common/main/gd.xml @@ -1,6 +1,6 @@ - + + + + + + + + አፋርኛ + አብሐዚኛ + አፍሪቃንስኛ + አምሐረኛ + ዐርቢኛ + አሳሜዛዊ + አያማርኛ + አዜርባይጃንኛ + ባስኪርኛ + ቤላራሻኛ + ቡልጋሪኛ + ቢስላምኛ + በንጋሊኛ + ትበትንኛ + ብሬቶንኛ + ብሊን + ካታላንኛ + ኮርሲካኛ + ቼክኛ + ወልሽ + ዴኒሽ + ጀርመን + ድዞንግኻኛ + ግሪክኛ + እንግሊዝኛ + ኤስፐራንቶ + ስፓኒሽ + ኤስቶኒአን + ባስክኛ + ፐርሲያኛ + ፊኒሽ + ፊጂኛ + ፋሮኛ + ፈረንሳይኛ + ፍሪስኛ + አይሪሽ + እስኮትስ፡ጌልክኛ + ግዕዝኛ + ጋለጋኛ + ጓራኒኛ + ጉጃርቲኛ + ሃውሳኛ + ዕብራስጥ + ሐንድኛ + ክሮሽያንኛ + ሀንጋሪኛ + አርመናዊ + ኢንቴርሊንጓ + እንዶኒሲኛ + እንተርሊንግወ + እኑፒያቅኛ + አይስላንድኛ + ጣሊያንኛ + እኑክቲቱትኛ + ጃፓንኛ + ጃቫንኛ + ጊዮርጊያን + ካዛክኛ + ካላሊሱትኛ + ክመርኛ + ካናዳኛ + ኮሪያኛ + ካሽሚርኛ + ኩርድሽኛ + ኪርጊዝኛ + ላቲንኛ + ሊንጋላኛ + ላውስኛ + ሊቱአኒያን + ላትቪያን + ማላጋስኛ + ማዮሪኛ + ማከዶኒኛ + ማላያላምኛ + ሞንጎላዊኛ + ማራዚኛ + ማላይኛ + ማልቲስኛ + ቡርማኛ + ናኡሩ + ኔፓሊኛ + ደች + ኖርዌጂያን + ኦኪታንኛ + ኦሮምኛ + ኦሪያኛ + ፓንጃቢኛ + ፖሊሽ + ፑሽቶኛ + ፖርቱጋሊኛ + ኵቿኛ + ሮማንስ + ሩንዲኛ + ሮማኒያን + ሞልዳቫዊና + ራሽኛ + ኪንያርዋንድኛ + ሳንስክሪትኛ + ሲንድሂኛ + ሳንጎኛ + ስንሃልኛ + ሲዳምኛ + ስሎቫክኛ + ስሎቪኛ + ሳሞአኛ + ሾናኛ + ሱማልኛ + ልቤኒኛ + ሰርቢኛ + ስዋቲኛ + ሶዞኛ + ሱዳንኛ + ስዊድንኛ + ስዋሂሊኛ + ታሚልኛ + ተሉጉኛ + ታጂኪኛ + ታይኛ + ትግርኛ + ትግረ + ቱርክመንኛ + ታጋሎገኛ + ጽዋናዊኛ + ቶንጋ + ቱርክኛ + ጾንጋኛ + ታታርኛ + ትዊኛ + ኡዊግሁርኛ + ዩክረኒኛ + ኡርዱኛ + ኡዝበክኛ + ቪትናምኛ + ቮላፑክኛ + ዎሎፍኛ + ዞሳኛ + ይዲሻዊኛ + ዮሩባዊኛ + ዡዋንግኛ + ቻይንኛ + ዙሉኛ + + + + + + አንዶራ + የተባበሩት፡አረብ፡ኤምሬትስ + አልባኒያ + አርሜኒያ + አርጀንቲና + ኦስትሪያ + አውስትሬሊያ + አዘርባጃን + ቦስኒያ፡እና፡ሄርዞጎቪኒያ + ባርቤዶስ + ቤልጄም + ቡልጌሪያ + ባህሬን + ቤርሙዳ + ቦሊቪያ + ብራዚል + ቡህታን + ቤላሩስ + ቤሊዘ + የመካከለኛው፡አፍሪካ፡ሪፐብሊክ + ስዊዘርላንድ + ቺሊ + ካሜሩን + ቻይና + ኮሎምቢያ + ኬፕ፡ቬርዴ + ሳይፕረስ + ቼክ፡ሪፑብሊክ + ጀርመን + ዴንማርክ + ዶሚኒካ + ዶሚኒክ፡ሪፑብሊክ + አልጄሪያ + ኢኳዶር + ኤስቶኒያ + ግብጽ + ምዕራባዊ፡ሳህራ + ኤርትራ + ስፔን + ኢትዮጵያ + ፊንላንድ + ፊጂ + ሚክሮኔዢያ + ፈረንሳይ + እንግሊዝ + ጆርጂያ + የፈረንሳይ፡ጉዊአና + ጋምቢያ + ጊኒ + ኢኳቶሪያል፡ጊኒ + ግሪክ + ቢሳዎ + ጉያና + ሆንግ፡ኮንግ + ክሮኤሽያ + ሀይቲ + ሀንጋሪ + ኢንዶኔዢያ + አየርላንድ + እስራኤል + ህንድ + ኢራቅ + አይስላንድ + ጣሊያን + ጃማይካ + ጆርዳን + ጃፓን + ካምቦዲያ + ኮሞሮስ + ደቡብ፡ኮሪያ + ሰሜን፡ኮሪያ + ክዌት + ሊባኖስ + ሊቱዌኒያ + ላትቪያ + ሊቢያ + ሞሮኮ + ሞልዶቫ + ማከዶኒያ + ሞንጎሊያ + ማካዎ + ሞሪቴኒያ + ማልታ + ማሩሸስ + ሜክሲኮ + ማሌዢያ + ናሚቢያ + ኒው፡ካሌዶኒያ + ናይጄሪያ + ኔዘርላንድ + ኖርዌ + ኔፓል + ኒው፡ዚላንድ + ፔሩ + የፈረንሳይ፡ፖሊኔዢያ + ፓፑዋ፡ኒው፡ጊኒ + ፖላንድ + ፖርታ፡ሪኮ + ሮሜኒያ + ሰርቢያ + ራሺያ + ሳውድአረቢያ + ሱዳን + ስዊድን + ሲንጋፖር + ስሎቬኒያ + ስሎቫኪያ + ሴኔጋል + ሱማሌ + ሲሪያ + ቻድ + የፈረንሳይ፡ደቡባዊ፡ግዛቶች + ታይላንድ + ታጃኪስታን + ምስራቅ፡ቲሞር + ቱኒዚያ + ቱርክ + ትሪኒዳድ፡እና፡ቶባጎ + ታንዛኒያ + ዩጋንዳ + አሜሪካ + ዩዝበኪስታን + ቬንዙዌላ + የእንግሊዝ፡ድንግል፡ደሴቶች + የአሜሪካ፡ቨርጂን፡ደሴቶች + የመን + ደቡብ፡አፍሪካ + ዛምቢያ + + + + [\u135F ᎐ ᎑ ᎒ ᎓ ᎔ ᎕ ᎖ ᎗ ᎘ ᎙ ሀ ሁ ሂ ሃ ሄ ህ ሆ ለ ሉ ሊ ላ ሌ ል ሎ ሐ ሑ ሒ ሓ ሔ ሕ ሖ መ ሙ ሚ ማ ሜ ም ሞ ሠ ሡ ሢ ሣ ሤ ሥ ሦ ረ ሩ ሪ ራ ሬ ር ሮ ሰ ሱ ሲ ሳ ሴ ስ ሶ ቀ ቁ ቂ ቃ ቄ ቅ ቆ ቈ ቊ ቋ ቌ ቍ በ ቡ ቢ ባ ቤ ብ ቦ ተ ቱ ቲ ታ ቴ ት ቶ ኀ ኁ ኂ ኃ ኄ ኅ ኆ ኈ ኊ ኋ ኌ ኍ ነ ኑ ኒ ና ኔ ን ኖ አ ኡ ኢ ኣ ኤ እ ኦ ከ ኩ ኪ ካ ኬ ክ ኮ ኰ ኲ ኳ ኴ ኵ ወ ዉ ዊ ዋ ዌ ው ዎ ዐ ዑ ዒ ዓ ዔ ዕ ዖ ዘ ዙ ዚ ዛ ዜ ዝ ዞ የ ዩ ዪ ያ ዬ ይ ዮ ደ ዱ ዲ ዳ ዴ ድ ዶ ገ ጉ ጊ ጋ ጌ ግ ጎ ጐ ጒ ጓ ጔ ጕ ጠ ጡ ጢ ጣ ጤ ጥ ጦ ጰ ጱ ጲ ጳ ጴ ጵ ጶ ጸ ጹ ጺ ጻ ጼ ጽ ጾ ፀ ፁ ፂ ፃ ፄ ፅ ፆ ፈ ፉ ፊ ፋ ፌ ፍ ፎ ፐ ፑ ፒ ፓ ፔ ፕ ፖ] + [ሇ ሏ ⶀ ሗ ሟ ᎀ ᎁ ᎂ ᎃ ⶁ ሧ ሯ ⶂ ሷ ⶃ ሸ ሹ ሺ ሻ ሼ ሽ ሾ ሿ ⶄ ቇ ቐ ቑ ቒ ቓ ቔ ቕ ቖ ቘ ቚ ቛ ቜ ቝ ቧ ᎄ ᎅ ᎆ ᎇ ⶅ ቮ ቯ ቷ ⶆ ቿ ⶇ ኇ ኗ ⶈ ኛ ኟ ⶉ ኧ ⶊ ኯ ኸ ኹ ኺ ኻ ኼ ኽ ኾ ዀ ዂ ዃ ዄ ዅ ዏ ዟ ⶋ ዠ ዡ ዢ ዣ ዤ ዥ ዦ ዧ ዷ ⶌ ዸ ዹ ዺ ዻ ዼ ዽ ዾ ዿ ⶍ ጀ ጁ ጂ ጃ ጄ ጅ ጆ ጇ ⶎ ጏ ጘ ጙ ጚ ጛ ጜ ጝ ጞ ጟ ⶓ ⶔ ⶕ ⶖ ጧ ⶏ ጨ ጩ ጪ ጫ ጬ ጭ ጮ ጯ ⶐ ጷ ⶑ ጿ ፇ ፏ ᎈ ᎉ ᎊ ᎋ ፗ ᎌ ᎍ ᎎ ᎏ ⶒ ፘ ፙ ፚ ⶠ ⶡ ⶢ ⶣ ⶤ ⶥ ⶦ ⶨ ⶩ ⶪ ⶫ ⶬ ⶭ ⶮ ⶰ ⶱ ⶲ ⶳ ⶴ ⶵ ⶶ ⶸ ⶹ ⶺ ⶻ ⶼ ⶽ ⶾ ⷀ ⷁ ⷂ ⷃ ⷄ ⷅ ⷆ ⷈ ⷉ ⷊ ⷋ ⷌ ⷍ ⷎ ⷐ ⷑ ⷒ ⷓ ⷔ ⷕ ⷖ ⷘ ⷙ ⷚ ⷛ ⷜ ⷝ ⷞ] + [ሀ ለ ሐ መ ሠ ረ ሰ ቀ ቈ በ ተ ኀ ኈ ነ አ ከ ኰ ወ ዐ ዘ የ ደ ገ ጐ ጠ ጰ ጸ ፀ ፈ ፐ] + + + + + + + + EEEE፥ dd MMMM መዓልት y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + ጠሐረ + ከተተ + መገበ + አኀዘ + ግንባት + ሠንየ + ሐመለ + ነሐሰ + ከረመ + ጠቀመ + ኀደረ + ኀሠሠ + + + + + + + + + + + + + + + + + + + + + + + እኁድ + ሰኑይ + ሠሉስ + ራብዕ + ሐሙስ + ዓርበ + ቀዳሚት + + + + + + + + + + + + + + + + + + ጽባሕ + ምሴት + + + ጽባሕ + ምሴት + + + + + + ዓ/ዓ + ዓ/ም + + + + + + EEEE፥ dd MMMM መዓልት y G + GyMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + + + + + ¤#,##0.00 + + + + + + የብራዚል ሪል + + + የቻይና ዩአን ረንሚንቢ + + + የኢትዮጵያ ብር + + + አውሮ + + + የእንግሊዝ ፓውንድ ስተርሊንግ + + + የሕንድ ሩፒ + + + የጃፓን የን + + + የራሻ ሩብል + + + የአሜሪካን ዶላር + + + + diff --git a/make/data/cldr/common/main/gez_ER.xml b/make/data/cldr/common/main/gez_ER.xml new file mode 100644 index 00000000000..c8df591a28e --- /dev/null +++ b/make/data/cldr/common/main/gez_ER.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + Nfk + + + + diff --git a/make/data/cldr/common/main/gez_ET.xml b/make/data/cldr/common/main/gez_ET.xml new file mode 100644 index 00000000000..84c9083021c --- /dev/null +++ b/make/data/cldr/common/main/gez_ET.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/gl.xml b/make/data/cldr/common/main/gl.xml index e1ef5ec1a20..d2593fc251c 100644 --- a/make/data/cldr/common/main/gl.xml +++ b/make/data/cldr/common/main/gl.xml @@ -1,6 +1,6 @@ - + + + + + + + + avañe’ẽ + + + yvóra + África + América del Norte + América del Sur + Oceanía + América Central + América + Norteamérica + Caribe + Ásia + Európa + América Latina + Argentína + Bolívia + Brasil + Chíle + Colómbia + Ecuador + Union Européa + Eurozóna + Guyána Francésa + Groenlandia + Guyana + México + Peru + Paraguai + Surinam + Naciónes Unídas + Estados Unidos + EE. UU. + Uruguay + Venezuéla + + + + + left-to-right + top-to-bottom + + + + [a ã {ch} e ẽ g {g\u0303} h i ĩ j k l m {mb} n ñ {nd} {ng} {nt} o õ p r {rr} s t u ũ v y ỹ ʼ] + [b c d f q w x z] + [A à {CH} E Ẽ G {G\u0303} H I Ĩ J K L M {MB} N Ñ {ND} {NG} {NT} O Õ P R {RR} S T U Ũ V Y Ỹ ʼ] + + + + + + + + Jasyteĩ + Jasykõi + Jasyapy + Jasyrundy + Jasypo + Jasypoteĩ + Jasypokõi + Jasypoapy + Jasyporundy + Jasypa + Jasypateĩ + Jasypakõi + + + + + + + Arateĩ + Arakõi + Araapy + Ararundy + Arapo + Arapoteĩ + Arapokõi + + + + + + + + ary + + + jasy + + + ára + + + kuehe + ko ára + koʼẽrõ + + + kuehe + ko ára + koʼẽrõ + + + arapokõindy + + + aravo’i + + + aravo’ive + + + + + + Bolivia óra + + + + + Ecuador óra + + + + + Galápagos óra + + + + + Venezuela óra + + + + + + + , + . + + + + + + + + diff --git a/make/data/cldr/common/main/gn_PY.xml b/make/data/cldr/common/main/gn_PY.xml new file mode 100644 index 00000000000..03fbf31e5f8 --- /dev/null +++ b/make/data/cldr/common/main/gn_PY.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/gsw.xml b/make/data/cldr/common/main/gsw.xml index 0004c8c0b62..f9187c89ca7 100644 --- a/make/data/cldr/common/main/gsw.xml +++ b/make/data/cldr/common/main/gsw.xml @@ -1,6 +1,6 @@ - + + + + + + + + 𞄒𞄫𞄱𞄔𞄩𞄴 + + + + + left-to-right + top-to-bottom + + + + [\U0001E131 \U0001E136 \U0001E132 \U0001E133 \U0001E130 \U0001E134 \U0001E135 𞅏 𞄼 𞄽 𞄀 𞄁 𞄂 𞄃 𞄄 𞄅 𞄆 𞄇 𞄈 𞄉 𞄊 𞄋 𞄌 𞄍 𞄎 𞄏 𞄐 𞄑 𞄒 𞄓 𞄔 𞄕 𞄖 𞄗 𞄘 𞄙 𞄚 𞄛 𞄜 𞄝 𞄞 𞄟 𞄠 𞄡 𞄢 𞄣 𞄤 𞄥 𞄦 𞄧 𞄨 𞄩 𞄪 𞄫 𞄬 𞅎] + + [𞄀 𞄁 𞄂 𞄃 𞄄 𞄅 𞄆 𞄇 𞄈 𞄉 𞄊 𞄋 𞄌 𞄍 𞄎 𞄏 𞄐 𞄑 𞄒 𞄓 𞄔 𞄕 𞄖 𞄗 𞄘 𞄙 𞄚 𞄛 𞄜 𞄝 𞄞 𞄟 𞄠 𞄡 𞄢 𞄣 𞄤 𞄥 𞄦 𞄧 𞄨 𞄩 𞄪 𞄫 𞄬] + [\- ‑ , . % + 𞅀 𞅁 𞅂 𞅃 𞅄 𞅅 𞅆 𞅇 𞅈 𞅉] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + 𞄆𞄬 + 𞄛𞄨𞄱𞄄𞄤𞄲𞄨 + 𞄒𞄫𞄰𞄒𞄪𞄱 + 𞄤𞄨𞄱 + 𞄀𞄪𞄴 + 𞄛𞄤𞄱𞄞𞄤𞄦 + 𞄔𞄩𞄴𞄆𞄨𞄰 + 𞄕𞄩𞄲𞄔𞄄𞄰𞄤 + 𞄛𞄤𞄱𞄒𞄤𞄰 + 𞄪𞄱𞄀𞄤𞄴 + 𞄚𞄦𞄲𞄤𞄚𞄄𞄰𞄫 + 𞄒𞄩𞄱𞄔𞄬𞄴 + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + 𞄆𞄬 + 𞄛𞄨𞄱𞄄𞄤𞄲𞄨 + 𞄒𞄫𞄰𞄒𞄪𞄱 + 𞄤𞄨𞄱 + 𞄀𞄪𞄴 + 𞄛𞄤𞄱𞄞𞄤𞄦 + 𞄔𞄩𞄴𞄆𞄨𞄰 + 𞄕𞄩𞄲𞄔𞄄𞄰𞄤 + 𞄛𞄤𞄱𞄒𞄤𞄰 + 𞄪𞄱𞄀𞄤𞄴 + 𞄚𞄦𞄲𞄤𞄚𞄄𞄰𞄫 + 𞄒𞄩𞄱𞄔𞄬𞄴 + + + + + 𞄆𞄬 + 𞄛𞄨𞄱𞄄𞄤𞄲𞄨 + 𞄒𞄫𞄰𞄒𞄪𞄱 + 𞄤𞄨𞄱 + 𞄀𞄪𞄴 + 𞄛𞄤𞄱𞄞𞄤𞄦 + 𞄔𞄩𞄴𞄆𞄨𞄰 + 𞄕𞄩𞄲𞄔𞄄𞄰𞄤 + 𞄛𞄤𞄱𞄒𞄤𞄰 + 𞄪𞄱𞄀𞄤𞄴 + 𞄚𞄦𞄲𞄤𞄚𞄄𞄰𞄫 + 𞄒𞄩𞄱𞄔𞄬𞄴 + + + 𞄆𞄬 + 𞄛𞄨𞄱𞄄𞄤𞄲𞄨 + 𞄒𞄫𞄰𞄒𞄪𞄱 + 𞄤𞄨𞄱 + 𞄀𞄪𞄴 + 𞄛𞄤𞄱𞄞𞄤𞄦 + 𞄔𞄩𞄴𞄆𞄨𞄰 + 𞄕𞄩𞄲𞄔𞄄𞄰𞄤 + 𞄛𞄤𞄱𞄒𞄤𞄰 + 𞄪𞄱𞄀𞄤𞄴 + 𞄚𞄦𞄲𞄤𞄚𞄄𞄰𞄫 + 𞄒𞄩𞄱𞄔𞄬𞄴 + + + + + + + 𞄎𞄤𞄲 + 𞄈𞄦 + 𞄆𞄨𞄰 + 𞄗𞄄𞄤𞄰𞄦 + 𞄙𞄤𞄱𞄨 + 𞄑𞄤𞄱𞄨 + 𞄊𞄧𞄳 + + + + + + + 𞅁 + 𞅂 + 𞅃 + 𞅄 + + + + + 𞅁 + 𞅂 + 𞅃 + 𞅄 + + + + + + 𞄜𞄆𞄪 + + + 𞄜𞄆𞄪 + + + + + + + 𞄛𞄩 + + + 𞄛𞄩 + + + 𞄛𞄩 + + + + + hmnp + latn + + + 𞅎 + + + + diff --git a/make/data/cldr/common/main/hnj_Hmnp.xml b/make/data/cldr/common/main/hnj_Hmnp.xml new file mode 100644 index 00000000000..0572f3ad943 --- /dev/null +++ b/make/data/cldr/common/main/hnj_Hmnp.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + + + + + + + + Mundus + Africa + America Septentrionalis + America Australis + Oceania + Africa Occidentalis + America Centralis + Africa Orientalis + Africa Septentrionalis + Africa Australis (regio) + America + Caribaeum + Asia Orientalis + Asia Meridiorientalis + Europa Centralis + Australasia + Melanesia + Micronesia (regio) + Polynesia + Asia + Media Asia + Europa + Europa Orientalis + Europa Septentrionalis + Europa Occidentalis + Andorra + Phylarchiarum Arabicarum Confoederatio + Afgania + Antiqua et Barbuda + Anguilla + Albania + Armenia + Angolia + Argentina + Samoa Americana + Austria + Australia + Aruba + Alandia + Atropatene + Bosnia et Herzegovina + Barbata + Bangladesha + Belgica + Burkina Faso + Bulgaria + Baharina + Burundia + Beninum + Insula Sancti Bartholomaei + Bermuda + Bruneium + Bolivia + Brasilia + Insulae Bahamenses + Butania + Birmania + Insula Bouvet + Botswana + Ruthenia Alba + Beliza + Canada + Insulae Cocos seu Keeling + Res publica Democratica Congensis + Res publica Africae Mediae + Res publica Congoliae + Helvetia + Litus Eburneum + Insulae Cook + Chilia + Cameronia + Res publica popularis Sinarum + Columbia + Costarica + Cuba + Res publica Capitis Viridis + Insula Curacensis + Insula Christi Natalis + Cyprus + Cechia + Res publica Democratica Germanica + Germania + Gibutum + Dania + Dominica + Res publica Dominicana + Algerium + Aequatoria + Estonia + Aegyptus + Sahara Occidentalis + Erythraea + Hispania + Aethiopia + Finnia + Viti + Insulae Malvinae + Micronesia + Faeroae insulae + Francia + Gabonia + Britanniarum Regnum + Granata + Georgia + Guiana Francica + Lisia + Gana + Gibraltar + Groenlandia + Gambia + Guinea + Guadalupa + Guinea Aequatorensis + Graecia + Guatimalia + Guama + Guinea Bissaviensis + Guiana + Hongcongum + Honduria + Croatia + Haitia + Hungaria + Indonesia + Hibernia + Israël + Monapia + India + Iracum + Irania + Islandia + Italia + Caesarea Insula + Iamaica + Iordania + Iaponia + Kenia + Chirgisia + Cambosia + Kiribati + Insulae Comorianae + Sanctus Christophorus et Nevis + Res publica Popularis Democratica Coreana + Res publica Coreana + Cuvaitum + Insulae Caimanenses + Kazachstania + Laotia + Libanus + Sancta Lucia + Lichtenstenum + Taprobane + Liberia + Lesothum + Lituania + Luxemburgum + Lettonia + Libya + Marocum + Monoecus + Res publica Moldavica + Mons Niger + Madagascaria + Insulae Marsalienses + Res publica Macedonica + Malium + Mongolia + Macaum + Insulae Marianae Septentrionales + Martinica + Mauritania + Montserrat + Melita + Mauritia + Insulae Maldivae + Malavium + Mexicum + Malaesia + Mozambicum + Namibia + Nova Caledonia + Res publica Nigritana + Insula Norfolcia + Nigeria + Nicaragua + Nederlandia + Regnum Nederlandiae + Norvegia + Nepalia + Nauru + Niue + Nova Zelandia + Omania + Panama + Peruvia + Polynesia Francica + Papua Nova Guinea + Philippinae + Pakistania + Polonia + Insulae Sancti Petri et Miquelonensis + Insulae Pitcairn + Portus Dives + Territoria Palaestinensia + Portugallia + Belavia + Paraquaria + Quataria + Reunio + Romania + Serbia + Russia + Ruanda + Arabia Saudiana + Insulae Salomonis + Insulae Seisellenses + Sudania + Suecia + Singapura + Sancta Helena, Ascensio et Tristan da Cunha + Slovenia + Slovacia + Mons Leoninus + Res publica Sancti Marini + Senegalia + Somalia + Surinamia + Sudania Australis + Insulae Sancti Thomae et Principis + Salvatoria + Syria + Swazia + Insulae Turcenses et Caicenses + Tzadia + Togum + Thailandia + Tadzikistania + Tokelau + Timoria Orientalis + Turcomannia + Tunesia + Tonga + Turcia + Trinitas et Tabacum + Tuvalu + Res publica Sinarum + Tanzania + Ucraina + Uganda + Civitates Foederatae Americae + Uraquaria + Uzbecia + Civitas Vaticana + Sanctus Vincentius et Granatinae + Venetiola + Virginis Insulae Britannicae + Virginis Insulae Americanae + Vietnamia + Vanuatu + Vallis et Futuna + Samoa + Kosovia + Iemenia + Maiotta + Iugoslavia + Africa Australis + Zambia + Zimbabua + + + + [a b c d e f g h i j k l m n o p q r s t u v w x y z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + + + + + + + Ian + Feb + Mar + Apr + Mai + Iun + Iul + Aug + Sep + Oct + Nov + Dec + + + Ianuarii + Februarii + Martii + Aprilis + Maii + Iunii + Iulii + Augusti + Septembris + Octobris + Novembris + Decembris + + + + + Ian + Feb + Mar + Apr + Mai + Iun + Iul + Aug + Sep + Oct + Nov + Dec + + + Ianuarius + Februarius + Martius + Aprilis + Maius + Iunius + Iulius + Augustus + September + October + November + December + + + + + + + Sol + Dom + Lun + Mar + Mer + Iov + Ven + Sat + Sab + + + dies Solis + Dominica + dies Lunae + dies Martis + dies Mercurii + dies Iovis + dies Veneris + dies Saturni + dies Sabbati + + + + + Sol + Dom + Lun + Mar + Mer + Iov + Ven + Sat + Sab + + + dies Solis + Dominica + dies Lunae + dies Martis + dies Mercurii + dies Iovis + dies Veneris + dies Saturni + Sabbatum + + + + + + + Q1 + Q2 + Q3 + Q4 + + + prima quarta + secunda quarta + tertia quarta + quarta quarta + + + + + Q1 + Q2 + Q3 + Q4 + + + prima quarta + secunda quarta + tertia quarta + quarta quarta + + + + + + + a.m. + p.m. + + + a.m. + p.m. + + + + + + ante Christum natum + post Christum natum + + + a.C.n. + p.C.n. + + + + + + EEEE, 'die' d MMMM y G + GyMMMMEEEEd + + + + + 'die' d MMMM y G + GyMMMMd + + + + + 'die' d MMM y G + GyMMMd + + + + + d M y G + GyMd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} 'de' {0} + + + + + {1} 'de' {0} + + + + + {1}, {0} + + + + + {1}, {0} + + + + + + + + eare + + + anno + priore anno + hoc anno + postero anno + + in {0} anno + in {0} annis + + + abhinc {0} annum + abhinc {0} annos + + + + an. + priore an. + hoc an. + postero an. + + in {0} an. + in {0} an. + + + abhinc {0} an. + abhinc {0} an. + + + + quarter + priore quarta + hac quarta + postera quarta + + in {0} quarta + in {0} quartis + + + abhinc {0} quartam + abhinc {0} quartas + + + + qrt. + priore qrt. + hac qrt. + postera qrt. + + in {0} qrt. + in {0} qrt. + + + abhinc {0} qrt. + abhinc {0} qrt. + + + + mensis + priore mense + hac mense + postera mense + + in {0} mense + in {0} mensibus + + + abhinc {0} mensem + abhinc {0} menses + + + + men. + priore men. + hac men. + postera men. + + in {0} men. + in {0} men. + + + abhinc {0} men. + abhinc {0} men. + + + + hebdomas + priore hebdomade + hac hebdomade + postera hebdomade + + in {0} hebdomade + in {0} hebdomadibus + + + abhinc {0} hebdomadem + abhinc {0} hebdomades + + the week of {0} + + + hebd. + priore hebd. + hac hebd. + postera hebd + + in {0} hebd. + in {0} hebd. + + + abhinc {0} hebd. + abhinc {0} hebd. + + + + dies + pridie + hodie + cras + + in {0} die + in {0} diebus + + + abhinc {0} diem + abhinc {0} dies + + + + dies + + in {0} die + in {0} diebus + + + abhinc {0} diem + abhinc {0} dies + + + + day of the week + + + priore die Solis + hoc die Solis + postero die Solis + + in {0} die Solis + in {0} diebus Solis + + + abhinc {0} diem Solis + abhinc {0} dies Solis + + + + prior. die Sol. + hoc die Sol. + post. die Sol. + + in {0} die Sol. + in {0} dieb. Sol. + + + abhinc {0} diem Sol. + abhinc {0} dies Sol. + + + + priore die Lunae + hoc die Lunae + postero die Lunae + + in {0} die Lunae + in {0} diebus Lunae + + + abhinc {0} diem Lunae + abhinc {0} dies Lunae + + + + priore die Lun. + hoc die Lun. + postero die Lun. + + in {0} die Lun. + in {0} diebus Lun. + + + abhinc {0} diem Lun. + abhinc {0} dies Lun. + + + + priore die Martis + hoc die Martis + postero die Martis + + in {0} die Martis + in {0} diebus Martis + + + abhinc {0} diem Martis + abhinc {0} dies Martis + + + + priore die Mar. + hoc die Mar. + postero die Mar. + + in {0} die Mar. + in {0} diebus Mar. + + + abhinc {0} diem Mar. + abhinc {0} dies Mar. + + + + priore die Mercurii + hoc die Mercurii + postero die Mercurii + + in {0} die Mercurii + in {0} diebus Mercurii + + + abhinc {0} diem Mercurii + abhinc {0} dies Mercurii + + + + priore die Merc. + hoc die Merc. + postero die Merc. + + in {0} die Merc. + in {0} diebus Merc. + + + abhinc {0} diem Merc. + abhinc {0} dies Merc. + + + + priore die Iovis + hoc die Iovis + postero die Iovis + + in {0} die Iovis + in {0} diebus Iovis + + + abhinc {0} diem Iovis + abhinc {0} dies Iovis + + + + priore die Iov. + hoc die Iov. + postero die Iov. + + in {0} die Iov. + in {0} diebus Iov. + + + abhinc {0} diem Iov. + abhinc {0} dies Iov. + + + + priore die Veneris + hoc die Veneris + postero die Veneris + + in {0} die Veneris + in {0} diebus Veneris + + + abhinc {0} diem Veneris + abhinc {0} dies Veneris + + + + priore die Ven. + hoc die Ven. + postero die Ven. + + in {0} die Ven. + in {0} diebus Ven. + + + abhinc {0} diem Ven. + abhinc {0} dies Ven. + + + + priore die Saturni + hoc die Saturni + postero die Saturni + + in {0} die Saturni + in {0} diebus Saturni + + + abhinc {0} diem Saturni + abhinc {0} dies Saturni + + + + priore die Sat. + hoc die Sat. + postero die Sat. + + in {0} die Sat. + in {0} diebus Sat. + + + abhinc {0} diem Sat. + abhinc {0} dies Sat. + + + + hora + hac hora + + in {0} hora + in {0} horis + + + abhinc {0} horam + abhinc {0} horas + + + + hr. + + in {0} hr. + in {0} hr. + + + abhinc {0} hr. + abhinc {0} hr. + + + + minuta + hac minuta + + in {0} minuta + in {0} minutis + + + abhinc {0} minutam + abhinc {0} minutas + + + + min. + + in {0} min. + in {0} min. + + + abhinc {0} min. + abhinc {0} min. + + + + secunda + nunc + + in {0} secunda + in {0} secundis + + + abhinc {0} secundam + abhinc {0} secundas + + + + sec. + nunc + + in {0} sec. + in {0} sec. + + + abhinc {0} sec. + abhinc {0} sec. + + + + time zone + + + + + latn + + latn + + 1 + + , +   + ; + % + + + - + + + : + + + + + #,##0.### + + + + + 0 mille + 0 millia + 00 millia + 00 millia + 000 millia + 000 millia + 0 milio + 0 miliones + 00 miliones + 00 miliones + 000 miliones + 000 miliones + 0 miliardum + 0 miliarda + 00 miliarda + 00 miliarda + 000 miliarda + 000 miliarda + 0 milies miliardum + 0 milies miliarda + 00 milies miliarda + 00 milies miliarda + 000 milies miliarda + 000 milies miliarda + + + + + 0M + 0M + 00M + 00M + 000M + 000M + 0 Mn + 0 Mn + 00 Mn + 00 Mn + 000 Mn + 000 Mn + 0 Md + 0 Md + 00 Md + 00 Md + 000 Md + 000 Md + 0 mil Md + 0 mil Md + 00 mil Md + 00 mil Md + 000 mil Md + 000 mil Md + + + + + + Francus Helveticus + + + Euro + + + Marca Finniae + + + Libra sterlingorum + + + Drachma + + + Dollarium Hongkongense + + + Lira Italiana + + + Yen + + + Pensum Mexicanum + + + Corona Norvegiae + + + Nuevo Sol + + + Rubelus Russicus + + + Dollarium Civitatum Foederatarum + + + Argentum + + + Aurum + + + Palladium + + + Platinum + + + + + + {0}, {1} + {0}, {1} + {0} et {1} + {0} et {1} + + + {0}, {1} + {0}, {1} + {0} et {1} + {0} et {1} + + + {0}, {1} + {0}, {1} + {0} et {1} + {0}, {1} + + + {0}, {1} + {0}, {1} + {0} et {1} + {0}, {1} + + + + + ita:i + non:n + + + diff --git a/make/data/cldr/common/main/la_VA.xml b/make/data/cldr/common/main/la_VA.xml new file mode 100644 index 00000000000..c14b6ed224e --- /dev/null +++ b/make/data/cldr/common/main/la_VA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/lag.xml b/make/data/cldr/common/main/lag.xml index b58b92937ef..38f473a3cc1 100644 --- a/make/data/cldr/common/main/lag.xml +++ b/make/data/cldr/common/main/lag.xml @@ -1,6 +1,6 @@ - + + + + + + + + {0} ({1}) + {0}, {1} + {0}: {1} + + + abcaso + aceh + adangme + adyghe + afrikaans + aghem + ainu + akan + aléuto + altai do meridion + amarico + aragoneise + obolo + angika + arabo + arabo moderno standard + mapuche + arpaho + arabo najd + assameise + asu + asturian + atikamekw + avaro + awadhi + aymara + azerbaigian + azero + baschiro + balineise + basaa + bielloruscio + bemba + bena + burgao + bhojpuri + bislama + bini + siksika + bambara + bengaleise + tibetan + breton + bòddo + bosniaco + bugineise + blin + catalan + cayuga + chakma + cecen + cebuano + chiga + chamorro + chuukeise + mari + choctaw + chipewyan + cherokee + cheyenne + curdo sorani + curdo do mezo + chilcotin + còrso + métchif + cree do sud-levante + cree de ciañe + cree do nòrd-levante + cree moose + algonchin da Carolina + ceco + cree de smeugge + chuvash + galleise + daneise + dakota + dargwa + taita + tedesco + tedesco de l’Austria + tedesco standard da Svissera + dogrib + zarma + dogri + basso sorabo + duala + divehi + jola-fonyi + dzongkha + dazaga + embu + ewe + efik + ekajuk + grego + ingleise + ingleise d’Australia + ingleise do Canadà + ingleise britannico + ingleise (RU) + ingleise d’America + ingleise (SUA) + esperanto + spagnòllo + spagnòllo d’America + spagnòllo da Spagna + spagnòllo do Mescico + estone + basco + ewondo + perscian + dari + fulah + finlandeise + filipin + fijian + faroeise + fòn + franseise + franseise do Canadà + franseise da Svissera + franseise cajun + frison do settentrion + furlan + frisian de ponente + irlandeise + ga + gaelico scoçeise + geez + gilberteise + galiçian + guarani + gorontalo + tedesco da Svissera + gujarati + gusii + manneise + gwichʼin + hausa + haida + hawaiian + haida do meridion + ebreo + hindi + hinglish + hiligaynon + hmong + croato + erto sorabo + creolo de Haiti + ongareise + hupa + halkomelem + ermeno + herero + interlingua + iban + ibibio + indonesian + igbo + yi do settentrion + inuktitut canadeise de ponente + ilocan + ingush + ido + islandeise + italian + inuktitut + giapponeise + lojban + ngomba + machame + giavaneise + georgian + cabilo + kachin + jju + kamba + cabardin + tyap + makonde + cappoverdian + koro + kaingang + khasi + koyra chiini + kikuyu + kuanyama + kazakh + kako + groenlandeise + kalenjin + khmer + kimbundu + kannada + corean + konkani + kpelle + kanuri + karchay-balkar + carelian + kurukh + kashmiri + shambala + bafia + colonieise + curdo + kumyk + komi + còrnico + kwakʼwala + kirghiso + latin + giudeo-spagnòllo + langi + luxemburgheise + lesgo + ganda + limburgheise + ligure + lillooet + lakota + lingala + lao + creolo da Louisiana + lozi + luri do settentrion + samia + lituan + luba-katanga + luba-lulua + lunda + luo + lushai + luyia + letton + madureise + magahi + maithili + makasar + masai + moksha + mende + meru + creolo mauriçian + malagascio + makhuwa-meetto + meta’ + marshalleise + maori + mi'kmaq + minangkabau + maçedone + malayalam + mongolo + manipuri + innu-aimun + mohawk + mossi + marathi + maleise + malteise + mudang + moltilengua + muscogee + mirandeise + birman + erzya + mazanderani + nauru + napolitan + nama + norvegin bokmål + ndebele do settentrion + basso tedesco + nepaleise + newari + ndonga + nias + niue + olandeise + sciammengo + kwasio + norvegin nynorsk + ngiemboon + norvegin + nogai + n’ko + ndebele do meridion + sotho do settentrion + nuer + navajo + nyanja + nyankole + oçitan + ojibwa do nòrd-ponente + ojibwa do mezo + oji-cree + ojibwa de ponente + okangan + oromo + ödia + oscetico + punjabi + pangasinan + pampanga + papiamento + palau + pidgin nigerian + pijin + polacco + malecite-passamaquoddy + pashto + portogheise + portogheise do Braxî + portogheise d’Euröpa + quechua + rapanui + rarotonga + rohingya + romancio + rundi + romen + rombo + ruscio + aromen + kinyarwanda + rwa + sanscrito + sandawe + sakha + samburu + santali + ngambay + sangu + sardo + siçilian + scoçeise + sindhi + sami do settentrion + sena + koyraboro senni + sango + tashelhit + shan + sinhala + slovacco + sloven + lushootseed do meridion + samoan + sami de Inari + sami skolt + shona + soninke + sòmalo + arbaneise + serbo + sranan tongo + swati + sotho do meridion + salish di streiti + sundaneise + sukuma + svedeise + swahili + comörian + sciriaco + tamil + tutchone do meridion + telugu + timne + teso + tetum + tagico + tagish + thai + tahltan + tigrinya + tigre + turcomanno + klingon + tlingit + tswana + tongan + toki pona + tok pisin + turco + taroko + tsonga + tataro + tutchone do settentrion + tumbuka + tuvalu + tasawaq + tahitian + tuvinian + tamazight de l’Atlante do mezo + udmurt + uiguro + ucrain + umbundu + lengua desconosciua + urdu + uzbeco + vai + venda + vietnamita + vunjo + vallon + walser + wolaytta + waray + wolof + cineise wu + kalmyk + xhosa + soga + yangben + yemba + yiddish + yoruba + nheengatu + cantoneise + cineise cantoneise + tamazight standard do Maròcco + cineise + cineise mandarin + cineise semplificou + cineise mandarin semplificou + cineise tradiçionale + cineise mandarin tradiçionale + zulu + zuni + sensa contegnuo linguistico + zaza + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mondo + Africa + America do settentrion + America do meridion + Oçeania + Africa de ponente + America do mezo + Africa de levante + Africa do settentrion + Africa do mezo + Africa do meridion + Americhe + America do nòrd + Caraibi + Asia de levante + Asia do meridion + Asia do sud-levante + Euröpa do meridion + Australasia + Melanesia + region da Micronesia + Polinesia + Asia + Asia do mezo + Asia de ponente + Euröpa + Euröpa de levante + Euröpa do settentrion + Euröpa de ponente + Africa subsahariaña + America latiña + Isoa de l’Ascension + Andòrra + Emirati arabi unii + Afghanistan + Antigua e Barbuda + Anguilla + Arbania + Ermenia + Angola + Antartide + Argentiña + Samoa americaña + Austria + Australia + Aruba + Isoe Åland + Azerbaigian + Bòsnia e Herzegòvina + Barbados + Bangladesh + Belgio + Burkina Faso + Borgaia + Bahrein + Burundi + Benin + San Bertomê + Bermuda + Brunei + Bolivia + Caraibi olandeixi + Braxî + Bahamas + Bhutan + Isoa Bouvet + Botswana + Bieloruscia + Belize + Canadà + Isoe Cocos (Keeling) + Congo-Kinshasa + Congo (RDC) + Repubrica çentrafricaña + Congo-Brazzaville + Congo (Repubrica) + Svissera + Còsta d’Avöio + Côte d’Ivoire + Isoe Cook + Cile + Cameron + Ciña + Colombia + Isoa de Clipperton + Còsta Rica + Cubba + Cappo Verde + Curaçao + Isoa Christmas + Çipri + Cechia + Repubrica ceca + Germania + Diego Garcia + Djibouti + Danimarca + Dominica + Repubrica dominicaña + Algeria + Çéuta e Melilla + Ecuador + Estònia + Egitto + Sahara de ponente + Eritrea + Spagna + Etiòpia + Union europea + zöna euro + Finlandia + Figi + Isoe Malviñe + Isoe Malviñe (Isoe Falkland) + Micronesia + Isoe Fær Øer + Fransa + Gabon + Regno Unio + RU + Granada + Geòrgia + Guyana franseise + Guernsey + Ghana + Gibertâ + Groenlandia + Gambia + Guinea + Guadaluppa + Guinea equatoiäle + Greçia + Geòrgia do Sud e Isoe Sandwich do Sud + Guatemala + Guam + Guinea Bissau + Guyana + RAS de Hong Kong (Ciña) + Hong Kong + Isoe Heard e McDonald + Honduras + Croaçia + Haiti + Ongaia + Isoe Canäie + Indonesia + Irlanda + Israele + Isoa de Man + India + Tære britanniche de l’oçeano Indian + Iraq + Iran + Islanda + Italia + Jersey + Giamaica + Giordania + Giappon + Kenya + Kirghizistan + Cambòggia + Kiribati + Comöre + San Cristòffa e Nevis + Corea do Nòrd + Corea do Sud + Kuwait + Isoe Cayman + Kazakistan + Laos + Libano + Santa Luçia + Liechtenstein + Sri Lanka + Liberia + Lesotho + Lituania + Luxemburgo + Lettònia + Libia + Maròcco + Monego + Moldavia + Monteneigro + San Martin + Madagascar + Isoe Marshall + Maçedònia do Nòrd + Mali + Myanmar (Birmania) + Mongòlia + RAS de Macao + Macao + Isoe Mariañe de settentrion + Martinica + Mauritania + Montserrat + Malta + Mauritius + Maldive + Malawi + Mescico + Malaysia + Mozambico + Namibia + Neuva Caledònia + Niger + Isoa Norfolk + Nigeria + Nicaragua + Paixi Basci + Norveggia + Nepal + Nauru + Niue + Neuva Zelanda + Aoteratoa Neuva Zelanda + Òman + Panama + Perù + Polinesia fraseise + Papua Neuva Guinea + Filipiñe + Pakistan + Polònia + San Pê e Miquelon + Isoe Pitcairn + Puerto Rico + Tære palestineixi + Palestiña + Portugâ + Palau + Paraguay + Qatar + regioin lontañe de l’Oçeania + Réunion + Romania + Serbia + Ruscia + Rwanda + Arabia saudia + Isoe Salomon + Seychelles + Sudan + Sveçia + Scingapô + Sant’Elena + Slovenia + Svalbard e Jan Mayen + Slovacchia + Sierra Leone + San Marin + Senegal + Somalia + Suriname + Sudan do Sud + Sao Tomé e Prinçipe + El Salvador + Sint Maarten + Sciria + Eswatini + Swaziland + Tristan da Cunha + Isoe Turks e Caicos + Chad + Tære australe franseixi + Tögo + Tailandia + Tagikistan + Tokelau + Timor Est + Timor-Leste + Turkmenistan + Tunexia + Tonga + Turchia + Trinidad e Tobago + Tuvalu + Taiwan + Tanzania + Ucraiña + Uganda + Isoe lontañe di SUA + Naçioin Unie + Stati Unii + SUA + Uruguay + Uzbekistan + Çittæ do Vatican + San Viçenso e e Granadiñe + Venessuela + Isoe Vergine britanniche + Isoe Vergine di Stati Unii + Vietnam + Vanuatu + Wallis e Futuna + Samoa + pseudo-açenti + pseudo-bidi + Kòsovo + Yemen + Maiòtta + Sudafrica + Zambia + Zimbabwe + region desconosciua + + + lunäio + formato de monæa + ordine + monæa + scistema oräio (12 ò 24 oe) + stilo de interruçion de linia + scistema de mesuaçion + numeri + + + lunäio buddista + lunäio cineise + lunäio còpto + lunäio dangi + lunäio etiope + lunäio etiope Amete Alem + lunäio gregorian + lunäio ebraico + lunäio islamico + lunäio çivile islamico + lunäio islamico (Umm al-Qura) + lunäio ISO-8601 + lunäio giapponeise + lunäio perscian + lunäio repubrican cineise + formato de monæa contabile + formato de monæa standard + ordine predefinio de Unicode + reçerca generica + ordine standard + scistema oräio à 12 oe (0–11) + scistema oräio à 12 oe (1–12) + scistema oräio à 24 oe (0–23) + scistema oräio à 24 oe (1–24) + stilo de interruçion de linia flescibile + stilo de interruçion de linia standard + stilo de interruçion de linia sforsou + scistema metrico + scistema de mesuaçion imperiale + scistema de mesuaçion american + giffre indo-arabe + giffre indo-arabe esteise + numeri ermeni + numeri ermeni piccin + giffre bengaleixi + giffre chakma + giffre devanagari + numeri etiopi + giffre à ampiessa intrega + numeri georgien + numeri greghi + numeri greghi piccin + giffre gujarati + giffre gurmuki + numeri deçimali cineixi + numeri cineixi semplificæ + numeri finansiäi in cineise semplificou + numeri cineixi tradiçionali + numeri finansiäi in cineise tradiçionale + numeri ebraichi + giffre giavaneixi + numeri giapponeixi + numeri finansiäi giapponeixi + giffre khmer + giffre kannada + giffre lao + giffre occidentale + giffre malayalam + giffre meetei mayek + giffre birmañe + giffre ol chiki + giffre ödia + numeri romoen + numeri romoen piccin + giffre tamil tradiçionale + giffre tamil + giffre telugu + giffre tailandeixi + giffre tibetañe + giffre vaii + + + metrico + imperiale + american + + + Lengua: {0} + Scrittua: {0} + Region: {0} + + + + [a à â ä æ b c ç d e é è ê ë f g h i ì î ï j k l m n ñ o ó ò ô ö p q r s t u ù û ü v w x y z] + [õ ō œ ř] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + [\- ‑ , . ' % ‰ + − 0 1 2 3 4 5 6 7 8 9 ª º] + [\- ‐ ‑ – — , ; \: ! ? . … ’ " “ ” « » ( ) \[ \] § @ * / \& # † ‡] + + + « + » + + + + + + + + + + EEEE d 'de' MMMM 'do' y G + + + + + d 'de' MMMM 'do' y G + + + + + d/M/y G + + + + + d/M/yy GGGGG + + + + + + + {1}, {0} + + + {1} 'à' {0} + + + + + {1}, {0} + + + {1} 'à' {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + E d + y G + d/M/y GGGGG + LLL y G + d MMM y G + E d MMM y G + H + d/M + E d/M + d MMM + E d MMM + d MMMM + y G + y G + M/y G + d/M/y G + E d/M/y GGGGG + LLL y G + d MMM y G + E d MMM y G + LLLL 'do' y G + QQQ y G + QQQQ y G + + + + y G – y G + y–y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + d/M/y – d/M/y GGGGG + d/M/y GGGGG – d/M/y GGGGG + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + + + E d/M/y – E d/M/y GGGGG + E d/M/y GGGGG – E d/M/y GGGGG + E d/M/y – E d/M/y GGGGG + E d/M/y – E d/M/y GGGGG + + + MMM y G – MMM y G + MMM–MMM y G + MMM y – MMM y G + + + d–d MMM, y G + d MMM y G – d MMM y G + d MMM y G – d MMM y G + d MMM y G – d MMM y G + + + E d MMM – E d MMM y G + E d MMM y G – E d MMM y G + E d MMM y – E d MMM y G + E d MMM y – E d MMM y G + + + M–M + + + d/M – d/M + d/M – d/M + + + E d/M – E d/M + E d/M – E d/M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E d – E d MMM + E d MMM – E d MMM + + + y–y G + + + M/y – M/y GGGGG + M/y – M/y GGGGG + + + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + d/M/y – d/M/y GGGGG + + + E d/M/y – E d/M/y GGGGG + E d/M/y – E d/M/y GGGGG + E d/M/y – E d/M/y GGGGG + + + MMM–MMM y G + MMM 'do' y – MMM 'do' y G + + + d–d MMM 'do' y G + d MMM – d MMM 'do' y G + d MMM 'do' y – d MMM 'do' y G + + + E d MMM – E d MMM 'do' y G + E d MMM – E d MMM 'do' y G + E d MMM 'do' y – E d MMM 'do' y G + + + MMMM–MMMM 'do' y G + MMMM 'do' y – MMMM 'do' y G + + + + + + + + + de zen. + de fre. + de mar. + d’arv. + de maz. + de zug. + de lug. + d’ago. + de set. + d’ott. + de nov. + de dex. + + + ZN + FR + MR + AR + MZ + ZG + LG + AG + ST + OT + NV + DX + + + de zenâ + de frevâ + de marso + d’arvî + de mazzo + de zugno + de luggio + d’agosto + de settembre + d’ottobre + de novembre + de dexembre + + + + + zen. + fre. + mar. + arv. + maz. + zug. + lug. + ago. + set. + ott. + nov. + dex. + + + ZN + FR + MR + AR + MZ + ZG + LG + AG + ST + OT + NV + DX + + + zenâ + frevâ + marso + arvî + mazzo + zugno + luggio + agosto + settembre + ottobre + novembre + dexembre + + + + + + + dom. + lun. + mät. + mäc. + zeu. + ven. + sab. + + + D + L + M + M + Z + V + S + + + dom. + lun. + mät. + mäc. + zeu. + ven. + sab. + + + domenega + lunesdì + mätesdì + mäcordì + zeuggia + venardì + sabbo + + + + + dom. + lun. + mät. + mäc. + zeu. + ven. + sab. + + + D + L + M + M + Z + V + S + + + dom. + lun. + mät. + mäc. + zeu. + ven. + sab. + + + domenega + lunesdì + mätesdì + mäcordì + zeuggia + venardì + sabbo + + + + + + + T1 + T2 + T3 + T4 + + + 1 + 2 + 3 + 4 + + + 1º trimestre + 2º trimestre + 3º trimestre + 4º trimestre + + + + + T1 + T2 + T3 + T4 + + + 1º trimestre + 2º trimestre + 3º trimestre + 4º trimestre + + + + + + + mëzaneutte + mëzogiorno + da mattin + do poidisnâ + da seia + da neutte + + + mëzaneutte + m. + mëzogiorno + p. + da mattin + do poidisnâ + da seia + da neutte + + + mëzaneutte + AM + mëzogiorno + PM + da mattin + do poidisnâ + da seia + da neutte + + + + + mëzaneutte + AM + mëzogiorno + PM + mattin + poidisnâ + seia + neutte + + + mëzaneutte + m. + mëzogiorno + p. + mattin + poidisnâ + seia + neutte + + + mëzaneutte + AM + mëzogiorno + PM + mattin + poidisnâ + seia + neutte + + + + + + avanti de Cristo + avanti de l’era commun + dòppo de Cristo + de l’era commun + + + aC + AEC + dC + EC + + + aC + AEC + dC + EC + + + + + + EEEE d MMMM 'do' y + + + + + d MMMM 'do' y + + + + + d MMM 'do' y + + + + + dd/MM/yy + + + + + + + HH:mm:ss zzzz + + + + + HH:mm:ss z + + + + + HH:mm:ss + + + + + HH:mm + + + + + + + {1}, {0} + + + {1} 'à' {0} + + + + + {1}, {0} + + + {1} 'à' {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1} {0} + + + {1}, {0} + + + + E d + y G + d/M/y G + MMM y G + d MMM 'do' y G + E d MMM 'do' y G + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + d/M + E d/M + d MMM + E d MMM + d MMMM + W'ª' 'settemaña' MMMM + W'ª' 'settemaña' MMMM + M/y + d/M/y + E d/M/y + LLL 'do' y + d MMM 'do' y + E d MMM 'do' y + LLLL 'do' y + QQQ y + QQQQ 'do' y + w'ª' 'settemaña' 'do' Y + w'ª' 'settemaña' 'do' Y + + + + h B – h B + h–h B + + + h:mm B – h:mm B + h:mm–h:mm B + h:mm–h:mm B + + + d–d + + + y G – y G + y–y G + + + M/y G – M/y G + M/y – M/y G + M/y – M/y G + + + d/M/y – d/M/y G + d/M/y G – d/M/y G + d/M/y – d/M/y G + d/M/y – d/M/y G + + + E d/M/y – E d/M/y G + E d/M/y – E d/M/y G + E d/M/y – E d/M/y G + E d/M/y – E d/M/y G + + + LLL 'do' y G – LLL 'do' y G + LLL – LLL 'do' y G + LLL 'do' y – LLL 'do' y G + + + d–d MMM 'do' y G + d MMM 'do' y G – d MMM 'do' y G + d MMM – d MMM 'do' y G + d MMM 'do' y – d MMM 'do' y G + + + E d MMM – E d MMM 'do' y G + E, d MMM 'do' y G – E d MMM 'do' y G + E d MMM – E d MMM 'do' y G + E d MMM 'do' y – E d MMM 'do' y G + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + M–M + + + d/M – d/M + d/M – d/M + + + E d/M – E d/M + E d/M – E d/M + + + d–d MMM + d MMM – d MMM + + + E d – E d MMM + E d MMM – E d MMM + + + M/y – M/y + M/y – M/y + + + d/M/y – d/M/y + d/M/y – d/M/y + d/M/y – d/M/y + + + E d/M/y – E d/M/y + E d/M/y – E d/M/y + E d/M/y – E d/M/y + + + LLL–LLL 'do' y + LLL 'do' y – LLL 'do' y + + + d–d MMM 'do' y + d MMM – d MMM 'do' y + d MMM 'do' y – d MMM 'do' y + + + E d – E d MMM 'do' y + E d MMM – E d MMM 'do' y + E d MMM 'do' y – E d MMM 'do' y + + + LLLL–LLLL 'do' y + LLLL 'do' y – LLLL 'do' y + + + + + + + + era + + + era + + + era + + + anno + l’anno passou + st’anno + l’anno ch’o vëgne + + de chì à {0} anno + de chì à {0} anni + + + l’é {0} anno + l’é {0} anni + + + + anno + l’anno passou + st’anno + l’anno ch’o ven + + de chì à {0} anno + de chì à {0} anni + + + l’é {0} anno + l’é {0} anni + + + + a + anno passou + st’anno + anno ch’o ven + + +{0}a + +{0}a + + + -{0}a + -{0}a + + + + trimestre + o trimestre passou + sto trimestre + o trimestre ch’o vëgne + + de chì à {0} trimestre + de chì à {0} trimestri + + + l’é {0} trimestre + l’é {0} trimestri + + + + trim. + o trim. passou + sto trim. + o trim. ch’o ven + + de chì à {0} trim. + de chì à {0} trim. + + + l’é {0} trim. + l’é {0} trim. + + + + tr + tr. passou + sto tr. + tr. ch’o ven + + +{0}tr + +{0}tr + + + -{0}tr + -{0}tr + + + + meise + o meise passou + sto meise + o meise ch’o vëgne + + de chì à {0} meise + de chì à {0} meixi + + + l’é {0} meise + l’é {0} meixi + + + + meise + o meise passou + sto meise + o meise ch’o ven + + de chì à {0} meise + de chì à {0} meixi + + + l’é {0} meise + l’é {0} meixi + + + + meise + meise passou + sto meise + meise ch’o ven + + +{0}meise + +{0}meixi + + + -{0}meise + -{0}meixi + + + + settemaña + a settemaña passâ + sta settemaña + a settemaña ch’a vëgne + + de chì à {0} settemaña + de chì à {0} settemañe + + + l’é {0} settemaña + l’é {0} settemañe + + a settemaña de {0} + + + sett. + a sett. passâ + sta sett. + a sett. ch’a ven + + de chì à {0} sett. + de chì à {0} sett. + + + l’é {0} sett. + l’é {0} sett. + + a sett. de {0} + + + sett + sett passâ + sta sett + sett ch’a ven + + +{0}sett + +{0}sett + + + -{0}sett + -{0}sett + + sett de {0} + + + settemaña do meise + + + sett. do meise + + + sett do meise + + + giorno + vëi + ancheu + doman + + de chì à {0} giorno + de chì à {0} giorni + + + l’é {0} giorno + l’é {0} giorni + + + + giorno + vëi + ancheu + doman + + de chì à {0} giorno + de chì à {0} giorni + + + l’é {0} giorno + l’é {0} giorni + + + + g + vëi + ancheu + doman + + +{0}g + +{0}g + + + -{0}g + -{0}g + + + + giorno de l’anno + + + giorno de l’anno + + + g de l’anno + + + giorno da settemaña + + + giorno da sett. + + + g da sett + + + giorno do meise + + + giorno do meise + + + g do meise + + + domenega passâ + sta domenega + domenega ch’a vëgne + + de chì à {0} domenega + de chì à {0} domeneghe + + + l’é {0} domenega + l’é {0} domeneghe + + + + dom. passâ + sta dom. + dom. ch’a ven + + de chì à {0} dom. + de chì à {0} dom. + + + l’é {0} dom. + l’é {0} dom. + + + + dom. passâ + sta dom. + dom. ch’a ven + + de chì à {0} dom. + de chì à {0} dom. + + + l’é {0} dom. + l’é {0} dom. + + + + lunesdì passou + sto lunesdì + lunesdì ch’o vëgne + + de chì à {0} lunesdì + de chì à {0} lunesdì + + + l’é {0} lunesdì + l’é {0} lunesdì + + + + lun. passou + sto lun. + lun. ch’o ven + + de chì à {0} lun. + de chì à {0} lun. + + + l’é {0} lun. + l’é {0} lun. + + + + lun. passou + sto lun. + lun. ch’o ven + + de chì à {0} lun. + de chì à {0} lun. + + + l’é {0} lun. + l’é {0} lun. + + + + mätesdì passou + sto mätesdì + mätesdì ch’o vëgne + + de chì à {0} mätesdì + de chì à {0} mätesdì + + + l’é {0} mätesdì + l’é {0} mätesdì + + + + mät. passou + sto mät. + mät. ch’o ven + + de chì à {0} mät. + de chì à {0} mät. + + + l’é {0} mät. + l’é {0} mät. + + + + mät. passou + sto mät. + mät. ch’o ven + + de chì à {0} mät. + de chì à {0} mät. + + + l’é {0} mät. + l’é {0} mät. + + + + mäcordì passou + sto mäcordì + mäcordì ch’o vëgne + + de chì à {0} mäcordì + de chì à {0} mäcordì + + + l’é {0} mäcordì + l’é {0} mäcordì + + + + mäc. passou + sto mäc. + mäc. ch’o ven + + de chì à {0} mäc. + de chì à {0} mäc. + + + l’é {0} mäc. + l’é {0} mäc. + + + + mäc. passou + sto mäc. + mäc. ch’o ven + + de chì à {0} mäc. + de chì à {0} mäc. + + + l’é {0} mäc. + l’é {0} mäc. + + + + zeuggia passâ + sta zeuggia + zeuggia ch’a vëgne + + de chì à {0} zeuggia + de chì à {0} zeugge + + + l’é {0} zeuggia + l’é {0} zeugge + + + + zeu. passâ + sta zeu. + zeu. ch’a ven + + de chì à {0} zeu. + de chì à {0} zeu. + + + l’é {0} zeu. + l’é {0} zeu. + + + + zeu. passâ + sta zeu. + zeu. ch’a ven + + de chì à {0} zeu. + de chì à {0} zeu. + + + l’é {0} zeu. + l’é {0} zeu. + + + + venardì passou + sto venardì + venardì ch’o vëgne + + de chì à {0} venardì + de chì à {0} venardì + + + l’é {0} venardì + l’é {0} venardì + + + + ven. passou + sto ven. + ven. ch’o ven + + de chì à {0} ven. + de chì à {0} ven. + + + l’é {0} ven. + l’é {0} ven. + + + + ven. passou + sto ven. + ven. ch’o ven + + de chì à {0} ven. + de chì à {0} ven. + + + l’é {0} ven. + l’é {0} ven. + + + + sabbo passou + sto sabbo + sabbo ch’o vëgne + + de chì à {0} sabbo + de chì à {0} sabbi + + + l’é {0} sabbo + l’é {0} sabbi + + + + sab. passou + sto sab. + sab. ch’o ven + + de chì à {0} sab. + de chì à {0} sab. + + + l’é {0} sab. + l’é {0} sab. + + + + sab. passou + sto sab. + sab. ch’o ven + + de chì à {0} sab. + de chì à {0} sab. + + + l’é {0} sab. + l’é {0} sab. + + + + AM/PM + + + AM/PM + + + AM/PM + + + oa + st’oa chì + + de chì à {0} oa + de chì à {0} oe + + + l’é {0} oa + l’é {0} oe + + + + oa + st’oa chì + + de chì à {0} oa + de chì à {0} oe + + + l’é {0} oa + l’é {0} oe + + + + h + st’oa chì + + +{0}h + +{0}h + + + -{0}h + -{0}h + + + + menuto + sto menuto chì + + de chì à {0} menuto + de chì à {0} menuti + + + l’é {0} menuto + l’é {0} menuti + + + + men + sto men. chì + + de chì à {0} men + de chì à {0} men + + + l’é {0} men + l’é {0} men + + + + men + sto men. chì + + +{0}men + +{0}men + + + -{0}men + -{0}men + + + + segondo + oua + + de chì à {0} segondo + de chì à {0} segondi + + + l’é {0} segondo + l’é {0} segondi + + + + s + oua + + de chì à {0} s + de chì à {0} s + + + l’é {0} s + l’é {0} s + + + + s + oua + + +{0}s + +{0}s + + + -{0}s + -{0}s + + + + fuso oräio + + + fuso + + + fuso + + + + +HH:mm;−HH:mm + UTC{0} + UTC + oa: {0} + oa de stæ: {0} + oa standard: {0} + {1} ({0}) + + + tempo universale coordinou + + + + çittæ desconosciua + + + Andòrra + + + Tiraña + + + Vostok + + + Còrdova + + + Vienna + + + Bruxelles + + + Bahrein + + + San Bertomê + + + San Poulo + + + Zurigo + + + Pasqua + + + Bogotà + + + Còsta Rica + + + Cappo Verde + + + Curaçao + + + Praga + + + Argê + + + Canäie + + + Çéuta + + + Addis Abeba + + + Figi + + + Fær Øer + + + Pariggi + + + + oa de stæ britannica + + Londra + + + Granada + + + Caieña + + + Gibertâ + + + Guadaluppa + + + Atene + + + Geòrgia do sud + + + Zagabria + + + Giacarta + + + + oa de stæ d’Irlanda + + Doblin + + + Gerusalemme + + + Isoa de Man + + + Calcutta + + + Romma + + + Nairöbi + + + Comöre + + + San Cristoffa + + + Santa Luçia + + + Luxemburgo + + + Monego + + + Ulan Bator + + + Martinica + + + Maldive + + + Çittæ do Mescico + + + Nouméa + + + Òslo + + + Marcheixi + + + Varsavia + + + Azore + + + Lisboña + + + Réunion + + + Belgraddo + + + Mosca + + + Ekaterinburg + + + Cita + + + Stoccolma + + + Scingapô + + + Sant’Elena + + + Lubiaña + + + San Marin + + + Mogadiscio + + + Sao Tomé + + + Damasco + + + N’Djamena + + + Lomé + + + Tunexi + + + Samarcanda + + + Vatican + + + San Viçenso + + + Maiòtta + + + + oa de l’Afghanistan + + + + + oa de l’Africa do mezo + + + + + oa de l’Africa de levante + + + + + oa de l’Africa do meridion + + + + + oa de l’Africa de ponente + oa standard de l’Africa de ponente + oa de stæ de l’Africa de ponente + + + + + oa de l’Alaska + oa standard de l’Alaska + oa de stæ de l’Alaska + + + + + oa de l’Amassònia + oa standard de l’Amassònia + oa de stæ de l’Amassònia + + + + + oa do mezo nordamericaña + oa standard do mezo nordamericaña + oa de stæ do mezo nordamericaña + + + + + oa do levante nordamericaña + oa standard do levante nordamericaña + oa de stæ do levante nordamericaña + + + + + oa de Montagne Alliggiæ + oa standard de Montagne Alliggiæ + oa de stæ de Montagne Alliggiæ + + + + + oa do Paçifico nordamericaña + oa standard do Paçifico nordamericaña + oa de stæ do Paçifico nordamericaña + + + + + oa de Apia + oa standard de Apia + oa de stæ de Apia + + + + + oa de l’Arabia + oa standard de l’Arabia + oa de stæ de l’Arabia + + + + + oa de l’Argentiña + oa standard de l’Argentiña + oa de stæ de l’Argentiña + + + + + oa de l’Argentiña de ponente + oa standard de l’Argentiña de ponente + oa de stæ de l’Argentiña de ponente + + + + + oa de l’Ermenia + oa standard de l’Ermenia + oa de stæ de l’Ermenia + + + + + oa de l’Atlantico nordamericaña + oa standard de l’Atlantico nordamericaña + oa de stæ de l’Atlantico nordamericaña + + + + + oa de l’Australia de mezo + oa standard de l’Australia de mezo + oa de stæ de l’Australia de mezo + + + + + oa de l’Australia do mezo-ponente + oa standard de l’Australia do mezo-ponente + oa de stæ de l’Australia do mezo-ponente + + + + + oa de l’Australia de levante + oa standard de l’Australia de levante + oa de stæ de l’Australia de levante + + + + + oa de l’Australia de ponente + oa standard de l’Australia de ponente + oa de stæ de l’Australia de ponente + + + + + oa de l’Azerbaigian + oa standard de l’Azerbaigian + oa de stæ de l’Azerbaigian + + + + + oa de Azore + oa standard de Azore + oa de stæ de Azore + + + + + oa do Bangladesh + oa standard do Bangladesh + oa de stæ do Bangladesh + + + + + oa do Bhutan + + + + + oa da Bolivia + + + + + oa de Brasilia + oa standard de Brasilia + oa de stæ de Brasilia + + + + + oa do Brunei Darussalam + + + + + oa de Cappo Verde + oa standard de Cappo Verde + oa de stæ de Cappo Verde + + + + + oa de Chamorro + + + + + oa de Chatham + oa standard de Chatham + oa de stæ de Chatham + + + + + oa do Cile + oa standard do Cile + oa de stæ do Cile + + + + + oa da Ciña + oa standard da Ciña + oa de stæ da Ciña + + + + + oa de Choibalsan + oa standard de Choibalsan + oa de stæ de Choibalsan + + + + + oa de l’isoa Christmas + + + + + oa de isoe Cocos + + + + + oa da Colombia + oa standard da Colombia + oa de stæ da Colombia + + + + + oa de isoe Cook + oa standard de isoe Cook + oa de stæ de isoe Cook + + + + + oa de Cubba + oa standard de Cubba + oa de stæ de Cubba + + + + + oa de Davis + + + + + oa de Dumont-d’Urville + + + + + oa de Timor Est + + + + + oa de l’isoa de Pasqua + oa standard de l’isoa de Pasqua + oa de stæ de l’isoa de Pasqua + + + + + oa de l’Ecuador + + + + + oa de l’Euröpa do mezo + oa standard de l’Euröpa do mezo + oa de stæ de l’Euröpa do mezo + + + + + oa de l’Euröpa de levante + oa standard de l’Euröpa de levante + oa de stæ de l’Euröpa de levante + + + + + oa de Kaliningrad + + + + + oa de l’Euröpa de ponente + oa standard de l’Euröpa de ponente + oa de stæ de l’Euröpa de ponente + + + + + oa de isoe Malviñe + oa standard de isoe Malviñe + oa de stæ de isoe Malviñe + + + + + oa de Figi + oa standard de Figi + oa de stæ de Figi + + + + + oa da Guyana franseise + + + + + oa de Tære australe e antartiche franseixi + + + + + oa de Galapagos + + + + + oa de Gambier + + + + + oa da Geòrgia + oa standard da Geòrgia + oa de stæ da Geòrgia + + + + + oa de isoe Gilbert + + + + + oa do meridian de Greenwich + + + + + oa da Groenlandia de levante + oa standard da Groenlandia de levante + oa de stæ da Groenlandia de levante + + + + + oa da Groenlandia de ponente + oa standard da Groenlandia de ponente + oa de stæ da Groenlandia de ponente + + + + + oa standard do Gorfo + + + + + oa da Guyana + + + + + oa de Hawaii-Aleutiñe + oa standard de Hawaii-Aleutiñe + oa de stæ de Hawaii-Aleutiñe + + + + + oa de Hong Kong + oa standard de Hong Kong + oa de stæ de Hong Kong + + + + + oa de Hovd + oa standard de Hovd + oa de stæ de Hovd + + + + + oa de l’India + + + + + oa de l’Oçeano Indian + + + + + oa de l’Indociña + + + + + oa de l’Indonesia de mezo + + + + + oa de l’Indonesia de levante + + + + + oa de l’Indonesia de ponente + + + + + oa de l’Iran + oa standard de l’Iran + oa de stæ de l’Iran + + + + + oa de Irkutsk + oa standard de Irkutsk + oa de stæ de Irkutsk + + + + + oa d’Israele + oa standard d’Israele + oa de stæ d’Israele + + + + + oa do Giappon + oa standard do Giappon + oa de stæ do Giappon + + + + + oa do Kazakistan de levante + + + + + oa do Kazakistan de ponente + + + + + oa da Corea + oa standard da Corea + oa de stæ da Corea + + + + + oa do Kosrae + + + + + oa de Krasnoyarsk + oa standard de Krasnoyarsk + oa de stæ de Krasnoyarsk + + + + + oa do Kirghizistan + + + + + oa de isoe da Linia + + + + + oa de Lord Howe + oa standard de Lord Howe + oa de stæ de Lord Howe + + + + + oa de l’isoa Macquarie + + + + + oa de Magadan + oa standard de Magadan + oa de stæ de Magadan + + + + + oa da Malesia + + + + + oa de Maldive + + + + + oa de Marcheixi + + + + + oa de isoe Marshall + + + + + oa de Mauritius + oa standard de Mauritius + oa de stæ de Mauritius + + + + + oa de Mawson + + + + + oa do Mescico do nòrd-ponente + oa standard do Mescico do nòrd-ponente + oa de stæ do Mescico do nòrd-ponente + + + + + oa do Paçifico mescicaña + oa standard do Paçifico mescicaña + oa de stæ do Paçifico mescicaña + + + + + oa d’Ulan Bator + oa standard d’Ulan Bator + oa de stæ d’Ulan Bator + + + + + oa de Mosca + oa standard de Mosca + oa de stæ de Mosca + + + + + oa da Birmania + + + + + oa de Nauru + + + + + oa do Nepal + + + + + oa da Neuva Caledònia + oa standard da Neuva Caledònia + oa de stæ da Neuva Caledònia + + + + + oa da Neuva Zelanda + oa standard da Neuva Zelanda + oa de stæ da Neuva Zelanda + + + + + oa de Tæraneuva + oa standard de Tæraneuva + oa de stæ de Tæraneuva + + + + + oa de Niue + + + + + oa de l’isoa Norfolk + oa standard de l’isoa Norfolk + oa de stæ de l’isoa Norfolk + + + + + oa de Fernando de Noronha + oa standard de Fernando de Noronha + oa de stæ de Fernando de Noronha + + + + + oa de Novosibirsk + oa standard de Novosibirsk + oa de stæ de Novosibirsk + + + + + oa de Òmsk + oa standard de Òmsk + oa de stæ de Òmsk + + + + + oa do Pakistan + oa standard do Pakistan + oa de stæ do Pakistan + + + + + oa de Palau + + + + + oa da Papua Neuva Guinea + + + + + oa do Paraguay + oa standard do Paraguay + oa de stæ do Paraguay + + + + + oa do Perù + oa standard do Perù + oa de stæ do Perù + + + + + oa de Filipiñe + oa standard de Filipiñe + oa de stæ de Filipiñe + + + + + oa de isoe Phoenix + + + + + oa de San Pê e Miquelon + oa standard de San Pê e Miquelon + oa de stæ de San Pê e Miquelon + + + + + oa de Pitcairn + + + + + oa de Pohnpei + + + + + oa de Pyongyang + + + + + oa da Réunion + + + + + oa de Rothera + + + + + oa de Sakhalin + oa standard de Sakhalin + oa de stæ de Sakhalin + + + + + oa de Samoa + oa standard de Samoa + oa de stæ de Samoa + + + + + oa de Seychelles + + + + + oa de Scingapô + + + + + oa de isoe Solomon + + + + + oa da Geòrgia do sud + + + + + oa do Suriname + + + + + oa de Syowa + + + + + oa de Tahiti + + + + + oa de Taipei + oa standard de Taipei + oa de stæ de Taipei + + + + + oa do Tagikistan + + + + + oa de Tokelau + + + + + oa de Tonga + oa standard de Tonga + oa de stæ de Tonga + + + + + oa do Chuuk + + + + + oa do Turkmenistan + oa standard do Turkmenistan + oa de stæ do Turkmenistan + + + + + oa de Tuvalu + + + + + oa de l’Uruguay + oa standard de l’Uruguay + oa de stæ de l’Uruguay + + + + + oa de l’Uzbekistan + oa standard de l’Uzbekistan + oa de stæ de l’Uzbekistan + + + + + oa de Vanuatu + oa standard de Vanuatu + oa de stæ de Vanuatu + + + + + oa do Venessuela + + + + + oa de Vladivostok + oa standard de Vladivostok + oa de stæ de Vladivostok + + + + + oa de Volgograd + oa standard de Volgograd + oa de stæ de Volgograd + + + + + oa de Vostok + + + + + oa de l’isoa de Wake + + + + + oa de Wallis e Futuna + + + + + oa de Yakutsk + oa standard de Yakutsk + oa de stæ de Yakutsk + + + + + oa d’Ekaterinburg + oa standard d’Ekaterinburg + oa de stæ d’Ekaterinburg + + + + + oa do Yukon + + + + + + latn + + latn + + 1 + + , + . + % + + + - + E + × + + + NaN + : + + + + + mille + 0 mia + 00 mia + 00 mia + 000 mia + 000 mia + 0 mion + 0 mioin + 00 mioin + 00 mioin + 000 mioin + 000 mioin + 0 miliardo + 0 miliardi + 00 miliardi + 00 miliardi + 000 miliardi + 000 miliardi + mille miliardi + 0 mia miliardi + 00 mia miliardi + 00 mia miliardi + 000 mia miliardi + 000 mia miliardi + + + + + 0 k + 0 k + 00 k + 00 k + 000 k + 000 k + 0 Mio + 0 Mio + 00 Mio + 00 Mio + 000 Mio + 000 Mio + 0 Mld + 0 Mld + 00 Mld + 00 Mld + 000 Mld + 000 Mld + 0 Bio + 0 Bio + 00 Bio + 00 Bio + 000 Bio + 000 Bio + + + + + + + #,##0% + + + + + + + #,##0.00 ¤ + + + #,##0.00 ¤;(#,##0.00 ¤) + #,##0.00;(#,##0.00) + + + + + 0 k ¤ + 0 k ¤ + 00 k ¤ + 00 k ¤ + 000 k ¤ + 000 k ¤ + 0 Mio ¤ + 0 Mio ¤ + 00 Mio ¤ + 00 Mio ¤ + 000 Mio ¤ + 000 Mio ¤ + 0 Mld ¤ + 0 Mld ¤ + 00 Mld ¤ + 00 Mld ¤ + 000 Mld ¤ + 000 Mld ¤ + 0 Bio ¤ + 0 Bio ¤ + 00 Bio ¤ + 00 Bio ¤ + 000 Bio ¤ + 000 Bio ¤ + + + {0} {1} + {0} {1} + + + + dirham di Emirati Arabi Unii + dirham di EAU + dirham di EAU + + + afghani + afghani + afghani + + + lek arbaneise + lek arbaneise + lekë arbaneixi + + + dram ermeno + dram ermeno + dram ermeni + + + fiorin de Antille olandeixi + fiorin de Antille olandeixi + fiorin de Antille olandeixi + + + kwanza angolan + kwanza angolan + kwanza angolen + + + peso argentin + peso argentin + pesos argentin + + + dòllao australian + dòllao australian + dòllai australien + AUD + + + fiorin d’Aruba + fiorin d’Aruba + fiorin d’Aruba + + + manat azero + manat azero + manat azeri + + + marco convertibile da Bòsnia-Herzegòvina + marco convertibile da Bòsnia-Herzegòvina + marchi convertibili da Bòsnia-Herzegòvina + + + dòllao de Barbados + dòllao de Barbados + dòllai de Barbados + + + taka bengaleise + taka bengaleise + taka bengaleixi + + + lev burgao + lev burgao + leva burgai + + + dinar do Bahrein + dinar do Bahrein + dinar do Bahrein + + + franco do Burundi + franco do Burundi + franchi do Burundi + + + dòllao de Bermuda + dòllao de Bermuda + dòllai de Bermuda + + + dòllao do Brunei + dòllao do Brunei + dòllai do Brunei + + + bolivian + bolivian + bolivien + + + real brasilian + real brasilian + reais brasilien + BRL + + + dòllao de Bahamas + dòllao de Bahamas + dòllai de Bahamas + + + ngultrum bhutaneise + ngultrum bhutaneise + ngultrum bhutaneixi + + + pula do Botswana + pula do Botswana + pula do Botswana + + + rubo belaruscio + rubo belaruscio + rubi belarusci + + + dòllao do Belize + dòllao do Belize + dòllai do Belize + + + dòllao canadeise + dòllao canadeise + dòllai canadeixi + CAD + + + franco congoleise + franco congoleise + franchi congoleixi + + + franco svissero + franco svissero + franchi svisseri + + + peso cileno + peso cileno + pesos cileni + + + renmimbi cineise (offshore) + renmimbi cineise (offshore) + renmimbi cineixi (offshore) + + + renmimbi cineise + renmimbi cineise + renmimbi cineixi + CNY + + + peso colombian + peso colombian + pesos colombien + + + colón costarican + colón costarican + colones costarichen + + + peso cuban convertibile + peso cuban convertibile + pesos cuben convertibili + + + peso cuban + peso cuban + pesos cuben + + + escudo capoverdian + escudo capoverdian + escudos capoverdien + + + coroña ceca + coroña ceca + coroñe ceche + + + franco do Djibouti + franco do Djibouti + franchi do Djibouti + + + coroña daneise + coroña daneise + coroñe daneixi + + + peso dominican + peso dominican + pesos dominichen + + + dinar algerian + dinar algerian + dinar algerien + + + sterliña egiçiaña + sterliña egiçiaña + sterliñe egiçiañe + + + nafka eritreo + nafka eritreo + nafka eritrëi + + + birr etiope + birr etiope + birr etiopi + + + euro + euro + euro + + + dòllao de Figi + dòllao de Figi + dòllai de Figi + + + sterliña de Malviñe + sterliña de Malviñe + sterliñe de Malviñe + + + sterliña britannica + sterliña britannica + sterliñe britanniche + GBP + + + lari georgian + lari georgian + lari georgien + + + cedi ghaneise + cedi ghaneise + cedi ghaneixi + + + sterliña de Gibertâ + sterliña de Gibertâ + sterliñe de Gibertâ + + + dalasi gambian + dalasi gambian + dalasi gambien + + + franco da Guinea + franco da Guinea + franchi da Guinea + + + quetzal guatemalteco + quetzal guatemalteco + quetzal guatemaltechi + + + dòllao da Guyana + dòllao da Guyana + dòllai da Guyana + + + dòllao de Hong Kong + dòllao de Hong Kong + dòllai de Hong Kong + HKD + + + lempira honduregna + lempira honduregna + lempire honduregne + + + kuna croata + kuna croata + kune croate + + + gourde haitian + gourde haitian + gourde haitien + + + fiorin ongareise + fiorin ongareise + fiorin ongareixi + + + rupia indonesiaña + rupia indonesiaña + rupie indonesiañe + + + neuvo sciclo israelian + neuvo sciclo israelian + neuvi scicli israelian + + + rupia indiaña + rupia indiaña + rupie indiañe + INR + + + dinar irachen + dinar irachen + dinar irachen + + + rial iranian + rial iranian + rial iranien + + + coroña islandeise + coroña islandeise + coroñe islandeixi + + + dòllao giamaican + dòllao giamaican + dòllai giamaichen + + + dinar giordan + dinar giordan + dinar giorden + + + yie giapponeise + yien giapponeise + yien giapponeixi + JPY + + + scellin Kenyan + scellin Kenyan + scellin Kenyen + + + som kirghiso + som kirghiso + som kirghixi + + + riel cambogian + riel cambogian + riel cambogien + + + franco comorian + franco comorian + franchi comorien + + + won nordcorean + won nordcorean + won nordcoreen + + + won sudcorean + won sudcorean + won sudcoreen + KRW + + + dinar do Kuwait + dinar do Kuwait + dinar do Kuwait + + + dòllao de isoe Cayman + dòllao de isoe Cayman + dòllai de isoe Cayman + + + tenge kazako + tenge kazako + tenge kazaki + + + kip laotian + kip laotian + kip laotien + + + sterliña libaneise + sterliña libaneise + sterliña libaneixi + + + rupia do Sri Lanka + rupia do Sri Lanka + rupie do Sri Lanka + + + dòllao liberian + dòllao liberian + dòllai liberian + + + loti do Lesotho + loti do Lesotho + maloti do Lesotho + + + dinar libico + dinar libico + dinar libichi + + + dirham marocchin + dirham marocchin + dirham marocchin + + + leu moldavo + leu moldavo + lei moldavi + + + ariary malgascio + ariary malgascio + ariary malgasci + + + dinao maçedone + dinao maçedone + dinai maçedoni + + + kyat do Myanmar + kyat do Myanmar + kyat do Myanmar + + + tugrik mongolo + tugrik mongolo + tugrik mongoli + + + pataca de Macao + pataca de Macao + patacas de Macao + + + ouguiya da Mauritania + ouguiya da Mauritania + ouguiya da Mauritania + + + rupia mauriçiaña + rupia mauriçiaña + rupie mauriçiañe + + + rufiyaa de Maldive + rufiyaa de Maldive + rufiyaa de Maldive + + + kwacha malawian + kwacha malawian + kwacha malawien + + + peso mescican + peso mescican + pesos mescichen + MXN + + + ringgit maleise + ringgit maleise + ringgit maleixi + + + metical mozambican + metical mozambican + meticales mozambichen + + + dòllao namibian + dòllao namibian + dòllai namibien + + + naira nigeriaña + naira nigeriaña + naire nigeriañe + + + córdoba do Nicaragua + córdoba do Nicaragua + córdobas do Nicaragua + + + coroña norvegiña + coroña norvegiña + coroñe norvegiñe + + + rupia nepaleise + rupia nepaleise + rupie nepaleixi + + + dòllao neozelandeise + dòllao neozelandeise + dòllai neozelandeixi + NZD + + + rial de l’Oman + rial de l’Oman + rial de l’Oman + + + balboa de Panama + balboa de Panama + balboas de Panama + + + sol peruvian + sol peruvian + soles peruvien + + + kina papuaña + kina papuaña + kina papuañe + + + peso filippin + peso filippin + pesos filippin + PHP + + + rupia pakistaña + rupia pakistaña + rupie pakistañe + + + złoty polacco + złoty polacco + złoty polacchi + + + guaraní paraguayan + guaraní paraguayan + guaraníes paraguayen + + + rial do Qatar + rial do Qatar + rial do Qatar + + + leu romen + leu romen + lei romen + + + dinao serbo + dinao serbo + dinai serbi + + + rublo ruscio + rublo ruscio + rubli rusci + + + franco do Rwanda + franco do Rwanda + franchi do Rwanda + + + rial saudita + rial saudita + rial sauditi + + + dòllao de Isoe Salomon + dòllao de Isoe Salomon + dòllai de Isoe Salomon + + + rupia de Seychelles + rupia de Seychelles + rupie de Seychelles + + + sterliña sudaneise + sterliña sudaneise + sterliñe sudaneixi + + + coroña svedeise + coroña svedeise + coroñe svedeixi + + + dòllao de Scingapô + dòllao de Scingapô + dòllai de Scingapô + + + sterliña de Sant’Elena + sterliña de Sant’Elena + sterliñe de Sant’Elena + + + lion da Sierra Leone + lion da Sierra Leone + lion da Sierra Leone + + + scellin da Somalia + scellin da Somalia + scellin da Somalia + + + dòllao do Suriname + dòllao do Suriname + dòllai do Suriname + + + sterliña sud-sudaneise + sterliña sud-sudaneise + sterliñe sud-sudaneixi + + + dobra de Sao Tomé e Prinçipe + dobra de Sao Tomé e Prinçipe + dobras de Sao Tomé e Prinçipe + + + sterliña sciriaña + sterliña sciriaña + sterliñe sciriañe + + + lilangeni do Swaziland + lilangeni do Swaziland + emalangeni do Swaziland + + + baht tailandeise + baht tailandeise + baht tailandeixi + + + somoni tagiko + somoni tagiko + somoni tagiki + + + manat turkmeno + manat turkmeno + manat turkmeni + + + dinar tunexian + dinar tunexian + dinar tunexien + + + paʻanga tongan + paʻanga tongan + paʻanga tonghen + + + lia turca + lia turca + lie turche + + + dòllao de Trinidad e Tobago + dòllao de Trinidad e Tobago + dòllai de Trinidad e Tobago + + + neuvo dòllao taiwaneise + neuvo dòllao taiwaneise + neuvi dòllai taiwaneixi + TWD + + + scellin da Tanzania + scellin da Tanzania + scellin da Tanzania + + + grivnia ucraiña + grivnia ucraiña + grivnie ucraiñe + + + scellin de l’Uganda + scellin de l’Uganda + scellin de l’Uganda + + + dòllao di Stati Unii + dòllao di Stati Unii + dòllai di Stati Unii + USD + + + peso uruguayan + peso uruguayan + pesos uruguayen + + + som uzbeco + som uzbeco + som uzbechi + + + bolívar venessuelan + bolívar venessuelan + bolívares venessuelen + + + dong vietnamita + dong vietnamita + dong vietnamiti + VND + + + vatu de Vanuatu + vatu de Vanuatu + vatu de Vanuatu + + + tala samoan + tala samoan + tala samoen + + + franco CFA BEAC + franco CFA BEAC + franchi CFA BEAC + + + dòllao di Caraibi de levante + dòllao di Caraibi de levante + dòllai di Caraibi de levante + XCD + + + franco CFA BCEAO + franco CFA BCEAO + franchi CFA BCEAO + + + franco CFP + franco CFP + franchi CFP + + + monæa desconosciua + (monæa desconosciua) + (monæe desconosciue) + + + rial do Yemen + rial do Yemen + rial do Yemen + + + rand sudafrican + rand sudafrican + rand sudafrichen + + + kwacha zambian + kwacha zambian + kwacha zambien + + + + ~{0} + ≥{0} + ≤{0} + {0}-{1} + + + {0} giorno + {0} giorni + Piggia l’{0}ª in sciâ drita. + Piggia a {0}ª in sciâ drita. + + + + + + dexi{0} + + + çenti{0} + + + milli{0} + + + micro{0} + + + nano{0} + + + pico{0} + + + femto{0} + + + atto{0} + + + zepto{0} + + + yocto{0} + + + deca{0} + + + etto{0} + + + chillo{0} + + + mega{0} + + + giga{0} + + + tera{0} + + + peta{0} + + + exa{0} + + + zetta{0} + + + yotta{0} + + + kibi{0} + + + mebi{0} + + + gibi{0} + + + tebi{0} + + + pebi{0} + + + exbi{0} + + + zebi{0} + + + yobi{0} + + + {0} pe {1} + + + {0} quaddro + {0} quaddri + + + {0} cubbo + {0} cubbi + + + {0}-{1} + + + fòrsa g + {0} fòrsa g + {0} fòrse g + + + metri a-o segondo quaddro + {0} metro a-o segondo quaddro + {0} metri a-o segondo quaddro + + + revoluçioin + {0} revoluçion + {0} revoluçioin + + + radianti + {0} radiante + {0} radianti + + + graddi + {0} graddo + {0} graddi + + + primmi d’erco + {0} primmo d’erco + {0} primmi d’erco + + + segondi d’erco + {0} segondo d’erco + {0} segondi d’erco + + + chillòmetri quaddri + {0} chillòmetro quaddro + {0} chillòmetri quaddri + {0} pe chillòmetro quaddro + + + ettari + {0} ettaro + {0} ha + + + metri quaddri + {0} metro quaddro + {0} metri quaddri + {0} pe metro quaddro + + + çentimetri quaddri + {0} çentimetro quaddro + {0} çentimetri quaddri + {0} pe çentimetro quaddro + + + miggia quaddre + {0} miggio quaddro + {0} miggia quaddre + {0} pe miggio quaddro + + + acri + {0} acro + {0} acri + + + iarde quaddre + {0} iarda quaddra + {0} yd² + + + pê quaddri + {0} pê quaddro + {0} pê quaddri + + + pòlliçi quaddri + {0} pòlliçe quaddro + {0} pòlliçi quaddri + {0} pe pòlliçe quaddro + + + dunam + {0} dunam + {0} dunam + + + caratti + {0} caratto + {0} caratti + + + milligrammi pe deçilitro + {0} milligrammo pe deçilitro + {0} milligrammi pe deçilitro + + + millimöle pe litro + {0} millimöle pe litro + {0} millimöle pe litro + + + elemento + {0} elemento + {0} elementi + + + parte pe mion + {0} parte pe mion + {0} parte pe mion + + + pe çento + {0} pe çento + {0} pe çento + + + pe mille + {0} pe mille + {0} pe mille + + + pe dexemia + {0} pe dexemia + {0} pe dexemia + + + möle + {0} möle + {0} möle + + + litri pe chillòmetri + {0} litro pe chillòmetri + {0} litri pe chillòmetri + + + litri pe 100 chillòmetri + {0} litro pe 100 chillòmetri + {0} litri pe 100 chillòmetri + + + miggia pe gallon + {0} miggio pe gallon + {0} miggia pe gallon + + + miggia pe gallon imperiale + {0} miggio pe gallon imperiale + {0} miggia pe gallon imperiale + + + petabyte + {0} petabyte + {0} petabyte + + + terabyte + {0} terabyte + {0} terabyte + + + terabit + {0} terabit + {0} terabit + + + gigabyte + {0} gigabyte + {0} gigabyte + + + gigabit + {0} gigabit + {0} gigabit + + + megabyte + {0} megabyte + {0} megabyte + + + megabit + {0} megabit + {0} megabit + + + chillobyte + {0} chillobyte + {0} chillobyte + + + chillobit + {0} chillobit + {0} chillobit + + + byte + {0} byte + {0} byte + + + bit + {0} bit + {0} bit + + + secoli + {0} secolo + {0} secoli + + + dëxennio + {0} dëxennio + {0} dëxenni + + + anni + {0} anno + {0} anni + {0} à l’anno + + + trimestri + {0} trimestre + {0} trimestri + {0} pe trimestre + + + meixi + {0} meise + {0} meixi + {0} a-o meise + + + settemañe + {0} settemaña + {0} settemañe + {0} a-a settemaña + + + giorni + {0} giorno + {0} giorni + {0} a-o giorno + + + oe + {0} oa + {0} oe + {0} à l’oa + + + menuti + {0} menuto + {0} menuti + {0} a-o menuto + + + segondi + {0} segondo + {0} segondi + {0} a-o segondo + + + millisegondi + {0} millisegondo + {0} millisegondi + + + microsegondi + {0} microsegondo + {0} microsegondi + + + nanosegondi + {0} nanosegondo + {0} nanosegondi + + + ampère + {0} ampère + {0} ampère + + + milliampère + {0} milliampère + {0} milliampère + + + ohm + {0} ohm + {0} ohm + + + vòlt + {0} vòlt + {0} vòlt + + + chillocalorie + {0} chillocaloria + {0} chillocalorie + + + calorie + {0} caloria + {0} calorie + + + chillojoule + {0} chillojoule + {0} chillojoule + + + J + {0} joule + {0} joule + + + chillowatt-oe + {0} chillowatt-oa + {0} chillowatt-oe + + + elettronvòlt + {0} elettronvòlt + {0} elettronvòlt + + + unitæ termiche britanniche + {0} unitæ termica britannica + {0} unitæ termiche britanniche + + + therm US + {0} therm US + {0} therm US + + + lie-fòrsa + {0} lia-fòrsa + {0} lie-fòrsa + + + newton + {0} newton + {0} newton + + + chillowatt-oe pe 100 chillòmetri + {0} chillowatt-oa pe 100 chillòmetri + {0} chillowatt-oe pe 100 chillòmetri + + + gigahertz + {0} gigahertz + {0} gigahertz + + + megahertz + {0} megahertz + {0} megahertz + + + chillohertz + {0} chillohertz + {0} chillohertz + + + hertz + {0} hertz + {0} hertz + + + emme tipografica + {0} em + {0} em + + + pixel + {0} px + {0} px + + + megapixel + {0} megapixel + {0} megapixel + + + pixel per çentimetro + {0} pixel per çentimetro + {0} pixel per çentimetro + + + pixel pe pòlliçe + {0} pixel pe pòlliçe + {0} pixel pe pòlliçe + + + raggi da Tæra + {0} raggio da Tæra + {0} raggi da Tæra + + + chillòmetri + {0} chillòmetro + {0} chillòmetri + {0} pe chillòmetro + + + metri + {0} metro + {0} metri + {0} pe metro + + + deximetri + {0} deximetro + {0} deximetri + + + çentimetri + {0} çentimetro + {0} çentimetri + {0} pe çentimetro + + + millimetri + {0} millimetro + {0} millimetri + + + micrometri + {0} micrometro + {0} micrometri + + + nanometri + {0} nanometro + {0} nanometri + + + picometri + {0} picometro + {0} picometri + + + miggia + {0} miggio + {0} miggia + + + iarde + {0} iarda + {0} iarde + + + + {0} pê + {0} pê + {0} pe pê + + + pòlliçi + {0} pòlliçe + {0} pòlliçi + {0} pe pòlliçe + + + parsec + {0} parsec + {0} parsec + + + anni luxe + {0} anno luxe + {0} anni luxe + + + unitæ astronòmiche + {0} unitæ astronòmica + {0} unitæ astronòmiche + + + furlong + {0} furlong + {0} furlong + + + brasse + {0} brasso + {0} brasse + + + miggia de navegaçion + {0} miggio de navegaçion + {0} miggia de navegaçion + + + miggia scandinave + {0} miggio scandinavo + {0} miggia scandinave + + + ponti tipografichi + {0} ponto tipografico + {0} ponti tipografichi + + + raggi do Sô + {0} raggio do Sô + {0} raggi do Sô + + + lux + {0} lux + {0} lux + + + candeie + {0} candeia + {0} candeie + + + lumen + {0} lumen + {0} lumen + + + luminoxitæ do Sô + {0} luminoxitæ do Sô + {0} luminoxitæ do Sô + + + tonnëi metrichi + {0} tonneo metrico + {0} tonnëi metrichi + + + chillogrammi + {0} chillogrammo + {0} chillogrammi + {0} pe chillogrammo + + + grammi + {0} grammo + {0} grammi + {0} pe grammo + + + milligrammi + {0} milligrammo + {0} milligrammi + + + microgrammi + {0} microgrammo + {0} microgrammi + + + tonnëi curti + {0} tonneo curto + {0} tonnëi curti + + + stone + {0} stone + {0} stone + + + lie + {0} lia + {0} lie + {0} pe lia + + + onse + {0} onsa + {0} onse + {0} pe onsa + + + onse troy + {0} onsa troy + {0} onse troy + + + caratti + {0} caratto + {0} caratti + + + dalton + {0} dalton + {0} dalton + + + masse da Tæra + {0} massa da Tæra + {0} masse da Tæra + + + masse do Sô + {0} massa do Sô + {0} masse do Sô + + + grañe + {0} graña + {0} grañe + + + gigawatt + {0} gigawatt + {0} gigawatt + + + megawatt + {0} megawatt + {0} megawatt + + + chillowatt + {0} chillowatt + {0} chillowatt + + + watt + {0} watt + {0} watt + + + milliwatt + {0} milliwatt + {0} milliwatt + + + cavalli vapô + {0} cavallo vapô + {0} cavalli vapô + + + millimetri de mercuio + {0} millimetro de mercuio + {0} millimetri de mercuio + + + lie-fòrsa pe pòlliçe quaddro + {0} lia-fòrsa pe pòlliçe quaddro + {0} lie-fòrsa pe pòlliçe quaddro + + + pòlliçi de mercuio + {0} pòlliçe de mercuio + {0} pòlliçi de mercuio + + + bar + {0} bar + {0} bar + + + millibar + {0} millibar + {0} millibar + + + atmosfere + {0} atmosfera + {0} atmosfere + + + pascal + {0} pascal + {0} pascal + + + ettopascal + {0} ettopascal + {0} ettopascal + + + chillopascal + {0} chillopascal + {0} chillopascal + + + megapascal + {0} megapascal + {0} megapascal + + + chillòmetri à l’oa + {0} chillòmetro à l’oa + {0} chillòmetri à l’oa + + + metri a-o segondo + {0} metro a-o segondo + {0} metri a-o segondo + + + miggia à l’oa + {0} miggio à l’oa + {0} miggia à l’oa + + + nödi + {0} nödo + {0} nödi + + + graddi + {0} graddo + {0} graddi + + + graddi Celsius + {0} graddo Celsius + {0} graddi Celsius + + + graddi Fahrenheit + {0} graddo Fahrenheit + {0} graddi Fahrenheit + + + kelvin + {0} kelvin + {0} kelvin + + + lie-fòrsa-pê + {0} lia-fòrsa-pê + {0} lie-fòrsa-pê + + + newton-metri + {0} newton-metro + {0} newton-metri + + + chillòmetri cubbi + {0} chillòmetro cubbo + {0} chillòmetri cubbi + + + metri cubbi + {0} metro cubbo + {0} metri cubbi + {0} pe metro cubbo + + + çentimetri cubbi + {0} çentimetro cubbo + {0} çentimetri cubbi + {0} pe çentimetro cubbo + + + miggia cubbe + {0} miggio cubbo + {0} miggia cubbe + + + iarde cubbe + {0} iarda cubba + {0} iarde cubbe + + + pê cubbi + {0} pê cubbo + {0} pê cubbi + + + pòlliçi cubbi + {0} pòlliçe cubbo + {0} pòlliçi cubbi + + + megalitri + {0} megalitro + {0} megalitri + + + ettòlitri + {0} ettòlitro + {0} ettòlitri + + + litri + {0} litro + {0} litri + {0} pe litro + + + dexilitri + {0} dexilitro + {0} dexilitri + + + çentilitri + {0} çentilitro + {0} çentilitri + + + millilitri + {0} millilitro + {0} millilitri + + + pinte metriche + {0} pinta metrica + {0} pinte metriche + + + tasse metriche + {0} tassa metrica + {0} tasse metriche + + + acri-pê + {0} acro-pê + {0} acri-pê + + + stæ + {0} stâ + {0} stæ + + + galloin + {0} gallon + {0} galloin + {0} pe gallon + + + galloin imperiali + {0} gallon imperiale + {0} galloin imperiali + {0} pe gallon imperiale + + + quarti + {0} quarto + {0} quarti + + + pinte + {0} pinta + {0} pinte + + + tassa + {0} tassa + {0} tasse + + + onse liquide + {0} onsa liquida + {0} onse liquide + + + onse liquide imperiale + {0} onsa liquida imperiale + {0} onse liquide imperiale + + + cuggiæ + {0} cuggiâ + {0} cuggiæ + + + cuggiæn + {0} cuggiæn + {0} cuggiæn + + + barî + {0} barî + {0} barî + + + cuggiæn da cafè + {0} cuggiæn da cafè + {0} cuggiæn da cafè + + + cuggiæn da cafè imperiali + {0} cuggiæn da cafè imperiale + {0} cuggiæn da cafè imperiali + + + stisse + {0} stissa + {0} stisse + + + dramme liquide + {0} dramma liquida + {0} dramme liquide + + + jigger + {0} jigger + {0} jigger + + + spellinsegæ + {0} spellinsegâ + {0} spellinsegæ + + + quarto imperiale + {0} quarto imperiale + {0} quarti imperiali + + + ponto cardinâ + {0} est + {0} nòrd + {0} sud + {0} òvest + + + + + {0}/{1} + + + {0}² + {0}² + + + {0}³ + {0}³ + + + {0}⋅{1} + + + fòrsa g + {0} G + {0} G + + + {0} m/s² + {0} m/s² + + + {0} rev + {0} rev + + + {0} rad + {0} rad + + + ° + {0}° + {0}° + + + + {0}′ + {0}′ + + + + {0}″ + {0}″ + + + {0} km² + {0} km² + {0}/km² + + + ha + {0} ha + {0} ha + + + {0} m² + {0} m² + + + {0} cm² + {0} cm² + + + {0} mi² + {0} mi² + + + ac + {0} ac + {0} ac + + + {0} yd² + {0} yd² + + + {0} ft² + {0} ft² + + + {0} in² + {0} in² + + + {0} dunam + {0} dunam + + + {0} kt + {0} kt + + + mg/dl + {0} mg/dl + {0} mg/dl + + + mmol/l + {0} mmol/l + {0} mmol/l + + + elem. + {0} elem. + {0} elem. + + + {0} ppm + {0} ppm + + + {0}% + {0}% + + + {0}‰ + {0}‰ + + + {0}‱ + {0}‱ + + + {0} mol + {0} mol + + + l/km + {0} l/km + {0} l/km + + + l/100km + {0} l/100km + {0} l/100km + + + mpg + {0} mpg + {0} mpg + + + mpg imp. + {0} mpg imp. + {0} mpg imp. + + + {0} PB + {0} PB + + + {0} TB + {0} TB + + + {0} Tb + {0} Tb + + + {0} GB + {0} GB + + + {0} Gb + {0} Gb + + + {0} MB + {0} MB + + + {0} Mb + {0} Mb + + + {0} kB + {0} kB + + + {0} kb + {0} kb + + + B + {0} B + {0} B + + + {0} bit + {0} bit + + + sec. + {0} sec. + {0} sec. + + + dëx. + {0} dëx. + {0} dëx. + + + anni + {0} anno + {0} anni + {0}/anno + + + trim. + {0} trim. + {0} trim. + {0}/trim. + + + meixi + {0} meise + {0} meixi + {0}/meise + + + sett. + {0} sett. + {0} sett. + {0}/sett. + + + g + {0} g + {0} g + {0}/g + + + oe + {0} oa + {0} oe + {0}/h + + + men + {0} men. + {0} men. + {0}/men + + + s + {0} s + {0} s + {0}/s + + + ms + {0} ms + {0} ms + + + μs + {0} μs + {0} μs + + + ns + {0} ns + {0} ns + + + A + {0} A + {0} A + + + {0} mA + {0} mA + + + Ω + {0} Ω + {0} Ω + + + V + {0} V + {0} V + + + {0} kcal + {0} kcal + + + {0} cal + {0} cal + + + {0} kJ + {0} kJ + + + J + {0} J + {0} J + + + {0} kWh + {0} kWh + + + {0} eV + {0} eV + + + BTU + {0} BTU + {0} BTU + + + thm US + {0} thm US + {0} thm US + + + {0} lbf + {0} lbf + + + {0} N + {0} N + + + {0} kWh/100km + {0} kWh/100km + + + {0} GHz + {0} GHz + + + {0} MHz + {0} MHz + + + {0} kHz + {0} kHz + + + {0} Hz + {0} Hz + + + {0} em + {0} em + + + pixel + {0} px + {0} px + + + megapixel + {0} Mpx + {0} Mpx + + + px/cm + {0} px/cm + {0} px/cm + + + px/in + {0} px/in + {0} px/in + + + {0} R⊕ + {0} R⊕ + + + {0} km + {0} km + + + m + {0} m + {0} m + + + {0} dm + {0} dm + + + {0} cm + {0} cm + + + {0} mm + {0} mm + + + {0} μm + {0} μm + + + {0} nm + {0} nm + + + {0} pm + {0} pm + + + {0} mi + {0} mi + + + {0} yd + {0} yd + + + {0} ft + {0} ft + + + {0} in + {0} in + + + {0} pc + {0} pc + + + {0} ly + {0} ly + + + {0} au + {0} au + + + {0} fur + {0} fur + + + {0} fth + {0} fth + + + {0} nmi + {0} nmi + + + {0} smi + {0} smi + + + {0} pt + {0} pt + + + {0} R☉ + {0} R☉ + + + {0} lx + {0} lx + + + {0} cd + {0} cd + + + {0} lm + {0} lm + + + {0} L☉ + {0} L☉ + + + {0} t + {0} t + + + {0} kg + {0} kg + + + g + {0} g + {0} g + + + {0} mg + {0} mg + + + {0} μg + {0} μg + + + {0} tn + {0} tn + + + {0} st + {0} st + + + {0} lb + {0} lb + + + {0} oz + {0} oz + + + {0} oz t + {0} oz t + + + ct + {0} ct + {0} ct + + + {0} Da + {0} Da + + + {0} M⊕ + {0} M⊕ + + + {0} M☉ + {0} M☉ + + + grañe + {0} graña + {0} grañe + + + {0} GW + {0} GW + + + {0} MW + {0} MW + + + {0} kW + {0} kW + + + W + {0} W + {0} W + + + {0} mW + {0} mW + + + {0} hp + {0} hp + + + mmHg + {0} mmHg + {0} mmHg + + + {0} psi + {0} psi + + + {0} inHg + {0} inHg + + + {0} bar + {0} bar + + + {0} mbar + {0} mbar + + + {0} atm + {0} atm + + + {0} Pa + {0} Pa + + + {0} hPa + {0} hPa + + + {0} kPa + {0} kPa + + + {0} MPa + {0} MPa + + + {0} km/h + {0} km/h + + + {0} m/s + {0} m/s + + + {0} mi/h + {0} mi/h + + + {0} kn + {0} kn + + + {0}° + {0}° + + + {0}°C + {0}°C + + + {0}°F + {0}°F + + + {0} K + {0} K + + + {0} lbf⋅ft + {0} lbf⋅ft + + + {0} N⋅m + {0} N⋅m + + + {0} km³ + {0} km³ + + + {0} m³ + {0} m³ + + + {0} cm³ + {0} cm³ + + + {0} mi³ + {0} mi³ + + + {0} yd³ + {0} yd³ + + + {0} ft³ + {0} ft³ + + + {0} in³ + {0} in³ + + + Ml + {0} Ml + {0} Ml + + + hl + {0} hL + {0} hL + + + l + {0} l + {0} l + {0}/l + + + dl + {0} dl + {0} dl + + + cl + {0} cl + {0} cl + + + ml + {0} ml + {0} ml + + + {0} mpt + {0} mpt + + + mc + {0} mc + {0} mc + + + {0} ac ft + {0} ac ft + + + {0} bu + {0} bu + + + gal + {0} gal + {0} gal + {0}/gal + + + gal imp. + {0} gal imp. + {0} gal imp. + {0}/gal imp. + + + qt + {0} qt + {0} qt + + + pt + {0} pt + {0} pt + + + c + {0} c + {0} c + + + fl oz + {0} fl oz + {0} fl oz + + + fl oz imp. + {0} fl oz imp. + {0} fl oz imp. + + + {0} tbsp + {0} tbsp + + + {0} tsp + {0} tsp + + + {0} bbl + {0} bbl + + + {0} dstspn + {0} dstspn + + + dstspn imp. + {0} dstspn imp. + {0} dstspn imp. + + + stisse + {0} stissa + {0} stisse + + + dramme liq. + {0} dramma liq. + {0} dramme liq. + + + {0} jigger + {0} jigger + + + spellinsegæ + {0} spellinsegâ + {0} spellinsegæ + + + qt imp. + {0} qt imp. + {0} qt imp. + + + ponto + {0} E + {0} N + {0} S + {0} Ò + + + + + d{0} + + + c{0} + + + m{0} + + + μ{0} + + + n{0} + + + p{0} + + + f{0} + + + a{0} + + + z{0} + + + y{0} + + + da{0} + + + h{0} + + + k{0} + + + M{0} + + + G{0} + + + T{0} + + + P{0} + + + E{0} + + + Z{0} + + + Y{0} + + + Ki{0} + + + Mi{0} + + + Gi{0} + + + Ti{0} + + + Pi{0} + + + Ei{0} + + + Zi{0} + + + Yi{0} + + + {0}/{1} + + + {0}² + {0}² + + + {0}³ + {0}³ + + + {0}⋅{1} + + + fòrsa g + {0} G + {0}G + + + m/s² + {0}m/s² + {0}m/s² + + + rev + {0}rev + {0}rev + + + rad + {0}rad + {0}rad + + + ° + {0}° + {0}° + + + + {0}′ + {0}′ + + + + {0}″ + {0}″ + + + km² + {0}km² + {0}km² + {0}/km² + + + ha + {0}ha + {0}ha + + + + {0}m² + {0}m² + {0}/m² + + + cm² + {0}cm² + {0}cm² + {0}/cm² + + + mi² + {0}mi² + {0}mi² + {0}/mi² + + + ac + {0}ac + {0}ac + + + yd² + {0}yd² + {0}yd² + + + ft² + {0}ft² + {0}ft² + + + in² + {0}in² + {0}in² + {0}/in² + + + dunam + {0}dunam + {0}dunam + + + kt + {0}kt + {0}kt + + + mg/dl + {0} mg/dl + {0} mg/dl + + + mmol/l + {0} mmol/l + {0} mmol/l + + + elem + {0}elem + {0}elem + + + ppm + {0}ppm + {0}ppm + + + % + {0}% + {0}% + + + + {0}‰ + {0}‰ + + + + {0}‱ + {0}‱ + + + mol + {0}mol + {0}mol + + + l/km + {0}l/km + {0}l/km + + + l/100km + {0}l/100km + {0}l/100km + + + mpg + {0}mpg + {0}mpg + + + mpg im + {0}mpg im + {0}mpg im + + + PB + {0}PB + {0}PB + + + TB + {0}TB + {0}TB + + + Tb + {0}Tb + {0}Tb + + + GB + {0}GB + {0}GB + + + Gb + {0}Gb + {0}Gb + + + MB + {0}MB + {0}MB + + + Mb + {0}Mb + {0}Mb + + + kB + {0}kB + {0}kB + + + kb + {0}kb + {0}kb + + + B + {0}B + {0}B + + + bit + {0}bit + {0}bit + + + sec + {0}sec + {0}sec + + + dëx + {0}dëx + {0}dëx + + + a + {0}a + {0}a + {0}/a + + + tr + {0}tr + {0}tr + {0}/tr + + + meixi + {0}meise + {0}meixi + {0}/meise + + + sett + {0}sett + {0}sett + {0}/sett + + + g + {0}g + {0}g + {0}/g + + + h + {0}h + {0}h + {0}/h + + + men + {0}men + {0}men + {0}/men + + + s + {0}s + {0}s + {0}/s + + + ms + {0}ms + {0}ms + + + μs + {0}μs + {0}μs + + + ns + {0}ns + {0}ns + + + A + {0}A + {0}A + + + mA + {0}mA + {0}mA + + + Ω + {0}Ω + {0}Ω + + + V + {0}V + {0}V + + + kcal + {0}kcal + {0}kcal + + + cal + {0}cal + {0}cal + + + kJ + {0}kJ + {0}kJ + + + J + {0}J + {0}J + + + kWh + {0}kWh + {0}kWh + + + eV + {0}eV + {0}eV + + + BTU + {0}BTU + {0}BTU + + + thm US + {0}thm US + {0}thm US + + + lbf + {0}lbf + {0}lbf + + + N + {0}N + {0}N + + + kWh/100km + {0}kWh/100km + {0}kWh/100km + + + GHz + {0}GHz + {0}GHz + + + MHz + {0}MHz + {0}MHz + + + kHz + {0}kHz + {0}kHz + + + Hz + {0}Hz + {0}Hz + + + em + {0}em + {0}em + + + px + {0}px + {0}px + + + MP + {0}Mpx + {0}Mpx + + + px/cm + {0}px/cm + {0}px/cm + + + px/in + {0} px/in + {0} px/in + + + R⊕ + {0}R⊕ + {0}R⊕ + + + km + {0}km + {0}km + {0}/km + + + m + {0}m + {0}m + {0}/m + + + dm + {0}dm + {0}dm + + + cm + {0}cm + {0}cm + {0}/cm + + + mm + {0}mm + {0}mm + + + μm + {0}μm + {0}μm + + + nm + {0}nm + {0}nm + + + pm + {0}pm + {0}pm + + + mi + {0}mi + {0}mi + + + yd + {0}yd + {0}yd + + + ft + {0}ft + {0}ft + {0}/ft + + + in + {0}in + {0}in + {0}/in + + + pc + {0}pc + {0}pc + + + ly + {0}ly + {0}ly + + + au + {0}au + {0}au + + + fur + {0}fur + {0}fur + + + fm + {0}fth + {0}fth + + + nmi + {0}nmi + {0}nmi + + + smi + {0}smi + {0}smi + + + pt + {0}pt + {0}pt + + + R☉ + {0}R☉ + {0}R☉ + + + lx + {0}lx + {0}lx + + + cd + {0}cd + {0}cd + + + lm + {0}lm + {0}lm + + + L☉ + {0}L☉ + {0}L☉ + + + t + {0}t + {0}t + + + kg + {0}kg + {0}kg + {0}/kg + + + g + {0}g + {0}g + {0}/g + + + mg + {0}mg + {0}mg + + + μg + {0}μg + {0}μg + + + tn + {0}tn + {0}tn + + + st + {0}st + {0}st + + + lb + {0}lb + {0}lb + {0}/lb + + + oz + {0}oz + {0}oz + {0}/oz + + + oz t + {0}oz t + {0}oz t + + + ct + {0}ct + {0}ct + + + Da + {0}Da + {0}Da + + + M⊕ + {0}M⊕ + {0}M⊕ + + + M☉ + {0}M☉ + {0}M☉ + + + grañe + {0}graña + {0}grañe + + + GW + {0}GW + {0}GW + + + MW + {0}MW + {0}MW + + + kW + {0}kW + {0}kW + + + W + {0}W + {0}W + + + mW + {0}mW + {0}mW + + + hp + {0}hp + {0}hp + + + mmHg + {0}mmHg + {0}mmHg + + + psi + {0}psi + {0}psi + + + inHg + {0}inHg + {0}inHg + + + bar + {0}bar + {0}bar + + + mbar + {0}mbar + {0}mbar + + + atm + {0}atm + {0}atm + + + Pa + {0}Pa + {0}Pa + + + hPa + {0}hPa + {0}hPa + + + kPa + {0}kPa + {0}kPa + + + MPa + {0}MPa + {0}MPa + + + km/h + {0}km/h + {0}km/h + + + m/s + {0}m/s + {0}m/s + + + mi/h + {0}mi/h + {0}mi/h + + + kn + {0}kn + {0}kn + + + ° + {0}° + {0}° + + + °C + {0}°C + {0}°C + + + °F + {0}°F + {0}°F + + + K + {0}K + {0}K + + + lbf⋅ft + {0}lbf⋅ft + {0}lbf⋅ft + + + N⋅m + {0}N⋅m + {0}N⋅m + + + km³ + {0}km³ + {0}km³ + + + + {0}m³ + {0}m³ + {0}/m³ + + + cm³ + {0}cm³ + {0}cm³ + {0}/cm³ + + + mi³ + {0}mi³ + {0}mi³ + + + yd³ + {0}yd³ + {0}yd³ + + + ft³ + {0}ft³ + {0}ft³ + + + in³ + {0}in³ + {0}in³ + + + Ml + {0}Ml + {0}Ml + + + hl + {0}hl + {0}hl + + + l + {0}l + {0}l + {0}/l + + + dl + {0}dl + {0}dl + + + cl + {0}cl + {0}cl + + + ml + {0}ml + {0}ml + + + mpt + {0}mpt + {0}mpt + + + mc + {0}mc + {0}mc + + + acft + {0}ac ft + {0}ac ft + + + bu + {0}bu + {0}bu + + + gal + {0}gal + {0}gal + {0}/gal + + + galim + {0}galim + {0}galim + {0}/galim + + + qt + {0}qt + {0}qt + + + pt + {0}pt + {0}pt + + + c + {0}c + {0}c + + + fl oz + {0}fl oz + {0}fl oz + + + fl oz im + {0}fl oz im + {0}fl oz im + + + tbsp + {0}tbsp + {0}tbsp + + + tsp + {0}tsp + {0}tsp + + + bbl + {0}bbl + {0}bbl + + + dsp + {0}dsp + {0}dsp + + + dsp im + {0}dsp im + {0}dsp im + + + st + {0}st + {0}st + + + dr liq + {0}dr liq + {0}dr liq + + + jigger + {0}jigger + {0}jigger + + + sp + {0}sp + {0}sp + + + qt im + {0}qt im + {0}qt im + + + ponto + {0}E + {0}N + {0}S + {0}Ò + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0} e {1} + {0} e {1} + + + {0} ò {1} + {0} ò {1} + + + {0}, {1} + {0}, {1} + {0} ò {1} + {0} ò {1} + + + {0}, {1} + {0}, {1} + {0} ò {1} + {0} ò {1} + + + {0}, {1} + {0}, {1} + {0} e {1} + {0} e {1} + + + {0}, {1} + {0}, {1} + {0} e {1} + {0} e {1} + + + {0}, {1} + {0}, {1} + {0} e {1} + {0} e {1} + + + {0} {1} + {0} {1} + {0} {1} + {0} {1} + + + {0}, {1} + {0}, {1} + {0} e {1} + {0} e {1} + + + + {0} — tutto + {0} — compatibilitæ + {0} — çerciou + {0} — esteiso + {0} — stòrico + {0} — vario + {0} — atro + scistemi de scrittua — {0} + {0} træto + {0} træti + {0} a-o pê + {0} in testa + attivitæ + scrittue africañe + scrittue americañe + bestie + bestie e natua + frecce + còrpo + caratteri riga + scrittua Braille + casamenti + ballin e stelle + jamo consonantichi + scimboli de monæa + trætin ò connettoî + giffre + pittogrammi + scimboli de divinaçion + frecce in zu + frecce in sciù e in zu + scrittue de l’Asia de levante + emoji + scrittue europee + femenin + bandea + bandee + mangiâ e beive + formato + formato e spaçiatua + variante à larghessa piña + forme geometriche + variante à meza larghessa + caratteri han + radicali han + hanja + caratteri cineixi semplificæ + caratteri cineixi tradiçionali + cheu + scrittue stòriche + caratteri ideografichi de descriçion + kana giapponeixi + kanbun + kanji + tasto + frecce a-a manciña + frecce a-a manciña e a-a drita + scimboli alfabetichi + feua de deuvia + mascolin + scimboli matematichi + scrittue do Levante + varri + scrittue moderne + modificatoî + scimboli muxicali + nauta + sensa spaçiatua + numeri + oggetti + atro + in cobbia + persoñe + alfabeto fonetico + pittogrammi + pòsti + ciante + pontezzatua + frecce a-a drita + segni e scimboli + variante picciñe + morin + morin e persoñe + scrittue de l’Asia do meridion + scrittue de l’Asia do sud-levante + con spaçio + spòrt + scimboli + scimboli tecnichi + açenti tonali + viægi + viægi e pòsti + frecce in sciù + variante + jamo vocalichi + tempo + scrittue de l’Asia de ponente + spaçiatua + + + corscivo + dimenscion òttica + inclinaçion + larghessa + peiso + corscivo + didascalia + testo + titolo + intestaçion + manifesto + corscivo inversou + drito + cegou + extracegou + ultrastreito + ultrastreito + ultrastreito + extrastreito + extrastreito + extrastreito + streito + streito + streito + semistreito + semistreito + semistreito + normale + semilargo + semilargo + semilargo + largo + largo + largo + extralargo + extralargo + extralargo + ultralargo + ultralargo + ultralargo + ultrafin + extrafin + extrafin + fin + semifin + libbro + regolâ + medio + semidruo + semidruo + druo + extradruo + scuo + scuo + extrascuo + extrascuo + extrascuo + fraçioin verticale + spaçiatua de lettie gròsse + ligatue facoltative + fraçioin diagonale + giffre alliniæ + giffre vegio stilo + ordinale + giffre à spaçiatua proporçionale + lettie gròsse picciñe + giffre à spaçiatua regolâ + zero barrou + + + und lij + + {title} {given} {given2} {surname} + + + {given-informal} {surname} + + + {title} {surname} + + + {given-informal} + + + {given-monogram-allCaps}{given2-monogram-allCaps}{surname-monogram-allCaps} + + + {given-informal-monogram-allCaps}{surname-monogram-allCaps} + + + {given} {given2-initial} {surname} + + + {given-informal} {surname} + + + {title} {surname} + + + {given-informal} + + + {given-monogram-allCaps}{given2-monogram-allCaps}{surname-monogram-allCaps} + + + {given-informal-monogram-allCaps}{surname-monogram-allCaps} + + + {given-initial} {given2-initial} {surname} + + + {given-informal} {surname-initial} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname} {given} {given2} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps}{given-monogram-allCaps}{given2-monogram-allCaps} + + + {surname-monogram-allCaps}{given-informal-monogram-allCaps} + + + {surname} {given} {given2-initial} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps}{given-monogram-allCaps} + + + {surname-monogram-allCaps}{given-informal-monogram-allCaps} + + + {surname} {given-initial} {given2-initial} + + + {surname} {given-informal-initial} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname-core}, {title} {given} {given2} {surname-prefix} + + + {surname-core}, {given-informal} {surname-prefix} + + + {surname-core}, {given} {given2-initial} {surname-prefix} + + + {surname-core}, {given-informal} {surname-prefix} + + + {surname-core}, {given-initial} {given2-initial} {surname-prefix} + + + {surname-core}, {given-informal-initial} {surname-prefix} + + + Zane + + + Luçia + Cangiaxo + + + Françesco + Maria + Parödi + + + Dott.a Prof.a + Maria Giöxeppiña + Maiòllo + Reusa Texa + De + Franchi + Carcagno Baçigalô + OMRI + + + diff --git a/make/data/cldr/common/main/lij_IT.xml b/make/data/cldr/common/main/lij_IT.xml new file mode 100644 index 00000000000..0c7b1575aa9 --- /dev/null +++ b/make/data/cldr/common/main/lij_IT.xml @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/lkt.xml b/make/data/cldr/common/main/lkt.xml index 860cd504f1c..1faeb9e2729 100644 --- a/make/data/cldr/common/main/lkt.xml +++ b/make/data/cldr/common/main/lkt.xml @@ -1,6 +1,6 @@ - + + + + + + + + ingles + Lombard + + + + + + Italia + + + metregh + + + + [a b c d e f g h i j k l m n o p q r s t u v w x y z] + [á à ă â å ä ã ā æ ç é è ĕ ê ë ē í ì ĭ î ï ī ñ ó ò ŏ ô ö ø ō œ ú ù ŭ û ü ū ÿ] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‑ — , ; \: ! ? . … ' ’ " “ ” « » ( ) \[ \] \{ \} @ /] + + + + + + + + sginer + fevrer + marz + avril + masg + sgiugn + luj + avost + setember + otover + november + dicember + + + + + + + domenega + lundì + mardì + mercoldì + sgiovedì + venerdì + sabet + + + + + + + del matin + de sira + + + + + + d MMM y + + + + + + + + Temp Medi de Greenwich + + + + + + + , + + + + + + Elisa + + + Pinina + + + Matilda Bossa + + + March Brambilla + + + Peder + + + Caterina + + + Luisa + + + Luisa Verda + + + diff --git a/make/data/cldr/common/main/lmo_IT.xml b/make/data/cldr/common/main/lmo_IT.xml new file mode 100644 index 00000000000..ecc417479a4 --- /dev/null +++ b/make/data/cldr/common/main/lmo_IT.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ln.xml b/make/data/cldr/common/main/ln.xml index 44a306fd68b..e648d6cbb3c 100644 --- a/make/data/cldr/common/main/ln.xml +++ b/make/data/cldr/common/main/ln.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + + + + + + + + ᠪᠷᠠᠽᠢᠯ + ᠬᠢᠳᠠᠳ + ᠭᠧᠷᠮᠠᠨ + ᠫᠷᠠᠨ᠋᠋ᠼᠠ + ᠶᠡᠺᠡ ᠪᠷᠢᠲ᠋ᠠᠨᠢ + ᠡᠨᠡᠳᠬᠡᠭ᠌ + ᠢᠲ᠋ᠠᠯᠢ + ᠶᠠᠫᠣᠨ + ᠮᠣᠩᠭᠣᠯ + ᠣᠷᠣᠰ + ᠠᠮᠸᠷᠢᠻᠠ ᠎ᠢᠢᠨ ᠨᠢᠭᠡᠳᠥᠭᠰᠡᠠ ᠡᠣᠯᠣᠰ + ᠳᠣᠳᠣᠷᠬᠠᠢ ᠥᠭᠡᠢ ᠪᠥᠰᠠ + + + ᠭᠸᠷᠸᠭᠣᠷᠢ ᠢᠨ ᠬᠣᠸᠠᠩᠯᠢ + ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠡᠷᠡᠮᠪᠡᠯᠡᠬᠥ ᠳᠠᠷᠠᠭᠠᠯᠠᠯ + ᠠᠷᠠᠪ ᠲᠣᠭ᠎ᠠ + ᠮᠣᠩᠭᠣᠯ ᠲᠣᠭ᠎ᠠ + + + ᠮᠧᠲ᠋ᠷ ᠦᠨ + ᠢ᠂ ᠪ + ᠠ᠂ ᠨ᠂ ᠣ + + + ᠺᠡᠯᠠ᠄ {0} + ᠪᠢᠴᠢᠭ᠌: {0} + ᠮᠣᠵᠢ᠄ {0} + + + + + + + + + y ᠤᠨ ᠣ MM ᠰᠠᠷ ᠠ ᠢᠢᠨ dd + yMMdd + + + + + y ᠣᠨ ᠎ᠤ MM ᠰᠠᠷ᠎ᠠ ᠎ᠢᠢᠨ dd + yMMdd + + + + + y MM d + yMMd + + + + + y-MM-dd + yMMdd + + + + + + {0} - {1} + + + + + + + + 1 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 2 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 3᠊ᠷ ᠰᠠᠷ᠎ᠠ + 4 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 5 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 6 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 7 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 8᠊ᠷ ᠰᠠᠷ᠎ᠠ + 9 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 10 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 11 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 12 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + + + I + II + III + IV + V + VI + VII + VIII + IX + X + XI + XII + + + ᠨᠢᠭᠡᠳᠥᠭᠡᠷ ᠰᠠᠷ᠎ᠠ + ᠬᠣᠶᠠᠳᠣᠭᠠᠷ ᠰᠠᠷ ᠠ + ᠭᠣᠷᠪᠡᠳᠣᠭᠠᠷ ᠰᠠᠷ ᠠ + ᠳᠥᠷᠪᠡᠳᠥᠭᠡᠷ ᠰᠠᠷ᠎ᠠ + ᠲᠠᠪᠣᠳᠣᠭᠠᠷ ᠰᠠᠷ ᠠ + ᠵᠢᠷᠭᠣᠭᠠᠳᠣᠭᠠᠷ ᠰᠠᠷ᠎ᠠ + ᠲᠣᠯᠣᠭᠠᠳᠣᠭᠠᠷ ᠰᠠᠷ᠎ᠠ + ᠨᠠᠢᠮᠠᠳᠥᠭᠠᠷ ᠰᠠᠷ᠎ᠠ + ᠶᠢᠰᠥᠳᠥᠭᠡᠷ ᠰᠠᠷ᠎ᠠ + ᠠᠷᠪᠠᠳᠣᠭᠠᠷ ᠰᠠᠷ᠎ᠠ + ᠠᠷᠪᠠᠨ ᠨᠢᠭᠡᠳᠥᠭᠡᠷ ᠰᠠᠷ᠎ᠠ + ᠠᠷᠪᠠᠨ ᠬᠣᠶᠠᠳᠣᠭᠠᠷ ᠰᠠᠷ᠎ᠠ + + + + + 1 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 2 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 3᠊ᠷ ᠰᠠᠷ᠎ᠠ + 4 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 5 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 6 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 7 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 8 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 9 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 10 ᠊ᠷ ᠰᠠᠷ᠎ᠠ + 11᠊ᠷ ᠰᠠᠷ᠎ᠠ + 12᠊ᠷ ᠰᠠᠷ᠎ᠠ + + + I + II + III + IV + V + VI + VII + VIII + IX + X + XI + XII + + + ᠳᠥᠷᠪᠡᠳᠥᠭᠡᠷ ᠰᠠᠷ᠎ᠠ + + + + + + + ᠨᠢ + ᠲᠠ + ᠮᠢᠭ + ᡀᠠ + ᠫᠥᠷ + ᠪᠠ + ᠪᠢᠮ + + + ᠨᠢ + ᠳᠠ + ᠮᠢᠭ + ᡀᠠ + ᠫᠥᠷ + ᠪᠠ + ᠪᠢ + + + ᠨᠢᠮ᠎ᠠ + ᠳᠠᠸᠠ + ᠮᠢᠠᠠᠮᠠᠷ + ᡀᠠᠭᠪᠠ + ᠫᠦᠷᠪᠦ + ᠪᠠᠰᠠᠩ + ᠪᠢᠮᠪᠠ + + + + + ᠨᠢ + ᠳᠠ + ᠮᠢᠭ + ᡀᠠ + ᠫᠦᠷ + ᠪᠠ + ᠪᠢᠮ + + + ᠨᠢ + ᠳᠠ + ᠮᠢᠭ + ᡀᠠ + ᠫᠥᠷ + ᠪᠠ + ᠪᠢᠮ + + + ᠨᠢᠮ᠎ᠠ + ᠳᠠᠸᠠ + ᠮᠢᠠᠠᠮᠠᠷ + ᡀᠠᠭᠪᠠ + ᠫᠦᠷᠪᠦ + ᠪᠠᠰᠠᠩ + ᠪᠢᠮᠪᠠ + + + + + + + 1 ᠣᠯᠠᠷᠢᠯ + 2 ᠣᠯᠠᠷᠢᠯ + 3 ᠣᠯᠠᠷᠢᠯ + 4 ᠣᠯᠠᠷᠢᠯ + + + I + II + III + IV + + + 1 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 2 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 3 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 4 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + + + + + I + II + III + IV + + + I + II + III + IV + + + 1 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 2 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 3 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + 4 ᠊ᠷ ᠣᠯᠠᠷᠢᠯ + + + + + + + ᠦ᠂ ᠥ + ᠦ᠂ ᠬᠣ + + + + + + ᠮ᠂ ᠡᠡ᠂ ᠦ + ᠨ᠂ ᠲ᠂ ᠥ + ᠮ᠂ ᠡ + ᠨ᠂ ᠲ + + + + + + y ᠣᠨ ᠎᠎᠎ᠤ MMMM᠎᠎ᠢᠢᠨd. EEEE ᠋ᠭᠠᠷᠠᠭ + yMMMMEEEEd + + + + + y ᠋ᠣᠨ ᠤMMMM᠎᠎ ᠤᠩ d + yMMMMd + + + + + y.MM.dd + yMMdd + + + + + y.MM.dd + yMMdd + + + + + + + HH:mm:ss (zzzz) + HHmmsszzzz + + + + + HH:mm:ss (z) + HHmmssz + + + + + + + + ᠡᠷᠢᠨ + + + ᠵᠢᠯ + + + ᠵᠢᠯ + + + ᠵᠢᠯ + + + ᠣᠯᠠᠷᠢᠯ + + + ᠣᠯᠠᠷᠢᠯ + + + ᠣᠯᠠᠷᠢᠯ + + + ᠰᠠᠷ ᠠ + + + ᠰᠠᠷ ᠠ + + + ᠰᠡᠷ ᠠ + + + ᠳᠣᠯᠣᠭ᠎ᠠ ᠬᠣᠨᠣᠭ + + + ᠳᠣᠯᠣᠭ᠎ᠠ ᠬᠣᠨᠣᠭ + + + 7 ᠬᠣᠨᠣᠭ + + + ᠡᠳᠥᠷ + ᠥᠴᠥᠬᠡᠳᠥᠷ + ᠥᠨᠥᠳᠥᠷ + ᠮᠠᠷᠭᠠᠰᠢ + + + ᠡᠳᠥᠷ + + + ᠡᠳᠥᠷ + + + ᠭᠠᠷᠠᠭ + + + ᠥᠳᠡ ᠡᠴᠠ ᠡᠮᠥᠨ᠎ᠠ / ᠥᠳᠡ ᠡᠴᠡ ᠬᠣᠢᠢᠰᠢ + + + ᠴᠠᠭ + + + + + + + + + ᠮᠢᠨᠥ᠋ᠲ᠋ᠠ + + + ᠮᠢᠨ + + + ᠮᠢᠨ + + + ᠰᠸᠻᠥ᠋ᠨ᠋ᠳᠡ + + + ᠰᠧᠻ + + + ᠰᠧᠻ + + + ᠴᠠᠭ ᠎ᠤᠨ ᠪᠥᠰᠡ + + + + GMT {0} + {0} ᠴᠠᠭ + {0} ᠵᠣᠨ ᠎᠎᠎ᠤ ᠴᠠᠭ + {0} ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + + + ᠣᠯᠠᠨ ᠣᠯᠣᠰ ᠤᠨ ᠵᠣᠬᠢᠴᠡᠭᠣᠯᠣᠯᠳᠠᠳᠠᠢ ᠴᠠᠭ + + + + ᠥᠯᠥ ᠮᠡᠳᠡᠭᠳᠡᠬᠥ ᠬᠣᠳᠠ + + + ᠬᠣᠪᠳᠣ + + + ᠣᠯᠠᠭᠠᠨᠪᠠᠭᠠᠳᠣᠷ + + + ᠴᠥᠢᠪᠠᠯᠰᠨᠩ + + + + ᠲᠥᠪ ᠴᠠᠭ + ᠳᠥᠪ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠲᠥᠪ ᠵᠣᠨ ᠎᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠵᠡᠭᠥᠨ ᠡᠷᠭᠡ ᠎ᠢᠢᠨ ᠴᠠᠭ + ᠵᠡᠭᠥᠨ ᠡᠷᠭᠡ ᠎ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠵᠡᠭᠥᠨ ᠡᠷᠭᠡ ᠎ᠢᠢᠨ ᠵᠣᠨ ᠎᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠠᠭᠣᠯᠠ ᠎᠎᠎᠎ᠢᠢᠨ ᠴᠠᠭ + ᠠᠭᠣᠯᠠ ᠎᠎᠎᠎ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠠᠭᠣᠯᠠ ᠎ᠢᠢᠨ ᠵᠣᠨ ᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠨᠣᠮᠣᠬᠠᠨ ᠳᠠᠯᠠᠢ ᠎ᠢᠢᠨ ᠴᠠᠭ + ᠨᠣᠮᠣᠬᠠᠨ ᠳᠠᠯᠠᠢ ᠎᠎ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠨᠣᠮᠣᠬᠠᠨ ᠳᠠᠯᠠᠢ ᠎ᠢᠢᠨ ᠵᠣᠨ ᠎᠎᠎ᠪ ᠴᠠᠭ + + + + + ᠠᠲ᠋ᠯᠠᠨ᠋ᠲ᠋ ᠎ᠤᠨ ᠴᠠᠭ + ᠠᠲ᠋ᠯᠠᠨ᠋ᠲ ᠎ᠤᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠠᠲ᠋ᠯᠠᠨ᠋ᠲ ᠎ᠤᠨ ᠵᠣᠨ ᠎ᠪ ᠴᠠᠭ + + + + + ᠲᠥᠪ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠴᠠᠭ + ᠲᠥᠪ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠲᠥᠪ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠵᠣᠨ ᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠵᠡᠭᠦᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠴᠠᠭ + ᠵᠡᠭᠦᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠵᠡᠭᠦᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠵᠣᠨ ᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠪᠠᠷᠠᠭᠣᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠴᠠᠭ + ᠪᠠᠷᠠᠭᠣᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠰᠲ᠋ᠠᠨ᠋ᠳᠠᠷᠳ᠋ ᠴᠠᠭ + ᠪᠠᠷᠠᠭᠣᠨ ᠡᠸᠣᠢᠷᠤᠫᠠ ᠢᠢᠨ ᠵᠣᠨ ᠎᠎ᠤ ᠴᠠᠭ + + + + + ᠭᠷᠢᠨ᠋ᠸᠢᠴᠢ ᠢᠢᠨ ᠴᠠᠭ + + + + + + + , + + + + + ¤#,##0.00 + + + + + + ᠪᠷᠠᠽᠢᠯ ᠤᠨ ᠷᠧᠠᠯ + ᠪᠷᠠᠽᠢᠯ ᠤᠨ ᠷᠧᠠᠯ + ᠪᠷᠠᠽᠢᠯ ᠤᠨ ᠷᠧᠠᠯ + + + ᠬᠢᠲᠠᠳ ᠶᠤᠸᠠᠨ + ᠬᠢᠲᠠᠳ ᠶᠤᠸᠠᠨ + ᠬᠢᠲᠠᠳ ᠶᠤᠸᠠᠨ + + + ᠶᠧᠸᠷᠣ + ᠶᠧᠸᠷᠣ + ᠶᠧᠸᠷᠣ + + + ᠪᠷᠢᠲ᠋ᠠᠨᠢ ᠢᠢᠨ ᠫᠤᠢᠨᠳ᠋ + ᠪᠷᠢᠲ᠋ᠠᠨᠢ ᠢᠢᠨ ᠫᠤᠢᠨᠳ᠋ + ᠪᠷᠢᠲ᠋ᠠᠨᠢ ᠢᠢᠨ ᠫᠤᠢᠨᠳ᠋ + + + ᠡᠨᠡᠳᠬᠡᠭ᠌ ᠷᠦᠫᠢ + ᠡᠨᠡᠳᠬᠡᠭ᠌ ᠷᠦᠫᠢ + ᠡᠨᠡᠳᠬᠡᠭ᠌ ᠷᠦᠫᠢ + + + ᠶᠠᠫᠣᠨ ᠧᠨ + ᠶᠠᠫᠣᠨ ᠧᠨ + ᠶᠠᠫᠣᠨ ᠧᠨ + + + ᠳᠥᠬᠥᠷᠢᠭ᠌ + ᠳᠥᠬᠥᠷᠢᠭ᠌ + ᠳᠥᠬᠥᠷᠢᠭ᠌ + + + + ᠣᠷᠥᠰ ᠷᠥᠪᠯᠢ + ᠣᠷᠥᠰ ᠷᠥᠪᠯᠢ + ᠣᠷᠥᠰ ᠷᠥᠪᠯᠢ + + + ᠠᠮᠸᠷᠢᠻᠠ ᠳ᠋ᠣᠯᠯᠠᠷ + ᠠᠮᠸᠷᠢᠻᠠ ᠳ᠋ᠣᠯᠯᠠᠷ + ᠠᠮᠸᠷᠢᠻᠠ ᠳ᠋ᠣᠯᠯᠠᠷ + + + ᠲᠣᠳᠣᠷᠬᠠᠢ ᠥᠭᠡᠢ ᠮᠥᠩᠭᠥᠨ ᠲᠡᠮᠳᠡᠭᠳᠥ + ᠲᠣᠳᠣᠷᠬᠠᠢ ᠥᠭᠡᠢ ᠮᠥᠩᠭᠥᠨ ᠲᠡᠮᠳᠡᠭᠳᠥ ᠢᠢᠨ ᠨᠢᠭᠡᠴᠡ + (ᠲᠣᠳᠣᠷᠬᠠᠢ ᠥᠭᠡᠢ ᠮᠥᠩᠭᠥᠨ ᠲᠡᠮᠳᠡᠭᠳᠥ) + + + + + + hh:mm + + + hh:mm:ss + + + + + ᠲᠡᠢᠢᠮᠣ᠄ ᠲ + ᠥᠬᠡᠢ᠄ ᠥ + + + diff --git a/make/data/cldr/common/main/mni.xml b/make/data/cldr/common/main/mni.xml index 8555dae9549..548762807a4 100644 --- a/make/data/cldr/common/main/mni.xml +++ b/make/data/cldr/common/main/mni.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + [꯬ ꯀ ꯁ ꯂ ꯃ ꯄ ꯅ ꯆ ꯇ ꯈ ꯉ ꯊ ꯋ ꯌ ꯍ ꯎ ꯏ ꯐ ꯑ ꯒ ꯓ ꯔ ꯕ ꯖ ꯗ ꯘ ꯙ ꯚ ꯣ ꯤ \uABE5 ꯦ ꯧ \uABE8 ꯩ ꯪ ꯛ ꯜ ꯝ ꯞ ꯟ ꯠ ꯡ ꯢ \uABED] + [\- ‑ , . % + 0꯰ 1꯱ 2꯲ 3꯳ 4꯴ 5꯵ 6꯶ 7꯷ 8꯸ 9꯹] + [\- ‑ , ; \: ! ? . … ꯫ ' " ( ) \[ \] @ * / \& #] + + + + + + + + EEEE, d MMMM, y + yMMMMEEEEd + + + + + d MMMM, y + yMMMMd + + + + + dd-MM-y + yMMdd + + + + + d-M-y + yMd + + + + + + + h.mm.ss a zzzz + ahmmsszzzz + + + + + h.mm.ss a z + ahmmssz + + + + + h.mm.ss a + ahmmss + + + + + h.mm. a + ahmm + + + + + + + + mtei + + diff --git a/make/data/cldr/common/main/mni_Mtei_IN.xml b/make/data/cldr/common/main/mni_Mtei_IN.xml new file mode 100644 index 00000000000..40c5a7b54c6 --- /dev/null +++ b/make/data/cldr/common/main/mni_Mtei_IN.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + + + + + + + + + + + دنيا + اسيا تيمور + اسيا سلاتن + اسيا تڠݢارا + اسيا + اسيا تڠه + اسيا بارات + اميريک لاتين + بروني + البرازيل + چينا + جرمان + ڤرنچيس + إندونيسيا + اينديا + إيطاليا + جڤون + مليسيا + عرب سعودي + سيڠاڤورا + تايلان + تايوان + اميريک شريکت + ولايه تيدق دکتاهوءي + + + کومبڠ + ماتواڠ + نو + زون وقتو + + + کومبڠ بودا + کومبڠ چينا + کومبڠ کبڠساٴن اينديا + کومبڠ اسلام + کومبڠ سيۏيل اسلام + کومبڠ جڤون + کومبڠ ڤرسي + اتورن ايسيه قاموس + اتورن ايسيه بوکو تيليفون + اوروتن ايسيه فونيتيک + اتورن ايسيه ڤمبهاروان + چارين توجوان عموم + اتورن ايسيه تراديسيونل + اتورن ايسيه چوريتن راديکل + اڠک کأواڠن + اڠک ڤرڤولوهن چينا + اڠک چينا ريڠکس + اڠک کأواڠن چينا ريڠکس + اڠک چينا تراديسيونل + اڠک کأواڠن چينا تراديسيونل + اڠک جڤون + اڠک کأواڠن جڤون + ديݢيت بارات + ديݢيت مالايالم + ديݢيت اصل + اڠک تاميل + ديݢيت تاميل + اڠک تراديسيونل + + + ميتريک + + + + + right-to-left + + + + [ء آ أ ؤ إ ئ ا ب ة ت ث ج چ ح خ د ذ ر ز س ش ص ض ط ظ ع غ ڠ ف ڤ ق ك ک ݢ ل م ن ڽ ه و ۏ ى ي] + [ڬ ۑ] + {0}… + …{0} + {0}…{1} + ؟ + + + + + + + + + + + + + + EEEE، d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + dd/MM/y G + GyMMdd + + + + + d/MM/y G + GyMMd + + + + + + E, d + d/M + E، d/M + d MMM + E، d MMM + d MMMM + M/y G + E، d/M/y G + MMM y G + d MMM y G + E، d MMM y G + + + + + + + + EEEE، U MMMM dd + UMMMMEEEEdd + + + + + U MMMM d + UMMMMd + + + + + U MMM d + UMMMd + + + + + y-M-d + yMd + + + + + + + + + EEEE، d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + dd/MM/y G + GyMMdd + + + + + d/MM/yy GGGGG + GGGGGyyMMd + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + d + d E + h a + HH + h:mm a + HH:mm + H:mm + h:mm:ss a + HH:mm:ss + L + d-M + E، d-M + dd/MM + LLL + d MMM + E، d MMM + d MMMM + mm:ss + y + M-y + d/M/y + E، d/M/y + MMM y + d MMM y + E، d MMM y + QQQ y + QQQQ y + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + M–M + + + d/M – d/M + d/M – d/M + + + E، d/M – E، d/M + E، d/M – E، d/M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d MMM – E، d MMM + E، d MMM – E، d MMM + + + y–y + + + M/y – M/y + M/y – M/y + + + d/M/y – d/M/y + d/M/y – d/M/y + d/M/y – d/M/y + + + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + + + MMM–MMM y + MMM y – MMM y + + + d–d MMM y + d MMM – d MMM، y + d MMM y – d MMM y + + + E، d MMM – E، d MMM، y + E، d MMM – E، d MMM، y + E، d MMM y – E، d MMM y + + + MMMM–MMMM y + MMMM y – MMMM y + + + + + + + + + جانواري + فيبواري + مچ + اڤريل + مي + جون + جولاي + ݢوس + سيڤتيمبر + اوکتوبر + نوۏيمبر + ديسيمبر + + + + + + + احد + اثنين + ثلاث + رابو + خميس + جمعة + سبتو + + + + + + + سوکو 1 + سوکو ک-2 + سوکو ک-3 + سوکو ک-4 + + + سوکو ڤرتام + سوکو ک-2 + سوکو ک-3 + سوکو ک-4 + + + + + سوکو 1 + سوکو ک-2 + سوکو ک-3 + سوکو ک-4 + + + سوکو ڤرتام + سوکو ک-2 + سوکو ک-3 + سوکو ک-4 + + + + + + + EEEE، d MMMM y + yMMMMEEEEd + + + + + d MMMM y + yMMMMd + + + + + dd/MM/y + yMMdd + + + + + d/MM/yy + yyMMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + d + d E + h a + HH + h:mm a + HH:mm + H:mm + h:mm:ss a + HH:mm:ss + L + d-M + E، d-M + dd/MM + LLL + d MMM + E، d MMM + d MMMM + mm:ss + y + M-y + d/M/y + E، d/M/y + MMM y + d MMM y + E، d MMM y + QQQ y + QQQQ y + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + M–M + + + d/M – d/M + d/M – d/M + + + E، d/M – E، d/M + E، d/M – E، d/M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d MMM – E، d MMM + E، d MMM – E، d MMM + + + y–y + + + M/y – M/y + M/y – M/y + + + d/M/y – d/M/y + d/M/y – d/M/y + d/M/y – d/M/y + + + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + + + MMM–MMM y + MMM y – MMM y + + + d–d MMM y + d MMM – d MMM، y + d MMM y – d MMM y + + + E، d MMM – E، d MMM، y + E، d MMM – E، d MMM، y + E، d MMM y – E، d MMM y + + + MMMM–MMMM y + MMMM y – MMMM y + + + + + + + + + EEEE، d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + dd/MM/y G + GyMMdd + + + + + d/MM/y G + GyMMd + + + + + + E، d + d/M + E، d/M + d MMM + E، d MMM + d MMMM + M/y G + E، d/M/y G + MMM y G + d MMM y G + E، d MMM y G + + + + + + + + EEEE، d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + dd/MM/y G + GyMMdd + + + + + d/MM/y G + GyMMd + + + + + + E، d + d/M + E، d/M + d MMM + E، d MMM + d MMMM + M/y G + E، d/M/y G + MMM y G + d MMM y G + E، d MMM y G + + + + + + + ايرا + + + تاهون + تاهون لڤس + تاهون ني + تاهون هدڤن + + دالم {0} تاهون + + + {0} تاهون لالو + + + + بولن + بولن لالو + بولن ني + بولن ستروسڽ + + دالم {0} بولن + + + {0} بولن لالو + + + + ميڠݢو + ميڠݢو لڤس + ميڠݢو ني + ميڠݢو ستروسڽ + + دالم {0} ميڠݢو + + + {0} ميڠݢو لالو + + + + هاري + هاري سبلوم سمالم + سمالم + هاري ني + ايسوق + هاري سلڤس ايسوق + + دالم {0} هاري + + + {0} هاري لالو + + + + هاري دالم ميڠݢو + + + جم + + دالم {0} جم + + + {0} جم لالو + + + + مينيت + + دالم {0} مينيت + + + {0} مينيت لالو + + + + کدوا + + دالم {0} ساعت + + + {0} ساعت لالو + + + + زون وقتو + + + + +HH:mm;-HH:mm + وقتو {0} + {1} ({0}) + + باندر تيدق دکتاهوءي + + + سيڠاڤورا + + + + وقتو بروني دارالسلام + + + + + وقتو ڤياواي اينديا + + + + + وقتو لاٴوتن هيندي + + + + + وقتو إندونيسيا تڠه + + + + + وقتو إندونيسيا تيمور + + + + + وقتو إندونيسيا بارات + + + + + وقتو مليسيا + + + + + + + . + , + ; + % + + + - + E + + + NaN + + + + + #,##0.### + + + + + 0 ريبو + 00 ريبو + 000 ريبو + 0 جوتا + 00 جوتا + 000 جوتا + 0 بيليون + 00 بيليون + 000 بيليون + 0 تريليون + 00 تريليون + 000 تريليون + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + ¤#,##0.00;(¤#,##0.00) + + + {0} {1} + + + + دولر بروني + + + ڤاٴون ستيرليڠ بريتيش + £ + + + روڤياە إندونيسيا + + + ريڠݢيت مليسيا + RM + + + دولر سيڠاڤورا + + + مات واڠ تيدق دکتاهوءي + + + + + + + {0} تاهون + + + {0} بولن + + + {0} ميڠݢو + + + {0} هاري + + + {0} جم + + + {0} مينيت + + + {0} ساعت + + + + + {0} thn + + + {0} بولن + + + {0} ميڠݢو + + + {0} هاري + + + {0} جم + + + {0} min + + + {0} ساعت + + + + diff --git a/make/data/cldr/common/main/ms_Arab_BN.xml b/make/data/cldr/common/main/ms_Arab_BN.xml new file mode 100644 index 00000000000..cfac2af9bcd --- /dev/null +++ b/make/data/cldr/common/main/ms_Arab_BN.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + Масторланго + Африка + Африкань чивалгома ёнкс + Африкань чилисема ёнкс + Африкань пелеве ёнкс + Африкань куншка + Америкат + Азиянь чилисема ёнкс + Азиянь чинеле ёнкс + Азиянь чинеле-чилисема ёнкс + Европань чипеле ёнкс + Азия + Азиянь куншка + Азиянь чивалгома ёнкс + Европа + Европань чилисема ёнкс + Европань пелеве ёнкс + Европань чивалгома ёнкс + Андорра + Афганистан + Албания + Арменэнь мастор + Ангола + Антарктида + Аргентина + Американь Самоа + Австрия + Австралия + Аландонь усият + Барбадос + Бангладеш + Белгия + Болгария + Бурунди + Бенин + Бермуда + Боливия + Бразил + Ботсвана + Беларусия + Канада + Швейцария + Кук усият + Чили + Китай + Колумбия + Куба + Чехия + Чех Раськемастор + Германия + Дания + Алгерия + Эстэнь мастор + Эритрея + Испания + Финнэнь мастор + Фиджи + Фарерэнь усият + Франция + Габон + Гренада + Гамбия + Грекень мастор + Гватемала + Гуам + Хорватия + Гаити + Венгрия + Ирландия + Ман усия + Индия + Иран + Исландия + Италия + Япононь мастор + Лихтенштейн + Литва + Люксембург + Латвия + Монако + Молдова + Монтенегро + Мали + Монголонь мастор + Малта + Малави + Намибия + Од Каледония + Нигер + Нигерия + Нидерланд + Норвегия + Непал + Науру + Од Зеландия + Аотеароа Од Зеландия + Панама + Перу + Пакистан + Польша + Португалонь мастор + Парагвай + Румыния + Сербень мастор + Рузонь мастор + Соломон усият + Судан + Шведэнь мастор + Словения + Словакия + Сенегал + Сомалия + Чад + Того + Таймастор + Тонга + Тувалу + Тайван + Танзания + Украина + Уганда + Вейсэндязь Раськетнень Организация + Американь Вейсэндявкс Штаттнэ + АВШ + Уругвай + Ватикан ош + Вануату + Самоа + Косово + Замбия + Зимбабве + Асодавикс Ёнкс + + + {0} + {0} + {0} + + + + + left-to-right + top-to-bottom + + + + [а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я] + [ӓ ә є җ ѕ і ҥ ў ѡ џ ѣ ѳ ѵ ѷ] + [А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я] + [\- ‐ ‑ – , ; \: ! ? . … ’ ” » ( ) \[ \] § @ * / \& #] + + + + + + + + якшамков + даволков + эйзюрков + чадыков + панжиков + аштемков + медьков + умарьков + таштамков + ожоков + сундерьков + ацамков + + + + + якш + дав + эйз + чад + пан + ашт + мед + ума + таш + ожо + сун + аца + + + + + + + тар + атя + вас + кун + кал + сюк + шля + + + тар + атя + вас + кун + кал + сюк + шля + + + таргочистэ + атяньчистэ + вастаньчистэ + куншкачистэ + калоньчистэ + сюконьчистэ + шлямочистэ + + + + + тар + атя + вас + кун + кал + сюк + шля + + + тар + атя + вас + кун + кал + сюк + шля + + + таргочи + атяньчи + вастаньчи + куншкачи + калоньчи + сюконьчи + шлямочи + + + + + + + обедтэ икеле + обедтэ мейле + + + + + обедтэ икеле + обедтэ мейле + + + + + + Христосонь чачомадо икеле + Минек эрадо икеле + Христосонь чачомадо мейле + Минек эрасто + + + + + + + пинге + + + ие + мелят + тедиде + сы иестэ + + + ие + мелят + тедиде + сы иестэ + + + ие + + + нилеце пелькс + + + нилеце пелькс + + + нилеце пелькс + + + ков + ютазь ковсто + те ковсто + сы ковсто + + + ков + + + ков + + + тарго + ютазь таргосто + те таргосто + сы таргосто + {0} таргостонть + + + тарго + + + тарго + + + чи + исяк + течи + ванды + + + чи + + + чи + + + таргоютконь чи + + + час + + + минута + + + секунда + + + + + Асодавикс Ош + + + Андорра + + + Тирана + + + Вена + + + Баку + + + Сараево + + + Брюссель + + + София + + + Бермуда + + + Минской + + + Цюрих + + + Шанхай + + + Прага + + + Берлин + + + Копенгаген + + + Таллин + + + Мадрид + + + Хельсинки + + + Париж + + + Лондон + + + Гренада + + + Афины + + + Гонконг + + + Загреб + + + Будапешт + + + Дублин + + + Багдад + + + Рейкьявик + + + Рим + + + Токио + + + Сеул + + + Вадуц + + + Вильнюс + + + Люксембург + + + Рига + + + Монако + + + Подгорица + + + Скопье + + + Улан-батор + + + Мальта + + + Амстердам + + + Осло + + + Панама + + + Варшава + + + Мадейра + + + Лиссабон + + + Бухарест + + + Белград + + + Москов + + + Саратов + + + Киров + + + Самара + + + Омской + + + Томской + + + Сахалин + + + Стокгольм + + + Любляна + + + Лонгйирбюен + + + Братислава + + + Сан-Марино + + + Тайпей + + + Ужгород + + + Киев + + + Симферополь + + + Запорожье + + + Бойси + + + Денвер + + + Шикаго + + + Самарканд + + + Ташкент + + + Ватикан + + + + Афганистанонь шка + + + + + Аляскань шка + Аляскань свалонь шка + Аляскань кизэнь шка + + + + + Амазононь шка + Амазононь свалонь шка + Амазононь кизэнь шка + + + + + Бангладешень шка + Бангладешень свалонь шка + Бангладешень кизэнь шка + + + + + Базилиянь шка + Базилиянь свалонь шка + Базилиянь кизэнь шка + + + + + Чилинь шка + Чилинь свалонь шка + Чилинь кизэнь шка + + + + + Китаень шка + Китаень свалонь шка + Китаень кизэнь шка + + + + + Кубань шка + Кубань свалонь шка + Кубань кизэнь шка + + + + + Индиянь свалонь шка + + + + + Иранонь шка + Иранонь свалонь шка + Иранонь кизэнь шка + + + + + Япониянь шка + Япониянь свалонь шка + Япониянь кизэнь шка + + + + + Казахстанонь чилисемань шка + + + + + Казахстанонь чивалгомань шка + + + + + Кореань шка + Кореань свалонь шка + Кореань кизэнь шка + + + + + Московонь шка + Московонь свалонь шка + Московонь кизэнь шка + + + + + Од Зеландиянь шка + Од Зеландиянь свалонь шка + Од Зеландиянь кизэнь шка + + + + + Омскоень шка + Омскоень свалонь шка + Омскоень кизэнь шка + + + + + Парагваень шка + Парагваень свалонь шка + Парагваень кизэнь шка + + + + + Сахалинэнь шка + Сахалинэнь свалонь шка + Сахалинэнь кизэнь шка + + + + + Уругваень шка + Уругваень свалонь шка + Уругваень кизэнь шка + + + + + Узбекистанонь шка + Узбекистанонь свалонь шка + Узбекистанонь кизэнь шка + + + + + + latn + + latn + + + + + истя:и + арась:а + + + diff --git a/make/data/cldr/common/main/myv_RU.xml b/make/data/cldr/common/main/myv_RU.xml new file mode 100644 index 00000000000..da3bfc9a168 --- /dev/null +++ b/make/data/cldr/common/main/myv_RU.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/mzn.xml b/make/data/cldr/common/main/mzn.xml index 87301122ec6..bfa844bbcd0 100644 --- a/make/data/cldr/common/main/mzn.xml +++ b/make/data/cldr/common/main/mzn.xml @@ -1,6 +1,6 @@ - - {given} {given2} {surname} {suffix} + {title} {given} {given2} {surname} {generation} {credentials} {given-informal} {surname} - {prefix} {surname} + {title} {surname} {given-informal} @@ -17924,13 +19105,13 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {given-informal-monogram-allCaps}{surname-prefix-monogram}{surname-core-monogram-allCaps} - {given} {given2-initial} {surname} {suffix} + {given} {given2-initial} {surname} {generation} {credentials} {given-informal} {surname} - {prefix} {surname} + {title} {surname} {given-informal} @@ -17948,7 +19129,7 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {given-informal} {surname-initial} - {prefix} {surname} + {title} {surname} {given-informal} @@ -17960,31 +19141,31 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {given-informal-monogram-allCaps} - {surname} {given} {given2} {suffix} + {title} {surname} {given} {given2} {generation} {credentials} {surname} {given-informal} - {prefix} {surname} + {title} {surname} {given-informal} - {surname-monogram-allCaps}{given-monogram-allCaps}{given2-monogram-allCaps} + {surname-prefix-monogram}{surname-core-monogram-allCaps}{given-monogram-allCaps}{given2-monogram-allCaps} - {surname-monogram-allCaps}{given-informal-monogram-allCaps} + {surname-prefix-monogram}{surname-core-monogram-allCaps}{given-informal-monogram-allCaps} - {surname} {given} {given2-initial} {suffix} + {surname} {given} {given2-initial} {generation} {credentials} {surname} {given-informal} - {prefix} {surname} + {title} {surname} {given-informal} @@ -17996,62 +19177,86 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {given-informal-monogram-allCaps} - {surname} {given-initial} {given2-initial} + {surname} {given-initial}{given2-initial} {surname} {given-initial} - {prefix} {surname} + {title} {surname} {given-informal} - {surname-prefix-monogram}{surname-core-monogram-allCaps} + {surname-monogram-allCaps} {given-informal-monogram-allCaps} - {surname}, {given} {given2} {suffix} + {surname-core}, {given} {given2} {surname-prefix} {surname}, {given-informal} - {surname}, {given} {given2-initial} {suffix} + {surname}, {given} {given2-initial} {credentials} {surname}, {given-informal} - {surname}, {given-initial} {given2-initial} + {surname}, {given-initial}{given2-initial} {surname}, {given-informal} - - Sinbad + + Fatima - + Irene Bakker - - Peter + + Heidi Johannes Willemse - - mevrouw - Ingrid - Ingy - Francina Zoë - van den - Berg - Wolff Metternich - PhD + + dhr. + Bertus Wevers + Bert + Harry Robert + de + Jong + ∅∅∅ + jr. + mp + + + Sinbad + + + Käthe + Müller + + + Zäzilia + Hamish + Stöber + + + mevrouw + Ada Cornelia + Neele + César Martín + von + Brühl + González Domingo + jr. + PhD diff --git a/make/data/cldr/common/main/nl_AW.xml b/make/data/cldr/common/main/nl_AW.xml index b7627f6bb33..8c50225ecaf 100644 --- a/make/data/cldr/common/main/nl_AW.xml +++ b/make/data/cldr/common/main/nl_AW.xml @@ -1,6 +1,6 @@ - - {prefix} {given-initial-allCaps}{given2-initial-allCaps} {surname} + {title} {given-initial-allCaps}{given2-initial-allCaps} {surname} - {prefix} {surname-core-initialCap} + {title} {surname-core-initialCap} {given-monogram-allCaps}{given2-monogram-allCaps}{surname-monogram-allCaps} @@ -131,7 +131,7 @@ CLDR data files are interpreted according to the LDML specification (http://unic {given-informal-monogram-allCaps}{surname-monogram-allCaps} - {prefix} {surname-initialCap} + {title} {surname-initialCap} {given-monogram-allCaps}{surname-monogram-allCaps} @@ -140,34 +140,31 @@ CLDR data files are interpreted according to the LDML specification (http://unic {given-informal} - {prefix} {surname-initialCap} + {title} {surname-initialCap} {surname-monogram-allCaps} - {surname}, {prefix} {given} {given2}, {suffix} + {surname}, {title} {given} {given2}, {credentials} - - {surname}, {given-initial}{given2-initial} - - + Liam - + Liam Van den Berg - + Liam Hugo Mees Van den Berg - + Juliette Juli - Van den Berg - Van den + Van den + Berg diff --git a/make/data/cldr/common/main/nl_BQ.xml b/make/data/cldr/common/main/nl_BQ.xml index 4abd9d8f817..f6a7ff1ed45 100644 --- a/make/data/cldr/common/main/nl_BQ.xml +++ b/make/data/cldr/common/main/nl_BQ.xml @@ -1,6 +1,6 @@ - + + + + + + + + {0}، {1} + + + ߊߝߙߌߞߊ߲߯ߛߑߞߊ߲ + ߊߜ߭ߍߡߑߞߊ߲ + ߊߞߊ߲ߞߊ + ߊߡߑߤߊߙߌ + ߊߙߓߎߞߊ߲ + ߊߙߊߓߎߞߊ߲ ߘߐߞߣߍߣߍ߲ + ߊߛߊߡߍߞߊ߲ + ߊߖ߭ߎߞߊ߲ + ߊߛߑߕߎߙߌߞߊ߲ + ߊߖߍߙߑߓߊߦߌߖߊߞߊ߲ + ߊߖߋߙߌߞߊ߲ + ߓߛߊߞߊ߲ + ߓߌߟߏߙߎ߳ߛߌߞߊ߲ + ߓߋ߲ߓߊߞߊ߲ + ߓߋߣߊߞߊ߲ + ߓߌߟߑߜ߭ߊߙߌߞߊ߲ + ߒߞߏ ߡߊߟߌ + ߓߍ߲ߜ߭ߊߟߌߞߊ߲ + ߕߌߓߋߕߌߞߊ߲ + ߓߙߋߕߐ߲ߞߊ߲ + ߓߏߘߏߞߊ߲ + ߓߐߛߑߣߌߞߊ߲ + ߞߕߊߟߊ߲ߞߊ߲ + ߞߏߘߊ߫ ߗߊߜ߭ߑߡߊߞߊ߲ + ߗߋߗߋߣߌߞߊ߲ + ߛߋߓߎߥߊߞߊ߲ + ߞߌߜ߭ߊߞߊ߲ + ߗߋߙߏߞߌߞߊ߲ + ߛߏߙߊߣߌߞߊ߲ + ߛߏߙߊߣߌ߫ ߞߎߙߑߘߎߞߊ߲ + ߞߐߙߑߛߌߞߊ߲ + ߗߍߞߌߞߊ߲ + ߛߌߟߊߝ߭ߐ߲ߞߊ߲ ߓߊ߬ߕߏ߬ߓߏ߲߬ߞߊ߲ + ߜ߭ߟߏߥߊߞߊ߲ + ߘߊߣߏߥߊߞߊ߲ + ߕߊߦߌߕߊߞߊ߲ + ߊߟߑߡߊ߲ߞߊ߲ + ߏߕߑߙߌߛߌ߬ ߊߟߑߡߊߞߊ߲ + ߛߥߌߛ ߊߟߑߡߊ߲ߞߊ߲ + ߖ߭ߍߙߑߡߊߞߊ߲ + ߘߏߜ߭ߙߌߞߊ߲ + ߛߏߙߊߓ-ߓߊߛߑߞߊ߲ + ߘߎߥߟߊߞߊ߲ + ߝߐߢߌ߫ ߖߏ߬ߟߊ߬ߞߊ߲ + ߖ߭ߏ߲ߜ߭ߊߞߊ߲ + ߋ߲ߓߎߞߊ߲ + ߋߥߋߞߊ߲ + ߜ߭ߙߍ߬ߞߌ߬ߞߊ߲ + ߊ߲߬ߜߑߟߋ߬ߞߊ߲ + ߐߛߑߕߙߊߟߌ߫ ߊ߲߬ߜ߭ߑߟߋ߬ߞߊ߲ + ߞߣߊߘߊ߫ ߊ߲߬ߜ߭ߑߟߋ߬ߞߊ߲ + ߓߙߌߕߊ߲ߓߊ߫ ߊ߲߬ߜ߭ߑߟߋ߬ߞߊ߲ + ߡ.ߟ. ߊ߲߬ߜ߭ߑߟߋ߲߬ߞߊ߲ + ߊߡߋߙߌߞߌ߬ ߊ߲߬ߜ߭ߑߟߋ߬ߞߊ߲ + ߞ.ߘ. ߊ߲߬ߜ߭ߑߟߋ߬ߞߊ߲ + ߍߛߑߔߋߙߊ߲ߕߏߞߊ߲ + ߊߛߌߔߞߊ߲ + ߊߡߋߙߌߞߌ߬ ߊߛߌߔߊ߲ߞߊ߲ ߟߊ߬ߕߍ߬ߡߊ + ߊߛߌߔߊ߲߫ ߊߛߌߔߊ߲ߞߊ߲ + ߡߍߞߑߛߌߞ ߊߛߌߔߊ߲ߞߊ߲ + ߍߛߑߕߏߣߌߞߊ߲ + ߓߊߛߑߞߌߞߊ߲ + ߋߥߏ߲ߘߏߞߊ߲ + ߝߊ߯ߙߛߌߞߊ߲ + ߘߊߙߌߞߊ߲ + ߝߎߟߊߞߊ߲ + ߝߍߣߏߥߊߞߊ߲ + ߝߟߌߔߌ߲ߞߊ߲ + ߝߋߙߏߞߊ + ߝߊ߬ߙߊ߲߬ߛߌ߬ߞߊ߲ + ߞߣߊߘߊ߫ ߝߊ߬ߙߊ߲߬ߛߌ߬ߞߊ߲ + ߛߥߌߛ ߝߙߊ߬ߛߌ߬ߞߊ߲ + ߞߊߘߌ߫ ߝߊ߬ߙߊ߲߬ߛߌ߬ߞߊ߲ + ߝߙߌߥߎߟߊߞߊ߲ + ߕߟߋ߬ߓߋ ߝߙߌߛߐ߲ߞߊ߲ + ߌߙߑߟߊ߲ߘߌߞߊ߲ + ߋߞߐߛߌ߬ ߖ߭ߋߏߟߌߞߊ߲ + ߜ߭ߊߟߌߛߌߞߊ߲ + ߛߥߌߛߌ߬ ߊߟߑߡߊ߲ߞߊ߲ + ߜ߭ߎߖߙߊߞߊ߲ + ߜߎ߭ߛߌߞߊ߲ + ߡߊߣߏߥߊߞߊ߲ + ߤߊߥߎߛߊߞߊ߲ + ߤߥߊߦߌߞߊ߲ + ߋߓߙߋߞߊ߲ + ߍ߲ߘߎߞߊ߲ + ߡߐ߲ߜ߭ߑߞߊ߲ + ߞߙߏߥߊߛߌߞߊ߲ + ߛߏߙߊߓߎ߫ ߛߊ߲ߘߐ߫ ߞߊ߲ + ߤߊߦߌߕߌ߫ ߕߊ߬ߓߎ߰ߛߌ߬ߞߊ߲ + ߤߐ߲ߜ߭ߙߌߞߊ߲ + ߊߙߊߡߋߣߌߞߊ߲ + ߍ߲ߕߍߙߑߟߌ߲ߜ߭ߏߥߊߞߊ߲ + ߍ߲ߘߣߏߛߌߞߊ߲ + ߊߜߏߞߊ߲ + ߛߌߛߎߥߊ߲߫ ߦߌߞߊ߲ + ߌߛߑߟߊ߲ߘߌߞߊ߲ + ߌߕߊߟߌߞߊ߲ + ߖ߭ߊߔߐ߲ߞߊ߲ + ߒߜ߭ߏ߲ߓߊߞߊ߲ + ߡߊߗߊߡߋߞߊ߲ + ߖ߭ߝ߭ߊߣߊߞߊ߲ + ߖ߭ߋߐߙߑߖ߭ߌߞߊ߲ + ߞߊߓߟߌߞߊ߲ + ߞߊ߲ߓߊߞߊ߲ + ߡߊߞߐ߲ߘߋߞߊ߲ + ߜߙߋߞߎ߲ߝߙߌߛߌߞߊ߲ + ߞߍ߲ߜ߭ߊ߲ߞߊ߲ + ߞߏߙߌߦߊߗߣߌߞߊ߲ + ߞߌߞߌߦߎߞߊ߲ + ߞߖ߭ߊߞߌߞߊ߲ + ߞߊߞߏߞߊ߲ + ߜ߭ߙߏߟߊ߲ߘߌߞߊ߲ + ߞߊߟߊ߲ߖߌߞߊ߲ + ߞߑߡߍߙߑߞߊ߲ + ߞߊ߲ߣߊߘߊߞߊ߲ + ߞߏߙߋߞߊ߲ + ߞߐ߲ߞߊߣߌߞߊ߲ + ߞߊߛߑߡߙߌߞߊ߲ + ߛߊ߲ߓߟߊߞߊ߲ + ߓߊߝߌߞߊ߲ + ߞߐߟߑߗߌߞߊ߲ + ߞߎߙߑߘߎߞߊ߲ + ߞߐߙߑߣߌߞߌߞߊ߲ + ߞߌߙߑߞߌߖ߭ߑߞߊ߲ + ߟߊ߬ߕߍ߲߬ߞߊ߲ + ߟߊ߲ߖߌߞߊ߲ + ߟߎߞߑߛߊ߲ߓߎ߯ߙߎߞߊ߲ + ߜ߭ߊ߲ߘߊߞߊ߲ + ߟߌ߭ߎ߳ߙߌߞߊ߲ + ߟߊߞߏߕߊߞߊ߲ + ߟߌ߲ߜ߭ߟߊߞߊ߲ + ߟߊߏߞߊ߲ + ߟߌߖ߭ߌߦߊߣߌ߫ ߕߊ߬ߓߎ߰ߛߌ߬ߞߊ߲ + ߕߟߋ߬ߓߐ ߟߏߙߌߞߊ߲ + ߟߌߕߎ߳ߦߊߣߌߞߊ߲ + ߞߊߕߊ߲ߜ߭ߊ߫-ߗߌ߬ߟߎ߬ߓߊ߬ߞߊ߲ + ߟߎ߳ߏߞߊ߲ + ߟߎ߳ߦߌߞߊ߲ + ߟߋߕߐ߲ߞߊ߲ + ߡߊߗߟߌߞߊ߲ + ߡߊ߯ߛߊߞߊ߲ + ߡߋߙߎߞߊ߲ + ߡߏߙߌߛ ߕߊ߬ߓߎ߰ߛߌ߬ߞߊ߲ + ߡߊߟߑߜ߭ߊߛߌߞߊ߲ + ߡߊߞߎߞߊ߲ + ߡߋߕߊߞߊ߲ + ߡߊߏߙߌߞߊ߲ + ߡߊߛߋߘߏߣߌߞߊ߲ + ߡߟߊߦߟߊߡߑߞߊ߲ + ߡߐ߲ߜ߭ߐߟߌߞߊ߲ + ߡߊߣߌߔߎߙߌߞߊ߲ + ߡߙߊߕߌߞߊ߲ + ߡߊߟߍߞߊ߲ + ߡߊߟߑߕߍߞߊ߲ + ߡߎ߲ߘߊ߲ߞߊ߲ + ߞߊ߲ߥߙߍߞߊ߲ + ߓߙߌߡߊ߲ߞߊ߲ + ߡߊߖ߭ߊ߲ߘߋߙߊߣߞߊ߲ + ߣߡߊߞߊ߲ + ߣߐߙߑߝ߭ߍߖ߭ ߓߏߞߑߡߊߟߑߞߊ߲ + ߕߟߋ߬ߓߐ ߒߘߓߋߟߋߞߊ߲ + ߊߟߑߡߊ߲ߘߎ߯-ߓߊߛߑߞߊ߲ + ߤߏߟߊ߲ߘߌ߬ ߓߊߛߊߞߑߛߐ߲ߞߊ߲ + ߣߋߔߌߟߌߞߊ߲ + ߣߍ߯ߙߑߟߊ߲ߘߌߞߊ߲ + ߝߌߟߊߡߊ߲ߞߊ߲ + ߒߜ߭ߎ߲ߓߊߞߊ߲ + ߣߐߙߑߝ߭ߍߖ߭ ߢߙߐߛߌߞߊ߲ + ߒߖߋ߲ߓߎ߲ߞߊ߲ + ߣߐߙߑߝ߭ߍߖ߭ߌߞߊ߲ + ߒߞߏ + ߣߎߦߋߞߊ߲ + ߣߝ߭ߊߖߏߞߊ߲ + ߛߋߥߞߊ߲ + ߢߊ߲ߞߏߟߋߞߊ߲ + ߏߙߏߡߏߞߊ߲ + ߏߖߊߞߊ߲ + ߏߛߍߕߌߞߊ߲ + ߔߍ߲ߖߊߓߌߞߊ߲ + ߖߋ߬ߟߌ߬ߓߊߟߊ߫ ߔߌߘߑߜ߭ߍ߲ߞߊ߲ + ߔߟߏߣߍߞߊ߲ + ߔߎߙߛߌߞߊ߲ + ߔߊߛߑߕߏߞߊ߲ + ߔߕߏ߬ߞߌ߬ߞߊ߲ + ߓߙߋߖ߭ߌߟ ߔߕߏ߬ߞߌ߬ߞߊ߲ + ߋߙߐߔߎ߬ ߔߕߏ߬ߞߌ߬ߞߊ߲ + ߞߋߛߎߥߊߞߊ߲ + ߙߏߤߌ߲ߜ߭ߊ + ߙߏߡߊ߲ߛߌߞߊ߲ + ߙߎ߲ߘߌߞߊ߲ + ߙߏߡߍߞߊ߲ + ߡߐߟߑߘߊߝ߭ߌߞߊ߲ + ߙߏ߲ߓߏߞߊ߲ + ߌ߬ߙߛߌ߬ߞߊ߲ + ߞߌ߲ߦߊߙߎߥߊ߲ߘߊߞߊ߲ + ߙߥߊߞߊ߲ + ߛߊߛߑߞߙߌߞߊ߲ + ߌߦߊߞߎߕߌߞߊ߲ + ߛߊ߲ߓߙߎߞߊ߲ + ߛߊ߲ߕߊߟߌߞߊ߲ + ߌߛߊ߲ߜ߭ߎߞߊ߲ + ߛߌ߲ߘߌߞߊ߲ + ߛߋߡߌ߫ ߕߟߋ߬ߓߐ߬ߞߊ߲ + ߛߌߛߋߣߊߞߊ߲ + ߞߏߦߌߙߊߓߙߏ߫ ߛߋߣߌߞߊ߲ + ߛߊ߲ߜߵߏߞߊ߲ + ߗߑߟߋߥߎߞߊ߲ + ߛߌ߲ߜ߭ߟߊߞߊ߲ + ߛߑߟߏߝ߭ߊߞߌߞߊ߲ + ߛߑߟߏߝ߭ߋߣߌߞߊ߲ + ߛߊߡߏߥߊߞߊ߲ + ߌߣߊߙߌ߫ ߛߊߡߌߞߊ߲ + ߛߏߣߊߞߊ߲ + ߛߏߡߊߟߌߞߊ߲ + ߊߟߑߓߊߣߌߞߊ߲ + ߛߍߙߑߓߌߞߊ߲ + ߛߕߏ߫ ߥߙߏ߬ߘߎ߰ߞߊ߲ + ߛߎ߲ߘߣߊߞߊ߲ + ߛߎߥߍߘߌߞߊ߲ + ߛߎߥߊߤߟߌߞߊ߲ + ߕߊߡߎߟߌߞߊ߲ + ߕߋߟߎߜ߭ߎߞߊ߲ + ߕߋߛߏߞߊ߲ + ߕߊߖߞߌߞߊ߲ + ߕߊߦߌߞߊ߲ + ߕߜ߭ߌߙߌߢߊߞߊ߲ + ߕߎߙߞߌߡߍߣߌߞߊ߲ + ߕߏ߲ߖ߭ߌߞߊ߲ + ߕߙߎߞߌߞߊ߲ + ߕߊߕߊߙߌߞߊ߲ + ߕߛߊߥߊߜ߭ߌߞߊ߲ + ߊߕߌߟߊ߲ߕߊ߫ ߕߊ߲ߓߊ߲ ߊߡߊ߲ߖ߭ߌ߲ߞߊ߲ + ߥߌߜ߭ߎ߯ߙߎߞߊ߲ + ߎߞߌߙߍߣߌߞߊ߲ + ߞߊ߲߫ ߘߊ߲߬ߠߊ߬ߕߍ߰ߓߊߟߌ + ߎߙߘߎߞߊ߲ + ߎߖ߭ߑߓߋߞߌߞߊ߲ + ߒߝ߭ߊߦߌ߲ߞߊ߲ + ߝ߭ߌߦߋߕߌߣߊߡߌߞߊ߲ + ߝ߭ߏߟߊߔߎߞߊ߲ + ߝ߭ߎߖߏߞߊ߲ + ߥߊߟߑߛߍߙߌߞߊ߲ + ߥߟߐߝߐߞߊ߲ + ߛߏߖ߭ߊߞߊ߲ + ߛߏߜ߭ߊߞߊ߲ + ߦߊ߲ߜߌߞߊ߲ + ߦߘߌߛߌߞߊ߲ + ߙߦߏߓߊߞߊ߲ + ߞߊ߲ߕߏߣߊߞߊ߲ + ߞߊ߲ߕߏߣߊ ߛߣߌߥߊߞߊ߲ + ߡߊ߬ߙߐߞߎ߬ ߢߊߓߘߍߡߊ + ߛߣߌߥߊߞߊ߲ + ߛߣߌߥߊ ߡߊ߲ߘߊߙߍ߲ߞߊ߲ + ߛߣߌߥߊߞߊ߲ ߘߐߞߣߍߣߍ߲ + ߡߊ߲ߘߊߙߍ߲ ߘߐߞߣߍߣߍ߲ + ߛߣߌߥߊߞߊ߲ ߦߋ߲ߢߐ߲߯ߠߊ + ߡߊ߲ߘߊߙߍ߲ߞߊ߲ ߢߋ߲ߢߐ߲߯ߠߊ + ߖ߭ߟߎߞߊ߲ + ߞߊ߲߫ ߘߐߞߏߟߏ߲ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ߞߌߢߍ߲߫ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ + ߊߡߋߙߌߞߌ߬ ߞߐ߬ߘߎ߮ + ߊߡߋߙߌߞߌ߬ ߥߙߏ߬ߘߎ߮ + ߟߌ߲ߓߊ߲ߘߎ߯ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߟߋ߬ߓߋ + ߊߡߋߙߌߞߌ߬ ߕߊ߲ߓߊ߲ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߟߋ߬ߓߐ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߞߐ߬ߘߎ߮ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߊ߲ߓߊ߲ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߥߙߏ߬ߘߎ߮ + ߊߡߋߙߌߞߌ߬ + ߞߐ߰ߘߎ߮ ߊߡߋߙߌߞߌ߬ + ߞߙߊߦߌߓ + ߊߖ߭ߌ߫ ߕߟߋ߬ߓߐ + ߊߖ߭ߌ߫ ߥߙߏ߬ߘߎ߮ + ߊߖ߭ߌ߫ ߥߙߏ߬ߘߎ߮-ߕߟߋ߬ߓߐ + ߋߙߐߔߎ߬ ߥߙߏ߬ߘߎ߮ + ߐߛߑߕߙߊߟߊߖ߭ߌ߫ + ߡߋߟߊߣߋߖ߭ߌ߫ + ߡߌߞߙߏߣߋߖ߭ߌ߫ ߕߌ߲߬ߞߎߘߎ߲ + ߔߏߟߣߋߖ߭ߌ߫ + ߊߖ߭ߌ߫ + ߊߖ߭ߌ߫ ߕߊ߲ߓߊ߲ + ߊߖ߭ߌ߫ ߕߟߋ߬ߓߋ + ߋߙߐߔߎ߬ + ߋߙߐߔߎ߬ ߕߟߋ߬ߓߐ + ߋߙߐߔߎ߬ ߞߐ߬ߘߎ߮ + ߋߙߐߔߎ߬ ߕߟߋ߬ߓߋ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߞߌ߬ߢߍ߬ߞߏ߲ߞߏ߫ ߘߎ߰ߟߊ߬-ߖߡߊߣߊ + ߊߡߋߙߞߌ߬ ߟߊ߬ߕߍ߬ߡߊ߬ ߦߙߐ + ߊߛߊ߲ߛߌߦߐ߲߫ ߕߌ߲ + ߊ߲ߘߐߙ + ߋߡߌߙߊߕ ߊߙߊߓߎ߫ ߘߍ߬ߣߍ߲ + ߊߝߎߜ߭ߊߣߌߛߑߕߊ߲߫ + ߊ߲ߕߌߞߎߥߊ߫ ߣߌ߫ ߓߊߙߑߓߎߘߊ߫ + ߊ߲ߞߎ߳ߟߊ߫ + ߊߟߑߓߊߣߌ߫ + ߊߙߑߡߋߣߌ߫ + ߊ߲ߜߏߟߊ߫ + ߊ߲ߕߊߙߑߛߕߌߞ + ߊߙߑߖ߭ߊ߲ߕߌߣ + ߛߊߡߏߥߊ߫ ߊߡߋߙߞߌߞߊ + ߏߕߑߙߌߛ + ߐߛߑߕߙߊߟߌ߫ + ߊߙߎߓߊ߫ + ߊߟߊ߲ߘ ߕߌ߲ + ߊߖߊߙߑߓߊߦߌߖߊ߲ + ߓߐߛߑߣߌ߫-ߍߙߑߖ߭ߋߜ߭ߏߝ߭ߌߣ + ߓߊߙߑߓߊߘ + ߓߊ߲ߜ߭ߑߟߊߘߍߛ + ߓߍߟߑߖ߭ߌߞ + ߓߙߎߞߌߣߊ߫ ߝߊ߬ߛߏ߫ + ߓߌߟߑߜ߭ߊ߯ߙߌ߫ + ߓߤߊ߬ߙߊߦߌ߬ߣ + ߓߎߙߎ߲ߘߌ߫ + ߓߋߣߍ߲߫ + ߛߍ߲ߕ-ߓߌߙߑߕߟߋߡߌ߫ + ߓߍߙߑߓߎߘ + ߓߙߎߣߋ߫ + ߓߏߟߝ߭ߌ߫ + ߤߏߟߊ߲ߘ ߞߊߙߌߓߋ߫ + ߓߙߋߖ߭ߌߟ + ߓߤߊߡߊߛ + ߓߎߕߊ߲߫ + ߓߎߝ߭ߋ߫ ߕߌ߲ + ߓߐߛߎߥߣߊ߫ + ߓߌߟߏߙߌߛ + ߓߋߟߌߖ߭ + ߞߣߊߘߊ߫ + ߞߏߞߏ߫ ߕߌ߲ + ߞߏ߲߬ߜ߭ߏ߫-ߞߌ߲ߛߊߛߊ߫ + ߞߏ߲߬ߜ߭ߏ߫ ߓߍ߯ߦߊ߫ ߞߊ߲ߓߍ߲ + ߕߊ߲ߓߊ߲-ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߞߊ߲ߓߍ߲ + ߞߏ߲߬ߜ߭ߏ߫-ߓߙߊߖ߭ߊ߫ + ߞߏ߲߬ߜ߭ߏ߫ ߞߊ߲ߓߍ߫ + ߛߎߥߌߛ + ߜߋ߲-ߞߐ߰ߖߌ߬ߘߊ + ߜߋ߲-ߞߐ߰ߖߌ߬ߘߊ ߞߊ߲ߓߍ߲ + ߞߎߞ ߕߌ߲ + ߛ߭ߟߌ߫ + ߞߊߡߋߙߎ߲ + ߛߌߣ + ߞߏߟߐ߲ߓߌ߫ + ߞߟߌߔߍߙߑߕߐ߲߫ ߕߌ߲ + ߞߐߛߑߕߊ߫ ߙߌߞߊ߫ + ߞߎ߳ߓߊ߫ + ߜߙߋߞߎ߲߫-ߝߙߌߛߌ߫ + ߞߎߙߛߊߏ߫ + ߞߙߌߛߑߕߌߡߊ߫ ߕߌ߲ + ߛߌߔߑߙߎ߫ + ߗߍߞ + ߗߍߞ ߞߊ߲ߓߍ߲ + ߊߟߑߡߊ߲ߘߎ߯ + ߖߋߜ߭ߏ߫-ߜ߭ߊߙߑߛߌߦߊ߫ + ߖߌߓߎߕߌ߫ + ߘߊߣߌߡߊߙߑߞ + ߘߏߡߣߌߞ + ߘߏߡߣߌߞ ߞߊ߲ߓߍ߲ + ߊߟߑߖ߭ߋߙߌ߫ + ߛߋߎߕߊ߫ ߣߌ߫ ߡߋߟߌߣߊ߫ + ߕߍߡߊߓߊ߲߮ + ߋߛߑߕߏߣߌ߫ + ߋߖ߭ߌߔߑߕ + ߞߌ߲߬ߢߍ߬ߞߏ߲ߞߏ߫ ߕߟߋ߬ߓߋ + ߋߙߕߌߙߋ߫ + ߊߛߌߔߊ߲߫ + ߋߗߏߔߌ߫ + ߋߙߐߔߎ߬ ߘߍ߭ + ߋߙߐߔߎ߬ ߞߣߍ + ߝߍ߲ߟߊ߲ߘ + ߝߖߌ߫ + ߡߊߟߎ߲ߌ߲߫ ߕߌ߲ + ߡߊߟߎ߲ߌ߲߫ ߕߌ߲ ( ߝߊߟߑߞߑߟߊ߲ ߕߌ߲ ) + ߡߌߞߙߏߣߋߖ߭ߌ߫ + ߝߋߙߏߦߋ߫ ߕߌ߲ + ߝߊ߬ߙߊ߲߬ߛߌ߫ + ߜ߭ߊߓߐ߲߫ + ߡߊ߲߬ߛߊ߬ߟߊ߫ ߟߊߘߍ߬ߣߍ߲ + ߡ.ߟ. + ߜ߭ߙߋߣߊߘ + ߖ߭ߋߐߙߑߖ߭ߌ߫ + ߝߊ߲߬ߙߊ߲߬ߛߌ߫ ߜ߭ߎ߳ߦߊߣ + ߜ߭ߋߙߑߣߋߖ߭ߌ߫ + ߜ߭ߊ߯ߣߊ߫ + ߜ߭ߌߓߙߊߟߑߕߊߙ + ߜ߭ߎߙߎ߲ߟߊ߲ߘ + ߜ߭ߊ߲ߓߌ߫ + ߖߌ߬ߣߍ߫ + ߜ߭ߎߥߊߘߋߟߎߔ + ߕߍߡߊߓߊ߲߮-ߖߌ߬ߣߍ߫ + ߜ߭ߙߍ߬ߞߌ߬ + ߖ߭ߐߙߑߖ߭ߌ߫ ߥߙߏ߬ߘߎ߮ ߣߌ߫ ߛߊ߲ߘߎߥߌߛ ߕߌ߲ + ߜ߭ߎߥߊߕߋߡߟߊ߫ + ߜ߭ߎߥߊߡ + ߖߌ߬ߣߍ߫ ߓߌߛߊߥߏ߫ + ߜ߭ߎߦߊߣ + ߛߌߣ ߕߌ߲߬ߞߎߘߎ߲߫ ߡߊߡߙߊ߬ߣߍ߲ ߤߐ߲ߞߐ߲߫ + ߤߐ߲ߞߐ߲߫ + ߡߊߞߑߘߏߣߊߟߑߘ ߕߌ߲ + ߤߎ߲ߘߎߙߊ߫ + ߞߙߏߥߊߛߌ߫ + ߤߊߦߕߌ߫ + ߤߐ߲ߜ߭ߙߌ߫ + ߞߣߊߙߌ߫ ߕߌ߲ + ߍ߲ߘߣߏߖ߭ߌ߫ + ߌߙߑߟߊ߲ߘ + ߌߛߑߙߊߍߟ + ߡߊ߲߯ ߕߌ߲ + ߌߘߎ߬ + ߓߙߌߕߊ߲ߓߊ߫ ߟߊ߫ ߌ߲ߘߎ߫ ߟߌ߲ߓߊ߲ ߞߣߍ + ߌߙߊߞߌ߬ + ߌߙߊ߲߫ + ߌߛߑߟߊߘ + ߌߕߊߟߌ߫ + ߖߋߙߑߖ߭ߌ߫ + ߖ߭ߡߊߦߌߞ + ߖߐߙߑߘߊߣߌ߫ + ߖ߭ߊߔߐ߲߫ + ߞߋߣߌߦߊ߫ + ߞߌߙߑߜ߭ߌߛߑߕߊ߲߫ + ߞߊ߲ߓߐߘߑߖ + ߞߙߌߓߊߕߌ߫ + ߞߡߐߙ + ߛߍ߲ߕ-ߞߙߌߛߑߕߐߝ ߣߌ߫ ߢߝ߭ߋ߫ + ߞߐ߬ߘߎ߮ ߞߏ߯ߙߋ߫ + ߕߟߋ߬ߓߋ ߞߏ߯ߙߋ߫ + ߞߎ߬ߥߊ߬ߕ + ߓߊ߲߬ߓߊ߬-ߕߌ߲ + ߞߖ߭ߊߞߌߛߑߕߊ߲߫ + ߟߊߐߛ + ߟߌߓߊ߲߫ + ߛߍ߲ߕ-ߟߎ߳ߛߌ߫ + ߟߎߛߑߕߊ߲ߛߑߕߍ߲߫ + ߛߙߌߟߊ߲ߞߊ߫ + ߟߌߓߋߙߌߦߊ߫ + ߟߋߛߕߏ߫ + ߟߎߕߎ߳ߦߊߣߌ߫ + ߟߎߜ߭ߑߛߊ߲ߓߎ߯ߙ + ߟߋߕߏߣߌ߫ + ߟߓߌ߫ + ߡߊ߬ߙߐߞߎ߬ + ߡߏߣߊߞߏ߫ + ߡߐߟߑߘߊߝ߭ߌ߫ + ߡߐ߲ߕߣߋߜ߭ߙߏ߫ + ߛߍ߲ߕ-ߡߊߙߑߕߍ߲߫ + ߡߘߊߜ߭ߛߑߞߊ߯ߙ + ߡߊߙߑߛߊߟ ߕߌ߲ + ߞߐ߬ߘߎ߮ ߡߊߛߋߘߏߣߌ߫ + ߡߊ߬ߟߌ߬ + ߡߌߦߊߡߊ߯ߙ ( ߓߙߌߡߊߣߌ߫ ) + ߡߐ߲ߜ߭ߐߟߌ߫ + ߛߌߣ ߕߌ߲߬ߞߎߘߎ߲߫ ߡߊߡߙߊ߬ߣߍ߲ ߡߞߊߥߏ߫ + ߡߞߊߥߏ߫ + ߡߊߙߌߦߊߣ ߞߐ߬ߘߎ߮ ߕߌ߲ + ߡߊߙߑߕߣߌߞ + ߡߏߙߌߕߊߣߌ߫ + ߡߐ߲ߗߋߙߊ߫ + ߡߊߟߑߕ + ߡߏߙߌߛ + ߡߊߟߑߘߌߝ߭ + ߡߟߊߥߌ߫ + ߡߍߞߑߛߌߞ + ߡߊߟߍߘߎ߯ + ߡߏߖ߭ߊ߲ߓߌߞ + ߣߊߡߌ߲ߓߌ߫ + ߞߊߟߋߘߏߣߌ߫-ߞߎߘߊ߫ + ߖߋ߬ߟߌ߬ߓߊߘߎ߯ + ߣߐߙߑߝߐߟߑߞ + ߖߋ߬ߟߌ߬ߓߊ߬ߟߊ߫ + ߣߌߞߙߊߜ߭ߎߥߊ߫ + ߤߏߟߊ߲ߘ + ߣߐߙߑߝ߭ߍߖ + ߣߋߔߊߟ + ߣߏ߯ߙߎ߫ + ߣߎ߳ߋ߫ + ߖ߭ߋߟߊ߲ߘߌ߫-ߞߎߘߊ߫ + ߏߡߊ߲߫ + ߔߣߊߡߊ߫ + ߔߋߙߎ߫ + ߝߊ߬ߙߊ߲߬ߛߌ߫ ߔߏߟߌߣߋߖ߭ߌ߫ + ߡߊߡߎߥߊߖ߭ߌ߫ ߖߌ߬ߣߍ߬-ߞߎߘߊ߫ + ߝߟߌߔߌ߲ߣ + ߔߊߞߌߛߑߕߊ߲߫ + ߔߏߟߐߢ + ߛߍ߲ߕ-ߔߍ߯ߙ ߣߌ߫ ߡߌ߲ߞߋߟߐ߲߫ + ߔߌߕߑߞߍ߲ ߕߌ߲ + ߔߐߙߑߕߏ߫-ߙߌߞߏ߫ + ߔߊߟߍߛߑߕߌߣ ߞߣߍ + ߔߊߟߍߛߑߕߌߣ + ߔߐߙߑߕߎߜ߭ߊߟ + ߔߟߊߐߛ + ߔߙߊߜ߭ߏߦߋ߫ + ߞߊߕߊ߯ߙ + ߟߌ߲ߓߊ߲ߘߎ߯ ߕߌ߲߬ߞߎߘߎ߲ ߦߙߐ߫ ߡߊߕߊ߯ߣߍ߲ + ߟߊ߬ߘߍ + ߙߎߡߊߣߌ߫ + ߛߍߙߑߓߌ߫ + ߌߙߌ߬ߛߌ߫ + ߙߎߥߊ߲ߘߊ߫ + ߛߎ߰ߘߎ߬ߟߊ߫-ߡߊ߲߬ߛߊ߬ߟߊ + ߛߊߟߏߡߐ߲߫ ߕߌ߲ + ߛߋߦߌߛߍߟ + ߛߎߘߊ߲߫ + ߛߎߥߍߘ + ߛߌ߲ߜ߭ߊߔߎߙ + ߛߍ߲ߕ-ߋߟߍߣ + ߛߑߟߏߝ߭ߋߣߌ߫ + ߛߊߟߑߓߊߙ ߣߌ߫ ߖ߭ߊ߲ ߡߊߦߍ߲߫ + ߛߑߟߏߝ߭ߊߞߌ߫ + ߛߙߊ߬ߟߏ߲߫ + ߛߍߕ-ߡߊߙߍ߲߫ + ߛߣߍ߬ߜߊ߯ߟߌ߫ + ߛߏߡߊߟߌ߫ + ߛߎߙߑߣߊߡ + ߥߙߏ߬ߘߎ߮ ߛߎ߬ߘߊ߲߫ + ߛߊߥߕߏߡߋ߫ ߣߌ߫ ߔߑߙߍ߲ߛߌߔ + ߛߊߟߑߝ߭ߊߘߐߙ + ߛߍ߲ߕ-ߡߊߙߑߕߍ߲߫ ( ߤߏߟߊ߲ߘ ߝߊ߲߭ߝߍ߬ ) + ߛߙߌ߫ + ߒߛߎߥߊߕߣߌ߫ + ߛߑߥߊߖ߭ߌߟߊ߲ߘ + ߞߎ߲ߓߊ߫ ߕߑߙߌߛߑߕߊ߫ + ߕߎߙߑߞߌ߫ ߣߌ߫ ߞߊߦߌߞ + ߗߊߘ + ߝߊ߬ߙߊ߲߬ߛߌ߫ ߘߎ߰ߞߟߏ ߓߊߙߌ ߘߐ߫ + ߕߜ߭ߏ߫ + ߕߊߦߌߘߎ߯ + ߕߊߖߞߌߛߑߕߊ߲߫ + ߕߏߞߋߟߊߏ߫ + ߕߌߡߐߙ ߕߟߋ߬ߓߐ߬ߝߊ߲ + ߕߌߡߐߙ ߕߟߋ߬ߓߐ + ߕߎߙߑߞߌߡߋߣߌߛߑߕߊ߲߫ + ߕߎߣߖ߭ߌ߫ + ߕߏ߲ߜ߭ߊ߫ + ߕߎߙߑߞߌ߫ + ߕߙߌߣߌߕߋ߫ ߣߌ߫ ߕߏߓߊߜ߭ߏ߫ + ߕߎߝ߭ߊߟߎ߫ + ߕߊߦߌߥߊ߲߫ + ߕߊ߲ߖ߭ߊߣߌ߫ + ߎ߳ߞߑߙߍߣ + ߎߜ߭ߊ߲ߘߊ߫ + ߞߊ߬ߝߏ߫ ߘߍ߬ߣߍ߲ ߘߌߣߍ߲߫ ߕߌ߲߫ ߡߊߕߊ߯ߣߍ߲ + ߡߊ߲߬ߕߏ߲߫ ߠߊߘߍ߬ߣߍ߲ ߛߌ߬ߝߏ߲߬ߧߊ߬ߟߌ + ߞߊ߬ߝߏ߫ ߘߍ߬ߣߍ߲ + ߞ.ߘ. + ߎ߳ߙߑߜ߭ߋߦߌ߫ + ߎߖ߭ߑߓߋߞߌߛߑߕߊ߲߫ + ߝ߭ߊߕߌߞߊ߲߫ ߞߊ߬ߝߏ + ߛߍ߲ߕ-ߝ߭ߍߛߊ߲ ߜ߭ߙߋߣߊߘߌ߫ + ߝ߭ߣߋߖ߭ߎߦߋߟߊ߫ + ߓߙߌߕߊ߲ߓߊ߫ ߕߌ߲߫ ߞߊߓߊ߲ + ߞߊ߬ߝߏ߫ ߘߍ߬ߣߍ߲ ߕߌ߲߫ ߞߊߓߊ߲߫ + ߝ߭ߌߦߍߕߑߣߊߡ + ߝ߭ߊߣߎߦߊߕߎ߫ + ߥߊߟߌߛߌ߫ ߣߌ߫ ߝߕߎߣߊ߫ + ߛߊߡߏߥߊ߫ + ߔߛߏߘߏ߫ ߊߞߑߛߊ߲ + ߔߛߔߘߏ߫-ߓߘߌ߫ + ߞߛߏߝ߭ߏ߫ + ߦߡߊߣߌ߲߫ + ߡߊߦߐߕ + ߥߙߏ߬ߘߎ߮ ߝߘߊ߬ߝߌ߲߬ߠߊ߫ + ߖ߭ߊ߲ߓߌ߫ + ߖ߭ߌ߲ߓߊߓߏߦߋ߫ + ߕߌ߲߬ߞߎߘߎ߲߫ ߕߊ߲߬ߠߊߕߍ߰ߓߊߟߌ + + + ߜߟߊ߬ߜߟߊ߬ߡߊ + ߓߙߌߕߊ߲ߓߊ߫ ߡߊ߲߬ߛߊ߬ߟߊ (ߓ.ߡ.) + ߞߊ߬ߝߏ߫ ߘߍ߬ߣߍ߲ (ߞ.ߘ.) + + + ߞߊ߲: {0} + ߛߓߍߟߌ: {0} + ߕߌ߲߬ߞߎߘߎ߲: {0} + + + + + right-to-left + top-to-bottom + + + + [\u07EB \u07EC \u07ED \u07EE \u07EF \u07F0 \u07F1 \u07F2 \u07F3 ߊ ߋ ߌ ߍ ߎ ߏ ߐ ߑ ߒ ߓ ߔ ߕ ߖ ߗ ߘ ߙ ߚ ߛ ߜ ߝ ߞ ߟ ߠ ߡ ߢ ߣ ߤ ߥ ߦ ߧ ߴ ߵ] + [ߨ ߩ ߪ] + [\- ‑ ، . % ‰ + ߀ ߁ ߂ ߃ ߄ ߅ ߆ ߇ ߈ ߉] + [߸ ߹ ߷] + + + + + + + + ߓߌ߲ߠ + ߞߏ߲ߞ + ߕߙߊ + ߞߏ߲ߘ + ߘߓߊ߬ߕ + ߥߊ߬ߛ + ߞߊ߬ߙ + ߘߓߊ߬ߓ + ߕߎߟߊߝߌ߲ + ߞߏ߲ߓ + ߣߍߣ + ߞߏߟ + + + ߓ + ߞ + ߕ + ߞ + ߘ + ߥ + ߞ + ߘ + ߕ + ߞ + ߣ + ߞ + + + ߓߌ߲ߠߊߥߎߟߋ߲ + ߞߏ߲ߞߏߜߍ + ߕߙߊߓߊ + ߞߏ߲ߞߏߘߌ߬ߓߌ + ߘߓߊ߬ߕߊ + ߥߊ߬ߛߌ߬ߥߙߊ + ߞߊ߬ߙߌߝߐ߭ + ߘߓߊ߬ߓߌߟߊ + ߕߎߟߊߝߌ߲ + ߞߏ߲ߓߌߕߌ߮ + ߣߍߣߍߓߊ + ߞߏߟߌ߲ߞߏߟߌ߲ + + + + + ߓߌ߲ߠ + ߞߏ߲ߞ + ߕߙߊ + ߞߏ߲ߘ + ߘߓߊ߬ߕ + ߥߊ߬ߛ + ߞߊ߬ߙ + ߘߓߊ߬ߓ + ߕߎߟߊߝߌ߲ + ߞߏ߲ߓ + ߣߍߣ + ߞߏߟ + + + ߓ + ߞ + ߕ + ߞ + ߘ + ߥ + ߞ + ߘ + ߕ + ߞ + ߣ + ߞ + + + ߓߌ߲ߠߊߥߎߟߋ߲ + ߞߏ߲ߞߏߜߍ + ߕߙߊߓߊ + ߞߏ߲ߞߏߘߌ߬ߓߌ + ߘߓߊ߬ߕߊ + ߥߊ߬ߛߌ߬ߥߙߊ + ߞߊ߬ߙߌߝߐ߭ + ߘߓߊ߬ߓߌߟߊ + ߕߎߟߊߝߌ߲ + ߞߏ߲ߓߌߕߌ߮ + ߣߍߣߍߓߊ + ߞߏߟߌ߲ߞߏߟߌ߲ + + + + + + + ߞߊ߯ߙ + ߞߐ߬ߓ + ߞߐ߬ߟߏ߲ + ߞߎߣ + ߓߌߟ + ߛߌ߬ߣ + ߞߍ߲ߘ + + + ߞ + ߞ + ߞ + ߞ + ߓ + ߛ + ߞ + + + ߞߊ߯ + ߞߐ߬ + ߞߐ߬ߟߏ߲ + ߞߎ + ߓߌ + ߛߌ߬ + ߞߍ߲ + + + ߞߊ߯ߙߌߟߏ߲ + ߞߐ߬ߓߊ߬ߟߏ߲ + ߞߐ߬ߟߏ߲ + ߞߎߣߎ߲ߟߏ߲ + ߓߌߟߏ߲ + ߛߌ߬ߣߌ߲߬ߟߏ߲ + ߞߍ߲ߘߍߟߏ߲ + + + + + ߞߊ߯ߙ + ߞߐ߬ߓ + ߞߐ߬ߟ + ߞߎߣ + ߓߌߟ + ߛߌ߬ߣ + ߞߍ߲ߘ + + + ߞ + ߞ + ߞ + ߞ + ߓ + ߛ + ߞ + + + ߞߊ߯ + ߞߐ߬ߓ + ߞߐ߬ߟ + ߞߎ + ߓߌ + ߛߌ߬ + ߞߍ߲ + + + ߞߊ߯ߙߌߟߏ߲ + ߞߐ߬ߓߊ߬ߟߏ߲ + ߞߐ߬ߟߏ߲ + ߞߎߣߎ߲ߟߏ߲ + ߓߌߟߏ߲ + ߛߌ߬ߣߌ߲߬ߟߏ߲ + ߞߍ߲ߘߍߟߏ߲ + + + + + + + ߞߛ߁ + ߞߛ߂ + ߞߛ߃ + ߞߛ߄ + + + ߁ + ߂ + ߃ + ߄ + + + ߞߊߙߏߛߓߊ߫ ߁߭ + ߞߊߙߏߛߓߊ߫ ߂߲ + ߞߊߙߏߛߓߊ߫ ߃߲ + ߞߊߙߏߛߓߊ߫ ߄߲ + + + + + ߞߛ߁ + ߞߛ߂ + ߞߛ߃ + ߞߛ߄ + + + ߁ + ߂ + ߃ + ߄ + + + ߞߊߙߏߛߓߊ߫ ߁߭ + ߞߊߙߏߛߓߊ߫ ߂߲ + ߞߊߙߏߛߓߊ߫ ߃߲ + ߞߊߙߏߛߓߊ߫ ߄߲ + + + + + + + ߛ + ߥ + + + ߛ + ߥ + + + ߛ + ߥ + + + + + ߛ + ߥ + + + ߛ + ߥ + + + ߛ + ߥ + + + + + + ߌߛߊ߫ ߡߏߦߌ ߢߍ߫ + ߞߊ߬ߝߏ߬ߙߋ߲ ߥߎ߬ߛߎ ߢߍ߫ + ߌߛߊ߫ ߡߏߦߌ ߞߐ߫ + ߞߊ߬ߝߏ߬ߙߋ߲ ߠߊ߫ ߥߎ߬ߛߎ + + + ߌߛ. ߡ. ߢߍ߫ + ߌߛ. ߡ. ߞߐ߫ + + + ߌߛ. ߢߍ߫ + ߌߛ. ߞߐ߫ + + + + + y / dd / MM + y / dd MMM + + + + + + ߜ߭ߕߖ{0} + ߜ߭ߕߖ + {0} ߕߎ߬ߡߊ + {0} ߕߎ߬ߡߊ߬-ߦߟߍߡߊ߲ + {0} ߕߎ߬ߡߊ߬-ߦߟߍߡߊ߲ߓߊߟߌ + + ߟߎߥߊ߲ߘߊ߫ + + + ߥߜ߭ߊ߬ߘߜ߭ߎ߫ + + + ߓߎߖ߭ߎ߲ߓߎߙߊ߫ + + + ߔߐߙߑߕߏ߫-ߣߝ߭ߏ߫ + + + ߜ߭ߊߓߏߙߐߣ + + + ߞߌ߲ߛߊߛߊ߫ + + + ߟߎߓߎ߲ߓߊߛߌ߫ + + + ߓߊ߲ߜ߭ߌ߫ + + + ߓߙߖ߭ߊߝ߭ߌߟ + + + ߊߓߌߖߊ߲߬ + + + ߘߎߥߟߊ߫ + + + ߜߦߋߞߎ߲߫-ߝߙߌߛߌ߫ + + + ߖߌߓߎߕߌ߫ + + + ߊߟߑߖ߭ߋ + + + ߞߍ߯ߙ + + + ߟߊ߯ߦߎߣ + + + ߊߛߑߡߙߊ߫ + + + ߊ߬ߘߌ߫ ߛߊ߬ߓߋߓߊ߫ + + + ߟߌߓߙߋߝ߭ߌߟ + + + ߊߞߙߊ߫ + + + ߓߊ߲ߖߎߟ + + + ߞߐߣߊߞߙߌ߫ + + + ߡߟߊߓߏ߫ + + + ߓߌߛߊߥߏ߫ + + + ߛߊߜ߭ߐߛ + + + ߣߊߦߙߏߓߌ߫ + + + ߞߐߡߐ߯ߙ + + + ߡߏ߬ߙߏߝ߭ߌߦߊ߫ + + + ߡߊߛߋߙߎ߫ + + + ߕߙߌߔߟߌ߫ ( ߟߓߌ߫ ) + + + ߞߛߊߓߎߟߊ߲ߞߊ߫ + + + ߊ߲ߕߣߊߣߊߙߌߝ߭ߏ߫ + + + ߓߡߊ߬ߞߐ߫ + + + ߣߎߥߊߞߑߛߐߕ + + + ߡߏߙߌߛ + + + ߓߑߟߊ߲ߕߌ߯ߙ + + + ߡߊߔߎߕߏ߫ + + + ߥߌ߲ߘߐߞ + + + ߢߊߡߋ߫ + + + ߟߋߜ߭ߐߛ + + + ߙߋߣߌߦߐ߲߫ + + + ߞߌߜ߭ߊߟߌ߫ + + + ߡߊߤߋ߫ + + + ߞߊߙߑߕߎߡ + + + ߛߍ߲ߕ ߤߋߟߍߣ + + + ߝߙߌߕߐ߲߬ + + + ߘߊ߬ߞߊ߯ߙߎ߫ + + + ߡߏߜ߭ߊߘߌߛߏ߫ + + + ߖߎߓߊ߫ + + + ߛߊߏ-ߕߏߡߋ߫ + + + ߒߓߊߓߊߣ + + + ߒߖߊߡߋߣߊ߫ + + + ߞߍߙߑߜ߭ߋߟߍ߲߫ + + + ߟߏߡߋ߫ + + + ߕߎߣߌߛ + + + ߘߊ߯ߙ-ߛߊ߬ߟߊ߯ߡ + + + ߞߊ߲ߔߟߊ߫ + + + ߡߊߦߐߕ + + + ߖ߭ߎߥߊߣߍߛߑߓߎ߯ߙ + + + ߟߎߛߞߊ߫ + + + ߤߙߊߙߋ߫ + + + + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߊ߲ߓߊ߲ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + + + + + ߝߘߊ߬ߌ߲߬ߠߊ߫ ߓߟߋ߬ߓߐ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + + + + + ߝߘߌ߬ߝߌ߲߬ߠߊ߫ ߥߙߏ߬ߘߎ߮ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + + + + + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߟߋ߬ߓߋ ߕߎ߬ߡߊ߬ߙߋ߲ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߟߋ߬ߓߋ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߟߋ߬ߓߋ ߕߟߋ߬ߡߊ߬ ߕߎߡߊߙߋ߲ + + + + + ߜߙߋߞߎ߲߫-ߝߙߌߛߌ߫ ߕߎ߬ߡߊ߬ߙߋ߲ + ߜߙߋߞߎ߲߫-ߝߙߌߛߌ߫ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + ߜߙߋߞߎ߲߫-ߝߙߌߛߌ߫ ߕߟߋ߬ߡߊ߬ ߕߎߡߊߙߋ߲ + + + + + ߐߛߑߕߙߊߟߌ߫ ߘߎ߰ߞߟߏ ߣߌ߫ ߝߊ߬ߙߊ߲߬ߛߌ߫ ߊ߲ߕߊߙߑߕߌߞ ߕߎ߬ߡߊ߬ߙߋ + + + + + ߜ߭ߙߋߣߍߕ ߕߎ߬ߡߊ߬ߘߊ + + + + + ߍ߲ߘߎ߫ ߟߌ߲ߓߊ߲ߘߎ߯ ߕߎ߬ߡߊ߬ߙߋ߲ + + + + + ߡߏߙߌߛ ߕߎ߬ߡߊ߬ߙߋ߲ + ߡߏߙߌߛ ߕߎ߬ߡߊ߬ߙߋ߲ ߢߊߓߘߍ + ߡߏߙߌߛ ߕߟߋ߬ߡߊ߬ ߕߎߡߊߙߋ߲ + + + + + ߙߋߣߌߦߐ߲߫ ߕߎ߬ߡߊ߬ߙߋ߲ + + + + + ߛߋߦߌߛߌߟ ߕߎ߬ߡߊ߬ߙߋ߲ + + + + + + nkoo + + nkoo + + + ، + + + + ߊ߲ߜ߭ߏߟߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߊ߲ߖ߭ߊ + ߊ߲ߜ߭ߏߟߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߊ߲ߖ߭ߊ + ߊ߲ߜ߭ߎ + ߞߖ߭ + + + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊ߲ߖ߭ߊ ( ߁߉߇߇–߁߉߉߀ ) + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊ߲ߖ߭ߊ ( ߁߉߇߇–߁߉߉߀ ) + + + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊߖ߭ߊ߫ ߞߎߘߊ ( ߁߉߉߀–߂߀߀߀ ) + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊߖ߭ߊ߫ ߞߎߘߊ ( ߁߉߉߀–߂߀߀߀ ) + ߊߜ߭ߞ + + + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊߖ߭ߊ ߝߊ߲߬ߞߊߘߏ߲߬ߣߍ߲ ( ߁߉߉߅–߁߉߉߉ ) + ߊ߲ߜ߭ߏߟߊ߫ ߞߎߥߊߖ߭ߊ ߝߊ߲߬ߞߊߘߏ߲߬ߣߍ߲ ( ߁߉߉߅–߁߉߉߉ ) + ߊߜ߭ߝ + + + ߓߎߙߎ߲ߘߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߓߎߙߎ߲ߘߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߓߙߝ + + + ߓߐߛߎߥߣߊߞߊ ߟߎ߬ ߟߊ߫ ߔߎߟߊ + ߓߐߛߎߥߣߊߞߊ ߟߎ߬ ߟߊ߫ ߔߎߟߊ + ߓߥߔ + ߔ + + + ߞߏ߲߬ߜ߭ߏ߬ߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߞߏ߲߬ߜ߭ߏ߬ߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߞߝ + + + ߜߙߋߞߎ߲߫ ߝߙߌߛߌߞߊ ߟߎ߬ ߍߛߑߞߎߘߐߛ + ߜߙߋߞߎ߲߫ ߝߙߌߛߌߞߊ ߟߎ߬ ߍߛߑߞߎߘߐߛ + ߍߛߞ + + + ߖߌߓߎߕߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߖߌߓߎߕߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߖߓߝ + + + ߊߟߌߖ߭ߋߙߌߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߣߊ߯ߙߌ + ߊߟߌߖ߭ߋߙߌߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߣߊ߯ߙߌ + ߊߟߘ + + + ߡߌߛߌߙߊ߲ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߡߌߛߌߙߊ߲ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߡߛߔ + + + ߋߙߌߕߙߋߞߊ ߟߎ߬ ߟߊ߫ ߣߊߝߑߞߊ + ߋߙߌߕߙߋߞߊ ߟߎ߬ ߟߊ߫ ߣߊߝߑߞߊ + ߋߙߝ + + + ߋߗߏߔߌߞߊ ߟߎ߬ ߟߊ߫ ߓߌߙߑߛ + ߋߗߏߔߌߞߊ ߟߎ߬ ߟߊ߫ ߓߌߙߑߛ + ߋߗߓ + + + ߛߘߌ + ߜ߭ߊ߯ߣߊ߫ ߛߘߌ ( ߁߉߆߇–߂߀߀߇ ) + + + ߜ߭ߊ߯ߣߊ߫ ߛߘߌ + ߜ߭ߊ߯ߣߞߊ ߟߎ߬ ߛߘߌ + ߜ߭ߛߘ + + + ߜ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߘߟߊߛߌ߫ + ߜ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߘߟߊߛߌ߫ + ߜ߭ߓߘ + + + ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߿ + ߿ + + + ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߛߟߌ + ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߛߟߌ + ߖߛ߾ + + + ߕߍߡߊߓߊ߲߮ ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߋߞߥߋߟߋ + ߕߍߡߊߓߊ߲߮ ߖߌ߬ߣߍ߬ߞߊ ߟߎ߬ ߟߊ߫ ߋߞߥߋߟߋ + ߕߖߋ + + + ߖߌߣߍ߫ ߓߌߛߊߥߏߞߊ ߟߎ߬ ߟߊ߫ ߍߛߑߞߎߘߐߛ + ߖߌߣߍ߫ ߓߌߛߊߥߏߞߊ ߟߎ߬ ߟߊ߫ ߍߛߑߞߎߘߐߛ + ߖߓߍ + + + ߖߌߣߍ߫ ߓߌߛߊߥߏߞߊ ߟߎ߬ ߟߊ߫ ߔߋߖ߭ߏ + ߖߌߣߍ߫ ߓߌߛߊߥߏߞߊ ߟߎ߬ ߟߊ߫ ߔߋߖ߭ߏ + ߖߓߔ + + + ߝߋߣߌߦߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߝߋߣߌߦߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߞߋߛ + + + ߞߐߡ߲߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߞߐߡ߲߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߞߡߝ + ߝߛ + + + ߟߌߓߋߙߌߦߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊߙ + ߟߌߓߋߙߌߦߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊߙ + ߟ߾ + + + ߟߋߛߕߏߞߊ ߟߎ߬ ߟߊ߫ ߟߏߕߌ + ߟߋߛߕߏߞߊ ߟߎ߬ ߟߊ߫ ߟߏߕߌ + ߟߛߟ + + + ߟߓߌ߫ ߘߌ߬ߣߊ߯ߙ + ߟߓߌߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߣߊ߯ߙ + ߟߓߘ + + + ߡߊ߬ߙߐߞߎ߬ ߘߌ߬ߙߑߤߊߡ + ߡߊ߬ߙߐ߬ߞߎ߬ߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߙߑߤߊߡ + ߡߘߤ + + + ߡߊ߬ߙߐ߬ߞߎߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߊ߬ߙߐ߬ߞߎߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߙߝ + + + ߡߘߊߜ߭ߊߛߑߞߊ߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߊߙߌߦߊߙߌ + ߡߘߊߜ߭ߊߛߑߞߊ߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߊߙߌߦߊߙߌ + ߡߘߙ + ߊߙ + + + ߡߘߊߜ߭ߊߑߞߊ߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߘߊߜ߭ߊߑߞߊ߯ߙߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߘߝ + + + ߡߊߟߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߊߟߌߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߡߝ + + + ߡߏߙߌߕߊߣߌߞߊ ߟߎ߬ ߟߊ߫ ߎ߬ߜ߭ߌߦߊ ( ߁߉߇߃–߂߀߁߇ ) + ߡߏߙߌߕߊߣߌߞߊ ߟߎ߬ ߟߊ߫ ߎ߬ߜ߭ߌߦߊ ( ߁߉߇߃–߂߀߁߇ ) + ߡߙߏ + + + ߡߏߙߌߕߊߣߌߞߊ ߟߎ߬ ߟߊ߫ ߎ߬ߜ߭ߌߦߊ + ߡߏߙߌߕߊߣߌߞߊ ߟߎ߬ ߟߊ߫ ߎ߬ߜ߭ߌߦߊ + ߡߎߜ߭ + + + ߡߏߙߛߌߞߊ ߟߎ߬ ߟߊ߫ ߙߔߎ + ߡߏߙߛߌߞߊ ߟߎ߬ ߟߊ߫ ߙߔߎ + ߡߙߔ + ߙߛ + + + ߡߟߊߥߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ + ߡߟߊߥߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ + ߡߟߞ + + + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߍߛߑߞߎߘߏߛ + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߍߛߑߞߎߘߏߛ + ߡߖ߭ߋ + + + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߡߋߕߌߞ ( ߁߉߈߀–߂߀߀߆ ) + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߡߋߕߌߞ ( ߁߉߈߀–߂߀߀߆ ) + ߡߖߡ + + + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߡߋߕߌߞߊߟ + ߡߏߖ߭ߊ߲ߓߞߌߞߊ ߟߎ߬ ߟߊ߫ ߡߋߕߌߞߊߟ + ߡߖ߭ߡ + + + ߣߊߡߌ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ + ߣߊߡߌ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ + ߣߡߘ + ߛ + + + ߖߋ߬ߟߌ߬ߓߊ߬ߞߊ ߟߎ߬ ߟߊ߫ ߣߍߙߊ + ߖߋ߬ߟߌ߬ߓߊ߬ߞߊ ߟߎ߬ ߟߊ߫ ߣߍߙߊ + ߖߣ + + + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ + ߖ߭ߓߘ + + + ߙߎߥߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߙߎߥߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߝߊߙߊ߲ + ߙߥߝ + ߝߙ + + + ߛߋߦߌߛߍߟߌߞߊ ߟߎ߬ ߟߊ߫ ߙߎߔߌ + ߛߋߦߌߛߍߟߌߞߊ ߟߎ߬ ߟߊ߫ ߙߎߔߌ + ߛߛߥ + + + ߛߎ߬ߘߊ߲߬ߞߊ ߟߎ߬ ߘߌ߬ߣߊ߯ߙ ( ߁߉߉߂–߂߀߀߇ ) + ߛߎ߬ߘߊ߲߬ߞߊ ߟߎ߬ ߘߌ߬ߣߊ߯ߙ ( ߁߉߉߂–߂߀߀߇ ) + ߛߘߘ + + + ߛߎߘߊ߲ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߎߘߊ߲ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߘߜ߭ + + + ߛߎ߬ߘ߲ߊ߬ߞߊ ߟߊ߫ ߔߐߣߌ߬ ( ߁߉߅߆–߂߀߀߇ ) + ߛߎ߬ߘ߲ߊ߬ߞߊ ߟߊ߫ ߔߐߣߌ߬ ( ߁߉߅߆–߂߀߀߇ ) + ߛߘߔ + + + ߛߍ߲ߕ ߤߌߟߋߣߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߍ߲ߕ ߤߌߟߋߣߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߤߔ + + + ߛߙߊ߬ߟߏ߲߬ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߙߊ߬ߟߏ߲߬ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߙߔ + + + ߛߏߡߊߟߌߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߛߏߡߊߟߌߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߛߡߛ + + + ߛߎ߬ߘߊ߲߬ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߎ߬ߘߊ߲߬ߞߊ ߟߎ߬ ߟߊ߫ ߔߐߣߌ߬ + ߛߛߔ + + + ߛߊߏߕߏߡߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߓߙߊߛ ( ߁߉߇߇– ߂߀߁߇ ) + ߛߊߏߕߏߡߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߓߙߊߛ ( ߁߉߇߇– ߂߀߁߇ ) + ߛߕߘ + + + ߛߊߏߕߏߡߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߓߙߊߛ + ߛߊߏߕߏߡߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߓߙߊߛ + ߛߔߘ + ߛߓ + + + ߛߑߥߊߕߣߞߊ ߟߎ߬ ߟߌߟߊ߲ߖ߭ߋߣߌߛ + ߛߑߥߊߕߣߞߊ ߟߎ߬ ߟߌߟߊ߲ߖ߭ߋߣߌߛ + ߛߖ߭ߟ + + + ߕߎߣߛߌߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߣߊ߯ߙ + ߕߎߣߛߌߞߊ ߟߎ߬ ߟߊ߫ ߘߌ߬ߣߊ߯ߙ + ߕߣߘ + + + ߕߊ߲ߖ߭ߊ߯ߣߌߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߕߊ߲ߖ߭ߊ߯ߣߌߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߕߖ߭ߛ + + + ߎߜ߭ߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ ( ߁߉߆߆–߁߉߈߇ ) + ߎߜ߭ߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ ( ߁߉߆߆–߁߉߈߇ ) + ߎߜ߭ߥ + + + ߎߜ߭ߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߎߜ߭ߊ߲ߘߞߊ ߟߎ߬ ߟߊ߫ ߛߌߟߌ߲ߜ߭ + ߎߜ߭ߛ + + + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߊ߲ߓߊ߲ ߠߎ߬ ߝߊߙߊ߲߫ ߛߍߝߊ + ߝߘߊ߬ߝߌ߲߬ߠߊ߫ ߕߊ߲ߓߊ߲ ߠߎ߬ ߝߊߙߊ߲߫ ߛߍߝߊ + ߝߛߝ + + + ߝߊߙߊ߲߫ ߛߍߝߊ + ߝߊߙߊ߲߫ ߛߍߝߊ + ߾ + + + ߥߙߏ߬ߘߎ߮ ߝߘߊ߬ߝߌ߲߬ߠߞߊ ߟߎ߬ ߟߊ߫ ߙߊ߲ߘ + ߥߙߏ߬ߘߎ߮ ߝߘߊ߬ߝߌ߲߬ߠߞߊ ߟߎ߬ ߟߊ߫ ߙߊ߲ߘ + ߥߝߙ + + + ߖ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ ( ߁߉߆߈–߂߀߁߂ ) + ߖ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ ( ߁߉߆߈–߂߀߁߂ ) + ߖ߭ߓߞ + + + ߖ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ + ߖ߭ߊ߲ߓߌߞߊ ߟߎ߬ ߟߊ߫ ߞߎߥߛߊ + ߖ߭ߓߥ + ߖ߭ߞ + + + ߖ߭ߊ߬ߦߌ߬ߞߊ ߟߎ߬ ߟߊ߫ ߖ߭ߊ߬ߦߌߙ ( ߁߉߉߃–߁߉߉߈ ) + ߖ߭ߊ߬ߦߌ߬ߞߊ ߟߎ߬ ߟߊ߫ ߖ߭ߊ߬ߦߌߙ ( ߁߉߉߃–߁߉߉߈ ) + ߖ߭ߙ + + + ߖ߭ߊߦߙߌߞߊ ߟߎ߫ ߟߊ߫ ߖ߭ߊ߬ߦߌߙ ( ߁߉߇߁–߁߉߉߃ ) + ߖ߭ߊߦߙߌߞߊ ߟߎ߫ ߟߊ߫ ߖ߭ߊ߬ߦߌߙ ( ߁߉߇߁–߁߉߉߃ ) + ߖ߭ߙߖ߭ + + + ߖߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ (߁߉߈߀–߂߀߀߈ ) + ߖߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ (߁߉߈߀–߂߀߀߈ ) + ߖ߭ߥߘ + + + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ ( ߂߀߀߉ ) + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ ( ߂߀߀߉ ) + ߖ߭ߥߟ + + + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ ( ߂߀߀߈ ) + ߖ߭ߌ߲ߓߊߓߏߦߋߞߊ ߟߎ߬ ߟߊ߫ ߘߏߟߊ߯ߙ ( ߂߀߀߈ ) + ߖ߭ߥߙ + + + + + + + ߝߊ߯ߘߐߞߍ + ߝߊ߯ߘߐߞߍ {0} + + + ߦߟߍ߬ߘߐ߬ߞߍ + ߦߟߍ߬ߘߐ߬ߞߍ {0} + + + ߛߊ߲߭ + ߛߊ߲߭ {0} + ߛߊ߲߭ ߠߊ߫ {0} + + + ߞߊߙߏ + ߞߊߙߏ {0} + ߞߊߙߏ ߟߊ߫ {0} + + + ߞߎ߲߬ߢߐ߮ + ߞߎ߲߬ߢߐ߮ {0} + ߞߎ߲߬ߢߐ߮ ߟߊ߫ {0} + + + ߟߏ߲ + ߟߏ߲ ߜߍ {0} + ߟߏ߲ ߠߊ߫ {0} + + + ߕߎ߬ߡߊ߬ߙߋ߲ + ߕߎ߬ߡߊ߬ߙߋ߲ {0} + ߕߎ߬ߡߊ߬ߙߋ߲ ߞߘߐ߫ {0} + + + ߡߌ߬ߛߍ߲ + ߡߌ߬ߛߍ߲ {0} + ߡߌ߬ߛߍ߲ ߠߊ߫ {0} + + + ߝߌ߬ߟߊ߲ + ߝߌ߬ߟߊ߲ {0} + + + ߝߌ߬ߟߊ߲߬ߥߊ߰ߘߋ߲ + ߝߌ߬ߟߊ߲߬ߥߊ߰ߘߋ߲ {0} + + + ߝߌ߬ߟߊ߲߬ߢߊ߲߯ߕߊ + ߝߌ߬ߟߊ߲߬ߢߊ߲߯ߕߊ {0} + + + ߝߌ߬ߟߊ߲߬ߞߏߦߋ + ߝߌ߬ߟߊ߲߬ߞߏߦߋ {0} + + + + + ߝߊ߯ߘߐߞߍ + ߝߊ߯ߘߐߞߍ {0} + + + ߦߟߍ߬ߘ + + + ߛߊ߲߭ + ߛߊ߲߭ {0} + {0}/ߛߊ߲߭ + + + ߞ. + ߞ. {0} + {0}/ߞ. + + + ߞߎ߲߬ߢ + ߞߎ߲߬ߢ{0} + {0}/ߞߎ߲߬ߢ + + + ߟ + ߟ {0} + {0}/ߟ + + + ߕߎ߬ߡߊ߬ߙߋ߲ + ߕ {0} + {0}/ߕ + + + ߡߌ߬ߛ + ߡߌ߬ߛ {0} + {0}/ߡߌ߬ߛ + + + ߝ + ߝ {0} + {0}/ߝ + + + ߝߥ + ߝߥ {0} + + + ߝߢ + ߝߢ {0} + + + ߝߌ߬ߟߞ + ߝߞ {0} + + + + + ߝߊ߯ߘߐߞߍ + ߝߊ߯ߘߞ{0} + + + ߦߟߍ߬ߘߐ߬ߞߍ + ߦߟߍ߬ߘߞ{0} + + + ߛߊ߲߭ + ߛߊ߲߭{0} + {0}/ߛߊ߲߭ + + + ߞߊߙߏ + ߞ.{0} + {0}/ߞ. + + + ߞߎ߲߬ߢ + ߞߎ߲߬ߢ{0} + {0}/ߞߎ߲߬ߢ + + + ߟߏ߲ + ߟ{0} + {0}/ߟ + + + ߕߎ߬ߡߊ߬ߙߋ߲ + ߕ{0} + {0}/ߕ + + + ߡߌ߬ߛ + ߡߌ߬ߛ{0} + {0}/ߡߌ߬ߛ + + + ߝ + ߝ{0} + {0}/ߝ + + + ߝߥ + ߝߥ{0} + + + ߝߢ + ߝߢ{0} + + + ߝߞ + ߝߞ{0} + + + + diff --git a/make/data/cldr/common/main/nqo_GN.xml b/make/data/cldr/common/main/nqo_GN.xml new file mode 100644 index 00000000000..3bde714a333 --- /dev/null +++ b/make/data/cldr/common/main/nqo_GN.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/nr.xml b/make/data/cldr/common/main/nr.xml new file mode 100644 index 00000000000..1c3d63f8f2a --- /dev/null +++ b/make/data/cldr/common/main/nr.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + isiNdebele + + + + [a b c d e f g h i j k l m n o p q s t u v w x y z] + [r] + [A B C D E F G H I J K L M N O P Q S T U V W X Y Z] + + + + + + + + + + + + + + Jan + Feb + Mat + Apr + Mey + Jun + Jul + Arh + Sep + Okt + Usi + Dis + + + Janabari + uFeberbari + uMatjhi + u-Apreli + Meyi + Juni + Julayi + Arhostosi + Septemba + Oktoba + Usinyikhaba + Disemba + + + + + + + Son + Mvu + Bil + Tha + Ne + Hla + Gqi + + + uSonto + uMvulo + uLesibili + Lesithathu + uLesine + ngoLesihlanu + umGqibelo + + + + + + BC + AD + + + + + + + + , +   + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + + + + R + + + + diff --git a/make/data/cldr/common/main/nr_ZA.xml b/make/data/cldr/common/main/nr_ZA.xml new file mode 100644 index 00000000000..b009779e64c --- /dev/null +++ b/make/data/cldr/common/main/nr_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/nso.xml b/make/data/cldr/common/main/nso.xml new file mode 100644 index 00000000000..d08f3724536 --- /dev/null +++ b/make/data/cldr/common/main/nso.xml @@ -0,0 +1,561 @@ + + + + + + + + + + + Sesotho sa Leboa + + + Afrika Borwa + + + + [a b d e ê f g h i j k l m n o ô p r s š t u w x y] + [c q v z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + Phere + Dibo + Hlak + Mora + Mopi + Phupu + Mose + Phato + Lewe + Dipha + Diba + Manth + + + P + D + H + M + M + P + M + P + L + D + D + M + + + Pherekgong + Dibokwane + Hlakola + Moranang + Mopitlo + Phupu + Mosegemanye + Phato + Lewedi + Diphalane + Dibatsela + Manthole + + + + + Phere + Dibo + Hlak + Mora + Mopi + Phupu + Mose + Phato + Lewe + Dipha + Diba + Manth + + + P + D + H + M + M + P + M + P + L + D + D + M + + + Pherekgong + Dibokwane + Hlakola + Moranang + Mopitlo + Phupu + Mosegemanye + Phato + Lewedi + Diphalane + Dibatsela + Manthole + + + + + + + Lam + Mos + Bed + Rar + Ne + Hla + Mok + + + L + M + B + R + N + H + M + + + Lam + Mos + Bed + Rar + Ne + Hla + Mok + + + Lamorena + Musopologo + Labobedi + Laboraro + Labone + Labohlano + Mokibelo + + + + + Lam + Mos + Bed + Rar + Ne + Hla + Mok + + + L + M + B + R + N + H + M + + + Lam + Mos + Bed + Rar + Ne + Hla + Mok + + + Lamorena + Musopologo + Labobedi + Laboraro + Labone + Labohlano + Mokibelo + + + + + + + 1st Kotara + 2nd Kotara + 3rd Kotara + 4th Kotara + + + 1 + 2 + 3 + 4 + + + 1st Kotara + 2nd Kotara + 3rd Kotara + 4th Kotara + + + + + 1st Kotara + 2nd Kotara + 3rd Kotara + 4th Kotara + + + 1 + 2 + 3 + 4 + + + 1st Kotara + 2nd Kotara + 3rd Kotara + 4th Kotara + + + + + + + AM + PM + + + a + p + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + Before Christ + Before Common Era + Anno Domini + Common Era + + + BC + BCE + AD + CE + + + + + + y MMMM d, EEEE + yMMMMEEEEd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + y-MM-dd + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} 'ka' {0} + + + + + {1} 'ka' {0} + + + + + {1}, {0} + + + + + {1}, {0} + + + + d + ccc + d, E + E h:mm a + E HH:mm + E h:mm:ss a + E HH:mm:ss + G y + G y MMM + G y MMM d + G y MMM d, E + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + L + MM-dd + MM-dd, E + LLL + MMM d + MMM d, E + MMMM d + 'beke' W 'ya' MMM + 'beke' 'ya' 'bo' W 'ya' MMM + mm:ss + y + y-MM + y-MM-dd + y-MM-dd, E + y MMM + y MMM d + y MMM d, E + y MMMM + y QQQ + y QQQQ + 'beke' 'ya' 'bo' w 'ya' Y + 'beke' 'ya' 'bo' w 'ya' Y + + + {0} {1} + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + MM-dd – MM-dd + MM-dd – MM-dd + + + MM-dd, E – MM-dd, E + MM-dd, E – MM-dd, E + + + LLL–LLL + + + MMM d–d + MMM d – MMM d + + + MMM d, E – MMM d, E + MMM d, E – MMM d, E + + + y–y + + + y-MM – y-MM + y-MM – y-MM + + + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + + + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + + + y MMM–MMM + y MMM – y MMM + + + y MMM d–d + y MMM d – MMM d + y MMM d – y MMM d + + + y MMM d, E – MMM d, E + y MMM d, E – MMM d, E + y MMM d, E – y MMM d, E + + + y MMMM–MMMM + y MMMM – y MMMM + + + + + + + + 1 + + . +   + % + + + - + E + × + + + NaN + : + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + ¤#,##0.00 + + + {0} {1} + {0} {1} + + + + R + + + + ≥{0} + {0}–{1} + + + diff --git a/make/data/cldr/common/main/nso_ZA.xml b/make/data/cldr/common/main/nso_ZA.xml new file mode 100644 index 00000000000..ae90284ca6b --- /dev/null +++ b/make/data/cldr/common/main/nso_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/nus.xml b/make/data/cldr/common/main/nus.xml index 36e6654cfb5..4164ad41d5f 100644 --- a/make/data/cldr/common/main/nus.xml +++ b/make/data/cldr/common/main/nus.xml @@ -1,6 +1,6 @@ - + + + + + + + + Diné Bizaad + + + + + left-to-right + top-to-bottom + + + + [a á ą {ą\u0301} b {ch} {ch’} d {dl} {dz} e é ę {ę\u0301} g {gh} h {hw} i í į {į\u0301} j k {k’} {kw} l ł m n o ó ǫ {ǫ\u0301} s {sh} t {t’} {tł} {tł’} {ts} {ts’} w x y z {zh}] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + diff --git a/make/data/cldr/common/main/nv_US.xml b/make/data/cldr/common/main/nv_US.xml new file mode 100644 index 00000000000..fb4fee38263 --- /dev/null +++ b/make/data/cldr/common/main/nv_US.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ny.xml b/make/data/cldr/common/main/ny.xml new file mode 100644 index 00000000000..31261bb7b63 --- /dev/null +++ b/make/data/cldr/common/main/ny.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + Nyanja + + + + [a b c d e f g h i j k l m n o p r s t u w ŵ y z] + [q v x] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + Jan + Feb + Mal + Epu + Mei + Jun + Jul + Oga + Sep + Oku + Nov + Dis + + + Januwale + Febuluwale + Malichi + Epulo + Mei + Juni + Julai + Ogasiti + Seputemba + Okutoba + Novemba + Disemba + + + + + + + Mul + Lem + Wir + Tat + Nai + San + Wer + + + Lamulungu + Lolemba + Lachiwiri + Lachitatu + Lachinayi + Lachisanu + Loweruka + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + Malawian Kwacha + + + + diff --git a/make/data/cldr/common/main/ny_MW.xml b/make/data/cldr/common/main/ny_MW.xml new file mode 100644 index 00000000000..acd7b467f2e --- /dev/null +++ b/make/data/cldr/common/main/ny_MW.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/nyn.xml b/make/data/cldr/common/main/nyn.xml index 8cee15975b9..ae6e6a12cba 100644 --- a/make/data/cldr/common/main/nyn.xml +++ b/make/data/cldr/common/main/nyn.xml @@ -1,6 +1,6 @@ - + + + + + + + + 𐓏𐓘𐓻𐓘𐓻𐓟 + + + United States + + + 𐓷𐓘𐓵𐓘𐓷𐓘 𐓨𐓣𐓡𐓣𐓵𐓟 𐓣͘𐓤𐓯𐓟 + + + US + + + + [𐓘 {𐓘\u0301} {𐓘\u0301\u0358} {𐓘\u030B} {𐓘\u030B\u0358} {𐓘\u0304} {𐓘\u0304\u0358} {𐓘\u0358} 𐓙 {𐓙\u0301} {𐓙\u030B} {𐓙\u0304} 𐓚 {𐓚\u0301} {𐓚\u030B} {𐓚\u0304} 𐓛 {𐓛\u0358} 𐓜 𐓝 𐓞 𐓟 {𐓟\u0301} {𐓟\u030B} {𐓟\u0304} 𐓠 {𐓠\u0301} {𐓠\u030B} {𐓠\u0304} 𐓡 𐓢 𐓣 {𐓣\u0301} {𐓣\u0301\u0358} {𐓣\u030B} {𐓣\u030B\u0358} {𐓣\u0304} {𐓣\u0304\u0358} {𐓣\u0358} 𐓤 𐓥 𐓦 𐓧 𐓨 𐓩 𐓪 {𐓪\u0301} {𐓪\u0301\u0358} {𐓪\u030B} {𐓪\u030B\u0358} {𐓪\u0304} {𐓪\u0304\u0358} {𐓪\u0358} 𐓫 {𐓫\u0301} {𐓫\u030B} {𐓫\u0304} 𐓬 𐓭 𐓮 𐓯 𐓰 𐓱 𐓲 𐓳 𐓴 𐓵 𐓶 {𐓶\u0301} {𐓶\u030B} {𐓶\u0304} 𐓷 𐓸 𐓹 𐓺 𐓻] + [] + [𐒰 {𐒰\u0358} 𐒱 𐒲 𐒳 𐒴 𐒵 𐒶 𐒷 𐒸 𐒹 𐒺 𐒻 {𐒻\u0358} 𐒼 𐒽 𐒾 𐒿 𐓀 𐓁 𐓂 {𐓂\u0358} 𐓃 𐓄 𐓅 𐓆 𐓇 𐓈 𐓉 𐓊 𐓋 𐓌 𐓍 𐓎 𐓏 𐓐 𐓑 𐓒 𐓓] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + EEEE, MMMM d, y G + GyMMMMEEEEd + + + + + MMMM d, y G + GyMMMMd + + + + + MMM d, y G + GyMMMd + + + + + M/d/y GGGGG + GGGGGyMd + + + + + + + + + 𐓄𐓘𐓡𐓛͘𐓧𐓟 + 𐓵𐓪͘𐓬𐓘 + 𐓵𐓘𐓜𐓣 + 𐓰𐓪𐓬𐓘 + 𐓮𐓘𐓰𐓘 + 𐓯𐓘𐓬𐓟 + 𐓄𐓟𐓵𐓪͘𐓬𐓘 + 𐒼𐓣𐓟𐓰𐓪𐓬𐓘 + 𐒿𐓟𐓜𐓛𐓲𐓟𐓷𐓣͘𐓤𐓟 + 𐒿𐓟𐓜𐓛 + 𐒰𐓧𐓣 𐓏𐓣͘𐓸𐓲𐓣 + 𐒰𐓧𐓣 𐓍𐓪͘𐓬𐓘 + + + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓄𐓘𐓡𐓛͘𐓧𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓵𐓪͘𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓵𐓘𐓜𐓣 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓰𐓪𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓮𐓘𐓰𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓯𐓘𐓬𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓄𐓟𐓵𐓪͘𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒼𐓣𐓟𐓰𐓪𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒿𐓟𐓜𐓛𐓲𐓟𐓷𐓣͘𐓤𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒿𐓟𐓜𐓛 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒰𐓧𐓣 𐓏𐓣͘𐓸𐓲𐓣 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒰𐓧𐓣 𐓍𐓪͘𐓬𐓘 + + + + + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓄𐓘𐓡𐓛͘𐓧𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓵𐓪͘𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓵𐓘𐓜𐓣 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓰𐓪𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓮𐓘𐓰𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓏𐓟𐓯𐓘𐓬𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐓄𐓟𐓵𐓪͘𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒼𐓣𐓟𐓰𐓪𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒿𐓟𐓜𐓛𐓲𐓟𐓷𐓣͘𐓤𐓟 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒿𐓟𐓜𐓛 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒰𐓧𐓣 𐓏𐓣͘𐓸𐓲𐓣 + 𐓀𐓣͘𐓪͘𐓬𐓘 𐒰𐓧𐓣 𐓍𐓪͘𐓬𐓘 + + + + + + + 𐓏 + 𐓄 + 𐓍 + 𐒴 + 𐓈 + 𐓊 + 𐓸 + + + 𐒹𐓘͘𐓬𐓘 𐓏𐓘𐓤𐓘͘𐓰𐓘𐓤𐓣 + 𐒹𐓘͘𐓬𐓘 𐓄𐓘𐓡𐓛͘𐓧𐓣 + 𐒹𐓘͘𐓬𐓘 𐓏𐓟𐓵𐓪͘𐓬𐓘 + 𐒹𐓘͘𐓬𐓘 𐓏𐓟𐓵𐓘𐓜𐓣 + 𐒹𐓘͘𐓬𐓘 𐓏𐓟𐓰𐓪𐓬𐓘 + 𐒹𐓘͘𐓬𐓘 𐓈𐓘 𐓵𐓘𐓲𐓘 𐓻𐓣͘ + 𐒹𐓘͘𐓬𐓘 𐓂𐓤𐓘𐓸𐓟 𐓣͘𐓤𐓟 + + + + + + + EEEE, MMMM d, y + yMMMMEEEEd + + + + + MMMM d, y + yMMMMd + + + + + MMM d, y + yMMMd + + + + + M/d/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + 𐓂𐓨𐓚𐓤𐓘 + + + 𐓀𐓣͘𐓪͘𐓬𐓘 + + + 𐒹𐓘͘𐓬𐓘 𐓷𐓘𐓤𐓘͘𐓰𐓘𐓤𐓣 + + + 𐒹𐓘͘𐓬𐓘 + + + 𐓨𐓣𐓪𐓵𐓘𐓤𐓟 𐓪𐓰𐓘𐓩𐓘͘ + + + 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 + + + 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 𐓻𐓣͘ + + + + + + . + , + ; + % + + + - + E + + + NaN + + + + + ¤ 0K + ¤ 00K + ¤ 000K + ¤ 0M + ¤ 00M + ¤ 000M + ¤ 0G + ¤ 00G + ¤ 000G + ¤ 0T + ¤ 00T + ¤ 000T + + + + + + $ + + + + + + + 𐓂𐓨𐓚𐓤𐓘 + 𐓂𐓨𐓚𐓤𐓘 {0} + + + 𐓀𐓣͘𐓪͘𐓬𐓘 + 𐓀𐓣͘𐓪͘𐓬𐓘 {0} + + + 𐒹𐓘͘𐓬𐓘𐓷𐓘𐓤𐓘͘𐓰𐓛𐓤𐓣 + 𐒹𐓘͘𐓬𐓘𐓷𐓘𐓤𐓘͘𐓰𐓛𐓤𐓣 {0} + + + 𐒹𐓘͘𐓬𐓘 + {0} 𐒹𐓘͘𐓬𐓘 + + + 𐓨𐓣𐓪𐓵𐓘𐓤𐓟 𐓪𐓰𐓘𐓩𐓘͘ + {0} 𐓨𐓣𐓪𐓵𐓘𐓤𐓟 𐓪𐓰𐓘𐓩𐓘͘ + + + 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 + {0} 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 + + + 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 𐓻𐓣͘ + {0} 𐓰𐓘𐓲𐓟 𐓤𐓯𐓣𐓵𐓟 𐓻𐓣͘ + + + + diff --git a/make/data/cldr/common/main/osa_US.xml b/make/data/cldr/common/main/osa_US.xml new file mode 100644 index 00000000000..9056a39064d --- /dev/null +++ b/make/data/cldr/common/main/osa_US.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/pa.xml b/make/data/cldr/common/main/pa.xml index 21427343646..f324ac5314a 100644 --- a/make/data/cldr/common/main/pa.xml +++ b/make/data/cldr/common/main/pa.xml @@ -1,6 +1,6 @@ - + + + + + + + + ingles + Papiamentu + + + + + + Aruba + Kòrsou + Turkia + + + meter + britániko + merikano + + + Idioma: {0} + Manera di skirbi: {0} + Region: {0} + + + + [a b c d e è f g h i j k l m n ñ o ò p q r s t u ù ü v w x y z] + [á é í ó ú] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‑ , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ / \& # % ′ ″] + + + + + + + + Yanüari + Febrüari + Mart + Aprel + Mei + Yüni + Yüli + Ougùstùs + Sèptèmber + Òktober + Novèmber + Desèmber + + + + + + + djadumingu + djaluna + djamars + djarason + djaweps + djabièrnè + djasabra + + + + + + + AM + PM + + + + + + dd-MM-y + d MMM y + + + + + + ora di {0} + + + Greenwich Mean Time + + + + + + + . + , + % + - + + + + + {title} {given} {given2} {surname} {surname2} + + + {title} {surname} {surname2} {given} {given2} + + + Zendaya + + + Irene + + + Mari-Sue + + + Jackson Martina + + + Ada Kornelia + + + diff --git a/make/data/cldr/common/main/pap_AW.xml b/make/data/cldr/common/main/pap_AW.xml new file mode 100644 index 00000000000..0b4b9f459e8 --- /dev/null +++ b/make/data/cldr/common/main/pap_AW.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/pap_CW.xml b/make/data/cldr/common/main/pap_CW.xml new file mode 100644 index 00000000000..d3e92b3856d --- /dev/null +++ b/make/data/cldr/common/main/pap_CW.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/pcm.xml b/make/data/cldr/common/main/pcm.xml index 25f9a4bf787..c94fd2b62fe 100644 --- a/make/data/cldr/common/main/pcm.xml +++ b/make/data/cldr/common/main/pcm.xml @@ -1,6 +1,6 @@ - + + + + + + + + {0} ({1}) + {0}, {1} + {0}: {1} + + + arābiskan + dāniskan + miksiskan + Āustrarīkis miksiskan + Šwēicis aūktamiksiskan + grēkiskan + ēngliskan + Austrālijas ēngliskan + Kanādas ēngliskan + brītiskan ēngliskan + amērikaniskan ēngliskan + APW ēngliskan + špāniskan + Lātiniskas Amērikas špāniskan + eurōpiskan špāniskan + Meksikus špāniskan + èstiskan + sōmiskan + prancōziskan + Kanādas prancōziskan + Šwēicis prancōziskan + wālkiskan + japāniskan + laītawiskan + lattawiskan + ullandiskan + pōliskan + prūsiskan + pōrtugaliskan + Brazīlijas pōrtugaliskan + eurōpiskan pōrtugaliskan + maskōwitiskan + šwēdiskan + turkiskan + niwaistā bilā + kīniskan + prastintan kīniskan + tradiciōnalin kīniskan + + + + + + + + + + + + + + + swītai + Afrika + Zēimanamērika + Pussideinanamērika + Amērika + Āzija + Eurōpa + Andōra + Antīgwa be Barbūda + Albānija + Argentīnija + Āustrarīki + Austrālija + Bōsnija be Ercegōwina + Barbādas + Belgija + Bulgārija + Bōliwija + Brazīlija + Bahāmai + Krēiwa + Belīzi + Kānada + Šwēici + Čīli + Kīna + Kōlumbija + Costa Rica + Kūba + Čekkija + Mikskātauta + Dānanmarki + Dōminika + Dōminikas Republīki + Ekwadōrs + Estantauta + Špānija + Sōmija + Farēirai + Prankrīki + Debabritānija + DB + Grenāda + Prancōziska Gujāna + Gibrāltars + Grēnlandan + Grēkantauta + Gwatemāla + Gujāna + Hōnduras + Kruātija + Haīti + Ungrai + Indōnezija + Īndija + Īslandan + Wālkija + Jamāika + Japānija + Pussideinankōreja + Līchtenšteinan + Laītawa + Luksemburgan + Lattawa + Mōnakō + Mōldawija + Mōntenegran + Mālta + Meksiku + Nikarāgwa + Nōrwigai + Nawazēlandan + Panāma + Perū + Pōli + Pōrtugalin + Palau + Paragwājs + Rumānija + Serbija + Russi + Saūdi Arābija + Šwēdija + Slōwenija + Slōwakei + San Marinō + Surināms + El Salvadōrs + Tāilandan + Turkāja + Trinidāds be Tobagō + Taiwāns + Ukrāini + Peraīnintas Wālstis + PW + Urugwājs + Venezuēla + Kōsawa + Pussideinanafrika + niwaistā regiōni + + + Gregōriskas kalāndars + sēisnas rikā + lātiniskas cipperis + + + mētriskan + brītiskan + amērikaniskan + + + Bilā: {0} + Skriptan: {0} + Regiōni: {0} + + + + [a ā b c d ḑ e ē f g ģ h i ī j k ķ l m n ņ o ō p q r ŗ s š t ț u ū v w x y z ž] + [] + [A Ā B C D Ḑ E Ē F G Ģ H I Ī J K Ķ L M N Ņ O Ō P Q R Ŗ S Š T Ț U Ū V W X Y Z Ž] + [  \- ‑ , % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … “ „ ( ) \[ \] \{ \}] + + + + + + + + + + + + + + EEEE, y 'mettas' d. MMMM G + GyMMMMEEEEd + + + + + y 'mettas' d. MMMM G + GyMMMMd + + + + + dd.MM 'st'. y G + GyMMdd + + + + + dd.MM.y GGGGG + GGGGGyMMdd + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + {0} – {1} + + + + + + + + rag + was + pūl + sak + zal + sīm + līp + dag + sil + spa + lap + sal + + + R + W + P + S + Z + S + L + D + S + S + L + S + + + rags + wassarins + pūlis + sakkis + zallaws + sīmenis + līpa + daggis + sillins + spallins + lapkrūtis + sallaws + + + + + rag + was + pūl + sak + zal + sīm + līp + dag + sil + spa + lap + sal + + + R + W + P + S + Z + S + L + D + S + S + L + S + + + rags + wassarins + pūlis + sakkis + zallaws + sīmenis + līpa + daggis + sillins + spallins + lapkrūtis + sallaws + + + + + + + nad + pan + wis + pus + ket + pēn + sab + + + N + P + W + P + K + P + S + + + nadīli + panadīli + wisasīdis + pussisawaiti + ketwirtiks + pēntniks + sabattika + + + + + nad + pan + wis + pus + ket + pēn + sab + + + N + P + W + P + K + P + S + + + nadīli + panadīli + wisasīdis + pussisawaiti + ketwirtiks + pēntniks + sabattika + + + + + + + 1. k. + 2. k. + 3. k. + 4. k. + + + 1 + 2 + 3 + 4 + + + 1. ketwirts + 2. ketwirts + 3. ketwirts + 4. ketwirts + + + + + 1. ketw. + 2. ketw. + 3. ketw. + 4. ketw. + + + 1 + 2 + 3 + 4 + + + 1. ketwirts + 2. ketwirts + 3. ketwirts + 4. ketwirts + + + + + + + AM + PM + + + ankstāinan + pa pussideinan + + + + + + BC + AD + + + + + + EEEE, y 'mettas' d. MMMM + yMMMMEEEEd + + + + + y 'mettas' d. MMMM + yMMMMd + + + + + dd.MM 'st'. y + yMMdd + + + + + dd.MM.yy + yyMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + d. + ccc + E, d. + E, h:mm a + E, HH:mm + E, h:mm:ss a + E, HH:mm:ss + y 'm'. G + y 'm'. MMM G + dd.MM 'st'. y G + E, dd.MM 'st'. y G + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a; v + HH:mm:ss; v + h:mm a; v + HH:mm; v + L. + d.M + E, d.M + LLL + d. MMM + E, d. MMM + mm:ss + y 'm'. + M.y + d.M.y + E, d.M.y + y 'm'. MMM + dd.MM 'st'. y + E, dd.MM 'st'. y + y 'm'. QQQ + y 'm'. QQQQ + + + {0} {1} + + + {0} – {1} + + d.–d. + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + M.–M. + + + dd.MM–dd.MM + dd.MM–dd.MM + + + E, dd.MM – E, dd.MM + E, dd.MM – E, dd.MM + + + MMM–MMM + + + d.–d. MMM + d. MMM – d. MMM + + + E, d. – E, d. MMM + E, d. MMM – E, d. MMM + + + y–y + + + MM.y–MM.y + MM.y–MM.y + + + dd.MM.y–dd.MM.y + dd.MM.y–dd.MM.y + dd.MM.y–dd.MM.y + + + E, dd.MM.y – E, dd.MM.y + E, dd.MM.y – E, dd.MM.y + E, dd.MM.y – E, dd.MM.y + + + y 'm'. MMM–MMM + y 'm'. MMM – y 'm'. MMM + + + dd.–dd.MM 'st'. y + dd.MM–dd.MM 'st'. y + dd.MM 'st'. y – dd.MM 'st'. y + + + E, dd. – E, dd.MM 'st'. y + E, dd.MM – E, dd.MM 'st'. y + E, dd.MM 'st'. y – E, dd.MM 'st'. y + + + y 'mettas' MMMM–MMMM + y 'mettas' MMMM – y 'mettas' MMMM + + + + + + + + ēra + + + mettan + panzdauman mettan + this year + next year + + + m. + + + m. + + + ketwirts + + + ketw. + + + ketw. + + + mīnss + + + mī. + + + mī. + + + sawaīti + + + saw. + + + saw. + + + deinā + bītan + šandēinan + ankstāinan + + + d. + + + d. + + + sawaītis deinā + + + ankstāinan / pa pussideinan + + + stūndi + + + st. + + + st. + + + minūti + + + min. + + + min. + + + sekūndi + + + sek. + + + sek. + + + kerdaszōni + + + + +HH:mm;-HH:mm + GMT{0} + GMT + Kerdā: {0} + Daggas kerdā: {0} + Zēimas kerdā: {0} + {1} ({0}) + + + Centrālas Amērikas kerdā + Centrālas Amērikas zēimas kerdā + Centrālas Amērikas daggas kerdā + + + + + Dēiniskas Amērikas kerdā + Dēiniskas Amērikas zēimas kerdā + Dēiniskas Amērikas daggas kerdā + + + + + Amērikas gārban kerdā + Amērikas gārban zēimas kerdā + Amērikas gārban daggas kerdā + + + + + Pacīfiskas Amērikas kerdā + Pacīfiskas Amērikas zēimas kerdā + Pacīfiskas Amērikas daggas kerdā + + + + + Atlāntiska kerdā + Atlāntiska zēimas kerdā + Atlāntiska daggas kerdā + + + + + Centrālas Eurōpas kerdā + Centrālas Eurōpas zēimas kerdā + Centrālas Eurōpas daggas kerdā + + + + + Dēiniskas Eurōpas kerdā + Dēiniskas Eurōpas zēimas kerdā + Dēiniskas Eurōpas daggas kerdā + + + + + Wakkariskas Eurōpas kerdā + Wakkariskas Eurōpas zēimas kerdā + Wakkariskas Eurōpas daggas kerdā + + + + + Greenwich kerdā + + + + + + latn + + latn + + + , +   + % + + + - + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + #,##0.00 ¤ + + + {0} {1} + {0} {1} + {0} {1} + + + + Brazīlijas reals + Brazīlijas realin + Brazīlijas reals + Brazīlijas realai + + + Kīnas juāns + Kīnas juānan + Kīnas juāns + Kīnas juānai + + + eurō + eurō + eurō + eurō + + + punds sterlings + pundan sterlingan + punds sterlings + pundai sterlingai + + + Īndijas rūpija + Īndijas rūpijan + Īndijas rūpija + Īndijas rūpijas + + + Japānijas jāns + Japānijas jānan + Japānijas jāns + Japānijas jānai + + + Russis rūbels + Russis rūblin + Russis rūbels + Russis rūblai + + + APW dālars + APW dālaran + APW dālars + APW dālarai + + + niwaistā walūta + (niwaistā walūta) + (niwaistā walūtas aīnibi) + (niwaistā walūta) + + + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0}, {1} + {0}, {1} + {0} be {1} + {0} be {1} + + + + + jā:j + ni:n + + + diff --git a/make/data/cldr/common/main/prg_001.xml b/make/data/cldr/common/main/prg_001.xml new file mode 100644 index 00000000000..c0be9e6d854 --- /dev/null +++ b/make/data/cldr/common/main/prg_001.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ps.xml b/make/data/cldr/common/main/ps.xml index 79d0f77ddfd..91101430729 100644 --- a/make/data/cldr/common/main/ps.xml +++ b/make/data/cldr/common/main/ps.xml @@ -1,6 +1,6 @@ - + + + + + + + + Kʼicheʼ + + + Macedonia del Norte + + + + + left-to-right + top-to-bottom + + + + [a ä {aʼ} {bʼ} {ch} {chʼ} e {eʼ} i {iʼ} j k {kʼ} l m n o p q {qʼ} r s t {tz} {tzʼ} {tʼ} u {uʼ} v w x y] + [c d f g h ñ z] + [A Ä {Bʼ} {CH} {CHʼ} E I J K {Kʼ} L M N O P Q {Qʼ} R S T {TZ} {TZʼ} {Tʼ} U V W X Y] + + + + + Q + + + + diff --git a/make/data/cldr/common/main/quc_GT.xml b/make/data/cldr/common/main/quc_GT.xml new file mode 100644 index 00000000000..2c64b467b7d --- /dev/null +++ b/make/data/cldr/common/main/quc_GT.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/raj.xml b/make/data/cldr/common/main/raj.xml index ee969948643..6b4bb042787 100644 --- a/make/data/cldr/common/main/raj.xml +++ b/make/data/cldr/common/main/raj.xml @@ -1,6 +1,6 @@ - + + + + + + + + 𐴌𐴗𐴥𐴝𐴙𐴚𐴒𐴙𐴝 + + + + + right-to-left + + + + [\U00010D24\U00010D25\U00010D26\U00010D27 𐴀 𐴝 𐴞 𐴟 𐴠 𐴡 𐴁 𐴂 𐴃 𐴄 𐴅 𐴆 𐴇 𐴈 𐴉 𐴊 𐴋 𐴌 𐴍 𐴎 𐴏 𐴐 𐴑 𐴒 𐴓 𐴔 𐴕 𐴖 𐴗 𐴘 𐴙 𐴚 𐴛 𐴢 𐴣] + [ـ] + [\- ‑ , . % + 0𐴰 1𐴱 2𐴲 3𐴳 4𐴴 5𐴵 6𐴶 7𐴷 8𐴸 9𐴹] + [\- ‐ ‑ – — ، ؛ \: ! ؟ . … ' " ( ) \[ \]] + + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + H:mm + Hmm + + + + + + + + 𐴎𐴡𐴁𐴝𐴕𐴝 + + + 𐴎𐴡𐴁𐴝𐴕𐴝 + + + 𐴎𐴡𐴁𐴝𐴕𐴝 + + + 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴡𐴏𐴥𐴡𐴌 + + + {0} 𐴁𐴡𐴏𐴥𐴡𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴡𐴏𐴥𐴡𐴌 + + + {0} 𐴁𐴡𐴏𐴥𐴡𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴡𐴏𐴥𐴡𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴡𐴏𐴥𐴡𐴌 + + + {0} 𐴁𐴡𐴏𐴥𐴡𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴉𐴝𐴁𐴝 + 𐴀𐴝𐴈𐴥𐴠𐴌𐴞 𐴉𐴝𐴁𐴝 + 𐴀𐴠 𐴉𐴝𐴁𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴉𐴝𐴁𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴉𐴝𐴁𐴝 + + + {0} 𐴉𐴝𐴁𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴉𐴝𐴁𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴉𐴝𐴁𐴝 + + + {0} 𐴉𐴝𐴁𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴉𐴝𐴁𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴉𐴝𐴁𐴝 + + + {0} 𐴉𐴝𐴁𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴝𐴐𐴢 + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴔𐴥𐴝𐴐𐴢 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴥𐴝𐴐𐴢 + + + {0} 𐴔𐴝𐴐𐴢 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴝𐴐𐴢 + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴔𐴥𐴝𐴐𐴢 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴥𐴝𐴐𐴢 + + + {0} 𐴔𐴝𐴐𐴢 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴝𐴐𐴢 + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴠 𐴔𐴥𐴝𐴐𐴢 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴔𐴥𐴝𐴐𐴢 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴥𐴝𐴐𐴢 + + + {0} 𐴔𐴝𐴐𐴢 𐴀𐴝𐴒𐴠 + + + + 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴒𐴠𐴓𐴊𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴇𐴥𐴝𐴉𐴃𐴝 + + + {0} 𐴇𐴥𐴝𐴉𐴃𐴝 𐴀𐴝𐴒𐴠 + + 𐴇𐴥𐴉𐴃𐴤𐴝𐴌 {0} + + + 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴒𐴠𐴓𐴊𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴇𐴥𐴝𐴉𐴃𐴝 + + + {0} 𐴇𐴥𐴝𐴉𐴃𐴝 𐴀𐴝𐴒𐴠 + + 𐴇𐴥𐴉𐴃𐴤𐴝𐴌 {0} + + + 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴒𐴠𐴓𐴊𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴇𐴥𐴝𐴉𐴃𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴇𐴥𐴝𐴉𐴃𐴝 + + + {0} 𐴇𐴥𐴝𐴉𐴃𐴝 𐴀𐴝𐴒𐴠 + + 𐴇𐴥𐴉𐴃𐴤𐴝𐴌 {0} + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝 + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝 + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝 + + + 𐴊𐴞𐴕 + 𐴒𐴠𐴓𐴊𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + 𐴀𐴝𐴙𐴅𐴧𐴙𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴊𐴞𐴕 + + + {0} 𐴊𐴞𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴊𐴞𐴕 + 𐴒𐴠𐴓𐴊𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + 𐴀𐴝𐴙𐴅𐴧𐴙𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴊𐴞𐴕 + + + {0} 𐴊𐴞𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴊𐴞𐴕 + 𐴒𐴠𐴓𐴊𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + 𐴀𐴝𐴙𐴅𐴧𐴙𐴝 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴈𐴝𐴙𐴓𐴧𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴊𐴞𐴕 + + + {0} 𐴊𐴞𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴁𐴡𐴏𐴥𐴡𐴌𐴡𐴌 𐴊𐴞𐴕 + + + 𐴁𐴡𐴏𐴥𐴡𐴌𐴡𐴌 𐴊𐴞𐴕 + + + 𐴁𐴡𐴏𐴥𐴡𐴌𐴡𐴌 𐴊𐴞𐴕 + + + 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴔𐴝𐴐𐴤𐴡𐴌 𐴇𐴥𐴝𐴉𐴃𐴝𐴌 𐴊𐴞𐴕 + + + 𐴒𐴠𐴓𐴊𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + + {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + + {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 + + + {0} 𐴌𐴦𐴡𐴘 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴔 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴝 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + + {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴝 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + + {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴠 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴝 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 + + + {0} 𐴔𐴡𐴚𐴒𐴡𐴓 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴟𐴙𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 + + + {0} 𐴁𐴞𐴐𐴤𐴞𐴃 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴠 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴟𐴑𐴧𐴟𐴌 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴠𐴓𐴊𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 + + + {0} 𐴐𐴤𐴡𐴕𐴞 𐴁𐴝𐴌 𐴀𐴝𐴒𐴠 + + + + 𐴊𐴞𐴕 / 𐴌𐴝𐴙𐴃𐴢 + + + 𐴊𐴞𐴕 / 𐴌𐴝𐴙𐴃𐴢 + + + 𐴊𐴞𐴕 / 𐴌𐴝𐴙𐴃𐴢 + + + 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + 𐴀𐴠 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + + {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + + {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 + + + {0} 𐴒𐴤𐴡𐴕𐴄𐴤𐴝 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴞𐴕𐴥𐴡𐴄𐴢 + 𐴀𐴠 𐴔𐴞𐴕𐴥𐴡𐴄 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴞𐴕𐴥𐴡𐴄 + + + {0} 𐴔𐴞𐴕𐴥𐴡𐴄 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴞𐴕𐴥𐴡𐴄𐴢 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴞𐴕𐴥𐴡𐴄 + + + {0} 𐴔𐴞𐴕𐴥𐴡𐴄 𐴀𐴝𐴒𐴠 + + + + 𐴔𐴞𐴕𐴥𐴡𐴄𐴢 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴔𐴞𐴕𐴥𐴡𐴄 + + + {0} 𐴔𐴞𐴕𐴥𐴡𐴄 𐴀𐴝𐴒𐴠 + + + + 𐴏𐴠𐴑𐴤𐴠𐴕 + 𐴀𐴠𐴈𐴥𐴡𐴕 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴏𐴠𐴑𐴤𐴠𐴕 + + + {0} 𐴏𐴠𐴑𐴤𐴠𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴏𐴠𐴑𐴤𐴠𐴕 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴏𐴠𐴑𐴤𐴠𐴕 + + + {0} 𐴏𐴠𐴑𐴤𐴠𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴏𐴠𐴑𐴤𐴠𐴕 + + 𐴀𐴝𐴘𐴧𐴥𐴠𐴌𐴊𐴧𐴠 {0} 𐴏𐴠𐴑𐴤𐴠𐴕 + + + {0} 𐴏𐴠𐴑𐴤𐴠𐴕 𐴀𐴝𐴒𐴠 + + + + 𐴀𐴠𐴓𐴝𐴑𐴝𐴀𐴞 𐴄𐴝𐴙𐴔 + + + 𐴀𐴠𐴓𐴝𐴑𐴝𐴀𐴞 𐴄𐴝𐴙𐴔 + + + 𐴀𐴠𐴓𐴝𐴑𐴝𐴀𐴞 𐴄𐴝𐴙𐴔 + + + + + und rhg + + diff --git a/make/data/cldr/common/main/rhg_Rohg.xml b/make/data/cldr/common/main/rhg_Rohg.xml new file mode 100644 index 00000000000..351938d4f6d --- /dev/null +++ b/make/data/cldr/common/main/rhg_Rohg.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + Lmuɣrib + Ṭurkya + + + amitrik + aglinziy + amirikaniy + + + tutlayt: {0} + tira: {0} + jjihet: {0} + + + + [a b c d ḍ e ɛ f g ɣ h ḥ i j k l m n p q r s ṣ t ṭ u w x y z ẓ] + [á à â ä ç é è ê ë î ï ñ o ó ô ö œ ß ú ù û ü v ʷ ÿ] + [A B C D Ḍ E Ɛ F G Ɣ H Ḥ I J K L M N P Q R S Ṣ T Ṭ U W X Y Z Ẓ] + [\- ‑ , . % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” « » ( ) \[ \] \{ \} § @ * / \& # `] + + + + + + + + yennayer + febrayer + mars + yebril + mayyu + yunyu + yulyuz + ɣucct + cutenber + kṭuber + nuwember + dujember + + + + + + + lḥed + letnayen + ttlat + larbeɛ + lexmis + jjemɛa + ssebt + + + + + + + AM + PM + + + + + + h:mm a + dd/MM/y + d MMM y + + + + + + akud n {0} + akud unebdu n {0} + akud anaway n {0} + + + GMT + + + + + + + , +   + + + + + #,##0.00 ¤ + + + + + + + Yamina + + + Faḍma + Awraɣ + + + Ɛellal + + + Muḥemmed Amin + + + Sinbad + + + Käthe + + + Zäzilia + + + Ada Cornelia + + + diff --git a/make/data/cldr/common/main/rif_MA.xml b/make/data/cldr/common/main/rif_MA.xml new file mode 100644 index 00000000000..b099abe9ca4 --- /dev/null +++ b/make/data/cldr/common/main/rif_MA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/rm.xml b/make/data/cldr/common/main/rm.xml index 64b205ffe8d..2918029f628 100644 --- a/make/data/cldr/common/main/rm.xml +++ b/make/data/cldr/common/main/rm.xml @@ -1,6 +1,6 @@ - @@ -2940,6 +2940,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ Macao + + Ciudad Juárez + + + Bahía de Banderas + + + Mérida + + + Cancún + Kathmandu @@ -2994,18 +3006,6 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ Ho Chi Minh - - Bahía de Banderas - - - Cancún - - - Ciudad Juárez - - - Mérida - @@ -3020,6 +3020,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + ٫ ٬ @@ -3056,6 +3059,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3068,6 +3074,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3086,6 +3095,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3095,6 +3107,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3131,12 +3146,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -3146,6 +3182,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3164,9 +3209,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3191,15 +3245,30 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + @@ -3212,6 +3281,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3224,6 +3296,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3242,12 +3317,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3295,12 +3379,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -3310,6 +3415,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3328,9 +3442,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3355,15 +3478,30 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + @@ -3376,6 +3514,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3388,6 +3529,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3406,12 +3550,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3440,12 +3593,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -3455,6 +3629,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3473,9 +3656,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3500,15 +3692,30 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + @@ -3525,6 +3732,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3537,6 +3747,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3555,12 +3768,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3589,12 +3811,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -3604,6 +3847,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3622,9 +3874,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3649,15 +3910,30 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + @@ -3681,6 +3957,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3693,6 +3972,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -3711,12 +3993,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3779,12 +4070,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -3794,6 +4106,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3812,9 +4133,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -3839,9 +4169,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + ؋ @@ -4178,6 +4520,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -4190,6 +4535,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -4202,6 +4550,9 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + @@ -4220,12 +4571,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -4253,12 +4613,33 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + + + + + + + + + + @@ -4268,6 +4649,15 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -4286,9 +4676,18 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + @@ -4313,9 +4712,21 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ + + + + + + + + + + + + {0}? {0}? @@ -5430,7 +5841,7 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ {0}. {0} {1} - {prefix} {given} {given2} {surname} {surname2} {suffix} + {title} {given} {given2} {surname} {surname2} {credentials} @@ -5484,7 +5895,7 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ - {surname} {surname2} {prefix} {given} {given2} {suffix} + {surname} {surname2} {title} {given} {given2} {credentials} @@ -5538,7 +5949,7 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ - {surname} {surname2}, {prefix} {given} {given2} {suffix} + {surname} {surname2}, {title} {given} {given2} {credentials} @@ -5555,27 +5966,5 @@ Warnings: All cp values have U+FE0F characters removed. See /annotationsDerived/ - - ∅∅∅ - - - ∅∅∅ - ∅∅∅ - - - ∅∅∅ - ∅∅∅ - ∅∅∅ - - - ∅∅∅ - ∅∅∅ - ∅∅∅ - ∅∅∅ - ∅∅∅ - ∅∅∅ - ∅∅∅ - ∅∅∅ - diff --git a/make/data/cldr/common/main/ru.xml b/make/data/cldr/common/main/ru.xml index 2d59a1bfd96..bcb30f54805 100644 --- a/make/data/cldr/common/main/ru.xml +++ b/make/data/cldr/common/main/ru.xml @@ -1,6 +1,6 @@ - + + + + + + + + + + [\u093C \u0902 अ आ ई उ ए ओ क ग च ज ञ ट ड ण त द न प ब म य र ल व स ह ा ी \u0941 \u0947 ो] + [\- ‑ , . % ‰ + 0० 1१ 2२ 3३ 4४ 5५ 6६ 7७ 8८ 9९] + [\- ‑ , ; \: ! ? . ‘ ’ “ ” ( ) \[ \] \{ \} ॰] + + + + + + + + EEEE, d MMMM y + yMMMMEEEEd + + + + + d MMMM y + yMMMMd + + + + + d MMM y + yMMMd + + + + + d/M/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + deva + + diff --git a/make/data/cldr/common/main/sat_Deva_IN.xml b/make/data/cldr/common/main/sat_Deva_IN.xml new file mode 100644 index 00000000000..9b343ae6dcf --- /dev/null +++ b/make/data/cldr/common/main/sat_Deva_IN.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Munnu + Àfrica + Uciania + Àfrica uccidintali + Mèrica cintrali + Àfrica urintali + Àfrica di menzu + Mèrichi + Asia urintali + Asia + Asia cintrali + Asia uccidintali + Europa + Europa urintali + Europa uccidintali + Mèrica latina + Antigua e Barbuda + Anguilla + Arbanìa + Antàrtidi + Argintina + Austria + Australia + Aruba + Barbados + Bergiu + Burkina Faso + Burgarìa + Benin + Bulivia + Brasili + Bahamas + Belize + Sbìzzira + Cili + Cina + Culommia + Cubba + Capu Virdi + Cechia + Ripùbblica Ceca + Girmania + Danimarca + Ripùbblica Duminicana + Ècuador + Estonia + Egittu + Sahara uccidintali + Spagna + Uniuni Eurupea + Zuna Euru + Francia + Regnu Unitu + RU + Guiana Francisi + Ghana + Grecia + Guiana + Honduras + Cruazzia + Haiti + Ungarìa + Ìsuli Canari + Irlanna + Ìnnia + Islanna + Italia + Giamàica + Giurdania + Giappuni + Camboggia + Kuwait + Lìbbanu + Liechtenstein + Libberia + Lituania + Lussimmurgu + Littonia + Libbia + Maroccu + Mònacu + Murdova + Mali + Mauritania + Marta + Mardivi + Mèssicu + Niger + Niggeria + Nicaragua + Paisi Vasci + Nurveggia + Pànama + Pirù + Pulonia + Purtugallu + Paraguay + Rumanìa + Serbia + Russia + Sbezzia + Sluvenia + Sluvacchia + San Marinu + Sènigal + El Salvador + Togu + Tunisìa + Turchìa + Nazziuna Uniti + Stati Uniti + SUM + Uruguay + Città dû Vaticanu + Accenti fausi + Bidirizziunali fausu + Kossovo + Riggiuni scanusciuta + + + Calannariu + Sistema di misura + Nùmmari + + + Calannariu buddista + Calannariu cinisi + Calannariu grigurianu + Calannariu ebbràicu + Calannariu ISO-8601 + Calannariu giappunisi + Sistema mètricu + Sistema mpiriali + Sistema miricanu + + + + [a à â b c d ḍ e è ê f g h i í î j l m n o ò ô p q r s t u ú û v z] + [ç đ é ë ə ḥ ì k š ù w x y] + [A B C D E F G H I J L M N O P Q R S T U V Z] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” ( ) \[ \] § @ * / \& # † ‡ ′ ″] + + + + + + + + jin + fri + mar + apr + maj + giu + gnt + agu + sit + utt + nuv + dic + + + J + F + M + A + M + G + G + A + S + U + N + D + + + jinnaru + frivaru + marzu + aprili + maju + giugnu + giugnettu + agustu + sittèmmiru + uttòviru + nuvèmmiru + dicèmmiru + + + + + jin + fri + mar + apr + maj + giu + gnt + agu + sit + utt + nuv + dic + + + J + F + M + A + M + G + G + A + S + U + N + D + + + jinnaru + frivaru + marzu + aprili + maju + giugnu + giugnettu + agustu + sittèmmiru + uttòviru + nuvèmmiru + dicèmmiru + + + + + + + dumìnica + lunnidìa + martidìa + mercuridìa + jovidìa + vennidìa + sàbbatu + + + + + + + + annu + l’annu passatu + st’annu + l’annu vinturu + + nna n’annu + nna {0} anni + + + n’annu nnarrè + {0} anni nnarrè + + + + a. + + + a. + + + misi + + + m. + + + m. + + + simana + + + smn. + + + smn. + + + simana dû misi + + + smn. dû m. + + + smn. dû m. + + + jornu + ajeri + stjornu + dumani + + + j. + ajeri + oji + dumani + + + j. + ajeri + oji + dumani + + + jornu di l’annu + + + j. di l’a. + + + j. di l’a. + + + jornu dâ simana + + + j. dâ smn. + + + j. dâ smn. + + + ura + + + u. + + + u. + + + minutu + + + min. + + + min. + + + sicunnu + ora + + + sic. + ora + + + sic. + ora + + + fusu urariu + + + fusu + + + fusu + + + + + + , + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + : + + + : + + + : + + + : + + + : + + + , + . + ; + % + + + - + ~ + E + × + + + NaN + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + , + . + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + + + se:s + + + diff --git a/make/data/cldr/common/main/scn_IT.xml b/make/data/cldr/common/main/scn_IT.xml new file mode 100644 index 00000000000..fac9de008ce --- /dev/null +++ b/make/data/cldr/common/main/scn_IT.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/sd.xml b/make/data/cldr/common/main/sd.xml index c6b206780bb..f7f9b1b4658 100644 --- a/make/data/cldr/common/main/sd.xml +++ b/make/data/cldr/common/main/sd.xml @@ -1,6 +1,6 @@ - + + + + + + + + ئسپرانتو + کوردی خوارگ + + + + + right-to-left + top-to-bottom + + + + [ئ ا ب پ ت ج چ ح خ د ر ز ڕ ژ س ش ع غ ف ڤ ق ک گ ل ڵ م ن ھ ە و ۆ ۊ ی ێ] + [\u200C\u200D\u200E\u200F \u064B \u064C \u064E \u064F \u0650 \u0651 \u0652 \u0654 \u0670 ء آ أ ؤ إ ة ث ذ ص ض ط ظ ك ه ى ي] + [ئ ا ب پ ت ج چ ح خ د ر ز ڕ ژ س ش ع غ ف ڤ ق ک گ ل ڵ م ن ھ ە و ۆ ۊ ی ێ] + [\- ‐ ‑ ، ٫ ٬ ؛ \: ! ؟ . … ‹ › « » ( ) \[ \] * / \\] + {0}… + …{0} + {0}…{1} + {0} … + … {0} + {0} … {1} + ؟ + + + « + » + + + + + arab + + arab + + + diff --git a/make/data/cldr/common/main/sdh_IQ.xml b/make/data/cldr/common/main/sdh_IQ.xml new file mode 100644 index 00000000000..3cc33628c03 --- /dev/null +++ b/make/data/cldr/common/main/sdh_IQ.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/sdh_IR.xml b/make/data/cldr/common/main/sdh_IR.xml new file mode 100644 index 00000000000..bd375ccdb19 --- /dev/null +++ b/make/data/cldr/common/main/sdh_IR.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/se.xml b/make/data/cldr/common/main/se.xml index 5945cd6517f..98b959774c5 100644 --- a/make/data/cldr/common/main/se.xml +++ b/make/data/cldr/common/main/se.xml @@ -1,6 +1,6 @@ - + + + + + + + + တႆး + + + + + + မျၢၼ်ႇမႃႇ (မိူင်းမၢၼ်ႈ) + မိူင်းထႆး + + + + [\u200B း ႞ ႟ ၵ ၶ ၷ င ၸ ၺ ꧣ တ ထ ၻ ၼ ပ ၽ ၾ ၿ ꧤ မ ယ ျ ရ ြ လ ဝ \u103D \u1082 ႀ သ ႁ ဢ ႃ \u102D \u102E \u102F \u1030 ေ ႄ \uA9E5 \u103A ႇ ႈ ႉ ႊ] + [ꩡ ꩦ ꩧ ꩨ ꩩ ꩮ] + [ၵ ၶ ၷ ꧠ င ၸ ꩡ ꧡ ꧢ ၺ ꩦ ꩧ ꩨ ꩩ တ ထ ၻ ၼ ပ ၽ ၾ ၿ ꧤ မ ယ ရ လ ဝ ႀ သ ႁ ꩮ ဢ] + [႐ ႑ ႒ ႓ ႔ ႕ ႖ ႗ ႘ ႙] + [၊ ။ ‘ ’ “ ”] + + diff --git a/make/data/cldr/common/main/shn_MM.xml b/make/data/cldr/common/main/shn_MM.xml new file mode 100644 index 00000000000..3433e268995 --- /dev/null +++ b/make/data/cldr/common/main/shn_MM.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/shn_TH.xml b/make/data/cldr/common/main/shn_TH.xml new file mode 100644 index 00000000000..9a6819b9544 --- /dev/null +++ b/make/data/cldr/common/main/shn_TH.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/si.xml b/make/data/cldr/common/main/si.xml index 2bdaaa250c6..b1d7c38e9b4 100644 --- a/make/data/cldr/common/main/si.xml +++ b/make/data/cldr/common/main/si.xml @@ -1,6 +1,6 @@ - + + + + + + + + Sidaamu Afo + + + + + + Itiyoophiya + + + + [a b c d e f g h i j k l m n o p q r s t u v w x y z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + EEEE, MMMM dd, y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + Sam + San + Mak + Row + Ham + Arb + Qid + + + Sambata + Sanyo + Maakisanyo + Roowe + Hamuse + Arbe + Qidaame + + + + + S + S + M + R + H + A + Q + + + + + + + soodo + hawwaro + + + soodo + hawwaro + + + + + + YIA + YIG + + + + + + EEEE, MMMM dd, y + yMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + + ¤#,##0.00 + + + + + + Br + + + + diff --git a/make/data/cldr/common/main/sid_ET.xml b/make/data/cldr/common/main/sid_ET.xml new file mode 100644 index 00000000000..f628f2fb25a --- /dev/null +++ b/make/data/cldr/common/main/sid_ET.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/sk.xml b/make/data/cldr/common/main/sk.xml index 36122aae93f..064b8c364ff 100644 --- a/make/data/cldr/common/main/sk.xml +++ b/make/data/cldr/common/main/sk.xml @@ -1,6 +1,6 @@ - + + + + + + + + Åarjelsaemien gïele + + + + + left-to-right + top-to-bottom + + + + [a å ä b d e f g h i j k l m n o ö p r s t u v y] + [c ï q w x z] + [A Å Ä B D E F G H I J K L M N O Ö P R S T U V Y] + + diff --git a/make/data/cldr/common/main/sma_NO.xml b/make/data/cldr/common/main/sma_NO.xml new file mode 100644 index 00000000000..30302dbe2e1 --- /dev/null +++ b/make/data/cldr/common/main/sma_NO.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + [a å æ b d e f g h i j k l m n o ø p r s t u v y] + [A Å Æ B D E F G H I J K L M N O Ø P R S T U V Y] + + diff --git a/make/data/cldr/common/main/sma_SE.xml b/make/data/cldr/common/main/sma_SE.xml new file mode 100644 index 00000000000..183903b78aa --- /dev/null +++ b/make/data/cldr/common/main/sma_SE.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/smj.xml b/make/data/cldr/common/main/smj.xml new file mode 100644 index 00000000000..2d7fc942467 --- /dev/null +++ b/make/data/cldr/common/main/smj.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + julevsámegiella + + + + + left-to-right + top-to-bottom + + + + [a á å ä b d e f g h i j k l m n ń o p r s t u v] + [c ñ ö q w x y z] + [A Á Å Ä B D E F G H I J K L M N Ń O P R S T U V] + + diff --git a/make/data/cldr/common/main/smj_NO.xml b/make/data/cldr/common/main/smj_NO.xml new file mode 100644 index 00000000000..a2dc043987b --- /dev/null +++ b/make/data/cldr/common/main/smj_NO.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/smj_SE.xml b/make/data/cldr/common/main/smj_SE.xml new file mode 100644 index 00000000000..a4187d0be90 --- /dev/null +++ b/make/data/cldr/common/main/smj_SE.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/smn.xml b/make/data/cldr/common/main/smn.xml index 46c39a7a2ff..a60ec691edd 100644 --- a/make/data/cldr/common/main/smn.xml +++ b/make/data/cldr/common/main/smn.xml @@ -1,6 +1,6 @@ - + + + + + + + + siSwati + + + eSwatini + + + + [a b c d e f g h i j k l m n o p q r s t u v w x y z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + Bhi + Van + Vol + Mab + Nkh + Nhl + Kho + Ngc + Nyo + Mph + Lwe + Ngo + + + Bhimbidvwane + iNdlovana + iNdlovu-lenkhulu + Mabasa + iNkhwekhweti + iNhlaba + Kholwane + iNgci + iNyoni + iMphala + Lweti + iNgongoni + + + + + + + Son + Mso + Bil + Tsa + Ne + Hla + Mgc + + + Lisontfo + uMsombuluko + Lesibili + Lesitsatfu + Lesine + Lesihlanu + uMgcibelo + + + + + + + + + , +   + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + + + + E + + + R + + + + diff --git a/make/data/cldr/common/main/ss_SZ.xml b/make/data/cldr/common/main/ss_SZ.xml new file mode 100644 index 00000000000..fa930615ead --- /dev/null +++ b/make/data/cldr/common/main/ss_SZ.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + diff --git a/make/data/cldr/common/main/ss_ZA.xml b/make/data/cldr/common/main/ss_ZA.xml new file mode 100644 index 00000000000..9e512c4d8b1 --- /dev/null +++ b/make/data/cldr/common/main/ss_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ssy.xml b/make/data/cldr/common/main/ssy.xml new file mode 100644 index 00000000000..9d816ee2f4f --- /dev/null +++ b/make/data/cldr/common/main/ssy.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + Qafar + Saho + + + + + + Yabuuti + Eretria + Otobbia + + + + [a b t s e c k x i d q r f g o l m n u w h y] + [j p v z] + [A B T S E C K X I D Q R F G O L M N U W H Y] + + + + + + + + EEEE, MMMM dd, y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + + + Qun + Nah + Cig + Agd + Cax + Qas + Qad + Leq + Way + Dit + Xim + Kax + + + Qunxa Garablu + Kudo + Ciggilta Kudo + Agda Baxis + Caxah Alsa + Qasa Dirri + Qado Dirri + Liiqen + Waysu + Diteli + Ximoli + Kaxxa Garablu + + + + + Q + N + C + A + C + Q + Q + L + W + D + X + K + + + + + + + Nab + San + Sal + Rab + Cam + Jum + Qun + + + Naba Sambat + Sani + Salus + Rabuq + Camus + Jumqata + Qunxa Sambat + + + + + N + S + S + R + C + J + Q + + + + + + + saaku + carra + + + saaku + carra + + + + + + Yaasuusuk Duma + Yaasuusuk Wadir + + + YD + YW + + + + + + EEEE, MMMM dd, y + yMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + + ¤#,##0.00 + + + + + + Nfk + + + + diff --git a/make/data/cldr/common/main/ssy_ER.xml b/make/data/cldr/common/main/ssy_ER.xml new file mode 100644 index 00000000000..33924045617 --- /dev/null +++ b/make/data/cldr/common/main/ssy_ER.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/st.xml b/make/data/cldr/common/main/st.xml new file mode 100644 index 00000000000..944fb014792 --- /dev/null +++ b/make/data/cldr/common/main/st.xml @@ -0,0 +1,650 @@ + + + + + + + + + + + Seburu + Se-amhari + Se-arab + Se-azerbaijani + Se-belarusia + Se-bulgaria + Se-bengali + Breton + Se-bosnia + Se-catalia + Se-czech + Se-welsh + Se-dutch + Se-jeremane + Se-greek + Senyesemane + Se-esperanto + Sespain + Se-estonia + Se-basque + Se-persia + Se-finnish + Se-tagalog + Se-foroese + Se-french + Se-frisia + Se-irish + Se-scots gaelic + Se-galicia + Guarani + Se-gujarati + Se-hebrew + Se-hindi + Se-croatia + Se-hungaria + Se-interlingua + Se-indonesia + Se-iceland + Se-tariana + Se-japane + Se-javane + Se-geogia + Se-kannada + Se-korea + Kurdish + Kyrgyz + Se-latino + Se-Lithuano + Se-masedonia + Se-malayalam + Se-marathi + Se-malay + Se-maltese + Se-nepali + Dutch + Se-norway (Nynorsk) + Se-norway + Se-occitan + Oriya + Se-punjabi + Se-polish + Pashto + Se-portugal + Seputukesi (sa Brazil) + Se-portugal (Portugal) + Se-romania + Se-rushia + Serbo-Croatian + Se-sinhali + Se-slovak + Se-slovania + Se-albanian + Se-serbian + Sesotho + Se-sundanese + Se-sweden + Se-swahili + Se-tamil + Se-telegu + Se-thai + Se-tigrinya + Turkmen + Se-klingon + Se-theki + Twi + Se-ukrania + Se-urdu + Se-uzbek + Se-vietnam + se Xhosa + Yiddish + se Zulu + + + + [a b d e f g h i j k l m n o p q r s t u w y] + [c v x z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + Phe + Kol + Ube + Mme + Mot + Jan + Upu + Pha + Leo + Mph + Pun + Tsh + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Phesekgong + Hlakola + Hlakubele + Mmese + Motsheanong + Phupjane + Phupu + Phata + Leotshe + Mphalane + Pundungwane + Tshitwe + + + + + Phe + Kol + Ube + Mme + Mot + Jan + Upu + Pha + Leo + Mph + Pun + Tsh + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Phesekgong + Hlakola + Hlakubele + Mmese + Motsheanong + Phupjane + Phupu + Phata + Leotshe + Mphalane + Pundungwane + Tshitwe + + + + + + + Son + Mma + Bed + Rar + Ne + Hla + Moq + + + S + M + T + W + T + F + S + + + Son + Mma + Bed + Rar + Ne + Hla + Moq + + + Sontaha + Mmantaha + Labobedi + Laboraru + Labone + Labohlane + Moqebelo + + + + + Son + Mma + Bed + Rar + Ne + Hla + Moq + + + S + M + T + W + T + F + S + + + Son + Mma + Bed + Rar + Ne + Hla + Moq + + + Sontaha + Mmantaha + Labobedi + Laboraru + Labone + Labohlane + Moqebelo + + + + + + + Q1 + Q2 + Q3 + Q4 + + + 1 + 2 + 3 + 4 + + + Q1 + Q2 + Q3 + Q4 + + + + + Q1 + Q2 + Q3 + Q4 + + + 1 + 2 + 3 + 4 + + + Q1 + Q2 + Q3 + Q4 + + + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + BCE + CE + + + BCE + CE + + + + + + y MMMM d, EEEE + yMMMMEEEEd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + y-MM-dd + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + d + ccc + d, E + E h:mm a + E HH:mm + E h:mm:ss a + E HH:mm:ss + G y + G y MMM + G y MMM d + G y MMM d, E + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + L + MM-dd + MM-dd, E + LLL + MMM d + MMM d, E + MMMM d + 'week' W 'of' MMM + 'week' W 'of' MMM + mm:ss + y + y-MM + y-MM-dd + y-MM-dd, E + y MMM + y MMM d + y MMM d, E + y MMMM + y QQQ + y QQQQ + 'week' w 'of' Y + 'week' w 'of' Y + + + {0} {1} + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + MM-dd – MM-dd + MM-dd – MM-dd + + + MM-dd, E – MM-dd, E + MM-dd, E – MM-dd, E + + + LLL–LLL + + + MMM d–d + MMM d – MMM d + + + MMM d, E – MMM d, E + MMM d, E – MMM d, E + + + y–y + + + y-MM – y-MM + y-MM – y-MM + + + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + + + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + + + y MMM–MMM + y MMM – y MMM + + + y MMM d–d + y MMM d – MMM d + y MMM d – y MMM d + + + y MMM d, E – MMM d, E + y MMM d, E – MMM d, E + y MMM d, E – y MMM d, E + + + y MMMM–MMMM + y MMMM – y MMMM + + + + + + + + 1 + + , +   + % + + + - + E + × + + + NaN + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + ¤#,##0.00 + + + {0} {1} + {0} {1} + + + + R + + + + ≥{0} + {0}–{1} + + + diff --git a/make/data/cldr/common/main/st_LS.xml b/make/data/cldr/common/main/st_LS.xml new file mode 100644 index 00000000000..5b5f213072e --- /dev/null +++ b/make/data/cldr/common/main/st_LS.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + + + M + + + + diff --git a/make/data/cldr/common/main/st_ZA.xml b/make/data/cldr/common/main/st_ZA.xml new file mode 100644 index 00000000000..8457779ae89 --- /dev/null +++ b/make/data/cldr/common/main/st_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/su.xml b/make/data/cldr/common/main/su.xml index 15dbcc9a319..59e2115b59b 100644 --- a/make/data/cldr/common/main/su.xml +++ b/make/data/cldr/common/main/su.xml @@ -1,6 +1,6 @@ - + + + + + + + + {0}، {1} + + + ܐܒܟܐܙܝܬ + ܐܡܪܢܝܬ + ܐܪܐܓܘܢܝܬ + ܥܪܒܝܬ + ܥܪܒܝܬ ܪܘܫܡܝܐ ܚܕܬܐ + ܐܪܐܦܗܝܬ + ܐܙܪܒܝܓܐܢܝܬ + ܐܙܪܝ + ܒܢܓܐܠܝܐ + ܩܪܕܝܬ ܩܢܛܪܘܢܝܐ + ܩܘܪܕܝܬ ܡܨܥܝܐ + ܩܘܪܕܝܬ ܣܘܪܢܝ + ܐܠܡܢܝܐ + ܝܘܢܐܝܬ + ܐܢܓܠܝܣ + ܐܢܓܠܝܣ (ܐܡܝܪܟܐ) + ܣܦܢܝܝܐ + ܦܪܣܝܬ + ܦܘܠܐܗܝܬ + ܦܝܢܠܢܕܝܬ + ܦܝܠܝܦܝܢܝܬ + ܦܘܢܝܬ + ܦܪܢܣܝܬ + ܓܐܝܬ + ܓܠܝܩܝܬ + ܓܘܓܐܪܝܬ + ܥܒܪܐܝܬ + ܗܢܕܝܐ + ܐܪܡܢܝܬ + ܐܝܛܠܝܬ + ܓܘܪܓܝܐܝܬ + ܩܘܪܕܝܬ + ܠܬܝܢܝܬ + ܓܢܕܝܬ + ܠܫ̈ܢܐ ܦܖ̈ܝܫܐ + ܐܠܡܢܝܐ ܠܐܠܬܚܬ + ܗܘܠܢܕܐ ܠܐܠܬܚܬ + ܗܘܠܢܕܝܬ + ܢܘܪܒܝܓܐܝܬ + ܐܘܪܘܡܘܐܝܬ + ܦܝܓܝܢܝܬ + ܦܘܠܢܕܐܝܬ + ܦܘܪܛܘܓܠܐܝܬ + ܪܘܡܢܐܝܬ + ܐܘܪܘܣܢܝܬ + ܣܟܘܬܠܢܕܐܝܬ + ܐܠܒܢܝܬ + ܣܘܝܕܐܝܬ + ܣܘܐܗܝܠܐܝܬ + ܣܘܪܝܝܐ + ܬܘܪܟܝܬ + ܐܘܟܪܐܝܢܐܝܬ + ܠܫܢܐ ܠܐ ܝܕܝܥܐ + ܐܘܪܕܘܝܬ + ܒܝܬܢܐܡܐܝܬ + ܝܕܝܬܝܬ + ܨܝܢܝܬ + ܨܝܢܝܬ (ܡܐܢܕܘܪܝܐ) + ܨܝܢܝܬ (ܦܫܝܛܐ) + ܨܝܢܝܬ (ܡܐܢܕܘܪܝܐ ܦܫܝܛܐ) + ܨܝܢܐܝܬ + + + + + + + + + + + + + + + + + ܬܐܒܝܠ + ܐܦܪܝܩܐ + ܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܐܡܪܝܟܐ ܬܝܡܢܝܬܐ + ܐܘܩܝܢܘܣܝܐ + ܐܦܪܝܩܐ ܡܥܪܒܝܬܐ + ܐܡܪܝܟܐ ܡܨܥܝܬܐ + ܐܦܪܝܩܐ ܡܕܢܚܝܬܐ + ܐܦܪܝܩܐ ܓܪܒܝܝܬܐ + ܐܦܪܝܩܐ ܡܨܥܝܬܐ + ܐܦܪܝܩܐ ܬܝܡܢܝܬܐ + ܐܡܪ̈ܝܟܐ + ܓܪܒܝܐ ܐܡܪܝܟܐ + ܟܐܪܝܒܝܢ + ܐܣܝܐ ܡܕܢܚܝܬܐ + ܐܣܝܐ ܬܝܡܢܝܬܐ + ܬܝܡܢ ܡܕܢܚ ܐܣܝܐ + ܐܘܪܘܦܐ ܬܝܡܢܝܬܐ + ܐܘܣܛܪܐܠܐܣܝܐ + ܡܝܠܐܢܝܣܝܐ + ܡܝܟܪܘܢܝܙܝܐ + ܦܘܠܢܝܣܝܐ + ܐܣܝܐ + ܐܣܝܐ ܡܨܥܝܬܐ + ܐܣܝܐ ܡܥܪܒܝܬܐ + ܐܘܪܘܦܐ + ܐܘܪܘܦܐ ܡܕܢܚܝܬܐ + ܐܘܪܘܦܐ ܓܪܒܝܝܬܐ + ܐܘܪܘܦܐ ܡܥܪܒ݂ܝܬܐ + ܐܦܪܝܩܐ ܨܚܪܐ ܬܝܡܢܝܬܐ + ܐܡܪܝܟܐ ܠܬܝܢܝܬܐ + ܓܙܪܬܐ ܕܐܣܝܢܫܘܢ + ܐܢܕܘܪܐ + ܐܡܝܪ̈ܘܬܐ ܡܚܝܕ̈ܬܐ ܥܪ̈ܒܝܐ + ܐܦܓܐܢܣܬܐܢ + ܐܢܬܝܓܘܐ ܘܒܐܪܒܘܕܐ + ܐܢܓܘܝܠܐ + ܐܠܒܢܝܐ + ܐܪܡܢܝܐ + ܐܢܓܘܠܐ + ܐܢܬܪܬܝܟܐ + ܐܪܓܢܬܝܢܐ + ܣܡܘܐ ܐܡܝܖ̈ܟܝܐ + ܐܘܣܛܪܝܐ + ܐܘܣܬܪܠܝܐ + ܐܪܘܒܐ + ܓܙܝܖ̈ܐ ܕܐܠܐܢܕ + ܐܙܪܒܝܓܐܢ + ܒܘܣܢܐ ܘܗܪܬܣܓܘܒܝܢܐ + ܒܪܒܐܕܘܣ + ܒܢܓܠܐܕܝܫ + ܒܠܓܝܩܐ + ܒܘܪܩܝܢܐ ܦܐܣܘ + ܒܘܠܓܐܪܝܐ + ܒܚܪܝܢ + ܒܘܪܘܢܕܝ + ܒܢܝܢ + ܡܪܬܝ ܒܪ ܬܘܠܡܝ + ܒܪܡܘܕܐ + ܒܪܘܢܐܝ + ܒܘܠܝܒܝܐ + ܟܐܪܝܒܝܢ ܕܢܝܬܝܪܠܐܢܕܣ + ܒܪܐܙܝܠ + ܒܗܐܡܣ + ܒܘܬܐܢ + ܓܙܪܬܐ ܕܒܘܒܝܬ + ܒܘܛܣܘܐܢܐ + ܒܠܐܪܘܣ + ܒܠܝܙ + ܟܢܕܐ + ܓܙܝܖ̈ܐ ܕܟܘܟܘܣ + ܟܘܢܓܘ - ܟܝܢܫܐܣܐ + ܩܘܛܢܝܘܬܐ ܕܝܡܘܩܪܛܝܬܐ ܕܟܘܢܓܘ + ܩܘܛܢܝܘܬܐ ܕܐܦܪܝܩܐ ܡܨܥܝܬܐ + ܟܘܢܓܘ - ܒܪܐܙܐܒܝܠ + ܩܘܛܢܝܘܬܐ ܕܟܘܢܓܘ + ܣܘܝܣܪܐ + ܩܘܛ ܕܝܒܘܐܪ + ܣܘܦܐ ܕܓܪܡܦܝܠܐ + ܓܙܪܬܐ ܟܘܟ + ܬܫܝܠܝ + ܟܐܡܪܘܢ + ܨܝܢ + ܟܘܠܘܡܒܝܐ + ܓܙܪܬܐ ܕܟܠܝܦܝܪܬܘܢ + ܟܘܣܬܐ ܪܝܩܐ + ܟܘܒܐ + ܟܐܦ ܒܝܪܕܝ (ܪܝܫܐ ܝܘܪܩܐ) + ܟܘܪܐܟܘ + ܓܙܪܬܐ ܕܟܪܝܣܬܡܣ + ܩܘܦܪܘܣ + ܬܫܝܟܝܐ + ܬܫܝܟ + ܐܠܡܢܝܐ + ܕܐܝܓܘ ܓܪܣܝܐ + ܓܝܒܘܛܝ + ܕܐܢܡܐܪܩ + ܕܘܡܝܢܝܩܐ + ܩܘܛܢܝܘܬܐ ܕܘܡܝܢܝܩܐܢܝܬܐ + ܓܙܐܪ + ܟܘܝܛܐ ܘܡܝܠܝܐ + ܐܩܘܐܕܘܪ + ܐܣܛܘܢܝܐ + ܡܨܪܝܢ + ܨܚܪܐ ܡܥܪܒܝܬܐ + ܐܪܬܪܝܐ + ܐܣܦܢܝܐ + ܟܘܫ + ܚܘܝܕܐ ܐܘܪܘܦܝܐ + ܩܠܝܡܐ ܕܐܘܪܘ + ܦܝܢܠܢܕ + ܦܝܓܝ + ܓܙܪܬܐ ܕܦܠܟܠܢܕ + ܓܙܪܬܐ ܕܡܠܒܢܐܣ + ܐܬܪܘܬܐ ܦܕܪܠܝܐ ܕܡܝܩܪܘܢܝܣܝܐ + ܓܙܝܖ̈ܐ ܕܦܪܘ + ܦܪܢܣܐ + ܓܒܘܢ + ܡܠܟܘܬܐ ܡܚܝܕܬܐ + ܓܪܝܢܐܕܐ + ܓܘܪܓܝܐ + ܓܘܝܐܢܐ ܦܪܢܣܝܬܐ + ܓܘܪܢܙܝ + ܓܐܢܐ + ܓܒܪܠܛܪ + ܓܪܝܢܠܢܕ + ܓܡܒܝܐ + ܓܝܢܝܐ + ܓܘܐܕܘܠܘܦܐܝ + ܓܝܢܝܐ ܫܘܝܬܐ + ܝܘܢ + ܓܙܝܖ̈ܐ ܕܓܘܪܓܝܐ ܘܣܐܢܕܘܝܟ ܬܝܡܢܝ̈ܐ + ܓܘܐܬܝܡܐܠܐ + ܓܘܐܡ + ܓܝܢܝܐ ܒܝܣܐܘ + ܓܘܝܐܢܐ + ܗܘܢܓ ܟܘܢܓ + ܓܙܝܪ̈ܐ ܕܗܪܕ ܘܡܟܕܘܢܠܕ + ܗܘܢܕܘܪܣ + ܩܪܘܐܛܝܐ + ܗܐܝܬܝ + ܡܓܪ + ܓܙܝܖ̈ܐ ܕܟܐܢܪܝ + ܐܝܢܕܘܢܝܣܝܐ + ܐܝܪܠܢܕ + ܐܝܣܪܐܝܠ + ܓܙܪܬܐ ܕܡܐܢ + ܗܢܕܘ + ܩܠܝܡܐ ܕܒܪܝܛܢܝܐ ܓܘ ܐܘܩܝܢܘܣ ܗܢܕܘܝܐ + ܥܝܪܩ + ܐܝܪܐܢ + ܐܝܣܠܢܕ + ܐܝܛܠܝܐ + ܓܝܪܙܝ + ܓܡܝܟܐ + ܐܘܪܕܘܢ + ܝܦܢ + ܩܝܢܝܐ + ܩܝܪܓܝܙܣܬܐܢ + ܟܡܒܘܕܝܐ + ܟܝܪܝܒܬܝ + ܓܙܪܬܐ ܕܩܡܪ + ܣܐܢܬ ܟܝܬܣ ܘܢܝܒܝܣ + ܟܘܪܝܐ ܕܓܪܒܝܐ + ܟܘܪܝܐ ܕܬܝܡܢܝܐ + ܟܘܝܬ + ܓܙܝܖ̈ܐ ܕܟܐܝܡܐܢ + ܟܙܩܣܬܐܢ + ܠܐܘܣ + ܠܒܢܢ + ܡܪܬܝ ܠܘܫܐ + ܠܝܟܛܢܫܛܝܢ + ܫܪܝ ܠܐܢܟܐ + ܠܝܒܝܪܝܐ + ܠܣܘܛܘ + ܠܬܘܢܝܐ + ܠܘܟܣܡܒܘܪܓ + ܠܐܛܒܝܐ + ܠܘܒܐ + ܡܓܪܒ + ܡܘܢܐܩܘ + ܡܘܠܕܘܒܐ + ܡܘܢܛܝܢܝܓܪܘ + ܣܐܢܬ ܡܐܪܬܝܢ + ܡܕܓܣܩܪ + ܓܙܪܬܐ ܡܐܪܫܐܠ + ܓܪܒܝ ܡܩܕܘܢܝܐ + ܡܐܠܝ + ܡܝܐܢܡܐܪ (ܒܘܪܡܐ) + ܡܘܢܓܘܠܝܐ + ܓܙܝܖ̈ܐ ܕܡܪܝܢܐ ܓܪܒܝܐ + ܡܐܪܬܝܢܝܩ + ܡܘܪܝܛܢܝܐ + ܡܘܢܣܝܪܐܬ + ܡܝܠܛܐ + ܡܘܪܝܛܝܘܣ + ܓܙܪܬܐ ܡܐܠܕܝܒܝܬܐ + ܡܠܐܘܝ + ܡܟܣܝܟܘ + ܡܠܝܙܝܐ + ܡܘܙܡܒܝܩ + ܢܡܝܒܝܐ + ܢܝܘ ܟܠܝܕܘܢܝܐ + ܢܝܓܪ + ܓܙܪܬܐ ܕܢܘܪܦܠܟ + ܢܝܓܝܪܝܐ + ܢܝܟܪܐܓܘܐ + ܗܘܠܢܕܐ + ܢܘܪܒܝܓ + ܢܝܦܐܠ + ܢܐܘܪܘ + ܢܘܥ + ܢܝܘ ܙܝܠܢܕ + ܐܬܝܐܐܪܐܘ ܢܝܘ ܙܝܠܢܕ + ܥܘܡܐܢ + ܦܢܡܐ + ܦܝܪܘ + ܦܘܠܝܢܝܣܝܐ ܦܪܢܣܝܐ + ܦܐܦܘܐ ܓܝܢܝܐ ܚܕܬܐ + ܦܝܠܝܦܝܢܝܐ + ܦܐܟܣܬܐܢ + ܦܘܠܢܕ + ܣܐܢܬ ܦܝܥܪ ܘܡܩܘܠܘܢ + ܓܙܝܪ̈ܐ ܕܦܝܬܟܐܝܪܢ + ܦܘܐܪܛܘ ܪܝܩܘ + ܐܬܖ̈ܘܬܐ ܕܦܠܣܛܝܢ + ܦܠܣܛܝܢ + ܦܘܪܛܘܓܠ + ܦܠܐܘ + ܦܪܓܘܐܝ + ܩܛܪ + ܐܘܩܝܢܘܣܝܐ ܒܪܝܬܐ + ܪܝܘܢܝܘܢ + ܪܘܡܢܝܐ + ܣܪܒܝܐ + ܪܘܣܝܐ + ܪܘܐܢܕܐ + ܣܥܘܕܝܐ + ܓܙܪܬܐ ܕܫܠܝܡܘܢ + ܣܐܝܫܝܠ + ܣܘܕܐܢ + ܣܘܝܕ + ܣܝܢܓܐܦܘܪ + ܡܪܬܝ ܗܝܠܝܢܐ + ܣܠܘܒܢܝܐ + ܣܒܠܕܒܪܕ ܘܓܐܢ ܡܐܝܝܢ + ܣܠܘܒܩܝܐ + ܣܝܝܪܐ ܠܝܐܘܢܝ + ܣܢ ܡܪܝܢܘ + ܣܢܓܐܠ + ܨܘܡܐܠ + ܣܘܪܝܢܐܡ + ܬܝܡܢ ܣܘܕܐܢ + ܣܐܘ ܛܘܡܝ ܘܦܪܝܢܣܝܦܝ + ܐܠ ܣܠܒܐܕܘܪ + ܣܢܬ ܡܐܪܬܝܢ + ܣܘܪܝܐ + ܐܣܘܐܛܝܢܝ + ܣܘܐܙܝܠܢܕ + ܬܪܝܣܬܢ ܕܟܘܢܗܐ + ܓܙܝܖ̈ܐ ܕܬܘܪܟܣ ܘܟܐܝܟܘܣ + ܬܫܐܕ + ܩܠܝܡ̈ܐ ܕܦܪܢܣܐ ܬܝܡܢܝܬܐ + ܬܘܓܘ + ܬܐܝܠܢܕ + ܬܐܓܝܟܣܬܐܢ + ܬܘܟܝܠܐܘ + ܬܝܡܘܪ-ܠܣܬܝ + ܬܝܡܘܪ ܡܕܢܚܐ + ܬܘܪܟܡܢܣܬܐܢ + ܬܘܢܣ + ܬܘܢܓܐ + ܬܘܪܟܝܐ + ܬܪܝܢܝܕܐܕ ܘܬܘܒܐܓܘ + ܬܘܒܐܠܘ + ܬܐܝܘܐܢ + ܛܢܙܢܝܐ + ܐܘܩܪܐܝܢܐ + ܐܘܓܢܕܐ + ܓܙܝܪ̈ܐ ܪ̈ܚܝܩܐ ܕܐܘܚܕ̈ܢܐ ܡܚܝܕ̈ܐ + ܐܡ̈ܘܬܐ ܡܚܝ̈ܕܬܐ + ܐܘܚܕ̈ܢܐ ܡܚܝܕ̈ܐ + ܐܘܪܘܓܘܐܝ + ܐܘܙܒܟܣܬܐܢ + ܡܕܝܢܬܐ ܕܘܛܝܩܢ + ܣܐܢܬ ܒܝܢܣܝܢܬ ܘܓܪܝܢܐܕܝܢܐܣ + ܒܢܙܘܝܠܐ + ܓܙܖ̈ܝܐ ܒܬܘ̈ܠܐ ܕܒܪܝܛܢܝܐ + ܓܙܖ̈ܝܐ ܒܬܘ̈ܠܐ ܕܐܡܝܪܟܐ + ܒܝܬܢܐܡ + ܒܐܢܘܐܛܘ + ܘܝܠܝܣ ܘܦܘܬܘܢܐ + ܣܡܘܐ + ܩܘܣܘܒܘ + ܝܡܢ + ܡܐܝܘܛ + ܬܝܡܢ ܐܦܪܝܩܐ + ܙܐܡܒܝܐ + ܙܝܡܒܐܒܘܝ + + + ܣܘܪܓܕܐ + ܛܘܦܣܐ ܕܙܘ̈ܙܐ + ܛܟܣܐ ܕܦܘܪܫܢܝܐ + ܙܘ̈ܙܐ + ܛܟ݂ܣܐ ܥܕܢܘܬܐ (12 ܠܘܩܒܠ 24) + ܛܟܣܐ ܕܟܝܠܬܐ + ܡܢܝ̈ܢܐ + + + ܣܘܪܓܕܐ ܒܘܕܗܝܝܐ + ܣܘܪܓܕܐ ܨܝܢܝܐ + ܣܘܪܓܕܐ ܐܓܒܛܝܐ + ܣܘܪܓܕܐ ܕܢܓܝ + ܣܘܪܓܕܐ ܟܘܫܝܐ + ܣܘܪܓܕܐ ܓܪܝܓܘܪܝܐ + ܣܘܪܓܕܐ ܝܗܘܕܝܐ + ܣܘܪܓܕܐ ܐܘܡܬܢܝܐ ܗܢܕܘܝܐ + ܣܘܪܓܕܐ ܡܫܠܡܢܝܐ + ܣܘܪܓܕܐ ܡܫܠܡܢܝܐ ܡܕܝܢܝܐ + ܣܘܪܓܕܐ ISO-8601 + ܣܘܪܓܕܐ ܝܦܢܝܐ + ܣܘܪܓܕܐ ܦܪܣܝܐ + ܣܘܪܓܕܐ ܡܝܢܓܘ + ܛܘܦܣܐ ܕܙܘ̈ܙܐ ܡܚܫܒܢܘܬܝܐ + ܛܘܦܣܐ ܕܙܘ̈ܙܐ ܫܪܫܝܐ + ܛܟ݂ܣܐ ܦܘܪܫܢܝܐ ܕܠܟܣܝܩܘܢ + ܟܬܒܐ ܕܡܢܝ̈ܢܐ ܕܬܝܠܝܦܘܢ + ܛܟ݂ܣܐ ܦܘܪܫܢܝܐ ܫܪܫܝܐ + ܛܟ݂ܣܐ ܦܘܪܫܢܝܐ ܥܝܕ݂ܝܐ + ܛܟ݂ܣܐ 12 ܫܥܬ݂ܐ (0–11) + ܛܟ݂ܣܐ 12 ܫܥܬ݂ܐ (1–12) + ܛܟ݂ܣܐ 24 ܫܥܬ݂ܐ (0–23) + ܛܟ݂ܣܐ 24 ܫܥܬ݂ܐ (0–23) + ܛܟܣܐ ܡܝܬܪܝܐ + ܛܟܣܐ ܕܟܝܠܬܐ ܒܪܝܛܢܝܝܐ + ܛܟܣܐ ܕܟܝܠܬܐ ܐܡܪܝܟܝܐ + ܡܢܝ̈ܢܐ ܕܥܖ̈ܒܝܐ ܗܢܕܘܝܐ + ܡܢܝ̈ܢܐ ܕܐܖ̈ܡܢܝܐ + ܡܢܝ̈ܢܐ ܟܘܫܝܐ + ܡܢܝ̈ܢܐ ܓܘܪܓܝܐ + ܡܢܝ̈ܢܐ ܕܝܘܢܝ̈ܐ + ܡܢܝ̈ܢܐ ܕܝܗܘܕܝ̈ܐ + ܡܢܝ̈ܢܐ ܕܝܦܢܝ̈ܐ + ܡܢܝ̈ܢܐ ܡܥܪܒܝܐ + ܡܢܝ̈ܢܐ ܕܡܘܢܓܘܠܢܝ̈ܐ + ܡܢܝ̈ܢܐ ܪܗܘܡܝܐ + + + ܛܟܣܐ ܡܝܬܪܝܐ + ܛܟܣܐ ܒܪܝܛܢܝܐ + ܛܟܣܐ ܐܡܝܪܟܐ + + + ܠܫܢܐ:‌ {0} + ܛܟܣܐ ܕܟܬܝܒܬܐ: {0} + ܩܠܝܡܐ: {0} + + + + + right-to-left + + + + [\u0740\u0743\u0744\u0747\u0748\u0749\u074A \u0741\u0745 \u0742\u0746 \u0711 \u0730 \u0731 \u0732 \u0733 \u0734 \u0735 \u0736 \u0737 \u0738 \u0739 \u073A \u073B \u073C \u073D \u073E \u073F ܃ ܄ ܅ ܆ ܇ ܈ ܉ ܁ ܂ ܀ ܊ ܋ ܌ ܍ ܐ ܒ ܓ ܔ ܖ ܕ ܗ ܘ ܙ ܚ ܛ ܜ ܝ ܞ ܟ ܠ ܡ ܢ ܣ ܤ ܥ ܦ ܧ ܨ ܩ ܪ ܫ ܬ] + [܏\u200C\u200D ܭ ܮ ܯ ݍ ݎ ݏ] + [ܐ ܒ ܓ ܖ ܕ ܗ ܘ ܙ ܚ ܛ ܝ ܟ ܠ ܡ ܢ ܣ ܥ ܦ ܨ ܩ ܪ ܫ ܬ] + [\u061C\u200E \- ‑ , ٫ ٬ . % ٪ ‰ ؉ + 0٠ 1١ 2٢ 3٣ 4٤ 5٥ 6٦ 7٧ 8٨ 9٩] + [\- ‐ ‑ – — ، ؛ \: ܃ ܄ ܅ ܆ ܇ ܈ ! ؟ ܉ . … ܁ ܂ ܀ ' ‘ ’ " “ ” « » ( ) \[ \] ܊ ܋ ܌ ܍] + ؟ + + [\:∶] + + + [\$﹩$$] + [£₤] + + + [\-‒⁻₋−➖﹣-] + + + + + + + + + + + + + + + EEEE، d MMMM y G + GyMMMMdd + + + + + d MMMM y G + GyMMMMdd + + + + + G y MMM d + GyMMdd + + + + + GGGGG y-MM-dd + GGGGGyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + {1} {0} + + + {1} {0} + + + + + {1} {0} + + + {1} {0} + + + + + {1} {0} + + + {1} {0} + + + + + {1} {0} + + + {1} {0} + + + + E، d + y G + d‏/M‏/y G + d MMM y G + E، d MMM y G + d/‏M + E، d/‏M + d MMM + E، d MMM + d MMMM + y G + y G + M‏/y G + d‏/M‏/y G + E، d/‏M/‏y G + MMM y G + d MMM y G + E، d MMM y G + MMMM y G + QQQ y G + QQQQ y G + + + + y G – y G + y–y G + + + MM-y GGGG – MM-y GGGG + MM-y – MM-y GGGG + MM-y – MM-y GGGG + + + dd-MM-y – dd-MM-y GGGG + dd-MM-y GGGG – dd-MM-y GGGG + dd-MM-y – dd-MM-y GGGG + dd-MM-y – dd-MM-y GGGG + + + E, dd-MM-y – E, dd-MM-y GGGG + E, dd-MM-y GGGG – E, dd-MM-y GGGG + E, dd-MM-y – E, dd-MM-y GGGG + E, dd-MM-y – E,dd-MM-y GGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + d–d MMM y G + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + M–M + + + d-M – d-M + d-M – d-M + + + E، d/‏M –‏ E، d/‏M + E، d/‏M – E، d/‏M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d – E، d MMM + E، d MMM – E، d MMM + + + y–y G + + + M‏/y – M‏/y G + M‏/y – M‏/y G + + + d‏/M‏/y – d‏/M‏/y G + d‏/M‏/y – d‏/M‏/y G + d‏/M‏/y – d‏/M‏/y G + + + E، dd‏/MM‏/y – E، dd‏/MM‏/y G + E، d‏/M‏/y – E، d‏/M‏/y G + E، d‏/M‏/y – E، d‏/M‏/y G + + + MMM – MMM y G + MMM، y – MMM y G + + + d–d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E، d – E، d MMM y G + E، d MMM – E، d MMM y G + E، d MMM y – E، d MMM y G + + + MMMM – MMMM y G + MMMM y – MMMM y G + + + + + + + + + ܟܢ܊ ܒ + ܫܒܛ + ܐܕܪ + ܢܝܣܢ + ܐܝܪ + ܚܙܝܪܢ + ܬܡܘܙ + ܐܒ + ܐܝܠܘܠ + ܬܫ܊ ܐ + ܬܫ܊ ܒ + ܟܢ܊ ܐ + + + ܐ + ܒ + ܓ + ܕ + ܗ + ܘ + ܙ + ܚ + ܛ + ܝ + ܝܐ + ܝܒ + + + ܟܢܘܢ ܐܚܪܝܐ + ܫܒܛ + ܐܕܪ + ܢܝܣܢ + ܐܝܪ + ܚܙܝܪܢ + ܬܡܘܙ + ܐܒ + ܐܝܠܘܠ + ܬܫܪܝܢ ܩܕܡܝܐ + ܬܫܪܝܢ ܐܚܪܝܐ + ܟܢܘܢ ܩܕܡܝܐ + + + + + ܟܢ܊ ܒ + ܫܒܛ + ܐܕܪ + ܢܝܣܢ + ܐܝܪ + ܚܙܝܪܢ + ܬܡܘܙ + ܐܒ + ܐܝܠܘܠ + ܬܫ܊ ܐ + ܬܫ܊ ܒ + ܟܢ܊ ܐ + + + ܐ + ܒ + ܓ + ܕ + ܗ + ܘ + ܙ + ܚ + ܛ + ܝ + ܝܐ + ܝܒ + + + ܟܢܘܢ ܐܚܪܝܐ + ܫܒܛ + ܐܕܪ + ܢܝܣܢ + ܐܝܪ + ܚܙܝܪܢ + ܬܡܘܙ + ܐܒ + ܐܝܠܘܠ + ܬܫܪܝܢ ܩܕܡܝܐ + ܬܫܪܝܼܢ ܐܚܪܝܐ + ܟܢܘܢ ܩܕܡܝܐ + + + + + + + ܚܕܒܫܒܐ + ܬܪܝܢܒܫܒܐ + ܬܠܬܒܫܒܐ + ܐܪܒܥܒܫܒܐ + ܚܡܫܒܫܒܐ + ܥܪܘܒܬܐ + ܫܒܬܐ + + + ܐ + ܒ + ܓ + ܕ + ܗ + ܥ + ܫ + + + ܚܕ + ܬܪܝܢ + ܬܠܬ + ܐܪܒܥ + ܚܡܫ + ܥܪܘ + ܫܒܬܐ + + + ܚܕܒܫܒܐ + ܬܪܝܢܒܫܒܐ + ܬܠܬܒܫܒܐ + ܐܪܒܥܒܫܒܐ + ܚܡܫܒܫܒܐ + ܥܪܘܒܬܐ + ܫܒܬܐ + + + + + ܚܕ + ܬܪܝܢ + ܬܠܬ + ܐܪܒܥ + ܚܡܫ + ܥܪܘ + ܫܒܬܐ + + + ܐ + ܒ + ܓ + ܕ + ܗ + ܥ + ܫ + + + ܚܕ + ܬܪܝܢ + ܬܠܬ + ܐܪܒܥ + ܚܡܫ + ܥܪܘ + ܫܒܬܐ + + + ܚܕܒܫܒܐ + ܬܪܝܢܒܫܒܐ + ܬܠܬܒܫܒܐ + ܐܪܒܥܒܫܒܐ + ܚܡܫܒܫܒܐ + ܥܪܘܒܬܐ + ܫܒܬܐ + + + + + + + ܪܘܒܥܐ ܐ + ܪܘܒܥܐ ܒ + ܪܘܒܥܐ ܓ + ܪܘܒܥܐ ܕ + + + ܐ + ܒ + ܓ + ܕ + + + ܪܘܒܥܐ ܩܕܡܝܐ + ܪܘܒܥܐ ܬܪܝܢܐ + ܪܘܒܥܐ ܬܠܝܬܝܐ + ܪܘܒܥܐ ܪܒܝܥܝܐ + + + + + ܪܘܒܥܐ ܐ + ܪܘܒܥܐ ܒ + ܪܘܒܥܐ ܓ + ܪܘܒܥܐ ܕ + + + ܐ + ܒ + ܓ + ܕ + + + ܪܘܒܥܐ ܩܕܡܝܐ + ܪܘܒܥܐ ܬܪܝܢܐ + ܪܘܒܥܐ ܬܠܝܬܝܐ + ܪܘܒܥܐ ܪܒܝܥܝܐ + + + + + + + ܩܛ + ܒܛ + + + ܩ + ܒ + + + ܩܛ + ܒܛ + + + + + ܩܛ + ܒܛ + + + ܩܛ + ܒܛ + + + ܩܛ + ܒܛ + + + + + + ܩܕܡ ܡܫܝܚܐ + ܩܕܡ ܕܪܐ ܚܕܬܐ + ܫܢܬܐ ܡܪܢܝܬܐ + ܕܪܐ ܚܕܬܐ + + + ܏ܩܡ + ܏ܩܕܚ + ܏ܫܡ + ܏ܕܚ + + + ܏ܩܡ + ܏ܩܕܚ + ܏ܫܡ + ܏ܕܚ + + + + + + EEEE، d MMMM y + yMMMMdd + + + + + y MMMM d + yMMMMdd + + + + + y MMM d + yMMdd + + + + + y-MM-dd + yMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + d + cccc + E، d + y G + MMM y G + d MMM y G + EEEE، d MMM y G + dd-MM + EEEE، dd-MM + d MMM + EEEE، d MMM + d MMMM + ܫܒܘܥܐ W ܒMMMM + ܫܒܘܥܐ W ܒMMMM + MM-y + d‏/M‏/y + E، d/‏M/‏y + MMM y + d MMM y + E، d MMM y + MMMM y + QQQ y + QQQQ y + ܫܒܘܥܐ w ܕܫܢܬܐ Y + ܫܒܘܥܐ w ܕܫܢܬܐ Y + + + + y G – y G + y – y G + + + MM-y GGGG – MM-y GGGG + MM-y – MM-y GGGG + MM-y – MM-y GGGG + + + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + M–M + + + d-M – d-M + M/d – M/d + + + E، d/‏M –‏ E، d/‏M + E، d/‏M – E، d/‏M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d – E، d MMM + E، d MMM – E، d MMM + + + M‏/y – M‏/y + + + d‏/M‏/y – d‏/M‏/y + d‏/M‏/y – d‏/M‏/y + d‏/M‏/y – d‏/M‏/y + + + E، dd‏/MM‏/y – E، dd‏/MM‏/y + E، d‏/M‏/y – E، d‏/M‏/y + E، d‏/M‏/y – E، d‏/M‏/y + + + MMM – MMM، y + MMM، y – MMM، y + + + d–d MMM، y + d MMM – d MMM، y + d MMM، y – d MMM، y + + + E، d – E، d MMM، y + E، d MMM – E، d MMM، y + E، d MMM، y – E، d MMM، y + + + MMMM–MMMM y + MMMM y – MMMM y + + + + + + + + ܕܪܐ + + + ܕܪܐ + + + ܕܪܐ + + + ܫܢܬܐ + ܐܫܬܩܕܝ + ܗܕܐ ܫܢܬܐ + ܫܢܬܐ ܐܚܪܬܐ + + ܒ{0} ܫܢܝ̈ܐ + ܒ{0} ܫܢܝ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + + + + ܫܢ܊ + ܐܫܬܩܕܝ + ܗܕܐ ܫܢܬܐ + ܫܢܬܐ ܐܚܪܬܐ + + ܒ{0} ܫܢܝ̈ܐ + ܒ{0} ܫܢܝ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + + + + ܫܢ܊ + ܐܫܬܩܕܝ + ܗܕܐ ܫܢܬܐ + ܫܢܬܐ ܐܚܪܬܐ + + ܒ{0} ܫܢܝ̈ܐ + ܒ{0} ܫܢܝ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + ܡ̣ܢ ܩܕܡ {0} ܫܢܝ̈ܐ + + + + ܪܘܒܥܐ ܕܫܢܬܐ + ܪܘܒܥܐ ܕܥܒܪ + ܗܢܐ ܪܘܒܥܐ + ܪܘܒܥܐ ܕܐܬܐ + + ܒ{0} ܪܘܒܥܐ + ܒ{0} ܪ̈ܘܒܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܘܒܥܐ + ܡ̣ܢ ܩܕܡ {0} ܪ̈ܘܒܥܐ + + + + ܪܘܒܥܐ ܕܫܢܬܐ + ܪܘܒܥܐ ܕܥܒܪ + ܗܢܐ ܪܘܒܥܐ + ܪܘܒܥܐ ܕܐܬܐ + + ܒ{0} ܪܘܒܥܐ + ܒ{0} ܪ̈ܘܒܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܘܒܥܐ + ܡ̣ܢ ܩܕܡ {0} ܪ̈ܘܒܥܐ + + + + ܪܘܒܥܐ ܕܫܢܬܐ + ܪܘܒܥܐ ܕܥܒܪ + ܗܢܐ ܪܘܒܥܐ + ܪܘܒܥܐ ܕܐܬܐ + + ܒ{0} ܪܘܒܥܐ + ܒ{0} ܪ̈ܘܒܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܘܒܥܐ + ܡ̣ܢ ܩܕܡ {0} ܪ̈ܘܒܥܐ + + + + ܝܪܚܐ + ܝܪܚܐ ܕܕܥܒܪ + ܗܢܐ ܝܪܚܐ + ܝܪܚܐ ܕܐܬܐ + + ܒ{0} ܝܪܚܐ + ܒ{0} ܝܪ̈ܚܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܪܚܐ + ܡ̣ܢ ܩܕܡ {0} ܝܪ̈ܚܐ + + + + ܝܪܚܐ + ܝܪܚܐ ܕܕܥܒܪ + ܗܢܐ ܝܪܚܐ + ܝܪܚܐ ܕܐܬܐ + + ܒ{0} ܝܪܚܐ + ܒ{0} ܝܪ̈ܚܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܪܚܐ + ܡ̣ܢ ܩܕܡ {0} ܝܖ̈ܚܐ + + + + ܝܪܚܐ + ܝܪܚܐ ܕܕܥܒܪ + ܗܢܐ ܝܪܚܐ + ܝܪܚܐ ܕܐܬܐ + + ܒ{0} ܝܪܚܐ + ܒ{0} ܝܪ̈ܚܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܪܚܐ + ܡ̣ܢ ܩܕܡ {0} ܝܖ̈ܚܐ + + + + ܫܒܘܥܐ + ܫܒܘܥܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܘܥܐ + ܫܒܘܥܐ ܕܐܬܐ + + ܒ{0} ܫܒܘܥܐ + ܒ{0} ܫܒ̈ܘܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܘܥܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܘܥܐ + + ܫܒܘܥܐ ܕ{0} + + + ܫܒ܊ + ܫܒܘܥܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܘܥܐ + ܫܒܘܥܐ ܕܐܬܐ + + ܒ{0} ܫܒܘܥܐ + ܒ{0} ܫܒ̈ܘܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܘܥܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܘܥܐ + + ܫܒܘܥܐ ܕ{0} + + + ܫܒ܊ + ܫܒܘܥܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܘܥܐ + ܫܒܘܥܐ ܕܐܬܐ + + ܒ{0} ܫܒܘܥܐ + ܒ{0} ܫܒ̈ܘܥܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܘܥܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܘܥܐ + + ܫܒܘܥܐ ܕ{0} + + + ܫܒܘܥܐ ܕܝܪܚܐ + + + ܫܒܘܥܐ ܕܝܪܚܐ + + + ܫܒܘܥܐ ܕܝܪܚܐ + + + ܝܘܡܐ + ܐܬܡܠܝ + ܐܕܝܘܡ + ܝܘܡܐ ܕܐܬܐ + + ܒ{0} ܝܘܡܐ + ܒ{0} ܝܘܡܢ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܐ + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܢ̈ܐ + + + + ܝܘܡܐ + ܐܬܡܠܝ + ܐܕܝܘܡ + ܝܘܡܐ ܕܐܬܐ + + ܒ{0} ܝܘܡܐ + ܒ{0} ܝܘܡܢ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܐ + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܢ̈ܐ + + + + ܝܘܡܐ + ܐܬܡܠܝ + ܐܕܝܘܡ + ܝܘܡܐ ܕܐܬܐ + + ܒ{0} ܝܘܡܐ + ܒ{0} ܝܘܡܢ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܐ + ܡ̣ܢ ܩܕܡ {0} ܝܘܡܢ̈ܐ + + + + ܝܘܡܐ ܕܫܢܬܐ + + + ܝܘܡܐ ܕܫܢܬܐ + + + ܝܘܡܐ ܕܫܢܬܐ + + + ܝܘܡܐ ܕܫܒܘܥܐ + + + ܝܘܡܐ ܕܫܒܘܥܐ + + + ܝܘܡܐ ܕܫܒܘܥܐ + + + ܝܘܡܐ ܦܘܠܚܢܐ ܕܫܒܘܥܐ + + + ܝܘܡܐ ܦܘܠܚܢܐ ܕܫܒܘܥܐ + + + ܝܘܡܐ ܦܘܠܚܢܐ ܕܫܒܘܥܐ + + + ܚܕܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܕܒܫܒܐ + ܚܕܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܕܒܫܒܐ + ܒ{0} ܚܕܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒ̈ܐ + + + + ܚܕܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܕܒܫܒܐ + ܚܕܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܕܒܫܒܐ + ܒ{0} ܚܕܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒ̈ܐ + + + + ܚܕܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܕܒܫܒܐ + ܚܕܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܕܒܫܒܐ + ܒ{0} ܚܕܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܕܒܫܒ̈ܐ + + + + ܬܪܝܢܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܪܝܢܒܫܒܐ + ܬܪܝܢܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܪܝܢܒܫܒܐ + ܒ{0} ܬܪܝܢܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒ̈ܐ + + + + ܬܪܝܢܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܪܝܢܒܫܒܐ + ܬܪܝܢܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܪܝܢܒܫܒܐ + ܒ{0} ܬܪܝܢܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒ̈ܐ + + + + ܬܪܝܢܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܪܝܢܒܫܒܐ + ܬܪܝܢܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܪܝܢܒܫܒܐ + ܒ{0} ܬܪܝܢܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܪܝܢܒܫܒ̈ܐ + + + + ܬܠܬܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܠܬܒܫܒܐ + ܬܠܬܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܠܬܒܫܒܐ + ܒ{0} ܬܠܬܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒ̈ܐ + + + + ܬܠܬܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܠܬܒܫܒܐ + ܬܠܬܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܠܬܒܫܒܐ + ܒ{0} ܬܠܬܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒ̈ܐ + + + + ܬܠܬܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܬܠܬܒܫܒܐ + ܬܠܬܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܬܠܬܒܫܒܐ + ܒ{0} ܬܠܬܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܬܠܬܒܫܒ̈ܐ + + + + ܐܪܒܥܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܐܪܒܥܒܫܒܐ + ܐܪܒܥܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܐܪܒܥܒܫܒܐ + ܒ{0} ܐܪܒܥܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒ̈ܐ + + + + ܐܪܒܥܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܐܪܒܥܒܫܒܐ + ܐܪܒܥܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܐܪܒܥܒܫܒܐ + ܒ{0} ܐܪܒܥܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒ̈ܐ + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒ̈ܐ + + + + ܐܪܒܥܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܐܪܒܥܒܫܒܐ + ܐܪܒܥܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܐܪܒܥܒܫܒܐ + ܒ{0} ܐܪܒܥܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒ̈ܐ + ܡ̣ܢ ܩܕܡ {0} ܐܪܒܥܒܫܒ̈ܐ + + + + ܚܡܫܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܡܫܒܫܒܐ + ܚܡܫܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܡܫܒܫܒܐ + ܒ{0} ܚܡܫܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒ̈ܐ + + + + ܚܡܫܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܡܫܒܫܒܐ + ܚܡܫܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܡܫܒܫܒܐ + ܒ{0} ܚܡܫܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒ̈ܐ + + + + ܚܡܫܒܫܒܐ ܕܕܥܒܪ + ܗܕܐ ܚܡܫܒܫܒܐ + ܚܡܫܒܫܒܐ ܕܐܬܐ + + ܒ{0} ܚܡܫܒܫܒܐ + ܒ{0} ܚܡܫܒܫܒ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒܐ + ܡ̣ܢ ܩܕܡ {0} ܚܡܫܒܫܒ̈ܐ + + + + ܥܪܘܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܥܪܘܒܬܐ + ܥܪܘܒܬܐ ܕܐܬܐ + + ܒ{0} ܥܪܘܒܬܐ + ܒ{0} ܥܪ̈ܘܒܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܥܪܘܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܥܪ̈ܘܒܬܐ + + + + ܥܪܘܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܥܪܘܒܬܐ + ܥܪܘܒܬܐ ܕܐܬܐ + + ܒ{0} ܥܪܘܒܬܐ + ܒ{0} ܥܪ̈ܘܒܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܥܪܘܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܥܪ̈ܘܒܬܐ + + + + ܥܪܘܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܥܪܘܒܬܐ + ܥܪܘܒܬܐ ܕܐܬܐ + + ܒ{0} ܥܪܘܒܬܐ + ܒ{0} ܥܪ̈ܘܒܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܥܪܘܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܥܪ̈ܘܒܬܐ + + + + ܫܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܬܐ + ܫܒܬܐ ܕܐܬܐ + + ܒ{0} ܫܒܬܐ + ܒ{0} ܫܒ̈ܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܬܐ + + + + ܫܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܬܐ + ܫܒܬܐ ܕܐܬܐ + + ܒ{0} ܫܒܬܐ + ܒ{0} ܫܒ̈ܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܬܐ + + + + ܫܒܬܐ ܕܕܥܒܪ + ܗܕܐ ܫܒܬܐ + ܫܒܬܐ ܕܐܬܐ + + ܒ{0} ܫܒܬܐ + ܒ{0} ܫܒ̈ܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܒܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܒ̈ܬܐ + + + + ܩܛ/ܒܛ + + + ܩܛ/ܒܛ + + + ܩܛ/ܒܛ + + + ܫܥܬܐ + ܗܕܐ ܫܥܬܐ + + ܒ{0} ܫܥܬܐ + ܒ{0} ܫܥ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܥܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܥ̈ܐ + + + + ܫܥ܊ + ܗܕܐ ܫܥܬܐ + + ܒ{0} ܫܥܬܐ + ܒ{0} ܫܥ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܥܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܥ̈ܐ + + + + ܫܥ܊ + ܗܕܐ ܫܥܬܐ + + ܒ{0} ܫܥܬܐ + ܒ{0} ܫܥ̈ܐ + + + ܡ̣ܢ ܩܕܡ {0} ܫܥܬܐ + ܡ̣ܢ ܩܕܡ {0} ܫܥ̈ܐ + + + + ܩܛܝܢܬܐ + ܗܢܐ ܩܛܝܢܐ + + ܒ{0} ܩܛܝܢܬܐ + ܒ{0} ܩܛܝ̈ܢܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܩܛܝܢܐ + ܡ̣ܢ ܩܕܡ {0} ܩܛܝ̈ܢܐ + + + + ܩܛܝܢܬܐ + ܗܢܐ ܩܛܝܢܐ + + ܒ{0} ܩܛܝܢܬܐ + ܒ{0} ܩܛܝ̈ܢܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܩܛܝܢܐ + ܡ̣ܢ ܩܕܡ {0} ܩܛܝ̈ܢܐ + + + + ܩܛܝܢܬܐ + ܗܢܐ ܩܛܝܢܐ + + ܒ{0} ܩܛܝܢܬܐ + ܒ{0} ܩܛܝ̈ܢܬܐ + + + ܡ̣ܢ ܩܕܡ {0} ܩܛܝܢܐ + ܡ̣ܢ ܩܕܡ {0} ܩܛܝ̈ܢܐ + + + + ܪܦܦܐ + ܗܫܐ + + ܒ{0} ܪܦܦܐ + ܒ{0} ܪ̈ܦܦܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܦܦܐ + ܡ̣ܢ ܩܕܡ {0} ܖ̈ܦܦܐ + + + + ܪܦܦܐ + ܗܫܐ + + ܒ{0} ܪܦܦܐ + ܒ{0} ܪ̈ܦܦܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܦܦܐ + ܡ̣ܢ ܩܕܡ {0} ܖ̈ܦܦܐ + + + + ܪܦܦܐ + ܗܫܐ + + ܒ{0} ܪܦܦܐ + ܒ{0} ܪ̈ܦܦܐ + + + ܡ̣ܢ ܩܕܡ {0} ܪܦܦܐ + ܡ̣ܢ ܩܕܡ {0} ܖ̈ܦܦܐ + + + + ܦܢܝܬܐ ܕܙܒܢܐ + + + ܦܢܝܬܐ ܕܙܒܢܐ + + + ܦܢܝܬܐ ܕܙܒܢܐ + + + + ܥܕܢܐ ܓܪܝܢܟ {0} + ܥܕܢܐ ܕܓܪܝܢܟ + ܥܕܢܐ {0} + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ {0} + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ {0} + + ܡܕܝܢܬܐ ܠܐ ܝܕܥܝܬܐ + + + ܐܢܕܘܪܐ + + + ܕܘܒܐܝ + + + ܟܐܒܘܠ + + + ܐܢܬܝܓܘܐ + + + ܐܢܓܘܝܐ + + + ܬܝܪܐܢ + + + ܝܪܒܐܢ + + + ܠܘܐܢܕܐ + + + ܪܘܬܝܪܐ + + + ܦܐܠܡܝܪ + + + ܬܪܘܠ + + + ܣܝܘܐ + + + ܡܐܘܣܘܢ + + + ܕܒܝܣ + + + ܒܘܣܬܘܟ + + + ܟܐܝܣܝ + + + ܕܘܡܘܢܬ ܕܐܘܪܒܝܠ + + + ܡܟܡܘܪܕܘ + + + ܪܝܘ ܓܝܓܘܣ + + + ܡܢܕܘܙܐ + + + ܣܐܢ ܘܐܢ + + + ܐܘܫܘܐܝܐ + + + ܠܐ ܪܝܘܗܐ + + + ܣܐܢ ܠܘܝܣ + + + ܟܐܬܐܡܪܟܐ + + + ܣܠܬܐ + + + ܓܘܓܘܝ + + + ܬܘܟܘܡܐܢ + + + ܟܘܪܕܘܒܐ + + + ܒܘܐܝܢܘܣ ܥܝܪܣ + + + ܦܐܓܘ ܦܐܓܘ + + + ܒܝܝܢܐ + + + ܦܝܪܬ + + + ܐܘܟܠܐ + + + ܕܪܘܝܢ + + + ܐܕܝܠܝܕ + + + ܒܪܘܟܝܢ ܗܝܠ + + + ܡܝܠܒܘܪܢ + + + ܗܘܒܪܬ + + + ܠܝܢܕܡܐܢ + + + ܣܝܕܢܝ + + + ܒܪܝܣܒܐܢ + + + ܡܐܟܐܘܪܝ + + + ܠܘܪܕ ܗܐܘ + + + ܐܪܘܒܐ + + + ܡܐܪܝܗܐܡ + + + ܒܐܟܘ + + + ܣܪܐܝܝܒܘ + + + ܒܐܪܒܕܘܣ + + + ܕܟܐ + + + ܒܪܘܟܣܠ + + + ܐܘܐܓܐܕܐܘܓܐܘ + + + ܣܘܦܝܐ + + + ܒܚܪܝܢ + + + ܒܘܓܘܡܒܘܪܐ + + + ܦܘܪܬܘ-ܢܘܒܘ + + + ܡܪ ܒܪ ܬܘܠܡܝ + + + ܒܝܪܡܝܘܕܐ + + + ܒܪܘܢܐܝ + + + ܠܐ ܦܐܙ + + + ܟܪܠܝܢܓܩ + + + ܐܝܪܘܢܝܦܝ + + + ܪܝܘ ܒܪܢܟܘ + + + ܦܘܪܬܘ ܒܝܠܗܘ + + + ܒܘܥ ܒܝܣܬܐ + + + ܡܐܢܐܘܣ + + + ܟܘܝܐܒܐ + + + ܣܐܢܬܐܪܡ + + + ܟܐܡܦܘ ܓܪܢܕܝ + + + ܒܝܠܝܡ + + + ܐܪܐܓܐܘܝܢܐ + + + ܣܐܘ ܦܐܘܠܘ + + + ܒܐܗܝܐ + + + ܦܘܪܬܐܠܝܙܐ + + + ܡܐܣܝܐܘ + + + ܪܝܣܝܦܝ + + + ܢܘܪܘܢܗܐ + + + ܢܐܣܐܘ + + + ܬܝܡܦܘ + + + ܓܒܘܪܘܢ + + + ܡܝܢܣܟ + + + ܒܝܠܝܙ + + + ܕܐܣܘܢ + + + ܣܘܣܬܐ ܚܘܪܬܐ + + + ܐܢܘܒܝܟ + + + ܒܢܟܘܒܝܪ + + + ܦܘܪܬ ܢܝܠܣܘܢ + + + ܕܐܣܘܢ ܟܪܝܟ + + + ܟܪܝܣܬܘܢ + + + ܝܠܘܢܝܦ + + + ܐܕܡܘܢܬܘܢ + + + ܢܕܘܪܬܐ + + + ܟܡܒܪܓ ܒܐܝ + + + ܪܝܓܝܢܐ + + + ܘܝܢܝܦܓ + + + ܪܝܣܘܠܘܬ + + + ܢܗܪܐ ܕܪܥܢܝ + + + ܪܐܢܟܢ ܐܢܠܝܬ + + + ܐܬܝܟܘܟܐܢ + + + ܬܐܢܕܐܪ ܒܐܝ + + + ܢܝܦܝܓܘܢ + + + ܬܘܪܘܢܬܘ + + + ܐܝܩܠܘܝܬ + + + ܦܐܢܓܢܝܪܬܘܢܓ + + + ܡܘܢܟܬܘܢ + + + ܗܠܝܦܐܟܣ + + + ܓܘܣ ܒܐܝ + + + ܓܠܝܣ ܒܐܝ + + + ܒܠܐܢܟ-ܣܐܒܠܘܢ + + + ܡܪ ܝܘܚܢܢ + + + ܟܘܟܘܣ + + + ܟܝܢܫܐܣܐ + + + ܠܘܒܘܡܒܫܝ + + + ܒܐܢܓܐܘܝ + + + ܒܪܐܙܐܒܝܠ + + + ܙܝܘܪܚ + + + ܐܒܕܓܢ + + + ܪܐܪܘܬܘܢܓܐ + + + ܦܨܚܐ + + + ܦܘܢܬܐ ܥܪܝܢܣ + + + ܣܐܢܬܝܐܓܘ + + + ܕܘܐܠܐ + + + ܐܘܪܘܡܟܝ + + + ܫܢܓܗܐܝܝ + + + ܒܘܓܘܬܐ + + + ܟܘܣܬܐ ܪܝܟܐ + + + ܗܐܒܐܢܐ + + + ܟܐܦ ܒܝܪܕܝ + + + ܟܘܪܐܟܐܘ + + + ܟܪܝܣܬܡܣ + + + ܢܝܩܘܣܝܐ + + + ܦܐܡܐܓܘܣܬܐ + + + ܦܪܐܓ + + + ܒܘܣܝܢܓܢ + + + ܒܪܠܝܢ + + + ܓܝܒܘܬܝ + + + ܟܘܦܢܗܐܓܢ + + + ܕܘܡܝܢܝܟܐ + + + ܣܢܬܘ ܕܘܡܝܢܓܘ + + + ܓܙܐܐܪ + + + ܓܐܠܐܦܓܘܣ + + + ܓܘܐܝܐܩܘܝܠ + + + ܬܐܠܝܢ + + + ܩܐܗܖ̈ܗ + + + ܐܠ ܥܝܘܢ + + + ܐܣܡܐܪܐ + + + ܟܐܢܪܝ + + + ܣܒܬܐ + + + ܡܕܪܝܕ + + + ܐܕܝܣ ܐܒܒܐ + + + ܗܠܣܢܟܝ + + + ܦܝܓܝ + + + ܣܬܐܢܠܝ + + + ܬܫܘܟ + + + ܦܘܗܢܦܐܝ + + + ܟܘܣܪܐܝ + + + ܦܐܪܘ + + + ܦܐܪܝܣ + + + ܠܝܒܪܝܒܝܠ + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܪܝܛܢܝܐ + + ܠܘܢܕܘܢ + + + ܓܪܝܢܕܐ + + + ܬܦܠܝܣ + + + ܟܐܝܐܢ + + + ܓܘܪܢܙܝ + + + ܐܟܪܐ + + + ܓܒܪܠܛܪ + + + ܬܘܠ + + + ܢܘܟ + + + ܐܝܛܘܩܘܪܡܝܬ + + + ܕܐܢܡܪܟܫܒܝܢ + + + ܒܐܢܓܘܠ + + + ܟܘܢܐܟܪܝ + + + ܓܘܐܕܐܠܘܦܝ + + + ܡܐܠܐܒܘ + + + ܐܬܢܘܣ + + + ܬܡܝܢ ܓܘܪܓܝܐ + + + ܓܘܐܬܡܐܠܐ + + + ܓܘܐܡ + + + ܒܝܣܐܘ + + + ܓܘܝܐܢܐ + + + ܗܘܢܓ ܟܘܢܓ + + + ܬܝܓܘܣܝܓܐܠܦܐ + + + ܙܐܓܪܒ + + + ܦܘܪܬ ܐܘ ܦܪܝܢܣ + + + ܒܘܕܦܫܛ + + + ܓܐܟܐܪܬܐ + + + ܦܘܢܬܝܐܢܐܟ + + + ܡܐܟܐܣܐܪ + + + ܓܐܝܦܘܪܐ + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܝܪܠܢܕ + + ܕܒܠܢ + + + ܐܘܪܫܠܡ + + + ܓܙܪܬܐ ܕܡܐܢ + + + ܟܘܠܟܬܐ + + + ܬܫܓܘܣ + + + ܒܓܕܕ + + + ܬܗܪܢ + + + ܪܐܝܟܒܝܟ + + + ܪܘܡܝ + + + ܓܝܪܙܝ + + + ܓܡܐܝܟܐ + + + ܥܡܐܢ + + + ܛܘܟܝܘ + + + ܢܝܪܘܒܝ + + + ܒܝܫܟܝܟ + + + ܦܢܘܡ ܦܢ + + + ܟܐܢܬܘܢ + + + ܟܝܪܝܡܐܬܝ + + + ܬܐܪܐܘܐ + + + ܟܘܡܘܪܘ + + + ܣܐܢܬ ܟܬܣ + + + ܦܝܘܢܓܝܢܓ + + + ܣܐܘܠ + + + ܟܘܝܬ + + + ܟܐܝܡܝܢ + + + ܐܟܬܐܘ + + + ܐܘܪܐܠ + + + ܐܬܝܪܘ + + + ܐܟܬܘܒ + + + ܟܘܣܬܐܢܐܝ + + + ܟܝܙܝܠܘܪܕܐ + + + ܐܠܡܐܬܝ + + + ܒܝܐܢܬܝܐܢ + + + ܒܝܪܘܬ + + + ܡܪܬܝ ܠܘܫܐ + + + ܒܕܘܙ + + + ܟܘܠܘܡܒܘ + + + ܡܘܢܪܘܒܝܐ + + + ܡܐܣܝܪܘ + + + ܒܠܢܘܣ + + + ܠܘܟܣܡܒܘܪܓ + + + ܪܝܓܐ + + + ܛܪܝܦܘܠܝܣ + + + ܟܐܣܐܒܠܢܟܐ + + + ܡܘܢܐܟܘ + + + ܟܝܣܝܢܐܘ + + + ܦܘܕܓܘܪܝܟܐ + + + ܡܪܝܓܘܬ + + + ܐܢܬܐܢܐܢܪܝܒܘ + + + ܟܘܐܓܐܠܝܢ + + + ܡܐܓܘܪܘ + + + ܣܩܘܦܝܐ + + + ܒܐܡܐܟܘ + + + ܝܢܓܘܢ + + + ܗܘܒܕ + + + ܐܘܠܐܢܒܐܬܘܪ + + + ܟܘܝܒܠܣܢ + + + ܡܐܟܐܘ + + + ܣܐܝܦܐܢ + + + ܡܐܪܬܝܢܝܩ + + + ܢܘܐܟܫܘܬ + + + ܡܘܢܬܣܝܪܐܬ + + + ܡܝܠܛܐ + + + ܡܘܪܝܫܘܣ + + + ܓܙܪܬܐ ܡܐܠܕܝܒܝܬܐ + + + ܒܠܢܬܝܪ + + + ܬܝܐܘܐܢܐ + + + ܗܝܪܡܘܣܝܐ + + + ܡܙܛܠܐܢ + + + ܟܝܘܐܘܐ + + + ܒܐܗܝܐ ܒܐܢܝܪܣ + + + ܘܓܝܢܐܓܐ + + + ܡܘܢܛܪܐܝ + + + ܡܕܝܢܬܐ ܕܡܟܣܝܟܘ + + + ܡܐܬܐܡܘܪܘܣ + + + ܡܪܝܕܐ + + + ܟܐܢܟܘܢ + + + ܟܘܐܠܐ ܠܘܡܦܘܪ + + + ܟܘܫܝܢܓ + + + ܡܐܦܘܬܘ + + + ܘܝܢܕܗܘܟ + + + ܢܘܡܝܐ + + + ܢܝܐܡܝ + + + ܢܘܪܦܠܟ + + + ܠܐܓܘܣ + + + ܡܐܢܐܓܘܐ + + + ܐܡܣܬܪܕܡ + + + ܐܘܣܠܘ + + + ܟܐܬܡܐܢܕܘ + + + ܢܐܘܪܘ + + + ܢܝܘܝ + + + ܬܫܐܬܡ + + + ܐܟܠܐܢܕ + + + ܡܣܩܛ + + + ܦܢܡܐ + + + ܠܝܡܐ + + + ܬܐܗܝܬܝ + + + ܡܐܪܟܐܘܣܐܣ + + + ܓܡܒܝܪ + + + ܦܘܪܬ ܡܘܪܝܣܒܐܝ + + + ܒܘܓܐܝܢܒܝܠ + + + ܡܐܢܝܠܐ + + + ܟܪܐܟܝ + + + ܘܐܪܣܘ + + + ܡܩܘܠܘܢ + + + ܦܝܬܟܐܝܪܢ + + + ܦܘܪܬܘ ܪܝܟܘ + + + ܥܙܐ + + + ܚܒܪܘܢ + + + ܓܙܪܬܐ ܕܐܙܘܪ + + + ܡܕܐܝܪܐ + + + ܠܫܒܘܢܐ + + + ܦܠܐܘ + + + ܐܣܘܢܟܣܝܘܢ + + + ܩܛܪ + + + ܪܝܘܢܝܘܢ + + + ܒܘܩܘܪܫܛ + + + ܒܠܓܪܕ + + + ܟܐܠܝܢܝܢܓܪܐܕ + + + ܡܘܣܟܘ + + + ܒܘܠܓܘܓܪܐܕ + + + ܣܪܐܬܘܒ + + + ܐܣܬܪܐܚܢ + + + ܐܘܠܝܢܘܒܣܟ + + + ܟܝܪܘܒ + + + ܣܡܐܪܐ + + + ܝܟܐܬܝܪܢܒܝܪܓ + + + ܐܘܡܣܟ + + + ܢܘܒܘܣܝܒܪܣܟ + + + ܒܐܪܢܐܘܠ + + + ܬܘܡܣܟ + + + ܢܘܒܘܟܘܙܢܝܬܣܟ + + + ܟܪܐܣܢܘܝܪܣܟ + + + ܐܝܪܟܘܬܣܟ + + + ܬܫܝܬܐ + + + ܝܐܟܘܬܣܟ + + + ܒܠܐܕܝܒܘܣܬܘܟ + + + ܚܐܢܕܝܓܐ + + + ܣܐܚܐܠܝܢ + + + ܐܘܣܬ-ܢܝܪܐ + + + ܡܐܓܐܕܐܢ + + + ܣܪܝܕܢܝܟܘܠܝܡܣܟ + + + ܟܐܡܬܫܐܬܟܐ + + + ܐܢܐܕܝܪ + + + ܟܝܓܐܠܝ + + + ܪܝܐܕ + + + ܓܘܐܕܐܠܟܐܢܐܠ + + + ܡܐܗܝ + + + ܚܪܛܘܡ + + + ܣܬܘܟܗܘܠܡ + + + ܣܝܢܓܐܦܘܪ + + + ܡܪܬܝ ܗܝܠܝܢܐ + + + ܠܝܘܒܠܝܐܢܐ + + + ܠܘܢܓܝܥܪܒܝܝܢ + + + ܒܪܬܝܣܠܒܐ‏ + + + ܦܪܝܬܐܘܢ + + + ܣܢ ܡܪܝܢܘ + + + ܕܐܟܐܪ + + + ܡܘܩܕܝܫܘ + + + ܦܐܪܐܡܐܪܝܒܘ + + + ܓܘܒܐ + + + ܣܐܘ ܬܘܡܝ + + + ܐܠ ܣܠܒܐܕܘܪ + + + ܪܘܒ݂ܥܐ ܕܫܠܝܛܐ ܬܚܬܝܐ + + + ܕܪܡܣܘܩ + + + ܡܒܐܒܐܢܝ + + + ܓܪܐܢܕ ܬܘܪܟ + + + ܢܓܡܝܢܐ + + + ܟܝܪܓܘܠܝܢ + + + ܠܘܡܝ + + + ܒܐܢܟܘܟ + + + ܕܘܫܐܢܒܝ + + + ܦܐܟܐܘܦܘ + + + ܕܝܠܝ + + + ܥܫܩܐܒܐܕ + + + ܬܘܢܣ + + + ܬܘܢܓܐܬܐܦܘ + + + ܐܣܛܢܒܘܠ + + + ܦܘܪܬ ܕܐܣܦܢܝܐ + + + ܦܘܢܐܦܘܬܝ + + + ܬܐܝܦܐܝ + + + ܕܐܪ ܫܠܡܐ + + + ܐܘܙܓܘܪܘܕ + + + ܟܝܝܒ + + + ܣܡܦܪܘܦܠ + + + ܙܐܦܘܪܝܓܝ + + + ܟܐܡܦܐܠܐ + + + ܡܝܕܘܐܝ + + + ܘܐܝܟ + + + ܐܕܐܟ + + + ܢܘܡ + + + ܓܘܢܣܬܘܢ + + + ܐܢܟܘܪܓ + + + ܝܩܘܬܐܬ + + + ܣܝܛܟܐ + + + ܓܘܢܘ + + + ܡܛܠܟܐܬܠܐ + + + ܠܘܣ ܐܢܓܠܘܣ + + + ܒܘܝܙܝ + + + ܦܝܢܝܟܣ + + + ܕܢܒܪ + + + ܒܝܘܠܐ، ܕܐܟܘܬܐ ܓܪܒܝܝܬܐ + + + ܢܝܘ ܣܐܠܝܡ،‌ ܕܐܟܘܬܐ ܓܪܒܝܝܬܐ + + + ܣܝܢܬܪ، ܕܐܟܘܬܐ ܓܪܒܝܝܬܐ + + + ܫܟܓܘ + + + ܡܢܘܡܝܢܝ + + + ܒܝܢܣܝܢܝܣ، ܐܢܕܝܐܢܐ + + + ܦܝܬܝܪܣܒܝܪܓ، ܐܢܕܝܐܢܐ + + + ܡܢܕܝܬܐ ܕܬܝܠ، ܐܢܕܝܐܢܐ + + + ܢܘܟܣ، ܐܢܕܝܐܢܐ + + + ܘܝܢܐܡܐܟ، ܐܢܕܝܐܢܐ + + + ܡܪܝܢܓܘ، ܐܢܕܝܐܢܐ + + + ܐܢܕܝܐܢܐܦܘܠܝܣ + + + ܠܘܝܣܒܝܠ + + + ܒܝܒܐܝ، ܐܢܕܝܐܢܐ + + + ܡܘܢܬܐܟܝܠܘ، ܟܝܢܬܐܟܝ + + + ܕܝܬܪܘܝܬ + + + ܢܝܘ ܝܘܪܟ + + + ܡܘܢܬܝܒܝܕܝܘ + + + ܣܡܪܟܢܕ + + + ܬܫܟܝܢܬ + + + ܘܐܬܝܩܐܢ + + + ܡܪ ܒܢܣܢܬ + + + ܟܐܪܐܟܣ + + + ܬܘܪܬܘܠܐ + + + ܡܪ ܬܐܘܡܐ + + + ܡܕܝܢܬܐ ܕܗܘ ܟܝ ܡܝܢ + + + ܝܦܐܬ + + + ܘܝܠܝܣ + + + ܐܦܝܐ + + + ܥܕܢ + + + ܡܐܝܘܬ + + + ܝܘܗܢܝܣܒܘܪܓ + + + ܠܘܣܐܟܐ + + + ܗܪܐܪܝ + + + + ܥܕܢܘܬܐ ܕܐܝܟܝܪ + ܥܕܢܘܬܐ ܫܪܫܝܬܐ ܥܕܢܘܬܐ ܫܪܫܝܬܐ ܕܐܝܟܝܪ + ܥܕܢܘܬܐ ܩܝܬܝܬܐ ܕܐܝܟܝܪ + + + + + ܥܕܢܐ ܕܐܦܓܐܢܣܬܐܢ + + + + + ܥܕܢܐ ܕܡܨܥܝܬܐ ܐܦܪܝܩܐ + + + + + ܥܕܢܐ ܕܡܕܢܚ ܐܦܪܝܩܐ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܝܡܢ ܐܦܪܝܩܐ + + + + + ܥܕܢܐ ܕܡܥܪܒ ܐܦܪܝܩܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܥܪܒ ܐܦܪܝܩܐ + ܥܕܢܐ ܩܝܬܝܬܐ ܕܡܥܪܒ ܐܦܪܝܩܐ + + + + + ܥܕܢܐ ܕܐܠܐܣܟܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܠܐܣܟܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܠܐܣܟܐ + + + + + ܥܕܢܐ ܕܐܠܡܐܬܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܠܡܐܬܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܠܡܐܬܝ + + + + + ܥܕܢܐ ܕܐܡܙܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܡܙܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܡܙܢ + + + + + ܥܕܢܐ ܡܨܥܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܡܨܥܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܡܨܥܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܡܕܢܚܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܡܕܢܚܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܡܕܢܚܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܛܘܪܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܛܘܪܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܛܘܪܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܫܝܢܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܫܝܢܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܫܝܢܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܕܐܢܐܕܝܪ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܢܐܕܝܪ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܢܐܕܝܪ + + + + + ܥܕܢܐ ܕܐܦܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܦܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܦܝܐ + + + + + ܥܕܢܐ ܐܟܬܐܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܟܬܐܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܟܬܐܘ + + + + + ܥܕܢܐ ܕܐܟܬܘܒ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܟܬܘܒ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܟܬܘܒ + + + + + ܥܕܢܐ ܕܐܪܒܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܪܒܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܪܒܝܐ + + + + + ܥܕܢܐ ܕܐܪܓܢܬܝܢܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܪܓܢܬܝܢܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܪܓܢܬܝܢܐ + + + + + ܥܕܢܐ ܕܐܪܓܢܬܝܢܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܪܓܢܬܝܢܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܪܓܢܬܝܢܐ ܡܥܪܒܝܬܐ + + + + + ܥܕܢܐ ܕܐܪܡܢܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܪܡܢܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܪܡܢܝܐ + + + + + ܥܕܢܐ ܐܛܠܢܛܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܐܛܠܢܛܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܐܛܠܢܛܝܬܐ ܕܐܡܪܝܟܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܕܐܘܣܬܪܠܝܐ ܡܨܥܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܣܬܪܠܝܐ ܡܨܥܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܣܬܪܠܝܐ ܡܨܥܝܬܐ + + + + + ܥܕܢܐ ܡܥܪܒܝܬܐ ܡܨܥܝܬܐ ܕܐܘܣܬܪܠܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܡܥܪܒܝܬܐ ܡܨܥܝܬܐ ܕܐܘܣܬܪܠܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܡܥܪܒܝܬܐ ܡܨܥܝܬܐ ܕܐܘܣܬܪܠܝܐ + + + + + ܥܕܢܐ ܕܐܘܣܬܪܠܝܐ ܡܕܢܚܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܣܬܪܠܝܐ ܡܕܢܚܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܣܬܪܠܝܐ ܡܕܢܚܝܬܐ + + + + + ܥܕܢܐ ܕܐܘܣܬܪܠܝܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܣܬܪܠܝܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܣܬܪܠܝܐ ܡܥܪܒܝܬܐ + + + + + ܥܕܢܐ ܕܐܙܪܒܝܓܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܙܪܒܝܓܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܙܪܒܝܓܐܢ + + + + + ܥܕܢܐ ܕܐܙܘܪ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܙܘܪ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܙܘܪ + + + + + ܥܕܢܐ ܕܒܢܓܠܐܕܝܫ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܢܓܠܐܕܝܫ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܒܢܓܠܐܕܝܫ + + + + + ܥܕܢܐ ܕܒܘܬܐܢ + + + + + ܥܕܢܐ ܕܒܘܠܝܒܝܐ + + + + + ܥܕܢܐ ܕܒܪܐܣܝܠܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܪܐܣܝܠܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܒܪܐܣܝܠܝܐ + + + + + ܥܕܢܐ ܕܒܪܘܢܐܝ ܕܐܪܘܣܐܠܡ + + + + + ܥܕܢܐ ܕܟܐܦ ܒܝܪܕܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܐܦ ܒܝܪܕܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܐܦ ܒܝܪܕܝ + + + + + ܥܕܢܐ ܕܟܐܝܣܝ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܫܐܡܘܪܘ + + + + + ܥܕܢܐ ܕܬܫܐܬܡ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܫܐܬܡ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܬܫܐܬܡ + + + + + ܥܕܢܐ ܕܬܫܝܠܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܫܝܠܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܬܫܝܠܝ + + + + + ܥܕܢܐ ܕܨܝܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܨܝܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܨܝܢ + + + + + ܥܕܢܐ ܕܟܘܝܒܠܣܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܘܝܒܠܣܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܘܝܒܠܣܢ + + + + + ܥܕܢܐ ܕܓܙܪܬܐ ܕܟܪܝܣܬܡܣ + + + + + ܥܕܢܐ ܕܓܙܝܖ̈ܐ ܕܟܘܟܘܣ + + + + + ܥܕܢܐ ܕܟܘܠܘܡܒܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܘܠܘܡܒܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܘܠܘܡܒܝܐ + + + + + ܥܕܢܐ ܓܙܝܪ̈ܐ ܕܟܘܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܓܙܝܪ̈ܐ ܕܟܘܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܓܙܝܪ̈ܐ ܕܟܘܟ + + + + + ܥܕܢܐ ܕܟܘܒܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܘܒܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܘܒܐ + + + + + ܥܕܢܐ ܕܕܒܝܣ + + + + + ܥܕܢܐ ܕܕܘܡܘܢܬ ܕܐܘܪܒܝܠ + + + + + ܥܕܢܐ ܕܡܕܢܚ ܬܝܡܘܪ + + + + + ܥܕܢܐ ܕܓܙܪܬܐ ܦܨܚܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܙܪܬܐ ܦܨܚܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܙܪܬܐ ܦܨܚܐ + + + + + ܥܕܢܐ ܕܐܩܘܐܕܘܪ + + + + + ܥܕܢܐ ܕܐܘܪܘܦܐ ܡܨܥܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܪܘܦܐ ܡܨܥܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܪܘܦܐ ܡܨܥܝܬܐ + + + + + ܥܕܢܐ ܕܐܘܪܘܦܐ ܡܕܢܚܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܪܘܦܐ ܡܕܢܚܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܪܘܦܐ ܡܕܢܚܝܬܐ + + + + + ܥܕܢܐ ܕܐܘܪܘܦܐ (ܗܡ ܡܕܢܚܐ) + + + + + ܥܕܢܐ ܕܐܘܪܘܦܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܪܘܦܐ ܡܥܪܒܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܪܘܦܐ ܡܥܪܒܝܬܐ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܦܠܟܠܢܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܙܝܪ̈ܐ ܕܦܠܟܠܢܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܙܝܪ̈ܐ ܕܦܠܟܠܢܕ + + + + + ܥܕܢܐ ܕܦܝܓܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܝܓܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܝܓܝ + + + + + ܥܕܢܐ ܕܓܘܝܐܢܐ ܦܪܢܣܝܬܐ + + + + + ܥܕܢܐ ܕܦܪܢܣܐ ܬܝܡܢܝܬܐ ܘܐܢܬܪܬܝܟܐ + + + + + ܥܕܢܐ ܕܓܐܠܦܐܓܘܣ + + + + + ܥܕܢܐ ܕܓܡܒܝܪ + + + + + ܥܕܢܐ ܕܓܘܪܓܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܘܪܓܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܘܪܓܝܐ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܓܝܠܒܪܬ + + + + + ܥܕܢܐ ܕܓܪܝܢܟ + + + + + ܥܕܢܐ ܕܡܕܢܚ ܓܪܝܢܠܢܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܕܢܚ ܓܪܝܢܠܢܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܕܢܚ ܓܪܝܢܠܢܕ + + + + + ܥܕܢܐ ܕܓܪܝܢܠܢܕ ܕܡܥܪܒܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܪܝܢܠܢܕ ܕܡܥܪܒܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܪܝܢܠܢܕ ܕܡܥܪܒܝܬܐ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܘܐܡ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܥܠܢܐ + + + + + ܥܕܢܐ ܕܓܘܝܐܢܐ + + + + + ܥܕܢܐ ܕܗܐܘܐܝܝ ܐܠܘܫܝܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܗܐܘܐܝܝ ܐܠܘܫܝܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܗܐܘܐܝܝ ܐܠܘܫܝܢ + + + + + ܥܕܢܐ ܕܗܘܢܓ ܟܘܢܓ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܗܘܢܓ ܟܘܢܓ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܗܘܢܓ ܟܘܢܓ + + + + + ܕܗܘܒܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܗܘܒܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܗܘܒܕ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܗܢܕܘ + + + + + ܥܕܢܐ ܕܐܘܩܝܢܘܣ ܗܢܕܘܝܐ + + + + + ܥܕܢܐ ܕܗܢܕܘܨܝܢ + + + + + ܥܕܢܐ ܕܗܢܕܘܨܝܢ ܡܨܥܝܬܐ + + + + + ܥܕܢܐ ܕܗܢܕܘܨܝܢ ܡܕܢܚܝܬܐ + + + + + ܥܕܢܐ ܕܗܢܕܘܨܝܢ ܡܥܪܒܝܬܐ + + + + + ܥܕܢܐ ܕܐܝܪܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܝܪܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܝܪܐܢ + + + + + ܥܕܢܐ ܕܐܝܪܟܘܬܣܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܝܪܟܘܬܣܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܝܪܟܘܬܣܟ + + + + + ܥܕܢܐ ܕܐܝܣܪܐܝܠ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܝܣܪܐܝܠ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܝܣܪܐܝܠ + + + + + ܥܕܢܐ ܕܝܦܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܝܦܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܝܦܢ + + + + + ܥܕܢܐ ܕܦܝܬܪܘܦܒܠܒܣܟܝ-ܟܐܡܟܬܣܟܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܝܬܪܘܦܒܠܒܣܟܝ-ܟܐܡܟܬܣܟܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܝܬܪܘܦܒܠܒܣܟܝ-ܟܐܡܟܬܣܟܝ + + + + + ܥܕܢܐ ܕܡܕܢܚ ܟܙܩܣܬܐܢ + + + + + ܥܕܢܐ ܕܡܥܪܒ ܟܙܩܣܬܐܢ + + + + + ܥܕܢܐ ܕܟܘܪܝܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܘܪܝܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܘܪܝܝܐ + + + + + ܥܕܢܐ ܟܘܣܪܐܝ + + + + + ܥܕܢܐ ܕܟܪܐܣܢܘܝܪܣܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܪܐܣܢܘܝܪܣܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܪܐܣܢܘܝܪܣܟ + + + + + ܥܕܢܐ ܕܩܝܪܓܝܙܣܬܐܢ + + + + + ܥܕܢܐ ܕܠܐܢܟܐ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܠܐܝܢ + + + + + ܥܕܢܐ ܕܠܘܪܕ ܗܐܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܠܘܪܕ ܗܐܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܠܘܪܕ ܗܐܘ + + + + + ܥܕܢܐ ܕܡܐܟܐܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܐܟܐܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܐܟܐܘ + + + + + ܥܕܢܐ ܕܓܙܪܬܐ ܡܐܟܐܘܪܝ + + + + + ܥܕܢܐ ܕܡܐܓܐܕܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܐܓܕܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܐܓܕܐܢ + + + + + ܥܕܢܐ ܕܡܠܝܙܝܐ + + + + + ܥܕܢܐ ܕܓܙܪܬܐ ܡܐܠܕܝܒܝܬܐ + + + + + ܥܕܢܐ ܕܡܐܪܟܐܘܣܐܣ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܡܐܪܫܐܠ + + + + + ܥܕܢܐ ܕܡܘܪܝܛܝܘܣ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܘܪܝܛܝܘܣ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܘܪܝܛܝܘܣ + + + + + ܥܕܢܐ ܕܡܐܘܣܘܢ + + + + + ܥܕܢܐ ܕܓܪܒܝ ܡܥܪܒܝܬܐ ܡܟܣܝܩܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܪܒܝ ܡܥܪܒܝܬܐ ܡܟܣܝܩܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܪܒܝ ܡܥܪܒܝܬܐ ܡܟܣܝܩܘ + + + + + ܥܕܢܐ ܕܡܟܣܝܩܘ ܫܝܢܝܬܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܟܣܝܩܘ ܫܝܢܝܬܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܟܣܝܩܘ ܫܝܢܝܬܐ + + + + + ܥܕܢܐ ܕܐܘܠܐܢܒܐܬܘܪ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܠܐܢܒܐܬܘܪ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܠܐܢܒܐܬܘܪ + + + + + ܥܕܢܐ ܕܡܘܣܟܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܡܘܣܟܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܡܘܣܟܘ + + + + + ܥܕܢܐ ܕܡܝܐܢܡܐܪ + + + + + ܥܕܢܐ ܕܢܐܘܪܘ + + + + + ܥܕܢܐ ܕܢܝܦܐܠ + + + + + ܥܕܢܐ ܕܢܝܘ ܟܠܝܕܘܢܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܢܝܘ ܟܠܝܕܘܢܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܢܝܘ ܟܠܝܕܘܢܝܐ + + + + + ܥܕܢܐ ܕܢܝܘ ܙܝܠܢܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܢܝܘ ܙܝܠܢܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܢܝܘ ܙܝܠܢܕ + + + + + ܥܕܢܐ ܕܢܝܘܦܐܘܢܠܢܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܢܝܘܦܐܘܢܠܢܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܢܝܘܦܐܘܢܠܢܕ + + + + + ܥܕܢܐ ܕܢܝܘܝ + + + + + ܥܕܢܐ ܕܓܙܪܬܐ ܕܢܘܪܦܠܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܓܙܪܬܐ ܕܢܘܪܦܠܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܓܙܪܬܐ ܕܢܘܪܦܠܟ + + + + + ܥܕܢܐ ܕܦܪܢܢܕܘ ܕܢܘܪܘܢܗܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܪܢܢܕܘ ܕܢܘܪܘܢܗܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܪܢܢܕܘ ܕܢܘܪܘܢܗܐ + + + + + ܥܕܢܐ ܕܓܙܝܖ̈ܐ ܕܡܪܝܐܢܐ ܓܪܒܝܝܬܐ + + + + + ܥܕܢܐ ܕܢܘܒܘܣܝܒܪܣܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܢܘܒܘܣܝܒܪܣܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܢܘܒܘܣܝܒܪܣܟ + + + + + ܥܕܢܐ ܕܘܡܣܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܘܡܣܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܘܡܣܟ + + + + + ܥܕܢܐ ܕܦܐܟܣܬܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܐܟܣܬܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܐܟܣܬܐܢ + + + + + ܥܕܢܐ ܕܦܠܐܘ + + + + + ܥܕܢܐ ܕܦܐܦܘܐ ܓܝܢܝܐ ܚܕܬܐ + + + + + ܥܕܢܐ ܕܦܪܓܘܐܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܪܓܘܐܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܪܓܘܐܝ + + + + + ܥܕܢܐ ܕܦܝܪܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܝܪܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܝܪܘ + + + + + ܥܕܢܐ ܕܦܝܠܝܦܝܢܝܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܦܝܠܝܦܝܢܝܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܦܝܠܝܦܝܢܝܐ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܦܝܢܝܟܣ + + + + + ܥܕܢܐ ܕܣܐܢܬ ܦܝܥܪ ܘܡܩܘܠܘܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܣܐܢܬ ܦܝܥܪ ܘܡܩܘܠܘܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܣܐܢܬ ܦܝܥܪ ܘܡܩܘܠܘܢ + + + + + ܥܕܢܐ ܕܦܝܬܟܐܝܪܢ + + + + + ܥܕܢܐ ܕܦܘܢܐܦܝ + + + + + ܥܕܢܐ ܕܦܝܘܢܓܝܢܓ + + + + + ܥܕܢܐ ܕܟܝܙܝܠܘܪܕܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܟܝܙܝܠܘܪܕܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܟܝܙܝܠܘܪܕܐ + + + + + ܥܕܢܐ ܕܪܝܘܢܝܘܢ + + + + + ܥܕܢܐ ܕܪܘܬܝܪܐ + + + + + ܥܕܢܐ ܕܣܐܚܐܠܝܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܣܐܚܐܠܝܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܣܐܚܐܠܝܢ + + + + + ܥܕܢܐ ܕܣܡܐܪܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܣܡܐܪܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܣܡܐܪܐ + + + + + ܥܕܢܐ ܕܣܡܘܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܣܡܘܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܣܡܘܐ + + + + + ܥܕܢܐ ܕܣܐܝܫܝܠ + + + + + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܣܝܢܓܐܦܘܪ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܫܠܝܡܘܢ + + + + + ܥܕܢܐ ܕܓܝܘܪܓܝܐ ܬܝܡܢܝܬܐ + + + + + ܥܕܢܐ ܕܣܘܪܝܢܐܡ + + + + + ܥܕܢܐ ܕܣܝܘܐ + + + + + ܥܕܢܐ ܕܬܗܝܬܝ + + + + + ܥܕܢܐ ܕܬܐܝܦܐܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܐܝܦܐܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܬܐܝܦܐܝ + + + + + ܥܕܢܐ ܕܬܐܓܝܟܣܬܐܢ + + + + + ܥܕܢܐ ܕܬܘܟܝܠܐܘ + + + + + ܥܕܢܐ ܬܘܢܓܐ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܬܘܢܓܐ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܬܘܢܓܐ + + + + + ܥܕܢܐ ܕܬܫܘܟ + + + + + ܥܕܢܐ ܕܬܘܪܟܡܢܣܬܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܬܘܪܟܡܢܣܬܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܬܘܪܟܡܢܣܬܐܢ + + + + + ܥܕܢܐ ܕܬܘܒܐܠܘ + + + + + ܥܕܢܐ ܕܐܘܪܘܓܘܐܝ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܪܘܓܘܐܝ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܪܘܓܘܐܝ + + + + + ܥܕܢܐ ܕܐܘܙܒܟܣܬܐܢ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܐܘܙܒܟܣܬܐܢ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܐܘܙܒܟܣܬܐܢ + + + + + ܥܕܢܐ ܕܒܐܢܘܐܛܘ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܐܢܘܐܛܘ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܒܐܢܘܐܛܘ + + + + + ܥܕܢܐ ܕܒܢܙܘܝܠܐ + + + + + ܥܕܢܐ ܕܒܠܐܕܝܒܘܣܬܘܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܠܐܕܝܒܘܣܬܘܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܒܠܐܕܝܒܘܣܬܘܟ + + + + + ܥܕܢܐ ܕܒܘܠܓܘܓܪܐܕ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܒܘܠܓܘܓܪܐܕ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܒܘܠܓܘܓܪܐܕ + + + + + ܥܕܢܐ ܕܒܘܣܬܘܟ + + + + + ܥܕܢܐ ܕܓܙܝܪ̈ܐ ܕܘܐܝܟ + + + + + ܥܕܢܐ ܕܘܝܠܝܣ ܘܦܘܬܘܢܐ + + + + + ܥܕܢܐ ܕܝܐܟܘܬܣܟ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܝܐܟܘܬܣܟ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܝܐܟܘܬܣܟ + + + + + ܥܕܢܐ ܕܝܟܐܬܝܪܢܒܝܪܓ + ܥܕܢܐ ܡܫܘܚܬܢܝܬܐ ܕܝܟܐܬܝܪܢܒܝܪܓ + ܥܕܢܐ ܕܒܗܪ ܝܘܡܐ ܕܝܟܐܬܝܪܢܒܝܪܓ + + + + + ܥܕܢܐ ܕܝܘܩܘܢ + + + + + + + : + + + ܠܝܬ ܡܢܝܢܐ + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + ܠܝܬ ܡܢܝܢܐ + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + : + + + + + #,##0.###;#,##0.###- + + + + + + + ¤ #,##0.00;¤ #,##0.00- + + + + + + + ¤ #,##0.00 + + + {0} {1} + {0} {1} + + + + ل.س.‏ + + + + ܝܠܐ ܝܠܗ ܥܬܝܕܐ + ܝܠ̈ܐ ܝܢܐ ܥܬܝܕ̈ܐ <RLM>{0} + ܫܩܘܠ ܦܬܠܐ ܕ{0} ܝܡܝܢܐ + + + + + + ܕܝܣܝ{0} + + + ܣܢܬܝ{0} + + + ܡܝܠܝ{0} + + + ܡܝܟܪܘ{0} + + + ܢܐܢܘ{0} + + + ܦܝܟܘ{0} + + + ܦ̮ܝܡܬܘ{0} + + + ܐܬܘ{0} + + + ܙܝܦܬܘ{0} + + + ܝܟܬܘ{0} + + + ܕܝܟܐ{0} + + + ܗܟܬܘ{0} + + + ܟܝܠܘ{0} + + + ܡܝܓܐ{0} + + + ܓܝܓܐ{0} + + + ܬܝܪܐ{0} + + + ܦܝܬܐ{0} + + + ܐܟܣܐ{0} + + + ܙܝܬܐ{0} + + + ܝܘܬܐ{0} + + + ܟܝܒܝ{0} + + + ܡܝܒܝ{0} + + + ܓܝܒܝ{0} + + + ܬܝܒܝ{0} + + + ܦܝܒܝ{0} + + + ܐܟܣܒܝ{0} + + + ܙܝܒܝ{0} + + + ܝܘܒܝ{0} + + + {0}/{1} + + + {0} ܡܪܒܥܐ + {0} ܡܪܒܥܐ + + + {0} ܡܩܦܣܐ + {0} ܡܩܦܣܐ + + + {0}⋅{1} + + + ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + + + ܡܝܬܪ̈ܐ ܒܪܦܦܐ ܡܪܒܥܐ + {0} ܡܝܬܪܐ ܒܪܦܦܐ ܡܪܒܥܐ + {0} ܡܝܬܪ̈ܐ ܒܪܦܦܐ ܡܪܒܥܐ + + + ܚܘܕܖ̈ܐ + {0} ܚܘܕܪܐ + {0} ܚܘܕܖ̈ܐ + + + ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + + + ܕܪ̈ܓ݂ܐ + ܕܪܓ݂ܐ + {0} ܕܪ̈ܓ݂ܐ + + + ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + ܩܛܝܢܐ ܩܫܬܢܝܐ + {0} ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + + + ܪ̈ܦܦܐ ܩܫܬܢܝܐ + {0} ܪ̈ܦܦܐ ܩܫܬܢܝܐ + {0} ܪ̈ܦܦܐ ܩܫܬܢ̈ܝܐ + + + ܟܝܠܘܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܟܝܠܘܡܝܬܪܐ ܡܪܒܥܐ + {0} ܟܝܠܘܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܒܟܝܠܘܡܝܬܪܐ ܡܪܒܥܐ + + + ܗܟܬܪ + {0} ܗܟܬܪ + {0} ܗܟܬܪ + + + ܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܡܝܬܪܐ ܡܪܒܥܐ + {0} ܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܒܡܝܬܪܐ ܡܪܒܥܐ + + + ܣܢܬܝܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܣܢܬܝܡܝܬܪܐ ܡܪܒܥܐ + {0} ܣܢܬܝܡܝܬܪ̈ܐ ܡܪܒܥܐ + {0} ܒܣܢܬܝܡܝܬܪܐ ܡܪܒܥܐ + + + ܡܝܠ̈ܐ ܡܪܒܥܐ + {0} ܡܝܠ̈ܐ ܡܪܒܥܐ + {0} ܡܝܠ̈ܐ ܡܪܒܥܐ + {0} ܒܡܝܠ̈ܐ ܡܪܒܥܐ + + + ܦ̈ܕܢܐ + {0} ܦܕܢܐ + {0} ܦ̈ܕܢܐ + + + ܝܪ̈ܕܐ ܡܪܒܥܐ + {0} ܝܪܕܐ ܡܪܒܥܐ + {0} ܝܪ̈ܕܐ ܡܪܒܥܐ + + + ܐܩܠ̈ܐ ܡܪܒܥܐ + {0} ܐܩܠܐ ܡܪܒܥܐ + {0} ܐܩܠ̈ܐ ܡܪܒܥܐ + + + ܐܢܟ̈ܐ ܡܪܒܥܐ + {0} ܐܢܟ ܡܪܒܥܐ + {0} ܐܢܟ̈ܐ ܡܪܒܥܐ + {0} ܒܐܢܟ ܡܪܒܥܐ + + + ܩܪ̈ܛܐ + ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܡܝܠܝܓܪ̈ܡܐ ܒܕܝܣܝܠܝܬܪܐ + {0} ܡܝܠܝܓܪܡܐ ܒܕܝܣܝܠܝܬܪ + {0} ܡܝܠܝܓܪ̈ܡܐ ܒܕܝܣܝܠܝܬܪܐ + + + ܡܝܠܝܡܘܠ ܒܠܝܬܪܐ + {0} ܡܝܠܝܡܘܠ ܒܠܝܬܪܐ + {0} ܡܝܠܝܡܘܠ ܒܠܝܬܪܐ + + + ܡܠܘܐ̈ܐ + ܚܕ ܡܠܘܐܐ + {0} ܡܠܘܐ̈ܐ + + + ܡܢܘ̈ܬܐ ܒܡܠܝܘܢ + {0} ܡܢܬܐ ܒܡܠܝܘܢ + {0} ܡܢܘ̈ܬܐ ܒܡܠܝܘܢ + + + ܒܡܐܐ + {0} ܒܡܐܐ + {0} ܒܡܐܐ + + + ܒܐܠܦܐ + {0} ܒܐܠܦܐ + {0} ܒܐܠܦܐ + + + + {0}‱ + {0}‱ + + + ܡܘܠ + {0} ܡܘܠ + {0} ܡܘܠ + + + ܠܝܬܪ̈ܐ ܒܟܝܠܘܡܝܬܪܐ + {0} ܠܝܬܪܐ ܒܟܝܠܘܡܝܬܪܐ + {0} ܠܝܬܪ̈ܐ ܒܟܝܠܘܡܝܬܪܐ + + + ܠܝܬܪ̈ܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܠܝܬܪܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܠܝܬܪ̈ܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + + + ܡܝܠ̈ܐ ܒܓܠܘܢܐ + {0} ܡܝܠܐ ܒܓܠܘܢܐ + {0} ܡܝܠ̈ܐ ܒܓܠܘܢܐ + + + ܡܝܠ̈ܐ ܒܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠܐ ܒܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠ̈ܐ ܒܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + + + ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + + + ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + + + ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + + + ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + + + ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + + + ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + + + ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + + + ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + + + ܒܐܝܬ + {0} ܒܐܝܬ + {0} ܒܐܝܬ + + + ܒܬ + {0} ܒܬ + {0} ܒܬ + + + ܕܪ̈ܐ + ܕܪܐ + {0} ܕܪ̈ܐ + + + ܥܣܝܪ̈ܘܬܐ + ܥܣܝܪܘܬܐ + {0} ܥܣܝܪ̈ܘܬܐ + + + ܫ̈ܢܐ + ܫܢܬܐ + {0} ܫ̈ܢܐ + {0} ܒܫܢܬܐ + + + ܪ̈ܘܒܥܐ + ܪܘܒܥܐ + {0} ܪ̈ܘܒܥܐ + {0}/ܪܘܒܥܐ + + + ܝܪ̈ܚܐ + ܝܪܚܐ + {0} ܝܪ̈ܚܐ + {0} ܒܝܪܚܐ + + + ܫܒ̈ܘܥܐ + ܫܒ݂ܘܥܐ + {0} ܫܒ݂̈ܘܥܐ + {0} ܒܫܒ݂ܘܥܐ + + + ܝܘ̈ܡܬܐ + ܝܘܡܐ + {0} ܝܘ̈ܡܬܐ + {0} ܒܝܘܡܐ + + + ܫ̈ܥܐ + ܫܥܬܐ + {0} ܫ̈ܥܐ + {0} ܒܫܥܬܐ + + + ܩܛܝܢ̈ܬܐ + ܩܛܝܢܐ + {0} ܩܛܝܢ̈ܬܐ + {0} ܒܩܛܝܢܐ + + + ܪ̈ܦܦܐ + ܪܦܦܐ + {0} ܪ̈ܦܦܐ + {0} ܒܪܦܦܐ + + + ܡܝܠܝܪ̈ܦܦܐ + {0} ܡܝܠܝܪܦܦܐ + {0} ܡܝܠܝܪ̈ܦܦܐ + + + ܡܝܟܪܘܪ̈ܦܦܐ + {0} ܡܝܟܪܘܪܦܦܐ + {0} ܡܝܟܪܘܪ̈ܦܦܐ + + + ܢܐܢܘܪ̈ܦܦܐ + {0} ܢܐܢܘܪܦܦܐ + {0} ܢܐܢܘܪ̈ܦܦܐ + + + ܐܡܦܝܪ + {0} ܐܡܦܝܪ + {0} ܐܡܦܝܪ + + + ܡܝܠܝܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + + + ܘܗܡ + {0} ܘܗܡ + {0} ܘܗܡ + + + ܒܘܠܬ + {0} ܒܘܠܬ + {0} ܒܘܠܬ + + + ܟ ܟܐܠܘܪܝ + {0} ܟ ܟܐܠܘܪܝ + {0} ܟܝܠܘܟܐܠܘܪܝ + + + ܟܐܠ + {0} ܟܐܠ + {0} ܟܐܠ + + + ܟܝܠܘܓܝܐܘܠ + {0} ܟܝܠܘܓܝܐܘܠ + {0} ܟܝܠܘܓܝܐܘܠ + + + ܓܝܐܘܠ + {0} ܓܝܐܘܠ + {0} ܓܝܐܘܠ + + + ܟܝܠܘܘܐܬ-ܫܥ̈ܐ + {0} ܟܝܠܘܘܐܬ-ܫܥܬܐ + {0} ܟܝܠܘܘܐܬ-ܫܥ̈ܐ + + + ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + + + ܢܝܘܬܢ + {0} ܢܝܘܬܢ + {0} ܢܝܘܬܢ + + + ܟܝܠܘܘܐܬ-ܫܥ̈ܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܟܝܠܘܘܐܬ-ܫܥܬܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܟܝܠܘܘܐܬ-ܫܥ̈ܐ ܒ 100 ܟܝܠܘܡܝܬܪ̈ܐ + + + ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + + + ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + + + ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + + + ܗܪܬܙ + {0} ܗܪܬܙ + {0} ܗܪܬܙ + + + ܦܝ̈ܟܣܠܐ + {0} ܦܝܟܣܠܐ + {0} ܦܝ̈ܟܣܠܐ + + + ܡܝܓܐܦܝ̈ܟܣܠܐ + {0} ܡܝܓܐܦܝܟܣܠܐ + {0} ܡܝܓܐܦܝ̈ܟܣܠܐ + + + ܦܝ̈ܟܣܠܐ ܒܣܢܬܝܡܝܬܪܐ + {0} ܦܝܟܣܠܐ ܒܣܢܬܝܡܝܬܪܐ + {0} ܦܝ̈ܟܣܠܐ ܒܣܢܬܝܡܝܬܪܐ + + + ܦܝ̈ܟܣܠܐ ܒܐܢܟ + {0} ܦܝܟܣܠܐ ܒܐܢܟ + {0} ܦܝ̈ܟܣܠܐ ܒܐܢܟ + + + ܥܘܒܐ ܦܫܝܬܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܦܫܝܬܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܦܫܝܬܐ ܐܪܥܝܐ + + + ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܟܝܠܘܡܝܬܪܐ + {0} ܟܝܠܘܡܝܬܪ̈ܐ + {0} ܒܟܝܠܘܡܝܬܪܐ + + + ܡܝܬܪ̈ܐ + ܡܝܬܪܐ + {0} ܡܝܬܪ̈ܐ + {0} ܒܡܝܬܪܐ + + + ܕܝܣܝܡܝܬܪ̈ܐ + {0} ܕܝܣܝܡܝܬܪܐ + {0} ܕܝܣܝܡܝܬܪ̈ܐ + + + ܣܢܬܝܡܝܬܪ̈ܐ + {0} ܣܢܬܝܡܝܬܪܐ + {0} ܣܢܬܝܡܝܬܪ̈ܐ + {0} ܒܣܢܬܝܡܝܬܪܐ + + + ܡܝܠܝܡܝܬܪ̈ܐ + {0} ܡܝܠܝܡܝܬܪܐ + {0} ܡܝܠܝܡܝܬܪ̈ܐ + + + ܡܝܟܪܘܡܝܬܪ̈ܐ + {0} ܡܟܡ + {0}ܡܟܡ + + + ܢܐܢܘܡܝܬܪ̈ܐ + {0} ܢܐܢܘܡܝܬܪܐ + {0} ܢܐܢܘܡܝܬܪ̈ܐ + + + ܦܝܟܘܡܝܬܪ̈ܐ + {0} ܦܝܟܘܡܝܬܪܐ + {0} ܦܝܟܘܡܝܬܪ̈ܐ + + + ܡܝܠ̈ܐ + {0} ܡܝܠܐ + {0} ܡܝܠ̈ܐ + + + ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + + + ܐܩܠ̈ܐ + {0} ܐܩܠܐ + {0} ܐܩܠ̈ܐ + {0}/ܐܩܠܐ + + + ܐܢܟ̈ܐ + ܚܕܐ ܐܢܟ + {0} ܐܢܟ̈ܐ + {0}/ܐܢܟ + + + ܦܪ̈ܣܚܐ + {0} ܦܪܣܚܐ + {0} ܦܪ̈ܣܚܐ + + + ܫ̈ܢܐ ܕܢܘܗܪܐ + {0} ܫܢܬܐ ܕܢܘܗܪܐ + {0} ܫ̈ܢܐ ܕܢܘܗܪܐ + + + ܡܫܘܚܬܐ ܪܩܝܥܝܬܐ + {0} ܡܫܘܚܬܐ ܪܩܝܥܝܬܐ + {0} ܡܫܘܚܬܐ ܪܩܝܥܝܬܐ + + + ܦܘܪ̈ܠܢܓ + {0} ܦܘܪܠܢܓ + {0} ܦܘܪ̈ܠܢܓ + + + ܡܝ̈ܠܐ ܝܡܝ̈ܐ + {0} ܡܝܠܐ ܝܡܝܐ + {0} ܡܝ̈ܠܐ ܝܡܝ̈ܐ + + + ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + + + ܢܘܩܙ̈ܐ + {0} ܢܘܩܙܐ + {0} ܢܘܩܙ̈ܐ + + + ܥܘܒܐ ܦܫܝܬܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܦܫܝܬܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܦܫܝܬܐ ܫܡܫܝܐ + + + ܠܘܩܣ + {0} ܠܘܩܣ + {0} ܠܘܩܣ + + + ܢܗܝܪܐ + {0} ܢܗܝܪܐ + {0} ܢܗܝܪܐ + + + ܠܘܡܝܢ + {0} ܠܘܡܝܢ + {0} ܠܘܡܝܢ + + + ܬܘܢ ܡܝܬܪܝܐ + {0} ܬܘܢ ܡܝܬܪܝܐ + {0} ܬܘܢ̈ ܡܝܬܪ̈ܝܐ + + + ܟܝܠܘܓܪ̈ܡܐ + {0} ܟܝܠܘܓܪܡܐ + {0} ܟܝܠܘܓܪ̈ܡܐ + {0} ܒܟܝܠܘܓܪܡܐ + + + ܓܪ̈ܡܐ + ܓܪܡܐ + {0} ܓܪ̈ܡܐ + {0} ܒܓܪܡܐ + + + ܡܝܠܝܓܪ̈ܡܐ + {0} ܡܝܠܝܓܪܡܐ + {0} ܡܝܠܝܓܪ̈ܡܐ + + + ܡܝܟܪܘܓܪ̈ܡܐ + {0} ܡܝܟܪܘܓܪܡܐ + {0} ܡܝܟܪܘܓܪ̈ܡܐ + + + ܬܘܢ̈ܐ + {0} ܬܘܢܐ + {0} ܬܘܢ̈ܐ + + + ܣܛܘܢ + {0} ܣܛܘܢ + {0} ܣܛܘܢ + + + ܡܢܝ̈ܐ + {0} ܡܢܝܐ + {0} ܡܢܝ̈ܐ + {0} ܒܡܢܝܐ + + + ܐܘܢܩ̈ܝܐ + {0} ܐܘܢܩܝܐ + {0} ܐܘܢܩ̈ܝܐ + {0} ܒܐܘܢܩܝܐ + + + ܩܪ̈ܛܐ + {0} ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + + + ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + + + ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + + + ܦܪ̈ܕܐ + {0} ܦܪܕܐ + {0} ܦܪ̈ܕܐ + + + ܓ ܘܐܬ + {0} ܓܝܓܐܘܐܬ + {0} ܓܝܓܐܘܐܬ + + + ܡ ܘܐܬ + {0} ܡܝܓܐܘܐܬ + {0} ܡܝܓܐܘܐܬ + + + ܟ ܘܐܬ + {0} ܟܝܠܘܘܐܬ + {0} ܟܝܠܘܘܐܬ + + + ܘܐܬ + {0} ܘܐܬ + {0} ܘܐܬ + + + ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + + + ܚܝܠܐ ܕܣܘܣܝܐ + {0} ܣܘܣܝܐ + {0} ܣܘܣܝܐ + + + ܦܣܟ̈ܠܐ + {0} ܦܣܟ̈ܠܐ + {0} ܦܣܟ̈ܠܐ + + + ܗܟܬܘܦܣܟ̈ܠܐ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + + + ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + + + ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + + + ܟܝܠܘܡܝܬܪ̈ܐ ܒܫܥܬܐ + {0} ܟܝܠܘܡܝܬܪܐ ܒܫܥܬܐ + {0} ܟܝܠܘܡܝܬܪ̈ܐ ܒܫܥܬܐ + + + ܡܝܬܪ̈ܐ ܒܪܦܦܐ + {0} ܡܝܬܪܐ ܒܪܦܦܐ + {0} ܡܝܬܪ̈ܐ ܒܪܦܦܐ + + + ܡܝܠ̈ܐ ܒܫܥܬܐ + {0} ܡܝܠܐ ܒܫܥܬܐ + {0} ܡܝܠ̈ܐ ܒܫܥܬܐ + + + ܩܛܪ̈ܐ + {0} ܩܛܪܐ + {0} ܩܛܪ̈ܐ + + + ° + {0}° + {0}° + + + ܕܪ̈ܓܐ ܡܐܢܝܐ + {0} ܕܪܓܐ ܡܐܢܝܐ + {0} ܕܪ̈ܓܐ ܡܐܢܝܐ + + + ܕܪ̈ܓܐ ܦܐܗܪܢܗܥܝܬ + {0} ܕܪܓܐ ܦܐܗܪܢܗܥܝܬ + {0} ܕܪ̈ܓܐ ܦܐܗܪܢܗܥܝܬ + + + ܕܪ̈ܓܐ ܟܠܒܝܢ + {0} ܕܪܓܐ ܟܠܒܝܢ + {0} ܕܪ̈ܓܐ ܟܠܒܝܢ + + + ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + {0} ܢܝܘܬܢ-ܡܝܬܪܐ + {0} ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + + + ܟܝܠܘܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0} ܟܝܠܘܡܝܬܪܐ ܡܩܦܣܐ + {0} ܟܝܠܘܡܝܬܪ̈ܐ ܡܩܦܣܐ + + + ܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0} ܡܝܬܪܐ ܡܩܦܣܐ + {0} ܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0}/ܡܝܬܪܐ ܡܩܦܣܐ + + + ܣܢܬܝܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0} ܣܢܬܝܡܝܬܪܐ ܡܩܦܣܐ + {0} ܣܢܬܝܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0}/ܣܢܬܝܡܝܬܪܐ ܡܩܦܣܐ + + + ܡܝܠ̈ܐ ܡܩܦܣܐ + {0} ܡܝܠܐ ܡܩܦܣܐ + {0} ܡܝܠ̈ܐ ܡܩܦܣܐ + + + ܝܪ̈ܕܐ ܡܩܦܣܐ + {0} ܝܪܕܐ ܡܩܦܣܐ + {0} ܝܪ̈ܕܐ ܡܩܦܣܐ + + + ܐܩܠ̈ܐ ܡܩܦܣܐ + {0} ܐܩܠܐ ܡܩܦܣܐ + {0} ܐܩܠ̈ܐ ܡܩܦܣܐ + + + ܐܢܟ̈ܐ ܡܩܦܣܐ + ܚܕܐ ܐܢܟ ܡܩܦܣܐ + {0} ܐܢܟ̈ܐ ܡܩܦܣܐ + + + ܡܝܓܐܠܝܬܪ̈ܐ + {0} ܡܝܓܐܠܝܬܪܐ + {0} ܡܝܓܐܠܝܬܪ̈ܐ + + + ܗܟܬܘܠܝܬܪ̈ܐ + {0} ܗܟܬܘܠܝܬܪܐ + {0} ܗܟܬܘܠܝܬܪ̈ܐ + + + ܠܝܬܪ̈ܐ + {0} ܠܝܬܪܐ + {0} ܠܝܬܪ̈ܐ + {0}/ܠܝܬܪܐ + + + ܕܝܣܝܠܝܬܪ̈ܐ + {0} ܕܝܣܝܠܝܬܪܐ + {0} ܕܝܣܝܠܝܬܪ̈ܐ + + + ܣܢܬܝܠܝܬܪ̈ܐ + {0} ܣܢܬܝܠܝܬܪܐ + {0} ܣܢܬܝܠܝܬܪ̈ܐ + + + ܡܝܠܝܠܝܬܪ̈ܐ + {0} ܡܝܠܝܠܝܬܪܐ + {0} ܡܝܠܝܠܝܬܪ̈ܐ + + + mpt + {0} mpt + {0} mpt + + + ܐܩܠ̈ܐ-ܦܕܢܐ + {0} ܐܩܠܐ-ܦܕܢܐ + {0} ܐܩܠ̈ܐ-ܦܕܢܐ + + + ܓܠܘܢ̈ܐ + {0} ܓܠܘܢܐ + {0} ܓܠܘܢ̈ܐ + {0}/ܓܠܘܢܐ + + + ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0}/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + + + ܬܪ̈ܘܕܐ ܪ̈ܒܐ + {0} ܬܪܘܕܐ ܪܒܐ + {0} ܬܪ̈ܘܕܐ ܪ̈ܒܐ + + + ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + {0} ܬܪܘܕܐ ܙܥܘܪܐ + {0} ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + {0} ܬܪܘܕܐ ܚܠܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪܘܕܐ ܚܠܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܛܘܦ̈ܐ + {0} ܛܘܦܬܐ + {0} ܛܘܦ̈ܐ + + + ܕܪ̈ܟܡܐ ܪ̈ܕܘܝܐ + {0} ܕܪܟܡܐ ܪܕܘܝܐ + {0} ܕܪ̈ܟܡܐ ܪ̈ܕܘܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܢܝܬܐ ܫܪܫܢܝܬܐ + {0} ܡܕܢܚܐ + {0} ܓܪܒܝܐ + {0} ܬܝܡܢܐ + {0} ܡܥܪܒ݂ܐ + + + + + ܕܝܣܝ{0} + + + ܣܢܬܝ{0} + + + ܡ{0} + + + ܡܟ{0} + + + ܢ{0} + + + ܦ{0} + + + ܦ̮{0} + + + ܐ{0} + + + ܙܝܦ{0} + + + ܝܟ{0} + + + ܕܐ{0} + + + ܗ{0} + + + ܟ{0} + + + ܡܝܓ{0} + + + ܓܝ{0} + + + ܬ{0} + + + ܦܝܬ{0} + + + ܐܟ{0} + + + ܙܬ{0} + + + ܝܘ{0} + + + ܟܝܒܝ{0} + + + ܡܝܒܝ{0} + + + ܓܝܒܝ{0} + + + ܬܝܒܝ{0} + + + ܦܝܒܝ{0} + + + ܐܟܣܒܝ{0} + + + ܙܝܒܝ{0} + + + ܝܘܒܝ{0} + + + {0}² + {0}² + + + {0}³ + {0}³ + + + ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + + + ܡ/ܪ² + {0} ܡ/ܪ² + {0} ܡ/ܪ² + + + ܚܘܕ + {0} ܚܘܕ + {0} ܚܘܕ + + + ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + + + ܕܪ̈ܓ݂ܐ + ܕܪܓ݂ܐ + {0} ܕܪ̈ܓ݂ܐ + + + ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + ܩܛܝܢܐ ܩܫܬܢܝܐ + {0} ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + + + ܪ̈ܦܦܐ ܩܫܬܢܝܐ + ܪܦܦܐ ܩܫܬܢܝܐ + {0} ܪ̈ܦܦܐ ܩܫܬܢ̈ܝܐ + + + ܟܡ² + {0} ܟܡ² + {0} ܟܡ² + {0}/ܟܡ² + + + ܗܟܬܪ + {0} ܗܟܬܪ + {0} ܗܟܬܪ + + + ܡ² + {0} ܡ² + {0} ܡ² + {0}/ܡ² + + + ܣܡ² + {0} ܣܡ² + {0} ܣܡ² + {0}/ܣܡ² + + + ܡܝܠ̈ܐ² + {0} ܡܝܠ̈ܐ² + {0} ܡܝܠ̈ܐ² + {0}/ܡܝܠ̈ܐ² + + + ܦ̈ܕܢܐ + {0} ܦܕܢܐ + {0} ܦ̈ܕܢܐ + + + ܝܪ̈ܕܐ² + {0} ܝܪܕܐ² + {0} ܝܪ̈ܕܐ² + + + ܐܩܠ̈ܐ² + {0} ܐܩܠܐ² + {0} ܐܩܠ̈ܐ² + + + ܐܢܟ̈ܐ² + {0}/ܐܢ² + {0}/ܐܢ² + {0}/ܐܢ² + + + ܩܪ̈ܛܐ + ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܡܓܡ/ܕܝܣܝܠܝܬܪܐ + {0} ܡܓܡ/ܕܝܣܝܠܝܬܪܐ + {0} ܡܓܡ/ܕܝܣܝܠܝܬܪܐ + + + ܡܡܘܠ܊/ܠ + {0} ܡܡܘܠ܊/ܠ + {0} ܡܡܘܠ܊/ܠ + + + ܡܠܘܐܐ + ܡܠܘܐܐ + {0} ܡܠܘܐ̈ܐ + + + ܡܢܘ̈ܬܐ/ܡܠܝܘܢ + {0} ܡܢܘܬܐ/ܡܠ܊ + {0} ܡܢܘ̈ܬܐ/ܡܠ܊ + + + ܒܡܐܐ + {0}% + {0}% + + + ܒܐܠܦܐ + {0}‰ + {0}‰ + + + {0}‱ + {0}‱ + + + ܡܘܠ + {0} ܡܘܠ + {0} ܡܘܠ + + + ܠܝܬܪ̈ܐ/ܟܡ + {0} ܠܝܬܪܐ/ܟܡ + {0} ܠܝܬܪ̈ܐ/ܟܡ + + + ܠܝܬܪ̈ܐ/100 ܟܡ + {0} ܠܝܬܪܐ/100 ܟܡ + {0} ܠܝܬܪ̈ܐ/100 ܟܡ + + + ܡܝܠ̈ܐ/ܓܠܘܢܐ + {0} ܡܝܠܐ ܒܓܠܘܢܐ + {0} ܡܝܠ̈ܐ ܒܓܠܘܢܐ + + + ܡܝܠ̈ܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + + + ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + + + ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + + + ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + + + ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + + + ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + + + ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + + + ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + + + ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + + + ܒܐܝܬ + {0} ܒܐܝܬ + {0} ܒܐܝܬ + + + ܒܬ + {0} ܒܬ + {0} ܒܬ + + + ܕܪܐ + ܕܪܐ + {0} ܕܪ̈ܐ + + + ܥܣܝܪܘܬܐ + ܥܣܝܪܘܬܐ + {0} ܥܣܝܪ̈ܘܬܐ + + + ܫ̈ܢܐ + ܫܢܬܐ + {0} ܫ̈ܢܐ + {0}/ܫܢܬܐ + + + ܪܘܒܥܐ + ܪܘܒܥܐ + {0} ܪ̈ܘܒܥܐ + {0}/ܪܘܒܥܐ + + + ܝܪ̈ܚܐ + ܝܪܚܐ + {0} ܝܪ̈ܚܐ + {0}/ܝܪܚܐ + + + ܫܒ̈ܘܥܐ + ܫܒ݂ܘܥܐ + {0} ܫܒ݂̈ܘܥܐ + {0}/ܫ + + + ܝܘ̈ܡܬܐ + ܝܘܡܐ + {0} ܝܘ̈ܡܬܐ + {0}/ܝܘܡܐ + + + ܫ̈ܥܐ + {0} ܫܥ + {0} ܫܥ + {0}/ܫܥ + + + ܩ + {0} ܩ + {0} ܩ + {0}/ܩ + + + ܪ̈ܦܦܐ + {0} ܪ + {0} ܪ + {0}/ܪ + + + ܡܝܠܝܪ̈ܦܦܐ + {0} ܡܝܠܝ ܪ + {0} ܡܝܠܝ ܪ + + + ܡܝܟܪܘ ܪ + {0} ܡܝܟܪܘ ܪ + {0} ܡܝܟܪܘ ܪ + + + ܢܐܢܘ ܪ + {0} ܢܐܢܘ ܪ + {0} ܢܐܢܘ ܪ + + + ܐܡܦܝܪ + {0} ܐܡܦܝܪ + {0} ܐܡܦܝܪ + + + ܡܝܠܝܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + + + ܘܗܡ + {0} ܘܗܡ + {0} ܘܗܡ + + + ܒܘܠܬ + {0} ܒܘܠܬ + {0} ܒܘܠܬ + + + ܟ ܟܐܠܘܪܝ + {0} ܟ ܟܐܠܘܪܝ + {0} ܟ ܟܐܠܘܪܝ + + + ܟܐܠ + {0} ܟܐܠ + {0} ܟܐܠ + + + ܟ ܓܝܐܘܠ + {0} ܟ ܓܝܐܘܠ + {0} ܟ ܓܝܐܘܠ + + + ܓܝܐܘܠ + {0} ܓܝܐܘܠ + {0} ܓܝܐܘܠ + + + ܟܝܠܘܘܐܬ-ܫ + {0} ܟܘܫ܏-ܫ + {0} ܟܘܫ܏-ܫ + + + ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + + + ܢܝܘܬܢ + {0} ܢܝܘܬܢ + {0} ܢܝܘܬܢ + + + ܟܘܫ܊ ܒ 100 ܟܡ + {0} ܟܘܫ܊ ܒ 100 ܟܡ + {0} ܟܘܫ܊ ܒ 100 ܟܡ + + + ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + + + ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + + + ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + + + ܗܪܬܙ + {0} ܗܪܬܙ + {0} ܗܪܬܙ + + + ܦܝ̈ܟܣܠܐ + {0} ܦܝܟܣܠܐ + {0} ܦܝܟܣܠܐ + + + ܡܝܓܐܦܝ̈ܟܣܠܐ + {0} ܡ.ܦܝܟܣܠܐ + {0} ܡ.ܦܝܟܣܠܐ + + + ܦܝ̈ܟܣܠܐ ܒܣܢܬܝܡܝܬܪܐ + {0} ܦܝ̈ܟܣܠܐ/ܣܡ + {0} ܦܝ̈ܟܣܠܐ/ܣܡ + + + ܦܝ̈ܟܣܠܐ ܒܐܢܟ + {0} ܦܝ̈ܟܣܠܐ/ܐܢ + {0} ܦܝ̈ܟܣܠܐ/ܐܢ + + + ܥܘܒܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܐܪܥܝܐ + + + ܟܡ + {0} ܟܡ + {0} ܟܡ + {0}/ܟܡ + + + ܡܝܬܪܐ + ܡܝܬܪܐ + {0} ܡ + {0}/ܡ + + + ܕܣܡ + {0} ܕܣܡ + {0} ܕܣܡ + + + ܣܡ + {0} ܣܡ + {0} ܣܡ + {0}/ܣܡ + + + ܡܡ + {0} ܡܡ + {0} ܡܡ + + + ܡܝܟܪܘܡܝܬܪ̈ܐ + {0} ܡܟܡ + {0}ܡܟܡ + + + ܢܡ + {0} ܢܡ + {0} ܢܡ + + + ܦܝܟܘܡܝܬܪܐ + {0} ܦܝܟܘܡܝܬܪܐ + {0} ܦܝܟܘܡܝܬܪܐ + + + ܡܝܠ̈ܐ + ܡܝܠܐ + {0} ܡܝܠ̈ܐ + + + ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + + + ܐܩܠ̈ܐ + {0} ܐܩܠ̈ܐ + {0} ܐܩܠ̈ܐ + {0}/ܐܩܠܐ + + + ܐܢܟ̈ܐ + ܚܕܐ ܐܢ܊ + {0} ܐܢ܊ + {0}/ܐܢܟ + + + ܦܪ̈ܣܚܐ + {0} ܦܪܣܚܐ + {0} ܦܪ̈ܣܚܐ + + + ܫ̈ܢܐ ܕܢܘܗܪܐ + {0} ܫܢܬܐ ܕܢܘܗܪܐ + {0} ܫ̈ܢܐ ܕܢܘܗܪܐ + + + ܡ.ܪ. + {0} ܡ.ܪ. + {0} ܡ.ܪ. + + + ܦܘܪ̈ܠܢܓ + {0} ܦܘܪܠܢܓ + {0} ܦܘܪ̈ܠܢܓ + + + ܡܝ̈ܠܐ ܝܡܝ̈ܐ + {0} ܡܝܠܐ ܝܡܝܐ + {0} ܡܝ̈ܠܐ ܝܡܝ̈ܐ + + + ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + + + ܢܘܩܙ̈ܐ + {0} ܢܘܩܙܐ + {0} ܢܘܩܙ̈ܐ + + + ܥܘܒܐ ܦܫܝܬܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܫܡܫܝܐ + + + ܠܘܩܣ + {0} ܠܘܩܣ + {0} ܠܘܩܣ + + + ܢܗܝܪܐ + {0} ܢܗܝܪܐ + {0} ܢܗܝܪܐ + + + ܠܘܡܝܢ + {0} ܠܘܡܝܢ + {0} ܠܘܡܝܢ + + + ܬ.ܡ + {0} ܬ.ܡ + {0} ܬ.ܡ + + + ܟܓܡ + {0} ܟܓܡ + {0} ܟܓܡ + {0}/ܟܓܡ + + + ܓܪ̈ܡܐ + ܓܪܡܐ + {0} ܓܪ̈ܡܐ + {0}/ܓܪܡܐ + + + ܡܓܡ + {0} ܡܓܡ + {0} ܡܓܡ + + + ܡܟܓܡ + {0} ܡܟܓܡ + {0} ܡܟܓܡ + + + ܬܘܢ̈ܐ + {0} ܬܘܢܐ + {0} ܬܘܢ̈ܐ + + + ܣܬܘܢ + {0} ܣܛܘܢ + {0} ܣܛܘܢ + + + ܡܢܝ̈ܐ + {0} ܡܢܝܐ + {0} ܡܢܝ̈ܐ + {0}/ܡܢܝܐ + + + ܐܘܢܩ̈ܝܐ + {0} ܐܘܢܩܝܐ + {0} ܐܘܢܩ̈ܝܐ + {0}/ܐܘܢܩܝܐ + + + ܩܪ̈ܛܐ + {0} ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + + + ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + + + ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + + + ܦܪܕܐ + {0} ܦܪܕܐ + {0} ܦܪ̈ܕܐ + + + ܓ ܘܐܬ + {0} ܓ ܘܐܬ + {0} ܓ ܘܐܬ + + + ܡ ܘܐܬ + {0} ܡ ܘܐܬ + {0} ܡ ܘܐܬ + + + ܟ ܘܐܬ + {0} ܟ ܘܐܬ + {0} ܟ ܘܐܬ + + + ܘܐܬ + {0} ܘܐܬ + {0} ܘܐܬ + + + ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + + + ܚܝܠܐ ܕܣܘܣܝܐ + {0} ܣܘܣܝܐ + {0} ܣܘܣܝܐ + + + ܦܣܟܠ + {0} ܦܣܟ̈ܠܐ + {0} ܦܣܟ̈ܠܐ + + + ܗܟܬܘܦܣܟܠ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + + + ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + + + ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + + + ܟܡ/ܫ + {0} ܟܡ/ܫ + {0} ܟܡ/ܫ + + + ܡ/ܪ + {0} ܡ/ܪ + {0} ܡ/ܪ + + + ܡܝܠ̈ܐ/ܫ + {0} ܡܝܠܐ/ܫ + {0} ܡܝܠ̈ܐ/ܫ + + + ܩܛܪ̈ܐ + {0} ܩܛܪܐ + {0} ܩܛܪ̈ܐ + + + {0}° + {0}° + + + ܕܪܓܐ ܡܐܢܝܐ + {0}°ܡ + {0}°ܡ + + + ܕܪܓܐ ܦܐܗܪܢܗܥܝܬ + {0}°ܦ + {0}°ܦ + + + ܕ ܟܠܒܝܢ + {0} ܕ ܟܠܒܝܢ + {0} ܕ ܟܠܒܝܢ + + + ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + {0} ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + {0} ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + + + ܟܡ³ + {0} ܟܡ³ + {0} ܟܡ³ + + + ܡܝܬܪ̈ܐ ܡܩܦܣܐ + {0} ܡ³ + {0} ܡ³ + {0}/ܡ³ + + + ܣܡ³ + {0} ܣܡ³ + {0} ܣܡ³ + {0}/ܣܡ³ + + + ܡܝܠ̈ܐ³ + {0} ܡܝܠܐ³ + {0} ܡܝܠ̈ܐ³ + + + ܝܪ̈ܕܐ³ + {0} ܝܪܕܐ³ + {0} ܝܪ̈ܕܐ³ + + + ܐܩܠ̈ܐ³ + {0} ܐܩܠܐ³ + {0} ܐܩܠ̈ܐ³ + + + ܐܢܟ̈ܐ³ + {0} ܐܢ³ + {0} ܐܢ³ + + + ܡܝܓܐܠܝܬܪ̈ܐ + {0} ܡܝܓܐܠܝܬܪܐ + {0} ܡܝܓܐܠܝܬܪ̈ܐ + + + ܗܟܬܘܠܝܬܪ̈ܐ + {0} ܗܟܬܘܠܝܬܪܐ + {0} ܗܟܬܘܠܝܬܪ̈ܐ + + + ܠܝܬܪ̈ܐ + {0} ܠܝܬܪܐ + {0} ܠܝܬܪ̈ܐ + {0}/ܠ + + + ܕܝܣܝܠܝܬܪ̈ܐ + {0} ܕܝܣܝܠܝܬܪܐ + {0} ܕܝܣܝܠܝܬܪ̈ܐ + + + ܣܢܬܝܠܝܬܪ̈ܐ + {0} ܣܢܬܝܠܝܬܪܐ + {0} ܣܢܬܝܠܝܬܪ̈ܐ + + + ܡܠܬܪ + {0} ܡܠܬܪ܊ + {0} ܡܠܬܪ̈܊ + + + {0} mpt + {0} mpt + + + ܐܩܠ̈ܐ-ܦܕܢܐ + {0} ܐܩܠ̈ܐ-ܦܕܢܐ + {0} ܐܩܠ̈ܐ-ܦܕܢܐ + + + ܓܠܘܢ̈ܐ + {0} ܓܠܘܢܐ + {0} ܓܠܘܢ̈ܐ + {0}/ܓܠܘܢ̈ܐ + + + ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0}/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + + + ܬܪ̈ܘܕܐ ܪ̈ܒܐ + {0} ܬܪܘܕܐ ܪܒܐ + {0} ܬܪ̈ܘܕܐ ܪ̈ܒܐ + + + ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + {0} ܬܪܘܕܐ ܙܥܘܪܐ + {0} ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + {0} ܬܪܘܕܐ ܚܠܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪܘܕܐ ܚܠܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܛܘܦܬܐ + {0} ܛܘܦܬܐ + {0} ܛܘܦ̈ܐ + + + ܕܪܟܡܐ ܪܕܘܝܐ + {0} ܕܪܟܡܐ ܪܕܘܝܐ + {0} ܕܪ̈ܟܡܐ ܪ̈ܕܘܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܢܝܬܐ ܫܪܫܢܝܬܐ + {0} ܡܕܢܚܐ + {0} ܓܪܒܝܐ + {0} ܬܝܡܢܐ + {0} ܡܥܪܒ݂ܐ + + + + + ܕܝܣܝ{0} + + + ܣܢܬܝ{0} + + + ܡ{0} + + + ܡܟ{0} + + + ܢ{0} + + + ܦ{0} + + + ܦ̮{0} + + + ܐ{0} + + + ܙܝܦ{0} + + + ܝܟ{0} + + + ܕܐ{0} + + + ܗ{0} + + + ܟ{0} + + + ܡܝܓ{0} + + + ܓܝ{0} + + + ܬ{0} + + + ܦܝܬ{0} + + + ܐܟ{0} + + + ܙܬ{0} + + + ܝܘ{0} + + + ܟܝܒܝ{0} + + + ܡܝܒܝ{0} + + + ܓܝܒܝ{0} + + + ܬܝܒܝ{0} + + + ܦܝܒܝ{0} + + + ܐܟܣܒܝ{0} + + + ܙܝܒܝ{0} + + + ܝܘܒܝ{0} + + + {0}/{1} + + + {0}² + {0}² + + + {0}³ + {0}³ + + + {0}⋅{1} + + + ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + {0} ܚܝܠܐ ܢܬܘܦܘܬܐ + + + ܡ/ܪ² + {0} ܡ/ܪ² + {0} ܡ/ܪ² + + + ܚܘܕ + {0} ܚܘܕ + {0} ܚܘܕ + + + ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + {0} ܪܐܕܝܐܢ + + + ܕܪ̈ܓ݂ܐ + ܕܪܓ݂ܐ + {0} ܕܪ̈ܓ݂ܐ + + + ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + ܩܛܝܢܐ ܩܫܬܢܝܐ + {0} ܩܛܝ̈ܢܬܐ ܩܫܬܢܝܬܐ + + + ܪ̈ܦܦܐ ܩܫܬܢܝܐ + ܪܦܦܐ ܩܫܬܢܝܐ + {0} ܪ̈ܦܦܐ ܩܫܬܢ̈ܝܐ + + + ܟܡ² + {0} ܟܡ² + {0} ܟܡ² + {0}/ܟܡ² + + + ܗܟܬܪ + {0} ܗܟܬܪ + {0} ܗܟܬܪ + + + ܡ² + {0} ܡ² + {0} ܡ² + {0}/ܡ² + + + ܣܡ² + {0} ܣܡ² + {0} ܣܡ² + {0}/ܣܡ² + + + ܡܝܠ̈ܐ² + {0} ܡܝܠ̈ܐ² + {0} ܡܝܠ̈ܐ² + {0}/ܡܝܠ̈ܐ² + + + ܦܕܢܐ + {0} ܦܕܢܐ + {0} ܦ̈ܕܢܐ + + + ܝܪ̈ܕܐ² + {0} ܝܪܕܐ² + {0} ܝܪ̈ܕܐ² + + + ܐܩܠ̈ܐ² + {0} ܐܩܠܐ² + {0} ܐܩܠ̈ܐ² + + + ܐܢ² + {0}/ܐܢ² + {0}/ܐܢ² + {0}/ܐܢ² + + + ܩܪܛܐ + ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܡܓ/ܕܝܣܝܠܝܬܪܐ + {0} ܡܓ/ܕܝܣܝܠܝܬܪܐ + {0} ܡܓ/ܕܝܣܝܠܝܬܪܐ + + + ܡܡܘܠ܊/ܠ + {0} ܡܡܘܠ܊/ܠ + {0} ܡܡܘܠ܊/ܠ + + + ܡܠܘܐܐ + ܡܠܘܐܐ + {0} ܡܠܘܐ̈ܐ + + + ܡܢܘ̈ܬܐ/ܡܠܝܘܢ + {0} ܡܢܘܬܐ/ܡܠ܊ + {0} ܡܢܘ̈ܬܐ/ܡܠ܊ + + + ܒܡܐܐ + {0}% + {0}% + + + ܒܐܠܦܐ + {0}‰ + {0}‰ + + + + {0}‱ + {0}‱ + + + ܡܘܠ + {0} ܡܘܠ + {0} ܡܘܠ + + + ܠ/ܟܡ + {0} ܠ/ܟܡ + {0} ܠ/ܟܡ + + + ܠ/100ܟܡ + {0} ܠ/100ܟܡ + {0} ܠ/100ܟܡ + + + ܡܝܠ̈ܐ/ܓܠܘܢܐ + {0} ܡܝܠܐ ܒܓܠܘܢܐ + {0} ܡܝܠ̈ܐ ܒܓܠܘܢܐ + + + ܡܝܠ̈ܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܡܝܠܐ/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + {0} ܦܝܬܐܒܐܝܬ + + + ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + {0} ܬܝܪܐܒܐܝܬ + + + ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + {0} ܬܝܪܐܒܬ + + + ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + {0} ܓܝܓܐܒܐܝܬ + + + ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + {0} ܓܝܓܐܒܬ + + + ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + {0} ܡܝܓܐܒܐܝܬ + + + ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + {0} ܡܝܓܐܒܬ + + + ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + {0} ܟܝܠܘܒܐܝܬ + + + ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + {0} ܟܝܠܘܒܬ + + + ܒܐܝܬ + {0} ܒܐܝܬ + {0} ܒܐܝܬ + + + ܒܬ + {0} ܒܬ + {0} ܒܬ + + + ܕܪܐ + {0} ܕܪܐ + {0} ܕܪ̈ܐ + + + ܥܣܝܪܘܬܐ + {0} ܥܣܝܪܘܬܐ + {0} ܥܣܝܪ̈ܘܬܐ + + + ܫܢܬܐ + {0} ܫܢܬܐ + {0} ܫ̈ܢܐ + {0}/ܫܢܬܐ + + + ܪܘܒܥܐ + {0} ܪܘܒܥܐ + {0} ܪ̈ܘܒܥܐ + {0}/ܪܘܒܥܐ + + + ܝܪܚܐ + {0} ܝܪܚܐ + {0} ܝܪ̈ܚܐ + {0}/ܝܪܚܐ + + + ܫܒܘܥܐ + {0} ܫ + {0} ܫ + {0}/ܫ + + + ܝܘܡܐ + {0} ܝ + {0} ܝ + {0}/ܝܘܡܐ + + + ܫܥܬܐ + {0} ܫܥ + {0} ܫܥ + {0}/ܫܥ + + + ܩ + {0} ܩ + {0} ܩ + {0}/ܩ + + + ܪ + {0} ܪ + {0} ܪ + {0}/ܪ + + + ܡܝܠܝ ܪ + {0} ܡܝܠܝ ܪ + {0} ܡܝܠܝ ܪ + + + ܡܝܟܪܘ ܪ + {0} ܡܝܟܪܘ ܪ + {0} ܡܝܟܪܘ ܪ + + + ܢܐܢܘ ܪ + {0} ܢܐܢܘ ܪ + {0} ܢܐܢܘ ܪ + + + ܐܡܦܝܪ + {0} ܐܡܦܝܪ + {0} ܐܡܦܝܪ + + + ܡܝܠܝܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + {0} ܡ ܐܡܦܝܪ + + + ܘܗܡ + {0} ܘܗܡ + {0} ܘܗܡ + + + ܒܘܠܬ + {0} ܒܘܠܬ + {0} ܒܘܠܬ + + + ܟ ܟܐܠܘܪܝ + {0} ܟ ܟܐܠܘܪܝ + {0} ܟ ܟܐܠܘܪܝ + + + ܟܐܠ + {0} ܟܐܠ + {0} ܟܐܠ + + + ܟ ܓܝܐܘܠ + {0} ܟ ܓܝܐܘܠ + {0} ܟ ܓܝܐܘܠ + + + ܓܝܐܘܠ + {0} ܓܝܐܘܠ + {0} ܓܝܐܘܠ + + + ܟܘܫ܏-ܫ + {0} ܟܘܫ܏-ܫ + {0} ܟܘܫ܏-ܫ + + + ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + {0} ܐܠܝܟܬܪܘܢ ܒܘܠܬ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܒܪܝܛܢܝܐ + + + ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + {0} ܡܫܘܚܬܐ ܕܫܚܝܢܘܬܐ ܕܐܡܪܝܟܐ + + + ܢܝܘܬܢ + {0} ܢܝܘܬܢ + {0} ܢܝܘܬܢ + + + ܟܘܫ܊/100 ܟܡ + {0} ܟܘܫ܊ ܒ 100 ܟܡ + {0} ܟܘܫ܊ ܒ 100 ܟܡ + + + ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + {0} ܓܝܓܐܗܪܬܙ + + + ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + {0} ܡܝܓܐܗܪܬܙ + + + ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + {0} ܟܝܠܘܗܪܬܙ + + + ܗܪܬܙ + {0} ܗܪܬܙ + {0} ܗܪܬܙ + + + ܦܝ̈ܟܣܠܐ + {0} ܦܝܟܣܠܐ + {0} ܦܝܟܣܠܐ + + + ܡܝܓܐܦܝ̈ܟܣܠܐ + {0} ܡ.ܦܝܟܣܠܐ + {0} ܡ.ܦܝܟܣܠܐ + + + ܦܝ̈ܟܣܠܐ/ܣܡ + {0} ܦܝ̈ܟܣܠܐ/ܣܡ + {0} ܦܝ̈ܟܣܠܐ/ܣܡ + + + ܦܝ̈ܟܣܠܐ ܒܐܢܟ + {0} ܦܝ̈ܟܣܠܐ/ܐܢ + {0} ܦܝ̈ܟܣܠܐ/ܐܢ + + + ܥܘܒܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܐܪܥܝܐ + {0} ܥܘܒܐ ܐܪܥܝܐ + + + ܟܡ + {0}ܟܡ + {0}ܟܡ + {0}/ܟܡ + + + ܡ + {0}ܡ + {0}ܡ + {0}/ܡ + + + ܕܣܡ + {0}ܕܣܡ + {0}ܕܣܡ + + + ܣܡ + {0}ܣܡ + {0}ܣܡ + {0}/ܣܡ + + + ܡܡ + {0}ܡܡ + {0}ܡܡ + + + ܡܟܡ + {0}ܡܟܡ + {0}ܡܟܡ + + + ܢܡ + {0}ܢܡ + {0}ܢܡ + + + ܦܝܟܘܡܝܬܪܐ + {0} ܦܝܟܘܡܝܬܪܐ + {0} ܦܝܟܘܡܝܬܪܐ + + + ܡܝܠܐ + {0} ܡܝܠܐ + {0} ܡܝܠ̈ܐ + + + ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + {0} ܝܪܕ̈ܐ + + + ܐܩܠ̈ܐ + {0} ܐܩܠܐ + {0} ܐܩܠ̈ܐ + {0}/ܐܩܠܐ + + + ܐܢ܊ + ܚܕܐ ܐܢ܊ + {0} ܐܢ܊ + {0}/ܐܢܟ + + + ܦܪܣܚܐ + {0} ܦܪܣܚܐ + {0} ܦܪ̈ܣܚܐ + + + ܫ̈ܢܐ ܕܢܘܗܪܐ + {0} ܫ ܢ + {0} ܫ ܢ + + + ܡ.ܪ. + {0} ܡ.ܪ. + {0} ܡ.ܪ. + + + ܦܘܪܠܢܓ + {0} ܦܘܪܠܢܓ + {0} ܦܘܪ̈ܠܢܓ + + + ܡܝ̈ܠܐ ܝܡܝ̈ܐ + {0} ܡܝܠܐ ܝܡܝܐ + {0} ܡܝ̈ܠܐ ܝܡܝ̈ܐ + + + ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + {0} ܡܝ̈ܠܐ-ܐܣܟܢܕܝܢܒܝܝܢ + + + ܢܘܩܙ̈ܐ + {0} ܢܘܩܙܐ + {0} ܢܘܩܙ̈ܐ + + + ܥܘܒܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܫܡܫܝܐ + {0} ܥܘܒܐ ܫܡܫܝܐ + + + ܠܘܩܣ + {0} ܠܘܩܣ + {0} ܠܘܩܣ + + + ܢܗܝܪܐ + {0} ܢܗܝܪܐ + {0} ܢܗܝܪܐ + + + ܠܘܡܝܢ + {0} ܠܘܡܝܢ + {0} ܠܘܡܝܢ + + + ܬ.ܡ + {0} ܬ.ܡ + {0} ܬ.ܡ + + + ܟܓ + {0} ܟܓ + {0} ܟܓ + {0}/ܟܓ + + + ܓ + {0} ܓ + {0} ܓ + {0}/ܓ + + + ܡܓܡ + {0} ܡܓܡ + {0} ܡܓܡ + + + ܡܟܓܡ + {0} ܡܟܓܡ + {0} ܡܟܓܡ + + + ܬܘܢܐ + {0} ܬܘܢܐ + {0} ܬܘܢ̈ܐ + + + ܣܬܘܢ + {0} ܣܛܘܢ + {0} ܣܛܘܢ + + + ܡܢܝܐ + {0} ܡܢܝܐ + {0} ܡܢܝ̈ܐ + {0}/ܡܢܝܐ + + + ܐܘܢܩ̈ܝܐ + {0} ܐܘܢܩܝܐ + {0} ܐܘܢܩ̈ܝܐ + {0}/ܐܘܢܩܝܐ + + + ܩܪܛܐ + {0} ܩܪܛܐ + {0} ܩܪ̈ܛܐ + + + ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + {0} ܕܐܠܬܘܢ + + + ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + {0} ܥܘܫܢܐ ܐܪܥܝܐ + + + ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + {0} ܥܘܫܢܐ ܫܡܫܝܐ + + + ܦܪܕܐ + {0} ܦܪܕܐ + {0} ܦܪ̈ܕܐ + + + ܓ ܘܐܬ + {0} ܓ ܘܐܬ + {0} ܓ ܘܐܬ + + + ܡ ܘܐܬ + {0} ܡ ܘܐܬ + {0} ܡ ܘܐܬ + + + ܟ ܘܐܬ + {0} ܟ ܘܐܬ + {0} ܟ ܘܐܬ + + + ܘܐܬ + {0} ܘܐܬ + {0} ܘܐܬ + + + ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + {0} ܡܝܠܝܘܐܬ + + + ܚܝܠܐ ܕܣܘܣܝܐ + {0} ܣܘܣܝܐ + {0} ܣܘܣܝܐ + + + ܦܣܟܠ + {0} ܦܣܟ̈ܠܐ + {0} ܦܣܟ̈ܠܐ + + + ܗܟܬܘܦܣܟܠ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + {0} ܗܟܬܘܦܣܟ̈ܠܐ + + + ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + {0} ܟܝܠܘܦܣܟܠ + + + ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + {0} ܡܝܓܐܦܣܟܠ + + + ܟܡ/ܫ + {0} ܟܡ/ܫ + {0} ܟܡ/ܫ + + + ܡ/ܪ + {0} ܡ/ܪ + {0} ܡ/ܪ + + + ܡܝܠ̈ܐ/ܫ + {0} ܡܝܠܐ/ܫ + {0} ܡܝܠ̈ܐ/ܫ + + + ܩܛܪ̈ܐ + {0} ܩܛܪܐ + {0} ܩܛܪ̈ܐ + + + ° + {0}° + {0}° + + + °ܡ + {0}°ܡ + {0}°ܡ + + + °ܦ + {0}°ܦ + {0}°ܦ + + + ܕ ܟܠܒܝܢ + {0} ܕ ܟܠܒܝܢ + {0} ܕ ܟܠܒܝܢ + + + ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + {0} ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + {0} ܢܝܘܬܢ-ܡܝܬܪ̈ܐ + + + ܟܡ³ + {0} ܟܡ³ + {0} ܟܡ³ + + + ܡ³ + {0} ܡ³ + {0} ܡ³ + {0}/ܡ³ + + + ܣܡ³ + {0} ܣܡ³ + {0} ܣܡ³ + {0}/ܣܡ³ + + + ܡܝܠ̈ܐ³ + {0} ܡܝܠܐ³ + {0} ܡܝܠ̈ܐ³ + + + ܝܪ̈ܕܐ³ + {0} ܝܪܕܐ³ + {0} ܝܪ̈ܕܐ³ + + + ܐܩܠ̈ܐ³ + {0} ܐܩܠܐ³ + {0} ܐܩܠ̈ܐ³ + + + ܐܢ³ + {0} ܐܢ³ + {0} ܐܢ³ + + + ܡܝܓܐܠܝܬܪ̈ܐ + {0} ܡܝܓܐܠܝܬܪܐ + {0} ܡܝܓܐܠܝܬܪ̈ܐ + + + ܗܟܬܘܠܝܬܪ̈ܐ + {0} ܗܟܬܘܠܝܬܪܐ + {0} ܗܟܬܘܠܝܬܪ̈ܐ + + + ܠܝܬܪܐ + {0} ܠܝܬܪܐ + {0} ܠܝܬܪ̈ܐ + {0}/ܠ + + + ܕܝܣܝܠܝܬܪ̈ܐ + {0} ܕܝܣܝܠܝܬܪܐ + {0} ܕܝܣܝܠܝܬܪ̈ܐ + + + ܣܢܬܝܠܝܬܪ̈ܐ + {0} ܣܢܬܝܠܝܬܪܐ + {0} ܣܢܬܝܠܝܬܪ̈ܐ + + + ܡܠܬܪ + {0} ܡܠܬܪ܊ + {0} ܡܠܬܪ̈܊ + + + mpt + {0} mpt + {0} mpt + + + ܐܩܠ̈ܐ-ܦܕܢܐ + {0} ܐܩܠ̈ܐ-ܦܕܢܐ + {0} ܐܩܠ̈ܐ-ܦܕܢܐ + + + ܓܠܘܢ̈ܐ + {0} ܓܠܘܢܐ + {0} ܓܠܘܢ̈ܐ + {0}/ܓܠܘܢ̈ܐ + + + ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0}/ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ + + + ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩܝܐ ܪܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܐܘܢܩ̈ܝܐ ܪ̈ܕܘܝܐ ܐܡܦܪܬܘܪܝܐ + + + ܬܪ̈ܘܕܐ ܪ̈ܒܐ + {0} ܬܪܘܕܐ ܪܒܐ + {0} ܬܪ̈ܘܕܐ ܪ̈ܒܐ + + + ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + {0} ܬܪܘܕܐ ܙܥܘܪܐ + {0} ܬܪ̈ܘܕܐ ܙܥܘܪ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + {0} ܬܪܘܕܐ ܚܠܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ + + + ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪܘܕܐ ܚܠܝܐ ܐܡܦܪܬܘܪܝܐ + {0} ܬܪ̈ܘܕܐ ܚܠܝ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܛܘܦܬܐ + {0} ܛܘܦܬܐ + {0} ܛܘܦ̈ܐ + + + ܕܪܟܡܐ ܪܕܘܝܐ + {0} ܕܪܟܡܐ ܪܕܘܝܐ + {0} ܕܪ̈ܟܡܐ ܪ̈ܕܘܝܐ + + + ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪܘܒܥܐ ܓܠܘܢܐ ܐܡܦܪܬܘܪܝܐ + {0} ܪ̈ܘܒܥܐ ܓܠܘܢ̈ܐ ܐܡܦܪܬܘܪܝܐ + + + ܦܢܝܬܐ ܫܪܫܢܝܬܐ + {0} ܡܕܢܚܐ + {0} ܓܪܒܝܐ + {0} ܬܝܡܢܐ + {0} ܡܥܪܒ݂ܐ + + + + + + {0}، ܘ{1} + {0} ܘ{1} + + + {0}، ܝܐ {1} + {0} ܝܐ {1} + + + {0}, {1} + {0}, {1} + {0}، ܝܐ {1} + {0} ܝܐ {1} + + + {0}, {1} + {0}, {1} + {0}، ܝܐ {1} + {0} ܝܐ {1} + + + {0}, {1} + {0}, {1} + {0}، ܘ{1} + {0} ܘ{1} + + + {0}, {1} + {0}, {1} + {0}، ܘ{1} + {0} ܘ{1} + + + {0}, {1} + {0}, {1} + {0}، ܘ{1} + {0} ܘ{1} + + + {0}, {1} + {0}, {1} + {0}، ܘ{1} + {0} ܘ{1} + + + {0}, {1} + {0}, {1} + {0}، ܘ{1} + {0} ܘ{1} + + + + + ܗܐ:ܗ + ܠܐ:ܠ + + + + und syr + {0} {1} + + {title} {given} {given2} {surname} + + + {given-informal} {surname} + + + {title} {given} {given2} {surname} + + + {title} {given} {given2} {surname} + + + {given-monogram-allCaps}{given2-monogram-allCaps}{surname-monogram-allCaps} + + + {given-informal-monogram-allCaps}.{surname-monogram-allCaps} + + + {title} {given} {given2-initial} {surname} + + + {given-informal} {surname} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-monogram-allCaps}.{surname-monogram-allCaps} + + + {title} {given-initial} {surname} + + + {given-informal-initial}. {surname} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-monogram-allCaps}.{surname-monogram-allCaps} + + + {surname}، {given} {given2} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps}.{given-monogram-allCaps}.{given2-monogram-allCaps} + + + {surname-monogram-allCaps}.{given-informal-monogram-allCaps} + + + {surname}، {given} {given2-initial} + + + {surname} {given-informal} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname}، {given-initial} + + + {surname} {given-initial} + + + {title} {surname} + + + {given-informal} + + + {surname-monogram-allCaps} + + + {given-informal-monogram-allCaps} + + + {surname-prefix} {surname-core}، {given} {given2} + + + {surname}، {given-informal} + + + {surname-prefix} {surname-core}، {given} {given2-initial} + + + {surname}، {given-informal} + + + {surname-prefix} {surname-core}، {given} {given2-initial} + + + {surname}، {given-informal} + + + ܣܪܓܘܢ + + + ܐܝܫܬܪ + ܒܝܬ ܣܪܓܝܣ + + + ܝܘܚܢܢ + ܢܝܢܘܣ + ܢܝܢܘܝܐ + + + ܕܘܟܬܘܪ ܡܠܦܢܐ + ܫܡܝܪܡ + ܨܦܪܐ + ܣܒܝܢܐ + ܕ + ܐܠܩܘܫ + ܒܪܣܝܢ ܣܒܪܬܘ + ܐܣܝܐ + + + diff --git a/make/data/cldr/common/main/syr_IQ.xml b/make/data/cldr/common/main/syr_IQ.xml new file mode 100644 index 00000000000..01741894830 --- /dev/null +++ b/make/data/cldr/common/main/syr_IQ.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/syr_SY.xml b/make/data/cldr/common/main/syr_SY.xml new file mode 100644 index 00000000000..7a342c7a419 --- /dev/null +++ b/make/data/cldr/common/main/syr_SY.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/szl.xml b/make/data/cldr/common/main/szl.xml new file mode 100644 index 00000000000..f4e2e7e9fd2 --- /dev/null +++ b/make/data/cldr/common/main/szl.xml @@ -0,0 +1,5412 @@ + + + + + + + + + + + afrikaans + aghym + akan + amharski + arabski + asamski + asu + asturyjski + azerbejdżański + azerski + basaa + biołoruski + bymba + byna + bułgarski + bambara + byngalski + tybetański + bretōński + bodo + bośniacki + katalōński + czakma + czeczyński + cebuano + chiga + czirokeski + sorani + korsykański + czeski + cerkiewnosłowiański + walijski + duński + taita + niymiecki + austriacki niymiecki + szwajcarski wysokoniymiecki + dżerma + dolnołużycki + duala + diola + dzongkha + ymbu + ewe + grecki + angelski + australijski angelski + kanadyjski angelski + brytyjski angelski + angelski (Wlk. Bryt.) + amerykański angelski + angelski (USA) + esperanto + hiszpański + amerykański hiszpański + europejski hiszpański + meksykański hiszpański + estōński + baskijski + ewōndo + perski + fulani + fiński + filipino + farerski + francuski + kanadyjski francuski + szwajcarski francuski + cajuński + friulski + zachodniofryzyjski + irlandzki + szkocki gaelicki + galicyjski + szwajcarski niymiecki + gudżarati + gusii + manx + hausa + hawajski + hebrajski + hindi + hmōng + chorwacki + gōrnołużycki + kreolski haitański + wyngerski + ôrmiański + interlingua + indōnezyjski + igbo + syczuański + islandzki + italijański + japōński + ngōmbe + machame + jawajski + gruziński + kabylski + kamba + makōnde + kreolski Wysp Zielōnego Przilōndka + koyra chiini + kikuju + kazachski + kako + grynlandzki + kalynjin + khmerski + kannada + koreański + kōnkani + kaszmirski + sambala + bafia + gwara kolōńsko + kurdyjski + kornijski + kirgiski + łaciński + langi + luksymburski + ganda + lakota + lingala + laotański + kreolski luizjański + luryjski pōłnocny + litewski + luba-katanga + luo + luhya + łotewski + masajski + meru + kreolski Mauritiusa + malgaski + makua + meta + maoryjski + macedōński + malajalam + mōngolski + marathi + malajski + maltański + mundang + moc jynzykōw + birmański + mazanderański + nama + norweski (bokmål) + ndebele pōłnocny + dolnoniymiecki + dolnozaksōński + nepalski + niderlandzki + flamandzki + ngumba + norweski (nynorsk) + ngymboōn + nuer + njandża + nyankole + ôrōmo + ôrija + ôsetyjski + pyndżabski + polski + pruski + paszto + portugalski + brazylijski portugalski + europejski portugalski + keczua + retorōmański + rundi + rumuński + mołdawski + rōmbo + ruski + kinya-ruanda + rwa + sanskryt + jakucki + samburu + sangu + sindhi + pōłnocnolapōński + syna + koyraboro synni + sango + tashelhiyt + syngaleski + słowacki + słowyński + samoański + inari + shōna + sōmalijski + albański + serbski + sotho połedniowy + sundajski + szwedzki + suahili + kōngijski suahili + ślōnski + tamilski + telugu + ateso + tadżycki + tajski + tigrinia + turkmyński + tōnga + turecki + tatarski + tasawaq + tamazight (Atlas Postrzodkowy) + ujgurski + ukraiński + niyznōmy jynzyk + urdu + uzbecki + wai + wietnamski + wolapik + vunjo + walser + wolof + khosa + soga + yangbyn + jidysz + joruba + kantōński + standardowy marokański tamazight + chiński + chiński mandaryński + chiński uproszczōny + uproszczōny chiński mandaryński + chiński tradycyjny + tradycyjny chiński mandaryński + zulu + brak treści natury jynzykowyj + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Świat + Afryka + Pōłnocno Ameryka + Połedniowo Ameryka + Ôceanijo + Zachodnio Afryka + Postrzodkowo Ameryka + Wschodnio Afryka + Pōłnocno Afryka + Postrzodkowo Afryka + Połedniowo Afryka + Ameryka + Pōłnocno Ameryka (USA, Kanada) + Karajiby + Wschodnio Azyjo + Połedniowo Azyjo + Połedniowo-wschodnio Azyjo + Połedniowo Europa + Australazyjo + Melanezyjo + Regiōn Mikrōnezyje + Polinezyjo + Azyjo + Postrzodkowo Azyjo + Zachodnio Azyjo + Europa + Wschodnio Europa + Pōłnocno Europa + Zachodnio Europa + Subsaharyjsko Afryka + Łacińsko Ameryka + Wyspa Wniebostōmpiynio + Andora + Zjednoczōne Ymiraty Arabske + Afganistan + Antigua i Barbuda + Anguilla + Albanijo + Armynijo + Angola + Antarktyda + Argyntyna + Amerykańske Samoa + Austryjo + Australijo + Aruba + Wyspy Alandzkie + Azerbejdżan + Bośnia i Hercegowina + Barbados + Bangladesz + Belgijo + Burkina Faso + Bułgaryjo + Bahrajn + Burundi + Bynin + Saint-Barthélemy + Bermudy + Brunei + Boliwijo + Karajibske Niderlandy + Brazylijo + Bahamy + Bhutan + Wyspa Bouveta + Botswana + Biołoruś + Belize + Kanada + Kokosowe Wyspy + Dymokratyczno Republika Kōnga + Kōngo (DRK) + Republika Postrzodkowoafrykańsko + Kōngo + Republika Kōnga + Szwajcaryjo + Côte d’Ivoire + Wybrzeże Kości Słōniowyj + Wyspy Cooka + Chile + Kamerun + Chiny + Kolumbijo + Wyspa Clippertona + Kostaryka + Kuba + Republika Zielōnego Przilōndka + Curaçao + Godnio Wyspa + Cypr + Czechy + Czesko Republika + Niymcy + Diego Garcia + Dżibuti + Danijo + Dōminika + Dōminikana + Algeryjo + Ceuta i Melilla + Ekwador + Estōnijo + Egipt + Zachodnio Sahara + Erytrea + Hiszpanijo + Etiopijo + Europejsko Unijo + Strefa euro + Finlandyjo + Fidżi + Falklandy + Falklandy (Malwiny) + Mikrōnezyjo + Wyspy Ôwcze + Francyjo + Gabōn + Wielko Brytanijo + Wlk. Bryt. + Grynada + Gruzyjo + Francusko Gujana + Guernsey + Ghana + Gibraltar + Grynlandyjo + Gambijo + Gwinea + Gwadelupa + Rōwnikowo Gwinea + Grecyjo + Połedniowo Georgia i Połedniowy Sandwich + Gwatymala + Guam + Gwinea Bissau + Gujana + SRA Hōngkōng (Chiny) + Hōngkōng + Wyspy Heard i McDonalda + Hōnduras + Chorwacyjo + Haiti + Wyngry + Kanaryjske Wyspy + Indōnezyjo + Irlandyjo + Izrael + Wyspa Man + Indyjo + Brytyjske Terytorium Indyjskigo Ôceanu + Irak + Iran + Islandyjo + Italijo + Jersey + Jamajka + Jordanijo + Japōnijo + Kynijo + Kirgistan + Kambodża + Kiribati + Kōmory + Saint Kitts i Nevis + Pōłnocno Korea + Połedniowo Korea + Kuwejt + Kajmany + Kazachstan + Laos + Liban + Saint Lucia + Liechtenstein + Sri Lanka + Liberyjo + Lesotho + Litwa + Luksymburg + Łotwa + Libijo + Maroko + Mōnako + Mołdawijo + Czornogōra + Saint-Martin + Madagaskar + Wyspy Marshalla + Pōłnocno Macedōnijo + Mali + Mjanma (Birma) + Mōngolijo + SRA Makau (Chiny) + Makau + Pōłnocne Mariany + Martynika + Mauretanijo + Mōntserrat + Malta + Mauritius + Malediwy + Malawi + Meksyk + Malezyjo + Mozambik + Namibijo + Nowo Kaledōnijo + Niger + Norfolk + Nigeryjo + Nikaragua + Niderlandy + Norwegijo + Nepal + Nauru + Niue + Nowo Zelandyjo + Ōman + Panama + Peru + Francusko Polinezyjo + Papua-Nowo Gwinea + Filipiny + Pakistan + Polska + Saint-Pierre i Miquelon + Pitcairn + Portoryko + Palestyńske Terytoria + Palestyna + Portugalijo + Palau + Paragwaj + Katar + Ôceanijo — wyspy daleke + Reunion + Rumunijo + Serbijo + Rusyjo + Rwanda + Saudyjsko Arabijo + Wyspy Salōmōna + Seszele + Sudan + Szwecyjo + Singapur + Wyspa Świyntyj Helyny + Słowynijo + Svalbard i Jan Mayen + Słowacyjo + Sierra Leone + San Marino + Synegal + Sōmalijo + Surinam + Połedniowy Sudan + Wyspy Świyntego Tōmasza i Princowa + Salwador + Sint Maarten + Syryjo + Eswatini + Suazi + Tristan da Cunha + Turks i Caicos + Czad + Francuske Terytoria Połedniowe i Antarktyczne + Togo + Tajlandyjo + Tadżykistan + Tokelau + Timor-Leste + Wschodni Timor + Turkmynistan + Tunezyjo + Tōnga + Turcyjo + Trynidad i Tobago + Tuvalu + Tajwan + Tanzanijo + Ukrajina + Uganda + Daleke Myńsze Wyspy Stanōw Zjednoczōnych + Ôrganizacyjo Norodōw Zjednoczōnych + Stany Zjednoczōne + USA + Urugwaj + Uzbekistan + Watykan + Saint Vincent i Grynadyny + Wynezuela + Brytyjske Wyspy Dziewicze + Wyspy Dziewicze Stanōw Zjednoczōnych + Wietnam + Vanuatu + Wallis i Futuna + Samoa + Pseudoakcynty + Pseudodwurychtōnkowe + Kosowo + Jymyn + Majotta + Republika Połedniowyj Afryki + Zambijo + Zimbabwe + Niyznōmy regiōn + + + Gregoriański kalyndorz + Kalyndorz ISO-8601 + Sztandardowy porzōndek zortowanio + Cyfry zachodnie + + + brytyjski + amerykański + + + Jynzyk: {0} + Pismo: {0} + Regiōn: {0} + + + + [a ã b c ć d e f g h i j k l ł m n ń o ŏ ô õ ō p r s ś t u w y z ź ż] + [à ă â å ä ą ā æ č ç ď é è ĕ ê ě ë ę ē í ì ĭ î ï ī ľ ň ñ ó ò ö ø œ q ŕ ř š ß ť ú ù ŭ û ů ü ū v x ý ÿ ž] + [A B C Ć D E F G H I J K L Ł M N Ń O Ô Ō P Q R S Ś T U V W X Y Z Ź Ż] + [  \- ‑ , % ‰ + 0 1 2 3 4 5 6 7 8 9] + [\- ‐ ‑ – — , ; \: ! ? . … ' " ” „ « » ( ) \[ \] \{ \} § @ * / \& # % † ‡ ′ ″ ° ~] + + + + + » + « + + + + + + + + EEEE, d MMMM y G + GyMMMMEEEEd + + + + + d MMMM y G + GyMMMMd + + + + + d MMM y G + GyMMMd + + + + + dd.MM.y G + GyMMdd + + + + + + + {1} 'ô' {0} + + + {1} 'ô' {0} + + + + + {1} 'ô' {0} + + + {1} 'ô' {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + E, d + E, h:mm a + E, HH:mm + E, h:mm:ss a + E, HH:mm:ss + y G + MMM y G + d MMM y G + E, d MMM y G + d.MM + E, d.MM + d MMM + E, d MMM + d MMMM + y G + y G + MM.y G + d.MM.y G + E, d.MM.y G + LLL y G + d MMM y G + E, d MMM y G + LLLL y G + QQQ y G + QQQQ y G + + + {0}–{1} + + h B – h B + h–h B + + + h:mm B – h:mm B + h:mm–h:mm B + h:mm–h:mm B + + + d–d + + + y G – y G + y–y G + + + M.y GGGGG – M.y GGGGG + M.y – M.y GGGGG + M.y – M.y GGGGG + + + d.M.y – d.M.y GGGGG + d.M.y GGGGG – d.M.y GGGGG + d.M.y – d.M.y GGGGG + d.M.y – d.M.y GGGGG + + + E, d.M.y – E, d.M.y GGGGG + E, d.M.y GGGGG – E, d.M.y GGGGG + E, d.M.y – E, d.M.y GGGGG + E, d.M.y – E, d.M.y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + d–d MMM y G + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + h a–h a + h–h a + + + HH–HH + + + h:mm a–h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a–h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + dd.MM–dd.MM + dd.MM–dd.MM + + + E, dd.MM–E, dd.MM + E, dd.MM–E, dd.MM + + + LLL–LLL + + + d–d MMM + d MMM–d MMM + + + E, d MMM–E, d MMM + E, d MMM–E, d MMM + + + y–y + + + MM.y–MM.y + MM.y–MM.y + + + dd–dd.MM.y + dd.MM–dd.MM.y + dd.MM.y–dd.MM.y + + + E, dd.MM.y–E, dd.MM.y + E, dd.MM.y–E, dd.MM.y + E, dd.MM.y–E, dd.MM.y + + + LLL–LLL y + LLL y–LLL y + + + d–d MMM y + d MMM–d MMM y + d MMM y–d MMM y + + + E, d–E, d MMM y + E, d MMM y–E, d MMM y + E, d MMM y–E, d MMM y + + + LLLL–LLLL y + LLLL y–LLLL y + + + + + + + + + sty + lut + mar + kwi + moj + czy + lip + siy + wrz + paź + lis + gru + + + S + L + M + K + M + C + L + S + W + P + L + G + + + stycznia + lutego + marca + kwietnia + moja + czyrwca + lipca + siyrpnia + września + października + listopada + grudnia + + + + + sty + lut + mar + kwi + moj + czy + lip + siy + wrz + paź + lis + gru + + + S + L + M + K + M + C + L + S + W + P + L + G + + + styczyń + luty + marzec + kwieciyń + moj + czyrwiec + lipiec + siyrpiyń + wrzesiyń + październik + listopad + grudziyń + + + + + + + niy + pyń + wto + str + szt + piō + sob + + + n + p + w + s + s + p + s + + + nd + + wt + st + sz + pt + sb + + + niydziela + pyńdziałek + wtorek + strzoda + sztwortek + piōntek + sobota + + + + + niy + pyń + wto + str + szt + piō + sob + + + n + p + w + s + s + p + s + + + nd + + wt + st + sz + pt + sb + + + niydziela + pyńdziałek + wtorek + strzoda + sztwortek + piōntek + sobota + + + + + + + I szr. + II szr. + III szr. + IV szr. + + + I + II + III + IV + + + I sztwierć roku + II sztwierć roku + III sztwierć roku + IV sztwierć roku + + + + + I szr. + II szr. + III szr. + IV szr. + + + I + II + III + IV + + + I sztwierć roku + II sztwierć roku + III sztwierć roku + IV sztwierć roku + + + + + + + do połedniŏ + po połedniu + + + do połedniŏ + po połedniu + + + do połedniŏ + po połedniu + + + + + do połedniŏ + po połedniu + + + do połedniŏ + po połedniu + + + do połedniŏ + po połedniu + + + + + + przed naszōm erōm + p.n.e. + naszyj ery + n.e. + + + p.n.e. + n.e. + + + + + + EEEE, d MMMM y + yMMMMEEEEd + + + + + d MMMM y + yMMMMd + + + + + d MMM y + yMMMd + + + + + dd.MM.y + yMMdd + + + + + + + HH:mm:ss zzzz + + + + + HH:mm:ss z + + + + + HH:mm:ss + + + + + HH:mm + + + + + + + {1} 'ô' {0} + + + {1} 'ô' {0} + + + + + {1} 'ô' {0} + + + {1} 'ô' {0} + + + + + {1}, {0} + + + {1}, {0} + + + + + {1}, {0} + + + {1}, {0} + + + + E, d + E, HH:mm + E, HH:mm:ss + y G + MMM y G + d MMM y G + E, d MMM y G + d.MM + E, d.MM + d MMM + E, d MMM + d MMMM + MMMM, 'tydz'. W + MM.y + dd.MM.y + E, dd.MM.y + MMM y + d MMM y + E, d MMM y + MMMM y + QQQ y + QQQQ y + Y, 'tydz'. w + + + {0} {1} + + + {0}–{1} + + h B – h B + h–h B + + + h:mm B – h:mm B + h:mm–h:mm B + h:mm–h:mm B + + + d–d + + + y G – y G + y–y G + + + M.y GGGGG – M.y GGGGG + M.y – M.y GGGGG + M.y – M.y GGGGG + + + d.M.y – d.M.y GGGGG + d.M.y GGGGG – d.M.y GGGGG + d.M.y – d.M.y GGGGG + d.M.y – d.M.y GGGGG + + + E, d.M.y – E, d.M.y GGGGG + E, d.M.y GGGGG – E, d.M.y GGGGG + E, d.M.y – E, d.M.y GGGGG + E, d.M.y – E, d.M.y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + d–d MMM y G + d MMM y G – d MMM y G + d MMM – d MMM y G + d MMM y – d MMM y G + + + E, d MMM – E, d MMM y G + E, d MMM y G – E, d MMM y G + E, d MMM – E, d MMM y G + E, d MMM y – E, d MMM y G + + + h a–h a + h–h a + + + HH–HH + + + h:mm a–h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a–h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + dd.MM–dd.MM + dd.MM–dd.MM + + + E, dd.MM–E, dd.MM + E, dd.MM–E, dd.MM + + + LLL–LLL + + + d–d MMM + d MMM–d MMM + + + E, d MMM–E, d MMM + E, d MMM–E, d MMM + + + y–y + + + MM.y–MM.y + MM.y–MM.y + + + dd–dd.MM.y + dd.MM–dd.MM.y + dd.MM.y–dd.MM.y + + + E, dd.MM.y–E, dd.MM.y + E, dd.MM.y–E, dd.MM.y + E, dd.MM.y–E, dd.MM.y + + + LLL–LLL y + LLL y–LLL y + + + d–d MMM y + d MMM–d MMM y + d MMM y–d MMM y + + + E, d–E, d MMM y + E, d MMM y–E, d MMM y + E, d MMM y–E, d MMM y + + + LLLL–LLLL y + LLLL y–LLLL y + + + + + + + + era + + + era + + + era + + + rok + łōńskigo roku + latoś + na bezrok + + za {0} roku + + + {0} roku tymu + + + + r. + łōńskigo roku + latoś + na bezrok + + za {0} roku + + + {0} roku tymu + + + + r. + łōńskigo roku + latoś + na bezrok + + za {0} roku + + + {0} roku tymu + + + + sztwierć roku + w zeszłyj sztwierci roku + w tyj sztwierci roku + w prziszłyj sztwierci roku + + za {0} sztwierci roku + + + {0} sztwierci roku tymu + + + + szr. + w zeszłyj sztwierci roku + w tyj sztwierci roku + w prziszłyj sztwierci roku + + za {0} szr. + + + {0} szr. tymu + + + + szr. + w zeszłyj sztwierci roku + w tyj sztwierci roku + w prziszłyj sztwierci roku + + za {0} szr. + + + {0} szr. tymu + + + + miesiōnc + w zeszłym miesiōncu + w tym miesiōncu + na drugi miesiōnc + + za {0} miesiōnca + + + {0} miesiōnca tymu + + + + mies. + w zeszłym miesiōncu + w tym miesiōncu + na drugi miesiōnc + + za {0} mies. + + + {0} mies. tymu + + + + mc + w zeszłym miesiōncu + w tym miesiōncu + na drugi miesiōnc + + za {0} mies. + + + {0} mies. tymu + + + + tydziyń + w zeszłym tydniu + w tym tydniu + na drugi tydziyń + + za {0} tydnia + + + {0} tydnia tymu + + tydziyń {0} + + + tydz. + w zeszłym tydniu + w tym tydniu + na drugi tydziyń + + za {0} tyd. + + + {0} tyd. tymu + + tydziyń {0} + + + tydz. + w zeszłym tydniu + w tym tydniu + na drugi tydziyń + + za {0} tyd. + + + {0} tyd. tymu + + tydziyń {0} + + + tydziyń miesiōnca + + + tydz. mies. + + + tydz. mies. + + + dziyń + wczorej + dzisiej + jutro + + za {0} dnia + + + {0} dnia tymu + + + + dziyń + wczorej + dzisiej + jutro + + za {0} dnia + + + {0} dnia tymu + + + + dziyń + wczorej + dzisiej + jutro + + za {0} dnia + + + {0} dnia tymu + + + + dziyń roku + + + dz. roku + + + dz. r. + + + dziyń tydnia + + + dziyń tyd. + + + dziyń tyd. + + + dziyń miesiōnca + + + dziyń mies. + + + dziyń mies. + + + w zeszło niydziela + w ta niydziela + w prziszło niydziela + + za {0} niydziele + + + {0} niydziele tymu + + + + w zeszło niydziela + w ta niydziela + w prziszło niydziela + + za {0} niydziele + + + {0} niydziele tymu + + + + w zeszło niydziela + w ta niydziela + w prziszło niydziela + + za {0} niydziele + + + {0} niydziele tymu + + + + w zeszły pyńdziałek + w tyn pyńdziałek + w prziszły pyńdziałek + + za {0} pyńdziałku + + + {0} pyńdziałku tymu + + + + w zeszły pyńdziałek + w tyn pyńdziałek + w prziszły pyńdziałek + + za {0} pyńdziałku + + + {0} pyńdziałku tymu + + + + w zeszły pyńdziałek + w tyn pyńdziałek + w prziszły pyńdziałek + + za {0} pyńdziałku + + + {0} pyńdziałku tymu + + + + w zeszły wtorek + w tyn wtorek + w prziszły wtorek + + za {0} wtorku + + + {0} wtorku tymu + + + + w zeszły wtorek + w tyn wtorek + w prziszły wtorek + + za {0} wtorku + + + {0} wtorku tymu + + + + w zeszły wtorek + w tyn wtorek + w prziszły wtorek + + za {0} wtorku + + + {0} wtorku tymu + + + + w zeszło strzoda + w ta strzoda + w prziszło strzoda + + za {0} strzody + + + {0} strzody tymu + + + + w zeszło strzoda + w ta strzoda + w prziszło strzoda + + za {0} strzody + + + {0} strzody tymu + + + + w zeszło strzoda + w ta strzoda + w prziszło strzoda + + za {0} strzody + + + {0} strzody tymu + + + + w zeszły sztwortek + w tyn sztwortek + w prziszły sztwortek + + za {0} sztwortku + + + {0} sztwortku tymu + + + + w zeszły sztwortek + w tyn sztwortek + w prziszły sztwortek + + za {0} sztwortku + + + {0} sztwortku tymu + + + + w zeszły sztwortek + w tyn sztwortek + w prziszły sztwortek + + za {0} sztwortku + + + {0} sztwortku tymu + + + + w zeszły piōntek + w tyn piōntek + w prziszły piōntek + + za {0} piōntku + + + {0} piōntku tymu + + + + w zeszły piōntek + w tyn piōntek + w prziszły piōntek + + za {0} piōntku + + + {0} piōntku tymu + + + + w zeszły piōntek + w tyn piōntek + w prziszły piōntek + + za {0} piōntku + + + {0} piōntku tymu + + + + w zeszło sobota + w ta sobota + w prziszło sobota + + za {0} soboty + + + {0} soboty tymu + + + + w zeszło sobota + w ta sobota + w prziszło sobota + + za {0} soboty + + + {0} soboty tymu + + + + w zeszło sobota + w ta sobota + w prziszło sobota + + za {0} soboty + + + {0} soboty tymu + + + + rano / po połedniu / na wieczōr + + + rano / po połedniu / na wieczōr + + + rano / po poł. / na wiecz. + + + godzina + ta godzina + + za {0} godziny + + + {0} godziny tymu + + + + godz. + + za {0} godz. + + + {0} godz. tymu + + + + g. + + za {0} g. + + + {0} g. tymu + + + + minuta + ta minuta + + za {0} minuty + + + {0} minuty tymu + + + + min + + za {0} min + + + {0} min tymu + + + + min + + za {0} min + + + {0} min tymu + + + + sekunda + teraz + + za {0} sekundy + + + {0} sekundy tymu + + + + sek. + + za {0} sek. + + + {0} sek. tymu + + + + s + + za {0} s + + + {0} s tymu + + + + czasowo strefa + + + str. czasowo + + + str. czas. + + + + +HH:mm;-HH:mm + GMT{0} + GMT + czas: {0} + {0} (latowy czas) + {0} (sztandardowy czas) + {1} ({0}) + + + uniwersalny koordynowany czas + + + + Niyznōme miasto + + + Andora + + + Dubaj + + + Kabul + + + Antigua + + + Anguilla + + + Tirana + + + Erywań + + + Luanda + + + Rothera + + + Palmer + + + Troll + + + Syowa + + + Mawson + + + Davis + + + Wostok + + + Casey + + + Dumont d’Urville + + + McMurdo + + + Rio Gallegos + + + Myndoza + + + San Juan + + + Ushuaia + + + La Rioja + + + San Luis + + + Catamarca + + + Salta + + + Jujuy + + + Tucuman + + + Cordoba + + + Buenos Aires + + + Pago Pago + + + Wiedyń + + + Perth + + + Eucla + + + Darwin + + + Adelaide + + + Broken Hill + + + Melbourne + + + Currie + + + Hobart + + + Lindeman + + + Sydney + + + Brisbane + + + Macquarie + + + Lord Howe + + + Aruba + + + Maarianhamina + + + Baku + + + Sarajewo + + + Barbados + + + Dhaka + + + Bruksela + + + Wagadugu + + + Sofia + + + Bahrajn + + + Bużumbura + + + Porto Novo + + + Saint-Barthélymy + + + Bermudy + + + Brunei + + + La Paz + + + Kralendijk + + + Eirunepe + + + Rio Branco + + + Porto Velho + + + Boa Vista + + + Manaus + + + Cuiabá + + + Santarem + + + Campo Grande + + + Belém + + + Araguaina + + + Sao Paulo + + + Salvador + + + Fortaleza + + + Maceiō + + + Recife + + + Noronha + + + Nassau + + + Thimphu + + + Gaborone + + + Mińsk + + + Belize + + + Dawson + + + Whitehorse + + + Inuvik + + + Vancouver + + + Fort Nelson + + + Dawson Creek + + + Creston + + + Yellowknife + + + Edmonton + + + Swift Current + + + Cambridge Bay + + + Regina + + + Winnipeg + + + Resolute + + + Rainy River + + + Rankin Inlet + + + Atikokan + + + Thunder Bay + + + Nipigon + + + Toronto + + + Iqaluit + + + Pangnirtung + + + Moncton + + + Halifax + + + Goose Bay + + + Glace Bay + + + Blanc-Sablon + + + St. John’s + + + Wyspy Kokosowe + + + Kinszasa + + + Lubumbashi + + + Bangi + + + Brazzaville + + + Zurych + + + Abidżan + + + Rarotonga + + + Wyspa Wielkanocno + + + Punta Arenas + + + Santiago + + + Duala + + + Urumczi + + + Szanghaj + + + Bogota + + + Kostaryka + + + Hawana + + + Republika Zielōnego Przilōndka + + + Curaçao + + + Godnio Wyspa + + + Nikozja + + + Famagusta + + + Praga + + + Büsingen am Hochrhein + + + Berlin + + + Dżibuti + + + Kopynhaga + + + Dōminika + + + Santo Domingo + + + Alger + + + Galapagos + + + Guayaquil + + + Tallin + + + Kair + + + Al-Ujun + + + Asmara + + + Wyspy Kanaryjske + + + Ceuta + + + Madryt + + + Addis Abeba + + + Helsinki + + + Fidżi + + + Stanley + + + Chuuk + + + Pohnpei + + + Kosrae + + + Wyspy Ôwcze + + + Paryż + + + Libreville + + + + Brytyjski latowy czas + + Lōndyn + + + Grynada + + + Tbilisi + + + Kajynna + + + Guernsey + + + Akra + + + Gibraltar + + + Qaanaaq + + + Nuuk + + + Ittoqqortoormiit + + + Danmarkshavn + + + Bandżul + + + Kōnakry + + + Gwadelupa + + + Malabo + + + Atyny + + + Georgia Połedniowo + + + Gwatymala + + + Guam + + + Bissau + + + Gujana + + + Hōngkōng + + + Tegucigalpa + + + Zagrzeb + + + Port-au-Prince + + + Budapeszt + + + Dżakarta + + + Pontianak + + + Makassar + + + Jayapura + + + + Irlandyjo (latowy czas) + + Dublin + + + Jerozolima + + + Wyspa Man + + + Kalkuta + + + Czagos + + + Bagdad + + + Teheran + + + Reykjavik + + + Rzym + + + Jersey + + + Jamajka + + + Amman + + + Tokio + + + Nairobi + + + Biszkek + + + Phnom Penh + + + Enderbury + + + Kiritimati + + + Tarawa + + + Kōmory + + + Saint Kitts + + + Pjōngjang + + + Seul + + + Kuwejt + + + Kajmany + + + Aktau + + + Ôral + + + Atyrau + + + Aktiubińsk + + + Kustanaj + + + Kyzyłorda + + + Ałmaty + + + Wiyntian + + + Bejrut + + + Saint Lucia + + + Vaduz + + + Kolōmbo + + + Monrovia + + + Maseru + + + Wilno + + + Luksymburg + + + Ryga + + + Trypolis + + + Casablanca + + + Mōnako + + + Kiszyniōw + + + Podgorica + + + Marigot + + + Antananarywa + + + Kwajalein + + + Majuro + + + Skopje + + + Bamako + + + Rangun + + + Kobdo + + + Ułan Bator + + + Czojbalsan + + + Makau + + + Saipan + + + Martynika + + + Nawakszut + + + Mōntserrat + + + Malta + + + Malediwy + + + Blantyre + + + Tijuana + + + Hermosillo + + + Mazatlan + + + Chihuahua + + + Bahia Banderas + + + Ojinaga + + + Monterrey + + + Meksyk (miasto) + + + Matamoros + + + Merida + + + Cancún + + + Kuala Lumpur + + + Kuching + + + Maputo + + + Windhuk + + + Numea + + + Niamey + + + Norfolk + + + Lagos + + + Managua + + + Amsterdam + + + Ôslo + + + Katmandu + + + Nauru + + + Niue + + + Chatham + + + Auckland + + + Maskat + + + Panama + + + Lima + + + Tahiti + + + Markizy + + + Wyspy Gambiera + + + Port Moresby + + + Bougainville’owa Wyspa + + + Manila + + + Karaczi + + + Warszawa + + + Miquelon + + + Pitcairn + + + Portoryko + + + Gaza + + + Hebrōn + + + Azory + + + Madera + + + Lizbōna + + + Palau + + + Asuńcion + + + Katar + + + Réunion + + + Bukareszt + + + Belgrad + + + Kaliningrad + + + Moskwa + + + Wołgograd + + + Saratōw + + + Astrachań + + + Uljanowsk + + + Kirow + + + Samara + + + Jekaterynburg + + + Ômsk + + + Nowosybirsk + + + Barnauł + + + Tōmsk + + + Nowokuźnieck + + + Krasnojarsk + + + Irkuck + + + Czyta + + + Jakuck + + + Władywostok + + + Chandyga + + + Sachalin + + + Ust-Niera + + + Magadan + + + Sriedniekołymsk + + + Kamczatka + + + Anadyr + + + Kigali + + + Rijad + + + Guadalcanal + + + Mahé + + + Chartum + + + Sztokholm + + + Singapur + + + Świynto Helyna + + + Lublana + + + Longyearbyyn + + + Bratysława + + + Freetown + + + San Marino + + + Dakar + + + Mogadiszu + + + Paramaribo + + + Dżuba + + + São Tomé + + + Salwador + + + Lower Prince’s Quarter + + + Damaszek + + + Mbabane + + + Grand Turk + + + Ndżamena + + + Kerguelenowe Wyspy + + + Lomé + + + Bangkok + + + Duszanbe + + + Fakaofo + + + Dili + + + Aszchabad + + + Tunis + + + Tongatapu + + + Stambuł + + + Port-of-Spain + + + Funafuti + + + Tajpej + + + Dar es Salaam + + + Użgorod + + + Kijōw + + + Symferopol + + + Zaporoże + + + Kampala + + + Midway + + + Wake + + + Adak + + + Nome + + + Johnston + + + Anchorage + + + Yakutat + + + Sitka + + + Juneau + + + Metlakatla + + + Los Angeles + + + Boise + + + Phoenix + + + Denver + + + Beulah, Pōłnocno Dakota + + + New Salem, Pōłnocno Dakota + + + Center, Pōłnocno Dakota + + + Chicago + + + Mynominee + + + Vincennes, Indiana + + + Petersburg, Indiana + + + Tell City, Indiana + + + Knox, Indiana + + + Winamac, Indiana + + + Marengo, Indiana + + + Indianapolis + + + Louisville + + + Vevay, Indiana + + + Monticello + + + Detroit + + + Nowy Jork + + + Montevideo + + + Samarkanda + + + Taszkynt + + + Watykan + + + Saint Vincent + + + Caracas + + + Tortola + + + Saint Thomas + + + Ho Chi Minh + + + Efate + + + Wallis + + + Apia + + + Adyn + + + Majotta + + + Johannesburg + + + Lusaka + + + Harare + + + + Afganistan + + + + + postrzodkowoafrykański czas + + + + + wschodnioafrykański czas + + + + + połedniowoafrykański czas + + + + + zachodnioafrykański czas + zachodnioafrykański sztandardowy czas + zachodnioafrykański latowy czas + + + + + czas alaskański + alaskański czas sztandardowy + alaskański czas latowy + + + + + czas ałmacki + czas ałmacki sztandardowy + czas ałmacki latowy + + + + + amazōński czas + amazōński sztandardowy czas + amazōński latowy czas + + + + + czas postrzodkowoamerykański + czas postrzodkowoamerykański sztandardowy + czas postrzodkowoamerykański latowy + + + + + czas wschodnioamerykański + czas wschodnioamerykański sztandardowy + czas wschodnioamerykański latowy + + + + + czas gōrski + czas gōrski sztandardowy + czas gōrski latowy + + + + + czas pacyficzny + czas pacyficzny sztandardowy + czas pacyficzny latowy + + + + + czas Anadyr + sztandardowy czas Anadyr + latowy czas Anadyr + + + + + czas auktaucki + czas auktaucki sztandardowy + czas auktaucki latowy + + + + + czas aktiubiński + czas aktiubiński sztandardowy + czas aktiubiński latowy + + + + + Pōłwysep Arabski + Pōłwysep Arabski (sztandardowy czas) + Pōłwysep Arabski (latowy czas) + + + + + Argyntyna + Argyntyna (sztandardowy czas) + Argyntyna (latowy czas) + + + + + Argyntyna Zachodnio + Argyntyna Zachodnio (sztandardowy czas) + Argyntyna Zachodnio (latowy czas) + + + + + Armynijo + Armynijo (sztandardowy czas) + Armynijo (latowy czas) + + + + + czas atlantycki + czas atlantycki sztandardowy + czas atlantycki latowy + + + + + postrzodkowoaustralijski czas + postrzodkowoaustralijski sztandardowy czas + postrzodkowoaustralijski latowy czas + + + + + postrzodkowo-zachodnioaustralijski czas + postrzodkowo-zachodnioaustralijski sztandardowy czas + postrzodkowo-zachodnioaustralijski latowy czas + + + + + wschodnioaustralijski czas + wschodnioaustralijski sztandardowy czas + wschodnioaustralijski latowy czas + + + + + zachodnioaustralijski czas + zachodnioaustralijski sztandardowy czas + zachodnioaustralijski latowy czas + + + + + Azerbejdżan + Azerbejdżan (sztandardowy czas) + Azerbejdżan (latowy czas) + + + + + Azory + Azory (sztandardowy czas) + Azory (latowy czas) + + + + + Bangladesz + Bangladesz (sztandardowy czas) + Bangladesz (latowy czas) + + + + + Boliwijo + + + + + Brasília + Brasília (sztandardowy czas) + Brasília (latowy czas) + + + + + Wyspy Zielōnego Przilōndka + Wyspy Zielōnego Przilōndka (sztandardowy czas) + Wyspy Zielōnego Przilōndka (latowy czas) + + + + + Czamorro + + + + + czas Chile + Chile (sztandardowy czas) + Chile (latowy czas) + + + + + Chiny + Chiny (sztandardowy czas) + Chiny (latowy czas) + + + + + Czojbalsan + Czojbalsan (sztandardowy czas) + Czojbalsan (latowy czas) + + + + + Godnio Wyspa + + + + + Wyspy Kokosowe + + + + + Kolumbijo + Kolumbijo (sztandardowy czas) + Kolumbijo (latowy czas) + + + + + Wyspy Cooka + Wyspy Cooka (sztandardowy czas) + Wyspy Cooka (latowy czas) + + + + + Kuba + Kuba (sztandardowy czas) + Kuba (latowy czas) + + + + + Dumont-d’Urville + + + + + Timor Wschodni + + + + + Wyspa Wielkanocno + Wyspa Wielkanocno (sztandardowy czas) + Wyspa Wielkanocno (latowy czas) + + + + + Ekwador + + + + + postrzodkowoeuropejski czas + postrzodkowoeuropejski sztandardowy czas + postrzodkowoeuropejski latowy czas + + + CET + CET + CEST + + + + + wschodnioeuropejski czas + wschodnioeuropejski sztandardowy czas + wschodnioeuropejski latowy czas + + + EET + EET + EEST + + + + + wschodnioeuropejski dalszy czas + + + + + zachodnioeuropejski czas + zachodnioeuropejski sztandardowy czas + zachodnioeuropejski latowy czas + + + WET + WET + WEST + + + + + Falklandy + Falklandy (sztandardowy czas) + Falklandy (latowy czas) + + + + + Fidżi + Fidżi (sztandardowy czas) + Fidżi (latowy czas) + + + + + Gujana Francusko + + + + + Francuske Terytoria Połedniowe i Antarktyczne + + + + + czas Galapagos + + + + + Wyspy Gambiera + + + + + Gruzyjo + Gruzyjo (sztandardowy czas) + Gruzyjo (latowy czas) + + + + + Gilbertowe Wyspy + + + + + uniwersalny czas + + + + + Grynlandyjo Wschodnia + Grynlandyjo Wschodnia (sztandardowy czas) + Grynlandyjo Wschodnia (latowy czas) + + + + + Grynlandyjo Zachodnio + Grynlandyjo Zachodnio (sztandardowy czas) + Grynlandyjo Zachodnio (latowy czas) + + + + + Zatoka Perska + + + + + Gujana + + + + + Hawaje-Aleuty + Hawaje-Aleuty (sztandardowy czas) + Hawaje-Aleuty (latowy czas) + + + + + Hōngkōng + Hōngkōng (sztandardowy czas) + Hōngkōng (latowy czas) + + + + + Kobdo + Kobdo (sztandardowy czas) + Kobdo (latowy czas) + + + + + indyjski sztandardowy czas + + + + + Ôcean Indyjski + + + + + indochiński czas + + + + + Indōnezyjo Postrzodkowo + + + + + Indōnezyjo Wschodnio + + + + + Indōnezyjo Zachodnio + + + + + Irkuck + Irkuck (sztandardowy czas) + Irkuck (latowy czas) + + + + + Izrael + Izrael (sztandardowy czas) + Izrael (latowy czas) + + + + + Japōnijo + Japōnijo (sztandardowy czas) + Japōnijo (latowy czas) + + + + + czas Pietropawłowsk Kamczacki + sztandardowy czas Pietropawłowsk Kamczacki + czas Pietropawłowsk Kamczacki latowy + + + + + Kazachstan Wschodni + + + + + Kazachstan Zachodni + + + + + Krasnojarsk + Krasnojarsk (sztandardowy czas) + Krasnojarsk (latowy czas) + + + + + Kirgistan + + + + + Line Islands + + + + + Lord Howe + Lord Howe (sztandardowy czas) + Lord Howe (latowy czas) + + + + + Malezyjo + + + + + Malediwy + + + + + Markizy + + + + + Wyspy Marshalla + + + + + Meksyk Pōłnocno-Zachodni + Meksyk Pōłnocno-Zachodni (sztandardowy czas) + Meksyk Pōłnocno-Zachodni (latowy czas) + + + + + Meksyk (czas pacyficzny) + Meksyk (czas pacyficzny sztandardowy) + Meksyk (czas pacyficzny latowy) + + + + + Ułan Bator + Ułan Bator (sztandardowy czas) + Ułan Bator (latowy czas) + + + + + Moskwa + Moskwa (sztandardowy) + Moskwa (latowy) + + + + + Mjanma + + + + + Nowo Kaledōnijo + Nowo Kaledōnijo (sztandardowy czas) + Nowo Kaledōnijo (latowy czas) + + + + + Nowo Zelandyjo + Nowo Zelandyjo (sztandardowy czas) + Nowo Zelandyjo (latowy czas) + + + + + Nowo Fundlandyjo + Nowo Fundlandyjo (sztandardowy czas) + Nowo Fundlandyjo (latowy czas) + + + + + Fernando de Noronha + Fernando de Noronha (sztandardowy czas) + Fernando de Noronha (latowy czas) + + + + + Nowosybirsk + Nowosybirsk (sztandardowy czas) + Nowosybirsk (latowy czas) + + + + + Ômsk + Ômsk (sztandardowy czas) + Ômsk (latowy czas) + + + + + Papua-Nowo Gwinea + + + + + Paragwaj + Paragwaj (sztandardowy czas) + Paragwaj (latowy czas) + + + + + czas Peru + Peru (sztandardowy czas) + Peru (latowy czas) + + + + + Filipiny + Filipiny (sztandardowy czas) + Filipiny (latowy czas) + + + + + Fyniks + + + + + Saint-Pierre i Miquelon + Saint-Pierre i Miquelon (sztandardowy czas) + Saint-Pierre i Miquelon (latowy czas) + + + + + Pohnpei + + + + + Pjōngjang + + + + + czas kyzyłordzki + czas kyzyłordzki sztandardowy + czas kyzyłordzki latowy + + + + + Sachalin + Sachalin (sztandardowy czas) + Sachalin (latowy czas) + + + + + czas Samara + sztandardowy czas Samara + czas Samara latowy + + + + + Seszele + + + + + Singapur + + + + + Wyspy Salōmōna + + + + + Georgia Połedniowo + + + + + Surinam + + + + + Tajpej + Tajpej (sztandardowy czas) + Tajpej (latowy czas) + + + + + Tadżykistan + + + + + Tōnga + Tōnga (sztandardowy czas) + Tōnga (latowy czas) + + + + + Chuuk + + + + + Turkmynistan + Turkmynistan (sztandardowy czas) + Turkmynistan (latowy czas) + + + + + Urugwaj + Urugwaj (sztandardowy czas) + Urugwaj (latowy czas) + + + + + Wynezuela + + + + + Władywostok + Władywostok (sztandardowy czas) + Władywostok (latowy czas) + + + + + Wołgograd + Wołgograd (sztandardowy czas) + Wołgograd (latowy czas) + + + + + Wostok + + + + + Wallis i Futuna + + + + + Jakuck + Jakuck (sztandardowy czas) + Jakuck (latowy czas) + + + + + Jekaterynburg + Jekaterynburg (sztandardowy czas) + Jekaterynburg (latowy czas) + + + + + czas jukōński + + + + + + + , +   + + + + + ¤ #,##0.00 + #,##0.00 + + + + + + + + + + {0} dni + Skryńć we {0}. prawo. + + + + + + {0} na {1} + + + {0}⋅{1} + + + stało grawitacyje + {0} stałyj grawitacyje + + + metry na sekunda do kwadratu + {0} metra na sekunda do kwadratu + + + ôbrōt + {0} ôbrotu + + + radiany + {0} radiana + + + stopnie + {0} stopnia + + + minuty kōntowe + {0} minuty kōntowyj + + + sekundy kōntowe + {0} sekundy kōntowyj + + + kilōmetry kwadratowe + {0} kilōmetra kwadratowego + {0} na kilōmeter kwadratowy + + + hektary + {0} hektara + + + metry kwadratowe + {0} metra kwadratowego + {0} na meter kwadratowy + + + cyntymetry kwadratowe + {0} cyntymetra kwadratowego + {0} na cyntymeter kwadratowy + + + mile kwadratowe + {0} mili kwadratowyj + {0} na mila kwadratowōm + + + akry + {0} akra + + + jardy kwadratowe + {0} jarda kwadratowego + + + stopy kwadratowe + {0} stopy kwadratowyj + + + cale kwadratowe + {0} cala kwadratowego + {0} na cal kwadratowy + + + dunamy + {0} dunama + + + karaty + {0} karata + + + miligramy na decyliter + {0} miligrama na decyliter + + + milimole na liter + {0} milimola na liter + + + czyńści na milijōn + {0} czyńści na milijōn + + + procynt + {0} procynt + + + prōmil + {0} prōmila + + + punkt bazowy + {0} punktu bazowego + + + mol + {0} mola + + + litry na kilōmeter + {0} litra na kilōmeter + + + litry na 100 kilōmetrōw + {0} litra na 100 kilōmetrōw + + + mile na galōn + {0} mile na galōn + + + mile na galōn angelski + {0} mile na galōn angelski + + + petabajty + {0} petabajta + + + terabajty + {0} terabajta + + + terabity + {0} terabitu + + + gigabajty + {0} gigabajta + + + gigabity + {0} gigabitu + + + megabajty + {0} megabajta + + + megabity + {0} megabitu + + + kilobajty + {0} kilobajta + + + kilobity + {0} kilobitu + + + bajty + {0} bajta + + + bity + {0} bitu + + + stolecie + {0} stolecio + + + dekady + {0} dekady + + + lata + {0} roku + {0} na rok + + + miesiōnce + {0} miesiōnca + {0} na miesiōnc + + + tydnie + {0} tydnia + {0} na tydziyń + + + dni + {0} dnia + {0} na dziyń + + + godziny + {0} godziny + {0} na godzina + + + minuty + {0} minuty + {0} na minuta + + + sekundy + {0} sekundy + {0} na sekunda + + + milisekundy + {0} milisekundy + + + mikrosekundy + {0} mikrosekundy + + + nanosekundy + {0} nanosekundy + + + ampry + {0} ampra + + + miliampry + {0} miliampra + + + ōmy + {0} ōma + + + wolty + {0} wolta + + + kilokaloryje + {0} kilokaloryje + + + kaloryje + {0} kaloryje + + + kaloryje + {0} kaloryje + + + kilodżule + {0} kilodżula + + + dżule + {0} dżula + + + kilowatogodziny + {0} kilowatogodziny + + + elektrōnowolty + {0} elektrōnowolta + + + brytyjsko jednostka ciepła + {0} brytyjskij jednostki ciepła + + + term amerykański + {0} terma amerykańskigo + + + fōnt-siła + {0} fōnta-siły + + + niutōny + {0} niutōna + + + gigaherce + {0} gigaherca + + + megaherce + {0} megaherca + + + kiloherce + {0} kiloherca + + + herce + {0} herca + + + typograficzne ym + {0} yma + + + piksele + {0} piksela + + + megapiksele + {0} megapiksela + + + piksele na cyntymeter + {0} piksela na cyntymeter + + + piksele na col + {0} piksela na col + + + pōnkty na cyntymeter + {0} pōnkta na cyntymeter + + + pōnkty na col + {0} pōnkta na col + + + kilōmetry + {0} kilōmetra + {0} na kilōmeter + + + metry + {0} metra + {0} na meter + + + decymetry + {0} decymetra + + + cyntymetry + {0} cyntymetra + {0} na cyntymeter + + + milimetry + {0} milimetra + + + mikrōmetry + {0} mikrōmetra + + + nanōmetry + {0} nanōmetra + + + pikōmetry + {0} pikōmetra + + + mile + {0} mile + + + jardy + {0} jarda + + + stopy + {0} stopy + {0} na stopa + + + cole + {0} cola + {0} na col + + + parseki + {0} parseka + + + lata świytlne + {0} roku świytlnego + + + jednostki astrōnōmiczne + {0} jednostki astrōnōmicznyj + + + mile morske + {0} mile morskij + + + mila skandynawsko + {0} mile skandynawskij + + + punkty + {0} pkt. + + + prōmiynie Słōńca + {0} prōmiynia Słōńca + + + luksy + {0} luksu + + + jasność Słōńca + {0} jasności Słōńca + + + tōny + {0} tōny + + + kilogramy + {0} kilograma + {0} na kilogram + + + gramy + {0} grama + {0} na gram + + + miligramy + {0} miligrama + + + mikrogramy + {0} mikrograma + + + krōtke tōny + {0} krōtkij tōny + + + fōnty + {0} fōnta + {0} na fōnt + + + uncyje + {0} uncyje + {0} na uncyjo + + + uncyjo trojańsko + {0} uncyje trojańskij + + + karaty + {0} karata + + + daltōny + {0} daltōna + + + masa Ziymie + {0} masy Ziymie + + + masa Słōńca + {0} masy Słōńca + + + gigawaty + {0} gigawata + + + megawaty + {0} megawata + + + kilowaty + {0} kilowata + + + waty + {0} wata + + + miliwaty + {0} miliwata + + + kōnie mechaniczne + {0} kōnia mechanicznego + + + milimetry supa rtyńci + {0} milimetra supa rtyńci + + + fōnty na col kwadratowy + {0} fōnta na col kwadratowy + + + cole supa rtyńci + {0} cola supa rtyńci + + + bary + {0} bara + + + milibary + {0} millibara + + + atmosfery + {0} atmosfery + + + paskale + {0} paskala + + + hektopaskale + {0} hektopaskala + + + kilopaskale + {0} kilopaskala + + + megapaskale + {0} megapaskala + + + kilōmetry na godzina + {0} kilōmetra na godzina + + + metry na sekunda + {0} metra na sekunda + + + mile na godzina + {0} mile na godzina + + + wynzeł + {0} wynzła + + + stopnie + {0} stopnia + + + stopnie Celsjusza + {0} stopnia Celsjusza + + + stopnie Fahrenheita + {0} stopnia Fahrenheita + + + kelwiny + {0} kelwina + + + stopofunty + {0} stopofunt + + + niutōnōmetry + {0} niutōnōmetra + + + kilōmetry sześciynne + {0} kilōmetra sześciynnego + + + metry sześciynne + {0} metra sześciynnego + {0} na meter sześciynny + + + cyntymetry sześciynne + {0} cyntymetra sześciynnego + {0} na cyntymeter sześciynny + + + mile sześciynne + {0} mile sześciynnyj + + + jardy sześciynne + {0} jarda sześciynnego + + + stopy sześciynne + {0} stopy sześciynnyj + + + cale sześciynne + {0} cala sześciynnego + + + megalitry + {0} megalitra + + + hektolitry + {0} hektolitra + + + litry + {0} litra + {0} na liter + + + decylitry + {0} decylitra + + + cyntylitry + {0} cyntylitra + + + mililitry + {0} mililitra + + + pōłkworty metryczne + {0} pōłkworty metrycznyj + + + ćwierćkwarty metryczne + {0} ćwierćkwarty metrycznyj + + + akro-stopy + {0} akro-stopy + + + galōny + {0} galōna + {0} na galōn + + + galōny angelske + {0} galōna angelskigo + {0} na galōn angelski + + + kworty + {0} kworty + + + pōłkworty + {0} pōłkworty + + + ćwierćkworty + {0} ćwierćkworty + + + uncyje płynu + {0} uncyje płynu + + + uncyje płynu imp. + {0} uncyje płynu imp. + + + łyżki stołowe + {0} łyżki stołowyj + + + łyżeczki + {0} łyżeczki + + + baryłki + {0} baryłki + + + rychtōnek świata + {0} dugości geograficznyj wschodnij + {0} szyrokości geograficznyj pōłnocnyj + {0} szyrokości geograficznyj połedniowyj + {0} dugości geograficznyj zachodnij + + + + + G + {0} G + + + ôbr. + {0} ôbr. + + + stopnie + + + minuty + + + sekundy + + + ha + + + akry + + + jd² + {0} jd² + + + st² + {0} st² + + + + {0} c² + {0}/c² + + + dunamy + {0} dunama + + + karaty + + + mg/dl + {0} mg/dl + + + milimole/liter + {0} mmol/l + + + czyńści/miliōn + {0} cz/mln + + + procynt + + + prōmil + + + pōnkt bazowy + {0}‱ + + + mol + {0} mola + + + l/km + {0} l/km + + + l/100 km + {0} l/100 km + + + mpg + {0} mpg + + + mile/gal ang. + {0} mi/gal ang. + + + bajty + {0} B + + + bity + {0} b + + + st. + {0} st. + + + dek. + {0} dek. + + + lata + {0} roku + {0}/rok + + + miesiōnce + {0} mies. + {0}/mies. + + + tydnie + {0} tyd. + {0}/tydz. + + + dni + {0} dnia + {0}/dziyń + + + godziny + {0} godz. + + + minuty + + + sekundy + {0} sek. + + + milisekundy + + + ampry + + + ōmy + + + wolty + + + col + {0} col + + + J + + + elektrōnowolt + {0} eV + + + BTU + {0} Btu + + + term USA + {0} terma USA + + + fōnt-siła + {0} lbf + + + niutōn + {0} N + + + ym + {0} yma + + + piksele + {0} pks + + + megapiksele + {0} mp + + + pks/cm + {0} pks/cm + + + pks/c + {0} pks/c + + + pk/cm + {0} pk/cm + + + pk/c + {0} pk/c + + + metry + + + cyntymetry + + + mile + {0} mili + + + stopy + + + cale + {0} cala + {0}/cal + + + lata świetlne + {0} lś + + + j.a. + {0} j.a. + + + Mm + {0} Mm + + + punkty + {0} pkt. + + + prōmiynie Słōńca + {0} R☉ + + + lks + {0} lks + + + jasność Słōńca + {0} L☉ + + + g + + + fōnty + + + karaty + {0} kt + + + daltōny + {0} Da + + + masa Ziymie + {0} M⊕ + + + masa Słōńca + {0} M☉ + + + waty + + + KM + {0} KM + + + kPa + {0} kPa + + + MPa + {0} MPa + + + w. + {0} w. + + + lbf⋅ft + {0} lbf⋅ft + + + N⋅m + {0} N⋅m + + + jd³ + {0} jd³ + + + st³ + {0} st³ + + + + {0} c³ + + + Ml + {0} Ml + + + hl + {0} hl + + + litry + + + dl + {0} dl + + + cl + {0} cl + + + ml + {0} ml + + + pkwm. + {0} pkwm. + + + ćwkwm. + {0} ćwkwm. + + + akst. + {0} akst. + + + gal + {0} gal + {0}/gal + + + gal ang. + {0} gal ang. + {0}/gal ang. + + + kw. + {0} kw. + + + pōłkworty + {0} pkw. + + + ćwierćkworty + {0} ćwkw. + + + fl oz + {0} fl oz + + + fl oz imp. + {0} fl oz imp. + + + ł. stoł. + {0} ł. stoł. + + + łyżeczki + {0} łyżeczki + + + baryłki + {0} bbl + + + rychtōnek + + + + + {0}/{1} + + + {0}⋅{1} + + + {0} G + + + {0}′ + + + {0}″ + + + procynt + {0}% + + + l/100 km + {0} l/100 km + + + rok + {0} r. + + + miesiōnc + {0} mies. + + + tydziyń + {0} tyd. + + + dziyń + {0} dn. + {0}/d. + + + godzina + {0} g. + + + minuty + {0} min + + + sekundy + {0} sek. + + + milisekundy + {0} ms + + + km + {0} km + + + metry + {0} m + + + cyntymetry + {0} cm + + + mm + {0} mm + + + mile + + + stopy + + + cale + {0}″ + {0}/cal + + + kg + {0} kg + + + g + {0} g + + + funty + + + {0} KM + + + km/h + {0} km/h + + + °C + {0}°C + + + liter + {0} l + + + rychtōnek + {0}E + {0}N + {0}S + {0}W + + + + h:mm + + + h:mm:ss + + + m:ss + + + + + {0} i {1} + {0} i {1} + + + {0} abo {1} + {0} abo {1} + + + {0}, {1} + {0}, {1} + {0}, abo {1} + {0} abo {1} + + + {0}, {1} + {0}, {1} + {0}, abo {1} + {0} abo {1} + + + {0}, {1} + {0}, {1} + {0} i {1} + {0} i {1} + + + {0}, {1} + {0}, {1} + {0} i {1} + {0} i {1} + + + {0}, {1} + {0}, {1} + {0} i {1} + {0} i {1} + + + {0}, {1} + {0}, {1} + {0} i {1} + {0} i {1} + + + {0}, {1} + {0}, {1} + {0} i {1} + {0} i {1} + + + + + niy:n + ja:j + + + diff --git a/make/data/cldr/common/main/szl_PL.xml b/make/data/cldr/common/main/szl_PL.xml new file mode 100644 index 00000000000..bb8c99c383c --- /dev/null +++ b/make/data/cldr/common/main/szl_PL.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ta.xml b/make/data/cldr/common/main/ta.xml index 46a0903e2b0..9eaa6f37d39 100644 --- a/make/data/cldr/common/main/ta.xml +++ b/make/data/cldr/common/main/ta.xml @@ -1,6 +1,6 @@ - + + + + + + + + አፋርኛ + አብሐዚኛ + አፍሪቃንስኛ + አምሐረኛ + ዐርቢኛ + አሳሜዛዊ + አያማርኛ + አዜርባይጃንኛ + ባስኪርኛ + ቤላራሻኛ + ቡልጋሪኛ + ቢስላምኛ + በንጋሊኛ + ትበትንኛ + ብሬቶንኛ + ብሊን + ካታላንኛ + ኮርሲካኛ + ቼክኛ + ወልሽ + ዴኒሽ + ጀርመን + ድዞንግኻኛ + ግሪክኛ + እንግሊዝኛ + ኤስፐራንቶ + ስፓኒሽ + ኤስቶኒአን + ባስክኛ + ፐርሲያኛ + ፊኒሽ + ፊጂኛ + ፋሮኛ + ፈረንሳይኛ + ፍሪስኛ + አይሪሽ + እስኮትስ ጌልክኛ + ግዕዝኛ + ጋለጋኛ + ጓራኒኛ + ጉጃርቲኛ + ሃውሳኛ + ዕብራስጥ + ሐንድኛ + ክሮሽያንኛ + ሀንጋሪኛ + አርመናዊ + ኢንቴርሊንጓ + እንዶኒሲኛ + እንተርሊንግወ + እኑፒያቅኛ + አይስላንድኛ + ጣሊያንኛ + እኑክቲቱትኛ + ጃፓንኛ + ጃቫንኛ + ጊዮርጊያን + ካዛክኛ + ካላሊሱትኛ + ክመርኛ + ካናዳኛ + ኮሪያኛ + ካሽሚርኛ + ኩርድሽኛ + ኪርጊዝኛ + ላቲንኛ + ሊንጋላኛ + ላውስኛ + ሊቱአኒያን + ላትቪያን + ማላጋስኛ + ማዮሪኛ + ማከዶኒኛ + ማላያላምኛ + ሞንጎላዊኛ + ማራዚኛ + ማላይኛ + ማልቲስኛ + ቡርማኛ + ናኡሩ + ኔፓሊኛ + ደች + ኖርዌጂያን + ኦኪታንኛ + ኦሮምኛ + ኦሪያኛ + ፓንጃቢኛ + ፖሊሽ + ፑሽቶኛ + ፖርቱጋሊኛ + ኵቿኛ + ሮማንስ + ሩንዲኛ + ሮማኒያን + ሞልዳቫዊና + ራሽኛ + ኪንያርዋንድኛ + ሳንስክሪትኛ + ሲንድሂኛ + ሳንጎኛ + ስንሃልኛ + ሲዳምኛ + ስሎቫክኛ + ስሎቪኛ + ሳሞአኛ + ሾናኛ + ሱማልኛ + ልቤኒኛ + ሰርቢኛ + ስዋቲኛ + ሶዞኛ + ሱዳንኛ + ስዊድንኛ + ስዋሂሊኛ + ታሚልኛ + ተሉጉኛ + ታጂኪኛ + ታይኛ + ትግርኛ + ትግረ + ቱርክመንኛ + ታጋሎገኛ + ጽዋናዊኛ + ቶንጋ + ቱርክኛ + ጾንጋኛ + ታታርኛ + ትዊኛ + ኡዊግሁርኛ + ዩክረኒኛ + ኡርዱኛ + ኡዝበክኛ + ቪትናምኛ + ቮላፑክኛ + ዎሎፍኛ + ዞሳኛ + ይዲሻዊኛ + ዮሩባዊኛ + ዡዋንግኛ + ቻይንኛ + ዙሉኛ + + + + + + አንዶራ + የተባበሩት አረብ ኤምሬትስ + አልባኒያ + አርሜኒያ + አርጀንቲና + ኦስትሪያ + አውስትሬሊያ + አዘርባጃን + ቦስኒያ እና ሄርዞጎቪኒያ + ባርቤዶስ + ቤልጄም + ቡልጌሪያ + ባህሬን + ቤርሙዳ + ቦሊቪያ + ብራዚል + ቡህታን + ቤላሩስ + ቤሊዘ + ኮንጎ + የመካከለኛው አፍሪካ ሪፐብሊክ + ስዊዘርላንድ + ቺሊ + ካሜሩን + ቻይና + ኮሎምቢያ + ኬፕ ቬርዴ + ሳይፕረስ + ቼክ ሪፑብሊክ + ጀርመን + ዴንማርክ + ዶሚኒካ + ዶሚኒክ ሪፑብሊክ + አልጄሪያ + ኢኳዶር + ኤስቶኒያ + ግብጽ + ምዕራባዊ ሳህራ + ኤርትራ + ስፔን + ኢትዮጵያ + ፊንላንድ + ፊጂ + ሚክሮኔዢያ + ፈረንሳይ + እንግሊዝ + ጆርጂያ + የፈረንሳይ ጉዊአና + ጋምቢያ + ጊኒ + ኢኳቶሪያል ጊኒ + ግሪክ + ቢሳዎ + ጉያና + ሆንግ ኮንግ + ክሮኤሽያ + ሀይቲ + ሀንጋሪ + ኢንዶኔዢያ + አየርላንድ + እስራኤል + ህንድ + ኢራቅ + አይስላንድ + ጣሊያን + ጃማይካ + ጆርዳን + ጃፓን + ካምቦዲያ + ኮሞሮስ + ሰሜን ኮሪያ + ደቡብ ኮሪያ + ክዌት + ሊባኖስ + ሊቱዌኒያ + ላትቪያ + ሊቢያ + ሞሮኮ + ሞልዶቫ + ማከዶኒያ + ሞንጎሊያ + ማካዎ + ሞሪቴኒያ + ማልታ + ማሩሸስ + ሜክሲኮ + ማሌዢያ + ናሚቢያ + ኒው ካሌዶኒያ + ናይጄሪያ + ኔዘርላንድ + ኖርዌ + ኔፓል + ኒው ዚላንድ + ፔሩ + የፈረንሳይ ፖሊኔዢያ + ፓፑዋ ኒው ጊኒ + ፖላንድ + ፖርታ ሪኮ + ሮሜኒያ + ራሺያ + ሳውድአረቢያ + ሱዳን + ስዊድን + ሲንጋፖር + ስሎቬኒያ + ስሎቫኪያ + ሴኔጋል + ሱማሌ + ሲሪያ + ቻድ + የፈረንሳይ ደቡባዊ ግዛቶች + ታይላንድ + ታጃኪስታን + ምስራቅ ቲሞር + ቱኒዚያ + ቱርክ + ትሪኒዳድ እና ቶባጎ + ታንዛኒያ + ዩጋንዳ + አሜሪካ + ዩዝበኪስታን + ቬንዙዌላ + የእንግሊዝ ድንግል ደሴቶች + የአሜሪካ ቨርጂን ደሴቶች + የመን + ደቡብ አፍሪካ + ዛምቢያ + + + + [\u135F ፡ ፣-፧ ። ፠ ፨ ᎐-᎙ ፲-፼ ሀ-ሏ ⶀ ሐ-ሟ ᎀ-ᎃ ⶁ ሠ-ሯ ⶂ ሰ-ሷ ⶃ ሸ-ሿ ⶄ ቀ-ቈ ቊ-ቍ ቐ-ቖ ቘ ቚ-ቝ በ-ቧ ᎄ-ᎇ ⶅ ቨ-ቷ ⶆ ቸ-ቿ ⶇ ኀ-ኈ ኊ-ኍ ነ-ኗ ⶈ ኘ-ኟ ⶉ አ-ኧ ⶊ ከ-ኰ ኲ-ኵ ኸ-ኾ ዀ ዂ-ዅ ወ-ዖ ዘ-ዟ ⶋ ዠ-ዷ ⶌ ዸ-ዿ ⶍ ጀ-ጇ ⶎ ገ-ጐ ጒ-ጕ ጘ-ጟ ⶓ-ⶖ ጠ-ጧ ⶏ ጨ-ጯ ⶐ ጰ-ጷ ⶑ ጸ-ፏ ᎈ-ᎋ ፐ-ፗ ᎌ-ᎏ ⶒ ፘ-ፚ ⶠ-ⶦ ⶨ-ⶮ ⶰ-ⶶ ⶸ-ⶾ ⷀ-ⷆ ⷈ-ⷎ ⷐ-ⷖ ⷘ-ⷞ] + [ሀ ለ ⶀ መ ᎀ ᎁ ᎃ ⶁ ረ ⶂ ሰ ሸ ⶄ ቈ ቐ ቘ ᎄ ᎅ ᎇ ⶅ ቨ ⶆ ቸ ኀ ኈ ነ ኘ ⶉ ⶊ ከ ኰ ዀ ወ ዐ ⶋ ዠ ደ ⶌ ዸ ጀ ⶎ ጐ ጘ ⶓ ⶕ ⶖ ⶏ ጨ ⶐ ⶑ ጸ ፈ ᎈ ᎉ ᎋ ፐ ᎍ ᎎ ᎏ ፘ ⶠ ⶢ ⶣ ⶤ ⶦ ⶨ ⶩ ⶫ ⶬ ⶮ ⶰ ⶱ ⶳ ⶴ ⶶ ⶸ ⶹ ⶻ ⶼ ⶾ ⷀ ⷁ ⷃ ⷄ ⷆ ⷈ ⷉ ⷋ ⷌ ⷎ ⷐ ⷑ ⷓ ⷔ ⷖ ⷘ ⷙ ⷛ ⷜ ⷝ] + + + + + + + + EEEE፡ dd MMMM ዮም y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + + + ጃንዩ + ፌብሩ + ማርች + ኤፕረ + ሜይ + ጁን + ጁላይ + ኦገስ + ሴፕቴ + ኦክተ + ኖቬም + ዲሴም + + + ጃንዩወሪ + ፌብሩወሪ + ማርች + ኤፕረል + ሜይ + ጁን + ጁላይ + ኦገስት + ሴፕቴምበር + ኦክተውበር + ኖቬምበር + ዲሴምበር + + + + + + + + + + + + + + + + + + + + + + + ሰ/ዓ + ሰኖ + ታላሸ + ኣረር + ከሚሽ + ጅምዓ + ሰ/ን + + + ሰንበት ዓባይ + ሰኖ + ታላሸኖ + ኣረርባዓ + ከሚሽ + ጅምዓት + ሰንበት ንኢሽ + + + + + + + + + + + + + + + + + + ቀደም ሰርምዕል + ሓቆ ስርምዕል + + + ቀደም ሰርምዕል + ሓቆ ስርምዕል + + + + + + ዓ/ዓ + ዓ/ም + + + + + + EEEE፡ dd MMMM ዮም y G + GyMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + latn + + latn + ethi + + + + + ¤#,##0.00 + + + + + + የብራዚል ሪል + + + የቻይና ዩአን ረንሚንቢ + + + Nfk + + + የኢትዮጵያ ብር + + + አውሮ + + + የእንግሊዝ ፓውንድ ስተርሊንግ + + + የሕንድ ሩፒ + + + የጃፓን የን + + + የራሻ ሩብል + + + የአሜሪካን ዶላር + + + + diff --git a/make/data/cldr/common/main/tig_ER.xml b/make/data/cldr/common/main/tig_ER.xml new file mode 100644 index 00000000000..4a946eb9da7 --- /dev/null +++ b/make/data/cldr/common/main/tig_ER.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/tk.xml b/make/data/cldr/common/main/tk.xml index 25746e16259..c31689fa46e 100644 --- a/make/data/cldr/common/main/tk.xml +++ b/make/data/cldr/common/main/tk.xml @@ -1,6 +1,6 @@ - + + + + + + + + Seburu + Amhariki + Arabic + Azerbaijani + Belarusian + Bulgarian + Bengali + SeBosnia + Catalan + Se Czeck + Welsh + Danish + German + SeGerika + Sekgoa + Esperanto + Spanish + Estonian + Basque + Mo/SePerishia + Se-Finland + Tagalog + Faroese + Se Fora + Frisian + Irish + Scots Gaelic + Galician + Gujarati + Se heberu + Hindi + Croatian + Hungarian + Interlingua + Indonesian + Icelandic + Se Italiano + Se Japan + Javanese + Mo/SeJojia + Kannada + Se Korea + Latin + Lithuanian + Latvian + Macedonian + Malayalam + Marathi + Malay + Maltese + Nepali + Se Dutch + Puo ya kwa Norway + Occitan + Punjabi + Se Poland + Se Potoketsi + Se Roma + Russian + Slovak + Slovenian + Albanian + Serbian + Mo/SeSundane + Swedish + Swahili + Tamil + Telugu + Thai + Tigrinya + Klingon + Setswana + Turkish + Ukrainian + Urdu + Uzbek + Vietnamese + IsiXhosa + IsiZulu + + + Aforika Borwa + + + + [a b d e ê f g h i j k l m n o ô p r s t u w y] + [c q v x z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + G y MMMM d, EEEE + GyMMMMEEEEd + + + + + G y MMMM d + GyMMMMd + + + + + G y MMM d + GyMMMd + + + + + GGGGG y-MM-dd + GGGGGyMMdd + + + + + + + + + Fer + Tlh + Mop + Mor + Mot + See + Phu + Pha + Lwe + Dip + Ngw + Sed + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Ferikgong + Tlhakole + Mopitlo + Moranang + Motsheganang + Seetebosigo + Phukwi + Phatwe + Lwetse + Diphalane + Ngwanatsele + Sedimonthole + + + + + Fer + Tlh + Mop + Mor + Mot + See + Phu + Pha + Lwe + Dip + Ngw + Sed + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Ferikgong + Tlhakole + Mopitlo + Moranang + Motsheganang + Seetebosigo + Phukwi + Phatwe + Lwetse + Diphalane + Ngwanatsele + Sedimonthole + + + + + + + Tsh + Mos + Labb + Labr + Labn + Labt + Mat + + + S + M + T + W + T + F + S + + + Tsh + Mos + Labb + Labr + Labn + Labt + Mat + + + Tshipi + Mosopulogo + Labobedi + Laboraro + Labone + Labotlhano + Matlhatso + + + + + Tsh + Mos + Labb + Labr + Labn + Labt + Mat + + + S + M + T + W + T + F + S + + + Tsh + Mos + Labb + Labr + Labn + Labt + Mat + + + Tshipi + Mosopulogo + Labobedi + Laboraro + Labone + Labotlhano + Matlhatso + + + + + + + Q1 + Q2 + Q3 + Q4 + + + 1 + 2 + 3 + 4 + + + Sephatlho sa ntlha sa ngwaga + Sephatlho sa bobedi + Sephatlho sa boraro + Sephatlho sa bone + + + + + Q1 + Q2 + Q3 + Q4 + + + 1 + 2 + 3 + 4 + + + Sephatlho sa ntlha sa ngwaga + Sephatlho sa bobedi + Sephatlho sa boraro + Sephatlho sa bone + + + + + + + AM + PM + + + a + p + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + Pele ga tsalo ya Morena Jeso + Pele ga Krestie + Morago ga Leso la Morena Jeso + Morago ga Krestie + + + BC + BCE + AD + CE + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} 'ka' {0} + + + + + {1} 'ka' {0} + + + + + {1}, {0} + + + + + {1}, {0} + + + + d + ccc + d, E + E h:mm a + E HH:mm + E h:mm:ss a + E HH:mm:ss + G y + G y MMM + G y MMM d + G y MMM d, E + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + L + MM-dd + MM-dd, E + LLL + MMM d + MMM d, E + MMMM d + 'beke' 'ya' W 'ya' MMM + 'beke' 'ya' W 'ya' MMM + mm:ss + y + y-MM + y-MM-dd + y-MM-dd, E + y MMM + y MMM d + y MMM d, E + y MMMM + y QQQ + y QQQQ + 'beke' w 'ya' Y + 'beke' w 'ya' Y + + + {0} {1} + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + MM-dd – MM-dd + MM-dd – MM-dd + + + MM-dd, E – MM-dd, E + MM-dd, E – MM-dd, E + + + LLL–LLL + + + MMM d–d + MMM d – MMM d + + + MMM d, E – MMM d, E + MMM d, E – MMM d, E + + + y–y + + + y-MM – y-MM + y-MM – y-MM + + + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + + + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + + + y MMM–MMM + y MMM – y MMM + + + y MMM d–d + y MMM d – MMM d + y MMM d – y MMM d + + + y MMM d, E – MMM d, E + y MMM d, E – MMM d, E + y MMM d, E – y MMM d, E + + + y MMMM–MMMM + y MMMM – y MMMM + + + + + + + + 1 + + . +   + % + + + - + E + × + + + NaN + : + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + ¤#,##0.00 + + + {0} {1} + {0} {1} + + + + R + + + + ≥{0} + {0}–{1} + + + diff --git a/make/data/cldr/common/main/tn_BW.xml b/make/data/cldr/common/main/tn_BW.xml new file mode 100644 index 00000000000..9a07e5f9c3c --- /dev/null +++ b/make/data/cldr/common/main/tn_BW.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + P + + + + diff --git a/make/data/cldr/common/main/tn_ZA.xml b/make/data/cldr/common/main/tn_ZA.xml new file mode 100644 index 00000000000..d0a698ebd79 --- /dev/null +++ b/make/data/cldr/common/main/tn_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/to.xml b/make/data/cldr/common/main/to.xml index 3d38ee20179..4185fe4579e 100644 --- a/make/data/cldr/common/main/to.xml +++ b/make/data/cldr/common/main/to.xml @@ -1,6 +1,6 @@ - + + + + + + + + Jeman + Austria Jeman + Swis Jeman + Inglis + Australian Inglis + Kenedien Inglis + Britis Inglis + Amerikan Inglis + Spenis + Saut Amerikan Spenis + Spenis (Spein) + Meksikan Spenis + Frens + Kenedien Frens + Swis Frens + Italien + Japanis + Potigis + Brasilien Potigis + Yurop Potigis + Rasien + Tok Pisin + Tok ples i no stap + Sainis + Isipela Sainis + Tredisinol Sainis + + + + + + + + + + + + Brasil + Saina + Jemani + Frans + Yunaited Kingdom + India + Itali + Papua Niugini + Rijen i no stap + + + Gregorien kalenda + stendet karensi fomet + stendet oda bilong skelim + westen namba + + + tok ples: {0} + skript: {0} + rijen: {0} + + + + [a b d e f g h i j k l m n o p r s t u w y] + [c q v x z] + [A B D E F G H I J K L M N O P R S T U W Y] + + + + + + + + Jan + Feb + Mas + Epr + Me + Jun + Jul + Oga + Sep + Okt + Nov + Des + + + Janueri + Februeri + Mas + Epril + Me + Jun + Julai + Ogas + Septemba + Oktoba + Novemba + Desemba + + + + + + + San + Man + Tun + Tri + Fon + Fra + Sar + + + Sande + Mande + Tunde + Trinde + Fonde + Fraide + Sarere + + + + + + + AM + PM + + + + + + + EEE, dd MMMM y + yyyyMMMMEEEdd + + + + + dd MMMM y + yyyyMMMMdd + + + + + dd MMM y + yyyyMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + hh:mm:ss a zzzz + ahhmmsszzzz + + + + + hh:mm:ss a zzz + ahhmmsszzz + + + + + hh:mm:ss a + ahhmmss + + + + + hh:mm a + ahhmm + + + + + + d/M/y + d MMM y + + + + + + + latn + + . + , + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + #,##0.00 ¤ + + + + + + + yes:y + no:n + + + diff --git a/make/data/cldr/common/main/tpi_PG.xml b/make/data/cldr/common/main/tpi_PG.xml new file mode 100644 index 00000000000..59c299a7362 --- /dev/null +++ b/make/data/cldr/common/main/tpi_PG.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/tr.xml b/make/data/cldr/common/main/tr.xml index d41cc2f3d9e..28a8d7b4c06 100644 --- a/make/data/cldr/common/main/tr.xml +++ b/make/data/cldr/common/main/tr.xml @@ -1,6 +1,6 @@ - + + + + + + + + patas Monchiara + patas Towjih + patas Ingrisi + patas Espanniu + patas Bosey + patas Heyti + patas Itariya + patas Nihong + patas Bowdu + patas Pajey + patas Ruski + patas Srpian + patas Taroko + Ini klayna patas ni + patas Yurtu + patas Ipaw + Qantan Ipaw patas + Baday Ipaw patas + + + + + + + + + + + + alang Nanci + alang Posniya + alang Pajey + alang Puwei + alang Switjrrant + alang Ipaw + alang Towjih + alang Posey + alang Inglis + alang Nanjiouya ni Nansanminji + alang Htee ni Mayktan + alang Krowtia + alang Intu + alang Inglis niq Intu + alang Itariya + alang Nihong + alang Mondineygrw + alang Srbia + alang Ruski + alang Snmarinow + alang Posey niq Nan + alang Amarika + ini klayi na alang ni + + + Jiyax Yisu Thulang + + + Snamrika + Snyunaydi + + + Kari: {0} + Patas: {0} + Alang: {0} + + + + [a b c d e g h i j k l m n {ng} o p q r s t u w x y] + [ḏ f ɨ ḻ ṟ ṯ ʉ v z ʼ] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + EEEE, G y MMMM dd + GyMMMMEEEEdd + + + + + G y MMMM d + GyMMMMd + + + + + G y MMM d + GyMMMd + + + + + GGGGG y-MM-dd + GGGGGyMMdd + + + + + + d + H:mm + L + M-d + E, M-d + LLL + MMM d + E MMM d + MMMM d + E MMMM d + mm:ss + y + y-M + E, y-M-d + y MMM + E, y MMM d + y MMMM + y Q + y QQQ + + + + + + + + Kii + Dhi + Tri + Spi + Rii + Mti + Emi + Mai + Mni + Mxi + Mxk + Mxd + + + Kingal idas + Dha idas + Tru idas + Spat idas + Rima idas + Mataru idas + Empitu idas + Maspat idas + Mngari idas + Maxal idas + Maxal kingal idas + Maxal dha idas + + + + + K + D + T + S + R + M + E + P + A + M + K + D + + + + + + + Emp + Kin + Dha + Tru + Spa + Rim + Mat + + + Jiyax sngayan + tgKingal jiyax iyax sngayan + tgDha jiyax iyax sngayan + tgTru jiyax iyax sngayan + tgSpac jiyax iyax sngayan + tgRima jiyax iyax sngayan + tgMataru jiyax iyax sngayan + + + + + E + K + D + T + S + R + M + + + + + + + mn1 + mn2 + mn3 + mn4 + + + mnprxan + mndha + mntru + mnspat + + + + + + + AM + PM + + + Brax kndaax + Baubau kndaax + + + + + + Brah jikan Yisu Thulang + Bukuy jikan Yisu Thulang + + + BRY + BUY + + + + + + EEEE, y MMMM dd + yMMMMEEEEdd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + y-MM-dd + yMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + d + H:mm + L + M-d + E, M-d + LLL + MMM d + E MMM d + MMMM d + E MMMM d + mm:ss + y + y-M + E, y-M-d + y MMM + E, y MMM d + y MMMM + y Q + y QQQ + + + + + + + Hngkawas + + + hngkawas + + + Idas + + + Jiyax iyax sngayan + + + Jiyax + Shiga + Jiyax sayang + Saman + + + Jiyax quri jiyax iyax sngayan + + + Jikan + + + Tuki + + + Spngan + + + Seykn + + + Alang + + + + +HH:mm;-HH:mm + JQG{0} + Jikan {0} + + Ini klayi ka Jikan hini + + + Jikan alang Purank + + + Jikan alang Grad + + + Jikan alang Snpaurow + + + Jikan alang Honoruru + + + Jikan alang Ankriji + + + Jikan alang Rosanci + + + Jikan alang Bonhuan + + + Jikan alang Tanbo + + + Jikan alang Jiciak + + + Jikan alang Intiannaporis + + + Jikan alang Niuyue + + + + Jikan Con-Amarika + Snegun Jikan Con-Amarika + Jikan Con-Amarika o Karat Rbagan + + + JCA + SJCA + JCAKR + + + + + Jikan Ton-Amarika + Snegun Jikan Ton-Amarika + Jikan Ton-Amarika o Karat Rbagan + + + JTA + SJTA + JTAKR + + + + + Jikan Yama-Amarika + Snegun Jikan Yama-Amarika + Jikan Hidaw niq Yama-Amarika + + + JYA + SJYA + JHYA + + + + + Jikan Daybinyan + Snegun Jikan Amarika-Daybinyan + Jikan Amarika-Daybinyan o Karat Rbagan + + + JD + SJAD + JADKR + + + + + Jikan Yayun Tasiyan + Snegun Jikan Yayun Tasiyan + Jikan Yayun Tasiyan o Karat Rbagan + + + JYT + SJYT + JYTKR + + + + + Jikan Conow + Snegun Jikan Conow + Jikan Conow o Karat Rbagan + + + JC + JC + JCKR + + + + + Jikan Tonow + Snegun Jikan Tonow + Jikan Tonow o Karat Rbagan + + + JT + JT + JTKR + + + + + Jikan Siow + Snegun Jikan Siow + Jikan Siow o Karat Rbagan + + + JS + JS + JSKR + + + + + Jikan Quri Grinweyji + + + JQG + + + + + + + . + , + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + + + + pila Autaria + + + pila Pajey + + + pila Ipaw + + + pila Irow + + + pila Inglis + + + pila Hong Kong + + + pila Intia + + + pila Nihong + + + pila Macao + + + pila Nowey + + + pila Ruski + + + pila Taiwan + + + pila America + + + ini klayi pila ni + + + + + + + {0} Hnkawas + + + {0} Idas + + + {0} Jiyax iyax sngayan + + + {0} Jiyax + + + {0} Tuki + + + {0} spngan + + + {0} Seykn + + + + + + yiru:y + mnan:m + + + diff --git a/make/data/cldr/common/main/trv_TW.xml b/make/data/cldr/common/main/trv_TW.xml new file mode 100644 index 00000000000..f8194882dcf --- /dev/null +++ b/make/data/cldr/common/main/trv_TW.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/trw.xml b/make/data/cldr/common/main/trw.xml new file mode 100644 index 00000000000..5589a7966a1 --- /dev/null +++ b/make/data/cldr/common/main/trw.xml @@ -0,0 +1,6145 @@ + + + + + + + + + + + {0} ({1}) + {0}،{1} + {0}: {1} + + + افریقی + اگھیم + آکان + امھاریک + عربی + ماڈرن اسٹینڈرڈ عربی + اسامی + اسو + استوری + ازری + باسا + بیلاروسی + بیمبا + بینا + بلغاری + بمبارا + بنگلہ + بریٹون + بوڈو + بوسنیائی + جرمن + آسٹریائی جرمن + سوئس ہائی جرمن + انگریزی + آسٹریلیائی انگریزی + کینیڈین انگریزی + برطانوی انگریزی + انگریزی (یو کے) + امریکی انگریزی + ہسپانوی + لاطینی امریکی ہسپانوی + یورپی ہسپانوی + میکسیکن ہسپانوی + فرانسیسی + کینیڈین فرانسیسی + سوئس فرینچ + ہندی + ارمینی + انڈونیثیائی + اطالوی + جاپانی + کوریائی + بافیہ + برمی + ڈچ + فلیمِش + پولش + پُرتگالی + برازیلی پرتگالی + یورپی پرتگالی + روسی + البانی + تھائی + ترکی + توروالی + نامعلوم جِب + چینی + چینی، مندارن + چینی (آسان کوئیل) + سادہ مندارن چینی + روایتی چینی + روایتی مندارن چینی + + + + + + + + + + + + + + + + دونیئ + افریقہ + شمالی امریکہ + جنوبی امریکہ + اوشیانیا + مغربی افریقہ + وسطی امریکہ + مشرقی افریقہ + شمالی افریقہ + وسطی افریقہ + جنوبی افریقہ سی علاقہ + امیریکاز + شمالی امریکہ سی علاقہ + کریبیائی + مشرقی ایشیا + جنوبی ایشیا + جنوب مشرقی ایشیا + جنوبی یورپ + آسٹریلیشیا + مالینیشیا + مائکرونیشیائی علاقہ + پولینیشیا + ایشیا + وسطی ایشیا + مغربی ایشیا + یورپ + مشرقی یورپ + شمالی یورپ + مغربی یورپ + ذیلی صحارن افریقہ + لاطینی امریکہ + اسینشن آئلینڈ + انڈورا + متحدہ عرب امارات + افغانستان + انٹیگوا اور باربودا + انگوئیلا + البانیہ + آرمینیا + انگولا + انٹارکٹیکا + ارجنٹینا + امریکی ساموآ + آسٹریا + اسٹریلیا + اروبا + آلینڈ آئلینڈز + آذربائیجان + بوسنیا آں ہرزیگووینا + بارباڈوس + بنگلہ دیش + بیلجیم + برکینا فاسو + بلغاریہ + بحرین + برونڈی + بینن + سینٹ برتھلیمی + برمودا + برونائی + بولیویا + کریبیائی نیدرلینڈز + برازیل + بہاماس + بھوٹان + بؤویٹ آئلینڈ + بوتسوانا + بیلاروس + بیلائز + کینیڈا + کوکوس (کیلنگ) جزائر + کانگو - کنشاسا + کانگو (DRC) + وسط افریقی جمہوریہ + کانگو - برازاویلے + کانگو (جمہوریہ) + سوئٹزر لینڈ + کوٹ ڈی آئیوری + آئیوری کوسٹ + کک آئلینڈز + چلی + کیمرون + چین + کولمبیا + کلپرٹن آئلینڈ + کوسٹا ریکا + کیوبا + کیپ ورڈی + کیوراکاؤ + جزیرہ کرسمس + قبرص + چیکیا + چیک جمہوریہ + جرمنی + ڈائجو گارسیا + جبوتی + ڈنمارک + ڈومنیکا + جمہوریہ ڈومينيکن + الجیریا + سیئوٹا آں میلیلا + ایکواڈور + اسٹونیا + مصر + مغربی صحارا + اریٹیریا + ہسپانیہ + ایتھوپیا + یوروپی یونین + یوروزون + فن لینڈ + فجی + فاکلینڈ جزائر + فاکلینڈ جزائر (مالویناس) + مائکرونیشیا + جزائر فارو + فرانس + گیبون + سلطنت متحدہ + یو کے سلطنت متحدہ + گریناڈا + جارجیا + فرینچ گیانا + گوئرنسی + گھانا + جبل الطارق + گرین لینڈ + گیمبیا + گنی + گواڈیلوپ + استوائی گیانا + یونان + جنوبی جارجیا آں جنوبی سینڈوچ جزائر + گواٹے مالا + گوام + گنی بساؤ + گیانا + ہانگ کانگ SAR چین + ہانگ کانگ ہانگ کانگ SAR چین + ہیرڈ جزیرہ و میکڈولینڈ جزائر + ہونڈاروس + کروشیا + ہیٹی + ہنگری + کینری آئلینڈز + انڈونیشیا + آئرلینڈ + اسرائیل + آئل آف مین + بھارت + برطانوی بحر ہند سی علاقہ + عراق + ایران + آئس لینڈ + اٹلی + جرسی + جمائیکا + اردن + جاپان + کینیا + کرغزستان + کمبوڈیا + کریباتی + کوموروس + سینٹ کٹس اور نیویس + شمالی کوریا + جنوبی کوریا + کویت + کیمین آئلینڈز + قزاخستان + لاؤس + لبنان + سینٹ لوسیا + لیشٹنسٹائن + سری لنکا + لائبیریا + لیسوتھو + لیتھونیا + لکسمبرگ + لٹویا + لیبیا + مراکش + موناکو + مالدووا + مونٹے نیگرو + سینٹ مارٹن + مڈغاسکر + مارشل آئلینڈز + شمالی مقدونیہ + مالی + میانمار (برما) + منگولیا + مکاؤ SAR چین + مکاؤ مکاؤ SAR چین + شمالی ماریانا آئلینڈز + مارٹینک + موریطانیہ + مونٹسیراٹ + مالٹا + ماریشس + مالدیپ + ملاوی + میکسیکو + ملائشیا + موزمبیق + نامیبیا + نیو کلیڈونیا + نائجر + نارفوک آئلینڈ + نائجیریا + نکاراگووا + نیدر لینڈز + ناروے + نیپال + نؤرو + نیئو + نیوزی لینڈ + عمان + پانامہ + پیرو + فرانسیسی پولینیشیا + پاپوآ نیو گنی + فلپائن + پاکستان + پولینڈ + سینٹ پیئر آں میکلیئون + پٹکائرن جزائر + پیورٹو ریکو + فلسطینی خطے + فلسطین فلسطینی خطے + پرتگال + پلاؤ + پیراگوئے + قطر + بیرونی اوشیانیا + ری یونین + رومانیہ + سربیا + روس + روانڈا + سعودی عرب + سولومن آئلینڈز + سشلیز + سوڈان + سویڈن + سنگاپور + سینٹ ہیلینا + سلووینیا + سوالبرڈ آں جان ماین + سلوواکیہ + سیرالیون + سان مارینو + سینیگل + صومالیہ + سورینام + جنوبی سوڈان + ساؤ ٹومے آں پرنسپے + ال سلواڈور + سنٹ مارٹن + شام + سواتنی + سوازی لینڈ + ٹرسٹن ڈا کیونہا + ٹرکس آں کیکوس جزائر + چاڈ + فرانسیسی جنوبی خطے + ٹوگو + تھائی لینڈ + تاجکستان + ٹوکیلاؤ + تیمور لیسٹ + مشرقی تیمور تیمور لیسٹ + ترکمانستان + تونس + ٹونگا + ترکی + ترینیداد آں ٹوباگو + ٹووالو + تائیوان + تنزانیہ + یوکرین + یوگنڈا + امریکہ ما باہرسی لَو جزائز + اقوام متحدہ + ریاست ہائے متحدہ امریکہ + امریکا + یوروگوئے + ازبکستان + ویٹیکن سٹی + سینٹ ونسنٹ آں گرینیڈائنز + وینزوئیلا + برٹش ورجن آئلینڈز + امریکی ورجن آئلینڈز + ویتنام + وینوآٹو + ویلیز آں فیوٹیونا + ساموآ + بناوٹی لہجے + مصنوعی بیڑی + کوسووو + یمن + مایوٹ + جنوبی افریقہ + زامبیا + زمبابوے + نامعلوم علاقہ + + + جارجیائی کیلنڈر + ISO-8601 کیلنڈر + معیاری چھانٹی سی ترتیب + عربی ہندی ہندسے + مغربی ہندسے + + + میٹرک + برطانیہ + ریاست ہائے متحدہ امریکہ + + + جِب:{0} + لِک:{0} + علاقہ:{0} + + + + + right-to-left + top-to-bottom + + + + [ء ٶ آ أ ئ ا ب پ ت ث ٹ ج چ ڇ ح خ څ ݲ د ذ ڈ ر ز ڑ ژ ڙ س ش ݜ ص ض ط ظ ع غ ف ق ک گ ل م ن ں ھ ہ و ی ے] + [؀؁؂؃\u200C\u200D\u200E\u200F \u064B \u064C \u064D \u064E \u064F \u0650 \u0651 \u0652 \u0654 \u0656 \u0657 \u0658 \u0670 ٻ ٺ ټ ٽ ۃ ي] + [ء ٶ آ أ ئ ا ب پ ت ث ٹ ج چ ڇ ح خ څ ݲ د ذ ڈ ر ز ڑ ژ ڙ س ش ݜ ص ض ط ظ ع غ ف ق ک گ ل م ن ں ھ ہ و ی ے] + [\u200E \- ‑ , ٫ ٬ . % ‰ + 0۰ 1۱ 2۲ 3۳ 4۴ 5۵ 6۶ 7۷ 8۸ 9۹] + [، ؍ ٫ ٬ ؛ \: ؟ . ۔ ( ) \[ \]] + ؟ + + + + + + + + EEEE، d MMMM، y G + GyMMMMEEEEd + + + + + d MMMM، y G + GyMMMMd + + + + + d MMM، y G + GyMMMd + + + + + d/M/y GGGGG + GGGGGyMd + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + y G + MMM y G + d MMM، y G + E، d MMM، y G + d/M + E، d/M + d MMM + E، d MMM + d MMMM + y G + y G + M/y G + d/M/y G + E، d/M/y G + MMM y G + d MMM، y G + E، d MMM، y G + MMMM y G + QQQ y G + QQQQ y G + + + + y G – y G + y – y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + M/d/y – M/d/y GGGGG + M/d/y GGGGG – M/d/y GGGGG + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + + + E, M/d/y – E, M/d/y GGGGG + E, M/d/y GGGGG – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + MMM d – d, y G + MMM d, y G – MMM d, y G + MMM d – MMM d, y G + MMM d, y – MMM d, y G + + + E, MMM d – E, MMM d, y G + E, MMM d, y G – E, MMM d, y G + E, MMM d – E, MMM d, y G + E, MMM d, y – E, MMM d, y G + + + M–M + + + d/M – d/M + d/M – d/M + + + E، d/M – E، d/M + E، d/M – E، d/M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d MMM – E، d MMM + E، d MMM – E، d MMM + + + y–y G + + + M/y – M/y G + M/y – M/y G + + + d/M/y – d/M/y G + d/M/y – d/M/y G + d/M/y – d/M/y G + + + E، d/M/y – E، d/M/y G + E، d/M/y – E، d/M/y G + E، d/M/y – E، d/M/y G + + + MMM–MMM y G + MMM y – MMM y G + + + d–d MMM، y G + d MMM – d MMM، y G + d MMM، y – d MMM، y G + + + E، d MMM – E، d MMM، y G + E، d MMM – E، d MMM، y G + E، d MMM، y – E، d MMM، y G + + + MMMM–MMMM y G + MMMM y – MMMM y G + + + + + + + + + جنوری + فروری + مارچ + اپریل + مئ + جون + جولائی + اگست + ستمبر + اکتوبر + نومبر + دسمبر + + + ج + ف + م + ا + م + ج + ج + ا + س + ا + ن + د + + + جنوری + فروری + مارچ + اپریل + مئ + جون + جولائی + اگست + ستمبر + اکتوبر + نومبر + دسمبر + + + + + جنوری + فروری + مارچ + اپریل + مئ + جون + جولائی + اگست + ستمبر + اکتوبر + نومبر + دسمبر + + + ج + ف + م + ا + م + ج + ج + ا + س + ا + ن + د + + + جنوری + فروری + مارچ + اپریل + مئ + جون + جولائی + اگست + ستمبر + اکتوبر + نومبر + دسمبر + + + + + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + ا + د + گ + چ + پ + ش + ل + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + ا + د + گ + چ + پ + ش + ل + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + ایکشیمے + دُوشیمے + گھن آنگا + چارشیمے + پَئ شیمے + شُوگار + لَو آنگا + + + + + + + اول ڇامای + دوھیم ڇامای + ڇوی ڇامای + چوٹھوم ڇامای + + + 1 + 2 + 3 + 4 + + + اول ڇامای + دھویم ڇامای + ڇوی ڇامای + چوٹھوم ڇامای + + + + + اول ڇامای + دوھیم ڇامای + ڇوی ڇامای + چوٹھوم ڇامای + + + اول ڇامای + دوھیم ڇامای + ڇوی ڇامای + چوٹھوم ڇامای + + + + + + + a + p + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + عیسٰیؑ ما مُش + ع-م + عیسوی + عام دور + + + ع-م + ع + ع-د + + + + + + EEEE، d MMMM، y + yMMMMEEEEd + + + + + d MMMM، y + yMMMMd + + + + + d MMM، y + yMMMd + + + + + d/M/yy + yyMd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + E h:mm B + y G + MMM y G + d MMM، y G + E، d MMM، y G + d/M + E، d/M + d MMM + E، d MMM + d MMMM + MMMM سی ہفتہ W + M/y + d/M/y + E، d/M/y + MMM y + d MMM، y + E، d MMM، y + MMMM y + QQQ y + QQQQ y + Yسی w ہفتہ + + + + y G – y G + y – y G + + + M/y GGGGG – M/y GGGGG + M/y – M/y GGGGG + M/y – M/y GGGGG + + + M/d/y – M/d/y GGGGG + M/d/y GGGGG – M/d/y GGGGG + M/d/y – M/d/y GGGGG + M/d/y – M/d/y GGGGG + + + E, M/d/y GGGGG – E, M/d/y GGGGG + E, M/d/y GGGGG – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + E, M/d/y – E, M/d/y GGGGG + + + MMM y G – MMM y G + MMM – MMM y G + MMM y – MMM y G + + + MMM d – d, y G + MMM d, y G – MMM d, y G + MMM d – MMM d, y G + MMM d, y – MMM d, y G + + + E, MMM d – E, MMM d, y G + E, MMM d, y G – E, MMM d, y G + E, MMM d – E, MMM d, y G + E, MMM d, y – E, MMM d, y G + + + M–M + + + d/M – d/M + d/M – d/M + + + E، d/M – E، d/M + E، d/M – E، d/M + + + MMM–MMM + + + d–d MMM + d MMM – d MMM + + + E، d MMM – E، d MMM + E، d MMM – E، d MMM + + + y–y + + + M/y – M/y + M/y – M/y + + + d/M/y – d/M/y + d/M/y – d/M/y + d/M/y – d/M/y + + + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + E، d/M/y – E، d/M/y + + + MMM–MMM y + MMM y – MMM y + + + d–d MMM y + d MMM – d MMM، y + d MMM، y – d MMM، y + + + E، d MMM – E، d MMM، y + E، d MMM – E، d MMM، y + E، d MMM، y – E، d MMM، y + + + MMMM–MMMM y + MMMM y – MMMM y + + + + + + + + دور + + + دور + + + دور + + + کال + پیوک کال + ایݜ + کال گے + + {0} کالا میں + + + {0} کالا موش + + + + کال + پیوک کال + ایݜ + کال گے + + {0} کالا میں + + + {0} کالا موش + + + + کال + پیوک کال + ایݜ + کال گے + + {0} کالا میں + + + {0} کالا موش + + + + ڇا مای + + + ڇا مای + + + ڇا مای + + + ما + مُشُم ما + میں ما + دُوئی ما + + {0} ما میں + + + {0} مائے موش + + + + ما + مُشُم ما + میں ما + دُوئی ما + + {0} ما میں + + + {0} مائے موش + + + + ما + مُشُم ما + میں ما + دُوئی ما + + {0} ما میں + + + {0} مائے موش + + + + ہفتہ + مُشُم ہفتہ + میں ہفتہ + دُوئی ہفتہ + + {0} ہفتہ میں + + + {0} ہفتائے موش + + {0} سی ہفتہ + + + ہفتہ + مُشُم ہفتہ + میں ہفتہ + دُوئی ہفتہ + + {0} ہفتہ میں + + + {0} ہفتائے موش + + {0} سی ہفتہ + + + ہفتہ + مُشُم ہفتہ + میں ہفتہ + دُوئی ہفتہ + + {0} ہفتہ میں + + + {0} ہفتائے موش + + {0} سی ہفتہ + + + ما سی ہفتہ + + + ما سی ہفتہ + + + ما سی ہفتہ + + + دی + بأل + آش + بول + + {0} دیا میں + + + {0} دیےموش + + + + دی + بأل + آش + بول + + {0} دیا میں + + + {0} دیےموش + + + + دی + بأل + آش + بول + + {0} دیا میں + + + {0} دیےموش + + + + کال سی دی + + + کال سی دی + + + کال سی دی + + + ہفتہ سی دی + + + ہفتہ سی دی + + + ہفتہ سی دی + + + موشوم ایکشیمے + مے ایکشیمے + دوی ایکشیمے + + +{0} ایکشیمے + + + -{0} ایکشیمے + + + + موشوم ایکشیمے + مے ایکشیمے + دوی ایکشیمے + + +{0} ایکشیمے + + + -{0} ایکشیمے + + + + موشوم ایکشیمے + مے ایکشیمے + دوی ایکشیمے + + +{0} ایکشیمے + + + -{0} ایکشیمے + + + + موشوم دوشیمے + مے دوشیمے + دوی دوشیمے + + +{0} دوشیمے + + + -{0} دوشیمے + + + + موشوم دوشیمے + مے دوشیمے + دوی دوشیمے + + +{0} دوشیمے + + + -{0} دوشیمے + + + + موشوم دوشیمے + مے دوشیمے + دوی دوشیمے + + +{0} دوشیمے + + + -{0} دوشیمے + + + + موشوم گھن آنگا + مے گھن آنگا + دوی گھن آنگا + + +{0} گھن آنگا + + + -{0} گھن آنگا + + + + موشوم گھن آنگا + مے گھن آنگا + دوی گھن آنگا + + +{0} گھن آنگا + + + -{0} گھن آنگا + + + + موشوم گھن آنگا + مے گھن آنگا + دوی گھن آنگا + + +{0} گھن آنگا + + + -{0} گھن آنگا + + + + موشوم چارشیمے + مے چارشیمے + دوی چارشیمے + + +{0} چارشیمے + + + -{0} چارشیمے + + + + موشوم چارشیمے + مے چارشیمے + دوی چارشیمے + + +{0} چارشیمے + + + -{0} چارشیمے + + + + موشوم چارشیمے + مے چارشیمے + دوی چارشیمے + + +{0} چارشیمے + + + -{0} چارشیمے + + + + موشوم پئی شیمے + مے پئی شیمے + دوی پئی شیمے + + +{0} پئی شیمے + + + -{0} پئی شیمے + + + + موشوم پئی شیمے + مے پئی شیمے + دوی پئی شیمے + + +{0} پئی شیمے + + + -{0} پئی شیمے + + + + موشوم پئی شیمے + مے پئی شیمے + دوی پئی شیمے + + +{0} پئی شیمے + + + -{0} پئی شیمے + + + + موشوم شُوگار + مے شُوگار + دوی شُوگار + + +{0} شُوگار + + + -{0} شُوگار + + + + موشوم شُوگار + مے شُوگار + دوی شُوگار + + +{0} شُوگار + + + -{0} شُوگار + + + + موشوم شُوگار + مے شُوگار + دوی شُوگار + + +{0} شُوگار + + + -{0} شُوگار + + + + موشوم لَو آنگا + مے لَو آنگا + دوی لَو آنگا + + +{0} لَو آنگا + + + -{0} لَو آنگا + + + + موشوم لَو آنگا + مے لَو آنگا + دوی لَو آنگا + + +{0} لَو آنگا + + + -{0} لَو آنگا + + + + موشوم لَو آنگا + مے لَو آنگا + دوی لَو آنگا + + +{0} لَو آنگا + + + -{0} لَو آنگا + + + + پیشیا موش/پیشیا پأش + + + پیشیا موش/پیشیا پأش + + + پیشیا موش/پیشیا پأش + + + گینٹہ + میں گینٹہ + + {0} گینٹہ میں + + + {0} گینٹائے موش + + + + گینٹہ + میں گینٹہ + + {0} گینٹہ میں + + + {0} گینٹائے موش + + + + گینٹہ + میں گینٹہ + + {0} گینٹہ میں + + + {0} گینٹائے موش + + + + میلٹ + میں میلٹ + + +{0} میلڑا میں + + + -{0} میلڑے موش + + + + میلٹ + میں میلٹ + + +{0} میلڑا میں + + + -{0} میلڑے موش + + + + میلٹ + میں میلٹ + + +{0} میلٹ میں + + + -{0} میلٹ موش + + + + سیکنڈ + مھیرے + + +{0} سیکنڑا میں + + + -{0} سیکنڑے موش + + + + سیکنڈ + مھیرے + + +{0} سیکنڈ میں + + + -{0} سیکنڈ موش + + + + سیکنڈ + مھیرے + + +{0} سیکنڈ میں + + + -{0} سیکنڈ موش + + + + منطقۂ وَخ + + + منطقۂ وَخ + + + منطقۂ وَخ + + + + {0} وَخ + {0} دھات + {0} معیاری وَخ + + + کوآرڈینیٹڈ یونیورسل ٹائم + + + + نامعلوم خار + + + انڈورا + + + دبئی + + + سیبل + + + انٹیگوا + + + انگویلا + + + ٹیرانی + + + یریوان + + + لوانڈا + + + روتھیرا + + + پلمیر + + + ٹرول + + + سیووا + + + ماؤسن + + + ڈیوس + + + ووستوک + + + کیسی + + + ڈومونٹ ڈی ارویلے + + + میک مرڈو + + + ریو گالیگوس + + + مینڈوزا + + + سان جوآن + + + اوشوآئیا + + + لا ریئوجا + + + سان لوئس + + + کیٹامارسی + + + سالٹا + + + جوجوئی + + + ٹوکومین + + + کورڈوبا + + + بیونس آئرس + + + پاگو پاگو + + + ویانا + + + پرتھ + + + ایوکلا + + + ڈارون + + + اڈیلائڈ + + + بروکن ہِل + + + ملبورن + + + کیوری + + + ہوبارٹ + + + لِنڈمین + + + سڈنی + + + برسبین + + + میکواری + + + لارڈ ہووے + + + اروبا + + + میریہام + + + باکو + + + سراجیوو + + + بارباڈوس + + + ڈھاکہ + + + برسلز + + + اؤگاڈؤگوو + + + صوفیہ + + + بحرین + + + بجمبرا + + + پورٹو نووو + + + سینٹ برتھیلمی + + + برمودا + + + برونئی + + + لا پاز + + + کرالینڈیجک + + + ایرونیپ + + + ریئو برینکو + + + پورٹو ویلہو + + + بوآ وسٹا + + + مناؤس + + + کوئیابا + + + سنٹارین + + + کیمپو گرینڈ + + + بیلیم + + + اراگویانا + + + ساؤ پالو + + + باہیا + + + فورٹالیزا + + + میسیئو + + + ریسائف + + + نورونہا + + + نساؤ + + + تھمپو + + + گبرون + + + مِنسک + + + بیلائز + + + ڈاؤسن + + + وہائٹ ہارس + + + انووِک + + + وینکوور + + + فورٹ نیلسن + + + ڈاؤسن کریک + + + کریسٹون + + + ایلو نائف + + + ایڈمونٹن + + + سوِفٹ کرنٹ + + + کیمبرج سی کھاڑی + + + ریجینا + + + ونّیپیگ + + + ریزولیوٹ + + + رینی ریور + + + رینکن انلیٹ + + + اٹیکوکن + + + تھنڈر بے + + + نپیگون + + + ٹورنٹو + + + ایکالوئٹ + + + پینگنِرٹنگ + + + مونکٹن + + + ہیلیفیکس + + + گوس سی کھاڑی + + + گلیس سی کھاڑی + + + بلانک سبلون + + + سینٹ جانز + + + کوکوس + + + کنشاسا + + + لوبمباشی + + + بنگوئی + + + برازاویلے + + + زیورخ + + + عابدجان + + + راروٹونگا + + + ایسٹر + + + پنٹا اریناس + + + سنٹیاگو + + + ڈوآلا + + + یورومکی + + + شنگھائی + + + بگوٹا + + + کوسٹا ریکا + + + ہوانا + + + کیپ ورڈی + + + کیوراکاؤ + + + کرسمس + + + نکوسیا + + + فاماگوسٹا + + + پراگ + + + بزنجن + + + برلن + + + جبوتی + + + کوپن ہیگن + + + ڈومنیکا + + + سانتو ڈومنگو + + + الجیئرس + + + گیلاپیگوس + + + گوآیاکوئل + + + ٹالن + + + قاہرہ + + + العیون + + + اسمارا + + + کینری + + + سیوٹا + + + میڈرڈ + + + عدیس ابابا + + + ہیلسنکی + + + فجی + + + اسٹینلے + + + چیوک + + + پونپیئی + + + کوسرائی + + + فارو + + + پیرس + + + لبرے ویلے + + + + برٹش سمر ٹائم + + لندن + + + غرناطہ + + + طبلیسی + + + سیئین + + + گرنزی + + + اکّرا + + + جبل الطارق + + + تھولو + + + نوک + + + اسکورز بائی سنڈ + + + ڈنمارک شاون + + + بنجول + + + کونکری + + + گواڈیلوپ + + + ملابو + + + ایتھنز + + + جنوبی جارجیا + + + گواٹے مالا + + + گوآم + + + بِساؤ + + + گیانا + + + ہانگ سینگ + + + ٹیگوسیگالپے + + + زیگریب + + + پورٹ او پرنس + + + بڈاپسٹ + + + جکارتہ + + + پونٹیانک + + + مکاسر + + + جے پورہ + + + + آئرش اسٹینڈرڈ ٹائم + + ڈبلن + + + یروشلم + + + آئل آف مین + + + کولسیتا + + + چاگوس + + + بغداد + + + تہران + + + ریکجاوک + + + روم + + + جرسی + + + جمائیکا + + + امّان + + + ٹوکیو + + + نیروبی + + + بشکیک + + + پنوم پن + + + اینڈربری + + + کریتیماٹی + + + ٹراوا + + + کومورو + + + سینٹ کٹس + + + پیونگ یانگ + + + سیئول + + + کویت + + + کیمین + + + اکتاؤ + + + اورال + + + آتیراؤ + + + اکٹوب + + + کوستانے + + + کیزیلورڈا + + + الماٹی + + + وینٹیانا + + + بیروت + + + سینٹ لوسیا + + + ویڈوز + + + کولمبو + + + مونروویا + + + مسیرو + + + وِلنیئس + + + لگژمبرگ + + + ریگا + + + ٹریپولی + + + کیسا بلانکا + + + موناکو + + + چیسیناؤ + + + پوڈگورسیا + + + میریگوٹ + + + انٹاناناریوو + + + کواجیلین + + + مجورو + + + اسکوپجے + + + بماکو + + + رنگون + + + ہووارڈ + + + اولان باتار + + + چوئبالسان + + + مسیؤ + + + سائپین + + + مارٹینک + + + نواکشوط + + + مونٹسیراٹ + + + مالٹا + + + ماریشس + + + مالدیپ + + + بلینٹائر + + + تیجوآنا + + + ہرموسیلو + + + میزٹلان + + + چیہوآہوآ + + + بہیا بندراز + + + اوجیناگا + + + مونٹیری + + + میکسیکو سٹی + + + میٹاموروس + + + میریڈا + + + کنکیون + + + کوالا لمپور + + + کیوچنگ + + + مپوٹو + + + ونڈہوک + + + نؤمیا + + + نیامی + + + نورفوک + + + لاگوس + + + مناگوآ + + + ایمسٹرڈم + + + اوسلو + + + سیٹھمنڈو + + + ناؤرو + + + نیئو + + + چیتھم + + + آکلینڈ + + + مسقط + + + پنامہ + + + لیما + + + تاہیتی + + + مارکیساس + + + گامبیئر + + + پورٹ موریسبی + + + بوگینولے + + + منیلا + + + کراچی + + + وارسا + + + میکلیئون + + + پٹکائرن + + + پیورٹو ریکو + + + غزہ + + + ہیبرون + + + ازوریس + + + مڈیئرا + + + لسبن + + + پلاؤ + + + اسنسیئن + + + قطر + + + ری یونین + + + بخارسٹ + + + بلغراد + + + کالينينغراد + + + ماسکو + + + وولگوگراد + + + سیراٹو + + + استراخان + + + الیانوسک + + + کیروف + + + سمارا + + + یکاٹیرِنبرگ + + + اومسک + + + نوووسِبِرسک + + + برنال + + + ٹامسک + + + نوووکیوزنیسک + + + کریسنویارسک + + + ارکتسک + + + چیتا + + + یکوتسک + + + ولادی ووستک + + + خندیگا + + + سخالین + + + اوست-نیرا + + + میگیدن + + + سرہدنیکولیمسک + + + کیمچٹکا + + + انیدر + + + کگالی + + + ریاض + + + گواڈل کینال + + + ماہی + + + خرطوم + + + اسٹاک ہوم + + + سنگاپور + + + سینٹ ہیلینا + + + لیوبلیانا + + + لانگ ایئر بین + + + بریٹِسلاوا + + + فری ٹاؤن + + + سان ماریانو + + + ڈکار + + + موگادیشو + + + پراماریبو + + + جوبا + + + ساؤ ٹوم + + + ال سلواڈور + + + لوور پرنسس کوارٹر + + + دمشق + + + مبابین + + + عظیم ترک + + + اینجامینا + + + کرگیولین + + + لوم + + + بنکاک + + + دوشانبے + + + فکاؤفو + + + ڈلی + + + اشغبت + + + تیونس + + + ٹونگاٹاپو + + + استنبول + + + پورٹ آف اسپین + + + فیونافیوٹی + + + تائپے + + + دار السلام + + + ازہوراڈ + + + کیو + + + سمفروپول + + + زیپوروزائی + + + کیمپالا + + + مڈوے + + + ویک + + + اداک + + + نوم + + + جانسٹن + + + اینکریج + + + یکوٹیٹ + + + سیٹکا + + + جونیئو + + + میٹلا کاٹلا + + + لاس اینجلس + + + بوائس + + + فینکس + + + ڈینور + + + بیولاہ، شمالی ڈکوٹا + + + نیو سلیم، شمالی ڈکوٹا + + + وسط، شمالی ڈکوٹا + + + شکاگو + + + مینومینی + + + ونسینیز، انڈیانا + + + پیٹرزبرگ، انڈیانا + + + ٹیل سٹی، انڈیانا + + + کنوکس، انڈیانا + + + وینامیک، انڈیانا + + + مرینگو، انڈیانا + + + انڈیاناپولس + + + لوئس ویلے + + + ویوے، انڈیانا + + + مونٹیسیلو، کینٹوکی + + + ڈیٹرائٹ + + + نیو یارک + + + مونٹی ویڈیو + + + سمرقند + + + تاشقند + + + واٹیکن + + + سینٹ ونسنٹ + + + کراسیس + + + ٹورٹولا + + + سینٹ تھامس + + + ہو چی منہ سٹی + + + ایفیٹ + + + ولّیس + + + اپیا + + + عدن + + + مایوٹ + + + جوہانسبرگ + + + لیوساکا + + + ہرارے + + + + افغانستان سی وَخ + + + + + وسطی افریقہ ٹائم + + + + + مشرقی افریقہ ٹائم + + + + + جنوبی افریقہ سٹینڈرڈ ٹائم + + + + + مغربی افریقہ ٹائم + مغربی افریقہ سٹینڈرڈ ٹائم + مغربی افریقہ سمر ٹائم + + + + + الاسکا ٹائم + الاسکا اسٹینڈرڈ ٹائم + الاسکا ڈے لائٹ ٹائم + + + + + امیزون ٹائم + ایمیزون سی معیاری وَخ + امیزون سی موسم گرما سی وَخ + + + + + سنٹرل ٹائم + سنٹرل اسٹینڈرڈ ٹائم + سنٹرل ڈے لائٹ ٹائم + + + + + ایسٹرن ٹائم + ایسٹرن اسٹینڈرڈ ٹائم + ایسٹرن ڈے لائٹ ٹائم + + + + + ماؤنٹین ٹائم + ماؤنٹین اسٹینڈرڈ ٹائم + ماؤنٹین ڈے لائٹ ٹائم + + + + + پیسفک ٹائم + پیسفک اسٹینڈرڈ ٹائم + پیسفک ڈے لائٹ ٹائم + + + + + ایپیا ٹائم + ایپیا سٹینڈرڈ ٹائم + ایپیا ڈے لائٹ ٹائم + + + + + عرب سی وَخ + عرب سی معیاری وَخ + عرب ڈے لائٹ ٹائم + + + + + ارجنٹینا سی وَخ + ارجنٹینا سی معیاری وَخ + ارجنٹینا سی موسم گرما سی وَخ + + + + + مغربی ارجنٹینا سی وَخ + مغربی ارجنٹینا سی معیاری وَخ + مغربی ارجنٹینا سی موسم گرما سی وَخ + + + + + آرمینیا سی وَخ + آرمینیا سی معیاری وَخ + آرمینیا سی موسم گرما سی وَخ + + + + + اٹلانٹک ٹائم + اٹلانٹک اسٹینڈرڈ ٹائم + اٹلانٹک ڈے لائٹ ٹائم + + + + + سنٹرل آسٹریلیا ٹائم + آسٹریلین سنٹرل اسٹینڈرڈ ٹائم + آسٹریلین سنٹرل ڈے لائٹ ٹائم + + + + + آسٹریلین سنٹرل ویسٹرن ٹائم + آسٹریلین سنٹرل ویسٹرن اسٹینڈرڈ ٹائم + آسٹریلین سنٹرل ویسٹرن ڈے لائٹ ٹائم + + + + + ایسٹرن آسٹریلیا ٹائم + آسٹریلین ایسٹرن اسٹینڈرڈ ٹائم + آسٹریلین ایسٹرن ڈے لائٹ ٹائم + + + + + ویسٹرن آسٹریلیا ٹائم + سٹریلیا ویسٹرن اسٹینڈرڈ ٹائم + آسٹریلین ویسٹرن ڈے لائٹ ٹائم + + + + + آذربائیجان سی وَخ + آذربائیجان سی معیاری وَخ + آذربائیجان سی موسم گرما سی وَخ + + + + + ازوریس سی وَخ + ازوریس سی معیاری وَخ + ازوریس سی موسم گرما سی وَخ + + + + + بنگلہ دیش سی وَخ + بنگلہ دیش سی معیاری وَخ + بنگلہ دیش سی موسم گرما سی وَخ + + + + + بھوٹان سی وَخ + + + + + بولیویا سی وَخ + + + + + برازیلیا ٹائم + برازیلیا اسٹینڈرڈ ٹائم + برازیلیا سمر ٹائم + + + + + برونئی دارالسلام ٹائم + + + + + کیپ ورڈی ٹائم + کیپ ورڈی سٹینڈرڈ ٹائم + کیپ ورڈی سمر ٹائم + + + + + چامورو سٹینڈرڈ ٹائم + + + + + چیتھم ٹائم + چیتھم اسٹینڈرڈ ٹائم + چیتھم ڈے لائٹ ٹائم + + + + + چلی سی وَخ + چلی سی معیاری وَخ + چلی سی موسم گرما سی وَخ + + + + + چین سی وَخ + چین سٹینڈرڈ ٹائم + چینی ڈے لائٹ ٹائم + + + + + کوئبلسان ٹائم + کوئبلسان سٹینڈرڈ ٹائم + کوائبلسان سمر ٹائم + + + + + کرسمس آئلینڈ ٹائم + + + + + کوکوس آئلینڈز ٹائم + + + + + کولمبیا ٹائم + کولمبیا سی معیاری وَخ + کولمبیا سی موسم گرما سی وَخ + + + + + کک آئلینڈز ٹائم + کک آئلینڈز سٹینڈرڈ ٹائم + کک آئلینڈز نصف سمر ٹائم + + + + + کیوبا ٹائم + کیوبا اسٹینڈرڈ ٹائم + کیوبا ڈے لائٹ ٹائم + + + + + ڈیوس ٹائم + + + + + ڈومونٹ-ڈی’ارویلے ٹائم + + + + + مشرقی تیمور ٹائم + + + + + ایسٹر آئلینڈ سی وَخ + ایسٹر آئلینڈ سی معیاری وَخ + ایسٹر آئلینڈ سی موسم گرما سی وَخ + + + + + ایکواڈور سی وَخ + + + + + وسط یورپ سی وَخ + وسطی یورپ سی معیاری وَخ + وسطی یورپ سی موسم گرما سی وَخ + + + + + مشرقی یورپ سی وَخ + مشرقی یورپ سی معیاری وَخ + مشرقی یورپ سی موسم گرما سی وَخ + + + + + بعید مشرقی یورپی وَخ + + + + + مغربی یورپ سی وَخ + مغربی یورپ سی معیاری وَخ + مغربی یورپ سی موسم گرما سی وَخ + + + + + فاک لینڈ آئلینڈز سی وَخ + فاک لینڈ آئلینڈز سی معیاری وَخ + فاک لینڈ آئلینڈز سی موسم گرما سی وَخ + + + + + فجی ٹائم + فجی سٹینڈرڈ ٹائم + فجی سمر ٹائم + + + + + فرینچ گیانا سی وَخ + + + + + فرینچ جنوبی آں انٹارکٹک ٹائم + + + + + گالاپاگوز سی وَخ + + + + + گیمبیئر ٹائم + + + + + جارجیا سی وَخ + جارجیا سی معیاری وَخ + جارجیا سی موسم گرما سی وَخ + + + + + جلبرٹ آئلینڈز ٹائم + + + + + گرین وچ سی اصل وَخ + + + + + مشرقی گرین لینڈ ٹائم + مشرقی گرین لینڈ اسٹینڈرڈ ٹائم + مشرقی گرین لینڈ سی موسم گرما سی وَخ + + + + + مغربی گرین لینڈ ٹائم + مغربی گرین لینڈ اسٹینڈرڈ ٹائم + مغربی گرین لینڈ سی موسم گرما سی وَخ + + + + + خلیج سی معیاری وَخ + + + + + گیانا سی وَخ + + + + + ہوائی الیوٹیئن ٹائم + ہوائی الیوٹیئن اسٹینڈرڈ ٹائم + ہوائی الیوٹیئن ڈے لائٹ ٹائم + + + + + ہانگ سینگ ٹائم + ہانگ سینگ سٹینڈرڈ ٹائم + ہانگ سینگ سمر ٹائم + + + + + ہووڈ ٹائم + ہووڈ سٹینڈرڈ ٹائم + ہووڈ سمر ٹائم + + + + + ہندوستان سی معیاری وَخ + + + + + بحر ہند ٹائم + + + + + ہند چین ٹائم + + + + + وسطی انڈونیشیا ٹائم + + + + + مشرقی انڈونیشیا ٹائم + + + + + مغربی انڈونیشیا ٹائم + + + + + ایران سی وَخ + ایران سی معیاری وَخ + ایران ڈے لائٹ ٹائم + + + + + ارکتسک ٹائم + ارکتسک سٹینڈرڈ ٹائم + ارکتسک سمر ٹائم + + + + + اسرائیل سی وَخ + اسرائیل سی معیاری وَخ + اسرائیل ڈے لائٹ ٹائم + + + + + جاپان ٹائم + جاپان سٹینڈرڈ ٹائم + جاپان ڈے لائٹ ٹائم + + + + + مشرقی قزاخستان سی وَخ + + + + + مغربی قزاخستان سی وَخ + + + + + کوریا ٹائم + کوریا سٹینڈرڈ ٹائم + کوریا ڈے لائٹ ٹائم + + + + + کوسرے ٹائم + + + + + کریسنویارسک ٹائم + کرسنویارسک سٹینڈرڈ ٹائم + کریسنویارسک سمر ٹائم + + + + + کرغستان سی وَخ + + + + + لائن آئلینڈز ٹائم + + + + + لارڈ ہووے ٹائم + لارڈ ہووے اسٹینڈرڈ ٹائم + لارڈ ہووے ڈے لائٹ ٹائم + + + + + مکوآری آئلینڈ سی وَخ + + + + + میگیدن ٹائم + مگادان اسٹینڈرڈ ٹائم + میگیدن سمر ٹائم + + + + + ملیشیا ٹائم + + + + + مالدیپ سی وَخ + + + + + مارکیسس ٹائم + + + + + مارشل آئلینڈز ٹائم + + + + + ماریشس ٹائم + ماریشس سٹینڈرڈ ٹائم + ماریشس سمر ٹائم + + + + + ماؤسن ٹائم + + + + + شمال مغربی میکسیکو ٹائم + شمال مغربی میکسیکو اسٹینڈرڈ ٹائم + شمال مغربی میکسیکو ڈے لائٹ ٹائم + + + + + میکسیکن پیسفک ٹائم + میکسیکن پیسفک اسٹینڈرڈ ٹائم + میکسیکن پیسفک ڈے لائٹ ٹائم + + + + + یولان بیتور ٹائم + یولان بیتور سٹینڈرڈ ٹائم + یولان بیتور سمر ٹائم + + + + + ماسکو ٹائم + ماسکو اسٹینڈرڈ ٹائم + ماسکو سمر ٹائم + + + + + میانمار ٹائم + + + + + ناؤرو ٹائم + + + + + نیپال سی وَخ + + + + + نیو کیلیڈونیا ٹائم + نیو کیلیڈونیا سٹینڈرڈ ٹائم + نیو کیلیڈونیا سمر ٹائم + + + + + نیوزی لینڈ سی وَخ + نیوزی لینڈ سی معیاری وَخ + نیوزی لینڈ ڈے لائٹ ٹائم + + + + + نیو فاؤنڈ لینڈ ٹائم + نیو فاؤنڈ لینڈ اسٹینڈرڈ ٹائم + نیو فاؤنڈ لینڈ ڈے لائٹ ٹائم + + + + + نیئو ٹائم + + + + + نارفوک آئلینڈ سی وَخ + نارفوک آئلینڈ سی معیاری وَخ + نارفوک آئلینڈ سی موسم گرما سی وَخ + + + + + فرنانڈو ڈی نورنہا سی وَخ + فرنانڈو ڈی نورنہا سی معیاری وَخ + فرنانڈو ڈی نورونہا سمر ٹائم + + + + + نوووسیبرسک ٹائم + نوووسیبرسک سٹینڈرڈ ٹائم + نوووسیبرسک سمر ٹائم + + + + + اومسک ٹائم + اومسک سٹینڈرڈ ٹائم + اومسک سمر ٹائم + + + + + پاکستان سی وَخ + پاکستان سی معیاری وَخ + پاکستان سی موسم گرما سی وَخ + + + + + پلاؤ ٹائم + + + + + پاپوآ نیو گنی ٹائم + + + + + پیراگوئے سی وَخ + پیراگوئے سی معیاری وَخ + پیراگوئے سی موسم گرما سی وَخ + + + + + پیرو سی وَخ + پیرو سی معیاری وَخ + پیرو سی موسم گرما سی وَخ + + + + + فلپائن ٹائم + فلپائن سٹینڈرڈ ٹائم + فلپائن سمر ٹائم + + + + + فینکس آئلینڈز ٹائم + + + + + سینٹ پیئر آں مکلیئون ٹائم + سینٹ پیئر آں مکلیئون اسٹینڈرڈ ٹائم + سینٹ پیئر آں مکلیئون ڈے لائٹ ٹائم + + + + + پٹکائرن ٹائم + + + + + پوناپے ٹائم + + + + + پیانگ یانگ وَخ + + + + + ری یونین ٹائم + + + + + روتھیرا سی وَخ + + + + + سخالین ٹائم + سخالین سٹینڈرڈ ٹائم + سخالین سمر ٹائم + + + + + ساموآ ٹائم + ساموآ سٹینڈرڈ ٹائم + ساموآ ڈے لائٹ ٹائم + + + + + سیشلیز ٹائم + + + + + سنگاپور سٹینڈرڈ ٹائم + + + + + سولمن آئلینڈز ٹائم + + + + + جنوبی جارجیا ٹائم + + + + + سورینام سی وَخ + + + + + سیووا ٹائم + + + + + تاہیتی ٹائم + + + + + تائی پیئی ٹائم + تائی پیئی اسٹینڈرڈ ٹائم + تئی پیئی ڈے لائٹ ٹائم + + + + + تاجکستان سی وَخ + + + + + ٹوکیلاؤ ٹائم + + + + + ٹونگا ٹائم + ٹونگا سٹینڈرڈ ٹائم + ٹونگا سمر ٹائم + + + + + چوک ٹائم + + + + + ترکمانستان سی وَخ + ترکمانستان سی معیاری وَخ + ترکمانستان سی موسم گرما سی وَخ + + + + + ٹوالو ٹائم + + + + + یوروگوئے سی وَخ + یوروگوئے سی معیاری وَخ + یوروگوئے سی موسم گرما سی وَخ + + + + + ازبکستان سی وَخ + ازبکستان سی معیاری وَخ + ازبکستان سی موسم گرما سی وَخ + + + + + وانوآٹو ٹائم + وانوآٹو سٹینڈرڈ ٹائم + وانوآٹو سمر ٹائم + + + + + وینزوئیلا سی وَخ + + + + + ولادی ووستک ٹائم + ولادی ووستک سٹینڈرڈ ٹائم + ولادی ووستک سمر ٹائم + + + + + وولگوگراد ٹائم + وولگوگراد اسٹینڈرڈ ٹائم + وولگوگراد سمر ٹائم + + + + + ووسٹاک سی وَخ + + + + + ویک آئلینڈ ٹائم + + + + + والیز اور فٹونا ٹائم + + + + + یکوتسک ٹائم + یکوتسک اسٹینڈرڈ ٹائم + یکوتسک سمر ٹائم + + + + + یکاٹیرِنبرگ ٹائم + یکاٹیرِنبرگ اسٹینڈرڈ ٹائم + یکاٹیرِنبرگ سمر ٹائم + + + + + یوکون ٹائم + + + + + + + arabext + + + + + ¤ #,##0.00 + + + + + + متحدہ عرب اماراتی درہم + متحدہ عرب اماراتی درہم + + + افغان افغانی + افغان افغانی + + + البانیا سی لیک + البانیا سی لیک + + + آرمینیائی ڈرم + آرمینیائی ڈرم + + + نیدر لینڈز انٹیلیئن گلڈر + نیدر لینڈز انٹیلیئن گلڈر + + + انگولا سی کوانزا + انگولا سی کوانزا + + + ارجنٹائن پیسہ + ارجنٹائن پیسہ + + + آسٹریلین ڈالر + آسٹریلین ڈالر + + + اروبن فلورِن + اروبن فلورِن + + + آذربائجانی منات + آذربائجانی منات + + + بوسنیا ہرزیگووینا کا قابل منتقلی نشان + بوسنیا ہرزیگووینا کا قابل منتقلی نشان + + + باربیڈین ڈالر + باربیڈین ڈالر + + + بنگلہ دیشی ٹکا + بنگلہ دیشی ٹکا + + + بلغارین لیو + بلغارین لیو + + + بحرینی دینار + بحرینی دینار + + + برونڈیئن فرانک + برونڈیئن فرانک + + + برموڈا ڈالر + برموڈا ڈالر + + + برونئی ڈالر + برونئی ڈالر + + + بولیوین بولیویانو + بولیوین بولیویانو + + + برازیلی ریئل + برازیلی ریئل + + + بہامانی ڈالر + بہامانی ڈالر + + + بھوٹانی گُلٹرم + بھوٹانی گُلٹرم + + + بوتسوانا سی پولا + بوتسوانا سی پولا + + + بیلاروسی روبل + بیلاروسی روبل + BYN + + + بیلیز ڈالر + بیلیز ڈالر + + + کنیڈین ڈالر + کنیڈین ڈالر + CA$ + + + کانگولیز فرانک + کانگولیز فرانک + + + سوئس فرانکس + سوئس فرانکس + + + چلّین پیسہ + چلّین پیسہ + + + چینی یوآن (آف شور) + چینی یوآن (آف شور) + + + چینی یوآن + چینی یوآن + + + کولمبین پیسہ + کولمبین پیسہ + + + کوسٹا ریکا کا کولن + کوسٹا ریکا کا کولن + + + کیوبا کا قابل منتقلی پیسو + کیوبا کا قابل منتقلی پیسو + + + کیوبا سی پیسو + کیوبا سی پیسو + + + کیپ ورڈی سی اسکیوڈو + کیپ ورڈی سی اسکیوڈو + + + چیک کرونا + چیک کروناز + + + جبوتی فرانک + جبوتی فرانک + + + ڈنمارک کرون + ڈنمارک کرون + + + ڈومنیکن پیسو + ڈومنیکن پیسو + + + الجیریائی دینار + الجیریائی دینار + + + مصری پاؤنڈ + مصری پاؤنڈ + + + اریٹیریا سی نافکا + اریٹیریا سی نافکا + + + ایتھوپیائی بِرّ + ایتھوپیائی بِرّ + + + یورو + یورو + + + فجی سی ڈالر + فجی سی ڈالر + + + فاکلینڈ آئلینڈز پونڈ + فاکلینڈ آئلینڈز پونڈ + + + برطانوی پاؤنڈ + برطانوی پاؤنڈ + + + جارجیائی لاری + جارجیائی لاری + + + گھانا سی سیڈی + گھانا سی سیڈی + + + جبل الطارق پونڈ + جبل الطارق پونڈ + + + گامبیا سی ڈلاسی + گامبیا سی ڈلاسی + + + گنی فرانک + گنی فرانک + + + گواٹے مالا کا کوئٹزل + گواٹے مالا کا کوئٹزل + + + گویانیز ڈالر + گویانیز ڈالر + + + ھانگ کانگ ڈالر + ھانگ کانگ ڈالر + + + ہونڈوران لیمپیرا + ہونڈوران لیمپیرا + + + کروشین کونا + کروشین کونا + + + ہیتی کا گؤرڈی + ہیتی کا گؤرڈی + + + ہنگرین فورنٹ + ہنگرین فورنٹ + + + انڈونیشین روپیہ + انڈونیشین روپیہ + + + اسرائیلی نم شیکل + اسرائیلی نم شیکل + + + بھارتی روپیہ + بھارتی روپیہ + + + عراقی دینار + عراقی دینار + + + ایرانی ریال + ایرانی ریال + + + آئس لينڈی کرونا + آئس لينڈی کرونا + + + جمائیکن ڈالر + جمائیکن ڈالر + + + اردنی دینار + اردنی دینار + + + جاپانی ین + جاپانی ین + + + کینیائی شلنگ + کینیائی شلنگ + + + کرغستانی سوم + کرغستانی سوم + + + کمبوڈیائی ریئل + کمبوڈیائی ریئل + + + کوموریئن فرانک + کوموریئن فرانک + + + شمالی کوریائی وون + شمالی کوریائی وون + + + جنوبی کوریائی وون + جنوبی کوریائی وون + + + کویتی دینار + کویتی دینار + + + کیمین آئلینڈز ڈالر + کیمین آئلینڈز ڈالر + + + قزاخستانی ٹینگ + قزاخستانی ٹینگ + + + لاؤشیائی کِپ + لاؤشیائی کِپ + + + لبنانی پونڈ + لبنانی پونڈ + + + سری لنکائی روپیہ + سری لنکائی روپیہ + + + لائبریائی ڈالر + لائبریائی ڈالر + + + لیسوتو لوٹی + لیسوتو لوٹیس + + + لیبیائی دینار + لیبیائی دینار + + + مراکشی درہم + مراکشی درہم + + + مالدووی لیو + مالدووی لیو + + + ملاگاسی اریاری + ملاگاسی اریاری + + + مقدونیائی دینار + مقدونیائی دینار + + + میانمار کیاٹ + میانمار کیاٹ + + + منگولیائی ٹگرِ + منگولیائی ٹگرِ + + + میکانیز پٹاکا + میکانیز پٹاکا + + + موریطانیائی اوگوئیا + موریطانیائی اوگوئیا + + + ماریشس کا روپیہ + ماریشس کا روپیہ + + + مالدیپ سی روفیہ + مالدیپ سی روفیہ + + + ملاوی کواچا + ملاوی کواچا + + + میکسیکی پیسہ + میکسیکی پیسہ + + + ملیشیائی رنگِٹ + ملیشیائی رنگِٹ + + + موزامبیقی میٹیکل + موزامبیقی میٹیکل + + + نامیبیائی ڈالر + نامیبیائی ڈالر + + + نائیجیریائی نائرا + نائیجیریائی نائرا + + + نکارا گوا کا کورڈوبا + نکارا گوا کا کورڈوبا + + + ناروے کرون + ناروے کرون + + + نیپالی روپیہ + نیپالی روپیہ + + + نیوزی لینڈ ڈالر + نیوزی لینڈ ڈالر + + + عمانی ریال + عمانی ریال + + + پنامہ کا بالبوآ + پنامہ کا بالبوآ + + + پیروویئن سول + پیروویئن سول + + + پاپوآ نم گنی سی کینا + پاپوآ نم گنی سی کینا + + + فلپائینی پیسہ + فلپائینی پیسہ + + + پاکستانی روپیہ + پاکستانی روپیہ + + + پولش زلوٹی + پولش زلوٹی + + + پیراگوئے سی گوآرنی + پیراگوئے سی گوآرنی + + + قطری ریال + قطری ریال + + + رومانیائی لیو + رومانیائی لیو + + + سربین دینار + سربین دینار + + + روسی روبل + روسی روبل + + + روانڈا سی فرانک + روانڈا سی فرانک + + + سعودی ریال + سعودی ریال + + + سولومن آئلینڈز ڈالر + سولومن آئلینڈز ڈالر + + + سشلی کا روپیہ + سشلی کا روپیہ + + + سوڈانی پاؤنڈ + سوڈانی پاؤنڈ + + + سویڈن کرونا + سویڈن کرونا + + + سنگا پور ڈالر + سنگا پور ڈالر + + + سینٹ ہیلینا پاؤنڈ + سینٹ ہیلینا پاؤنڈ + + + سیئرا لیون لیون + سیئرا لیون لیون + + + صومالی شلنگ + صومالی شلنگ + + + سورینامی ڈالر + سورینامی ڈالر + + + جنوبی سوڈانی پاؤنڈ + جنوبی سوڈانی پاؤنڈ + + + ساؤ ٹومے آں پرنسپے ڈوبرا + ساؤ ٹومے آں پرنسپے ڈوبرا + + + شامی پونڈ + شامی پونڈ + + + سوازی لیلانجینی + سوازی لیلانجینی + + + تھائی باہت + تھائی باہت + + + تاجکستانی سومونی + تاجکستانی سومونی + + + ترکمانستانی منات + ترکمانستانی منات + + + تیونیسیائی دینار + تیونیسیائی دینار + + + ٹونگن پانگا + ٹونگن پانگا + + + ترکی لیرا + ترکی لیرا + + + ترینیداد آں ٹوباگو سی ڈالر + ترینیداد آں ٹوباگو سی ڈالر + + + نیو تائیوان ڈالر + نیو تائیوان ڈالر + + + تنزانیائی شلنگ + تنزانیائی شلنگ + + + یوکرینیائی ہریونیا + یوکرینیائی ہریونیا + + + یوگانڈا شلنگ + یوگانڈا شلنگ + + + امریکی ڈالر + امریکی ڈالر + $ + + + یوروگویان پیسو + یوروگویان پیسو + + + ازبکستانی سوم + ازبکستانی سوم + + + وینزویلا بولیور + وینزویلا بولیور + + + ویتنامی ڈانگ + ویتنامی ڈانگ + + + وینوواتو واتو + وینوواتو واتو + + + ساموآ سی ٹالا + ساموآ سی ٹالا + + + وسطی افریقی [CFA] فرانک + وسطی افریقی [CFA] فرانک + + + مشرقی کریبیا سی ڈالر + مشرقی کریبیا سی ڈالر + + + مغربی افریقی [CFA] فرانک + مغربی افریقی [CFA] فرانک + + + CFP فرانک + CFP فرانک + + + نامعلوم پیس + نامعلوم پیس + + + یمنی ریال + یمنی ریال + + + جنوبی افریقی رانڈ + جنوبی افریقی رانڈ + + + زامبیائی کواچا + زامبیائی کواچا + + + + {0} گینٹہ + دایاں موڑ نمبر {0} مڑیں + + + + + + ڈیسی {0} + + + سینٹی {0} + + + ملی {0} + + + مائکرو {0} + + + نینو {0} + + + پکو{0} + + + فیمٹو{0} + + + اٹو{0} + + + زپٹو{0} + + + یوکٹو{0} + + + ڈیکا{0} + + + ہیکٹو{0} + + + کلو{0} + + + میگا{0} + + + گیگا {0} + + + ٹیرا{0} + + + پیٹا{0} + + + اکسا{0} + + + زیٹا{0} + + + یوٹا{0} + + + کیبی{0} + + + میبی{0} + + + جیبی{0} + + + ٹیبی{0} + + + پیبی{0} + + + ایکسبی{0} + + + زیبی{0} + + + یوب{0} + + + {0} فی {1} + + + مربع {0} + + + کیوبک {0} + + + {0}⋅{1} + + + جی-فورس + {0} جی-فورس + + + میٹر فی مربع سیکنڈ + {0} میٹر فی مربع سیکنڈ + + + گردش + {0} rev + + + ریڈینس + {0} ریڈین + + + ڈگری + {0} ڈگری + + + آرک منٹ + {0} آرک منٹ + + + آرک سیکنڈ + {0} آرک سیکنڈ + + + مربع کلو میٹر + {0} مربع کلو میٹر + {0} فی مربع کلو میٹر + + + ہیکٹر + {0} ہیکٹر + + + مربع میٹر + {0} مربع میٹر + {0} فی مربع میٹر + + + مربع سینٹی میٹر + {0} مربع سینٹی میٹر + {0} فی مربع سینٹی میٹر + + + مربع میل + {0} مربع میل + {0} فی مربع میل + + + ایکڑ + {0} ایکڑ + + + مربع گز + {0} مربع گز + + + مربع فٹ + {0} مربع فٹ + + + مربع انچا + {0} مربع انچا + {0} فی مربع انچا + + + دُنامز + {0} دُنام + + + قیراط + {0} قیراط + + + ملی گرام فی ڈیسی لیٹر + {0} ملی گرام فی ڈیسی لیٹر + + + ملی مولس فی لیٹر + {0} ملی مول فی لیٹر + + + فی ملین حصے + {0} فی ملین حصے + + + فیصد + {0} فیصد + + + فی ملی + {0} فی ملی + + + پرمرئیڈ + {0} پرمرئیڈ + + + مولز + {0} مول + + + لیٹر فی کلومیٹر + {0} لیٹر فی کلومیٹر + + + لیٹر فی 100 کلو میٹر + {0} لیٹر فی 100 کلو میٹر + + + میل فی گیلن + {0} میل فی گیلن + + + میل فی امپیریل گیلن + {0} میل فی امپیریل گیلن + + + پیٹا بائٹس + {0} پیٹا بائٹ + + + ٹیرابائٹس + {0} ٹیرابائٹ + + + ٹیرابٹس + {0} ٹیرابٹ + + + گیگابائٹس + {0} گیگابائٹ + + + گیگابٹس + {0} گیگابٹ + + + ميگابائٹس + {0} میگابائٹ + + + میگابٹس + {0} میگابٹ + + + کلوبائٹس + {0} کلوبائٹ + + + کلوبٹس + {0} کلوبٹ + + + بائٹ + {0} بائٹ + + + بٹس + {0} بٹ + + + قرن + {0} قرن + + + دہائیاں + {0} دہائی + + + کال + {0} کال + فی کال {0} + + + ما + {0} ما + فی ما {0} + + + ہفتہ + {0} ہفتہ + {0} فی ہفتہ + + + دی + {0} دی + {0} فی دی + + + گینٹہ + {0} گینٹہ + {0} فی گینٹہ + + + میلٹ + {0} میلٹ + {0} فی میلٹ + + + سیکنڈ + {0} سیکنڈ + {0} فی سیکنڈ + + + ملی سیکنڈز + {0} ملی سیکنڈ + + + مائیکرو سیکنڈز + {0} مائیکرو سیکنڈ + + + نینو سیکنڈز + {0} نینو سیکنڈ + + + ایمپیئر + {0} ایمپیئر + + + ملی ایمپیئر + {0} ملی ایمپیئر + + + اوہم + {0} اوہم + + + وولٹ + {0} وولٹ + + + کلو کیلوریز + {0} کلو کیلوری + + + کیلوریز + {0} کیلوری + + + کیلوریز + {0} کیلوری + + + کلو جول + {0} کلو جول + + + جول + {0} جول + + + کلو واٹ آور + {0} کلو واٹ آور + + + الیکٹرون وولٹس + {0} الیکٹرون وولٹ + + + برطانوی تھرمل اکائیاں + {0} برطانوی تھرمل اکائی + + + امریکی تھرمز + {0} امریکی تھرم + + + پاؤنڈز قوت + {0} پاؤنڈ قوت + + + نیوٹنز + {0} نیوٹن + + + گیگاہرٹز + {0} گیگاہرٹز + + + میگاہرٹز + {0} میگاہرٹز + + + کلوہرٹز + {0} کلوہرٹز + + + ہرٹز + {0} ہرٹز + + + ٹائپوگرافک em + {0} em + + + پکسلز + {0} پکسل + + + میگا پکسلز + {0} میگا پکسل + + + پکسلز فی سینٹی میٹر + {0} پکسل فی سینٹی میٹر + + + پکسلز فی انچا + {0} پکسل فی انچا + + + ڈاٹس فی سینٹی میٹر + {0} ڈاٹ فی سینٹی میٹر + + + ڈاٹس فی انچا + {0} ڈاٹ فی انچا + + + ڈاٹ + {0} ڈاٹ + + + زمین کا رداس + {0} زمین رداس + + + کلو میٹر + {0} کلو میٹر + {0} فی کلومیٹر + + + میٹر + {0} میٹر + {0} فی میٹر + + + ڈیسی میٹر + {0} ڈیسی میٹر + + + سینٹی میٹر + {0} سینٹی میٹر + {0} فی سینٹی میٹر + + + ملی میٹر + {0} ملیمیٹر + + + مائیکرو میٹر + {0} مائیکرو میٹر + + + نینو میٹر + {0} نینو میٹر + + + پیکو میٹر + {0} پیکو میٹر + + + میل + {0} میل + + + گز + {0} گز + + + فٹ + {0} فٹ + {0} فی فٹ + + + انچا + {0} انچا + {0} فی انچا + + + پارسیک + {0} پارسیک + + + نوری کال + {0} نوری کال + + + ایسٹرونومیکل یونٹس + {0} ایسٹرونومیکل یونٹ + + + فرلانگ + {0} فرلانگ + + + فیتھامز + {0} فیتھامز + + + بحری میل + {0} بحری میل + + + اسکینڈی نیویائی میل + {0} اسکینڈی نیویائی میل + + + پوائنٹس + {0} پوائنٹس + + + شمسی رداس + {0} شمسی رداس + + + lux + {0} lux + + + کنڈیلا + {0} کنڈیلا + + + لیومِن + {0} لیومِن + + + شمسی چمک + {0} شمسی چمک + + + میٹرک ٹن + {0} میٹرک ٹن + + + کلو + {0} کلو + {0} فی کلو + + + گرام + {0} گرام + {0} فی گرام + + + ملی گرام + {0} ملی گرام + + + مائکرو گرام + {0} مائکرو گرام + + + ٹن + {0} ٹن + + + اسٹونز + {0} اسٹون + + + پاؤنڈ + {0} پاؤنڈ + {0} فی پاؤنڈ + + + اونس + {0} اونس + {0} فی اونس + + + ٹرائے اونس + {0} ٹرائے اونس + + + قیراط + {0} قیراط + + + ڈالٹنز + {0} ڈالٹن + + + زمینی کمیتیں + {0} زمینی کمیت + + + شمسی کمیتیں + {0} شمسی کمیت + + + گرین + {0} گرین + + + گیگا واٹ + {0} گیگا واٹ + + + میگا واٹ + {0} میگا واٹ + + + کلو واٹ + {0} کلو واٹ + + + واٹ + {0} واٹ + + + ملی واٹ + {0} ملی واٹ + + + ہارس پاور + {0} ہارس پاور + + + ملی میٹر مرکری + {0} ملی میٹر مرکری + + + پاؤنڈز فی مربع انچا + {0} پاؤنڈ فی مربع انچا + + + انچا مرکری + {0} انچا مرکری + + + بارز + {0} بار + + + ملی بار + {0} ملی بار + + + ماحول + {0} ماحول + + + پاسکل + {0} پاسکل + + + ہیکٹو پاسکل + {0} ہیکٹو پاسکل + + + کلو پاسکلز + {0} کلو پاسکل + + + میگا پاسکلز + {0} میگا پاسکل + + + کلومیٹر فی گینٹہ + {0} کلومیٹر فی گینٹہ + + + میٹر فی سیکنڈ + {0} میٹر فی سیکنڈ + + + میل فی گینٹہ + {0} میل فی گینٹہ + + + ناٹس + {0} ناٹ + + + ° + {0}° + + + ڈگری سیلسیس + {0} ڈگری سیلسیس + + + ڈگری فارن ہائیٹ + {0} ڈگری فارن ہائیٹ + + + کیلون + {0} کیلون + + + پاؤنڈ فٹ + {0} پاؤنڈ فٹ + + + نیوٹن میٹر + {0} نیوٹن میٹر + + + کیوبک کلو میٹر + {0} کیوبک کلو میٹر + + + کیوبک میٹر + {0} کیوبک میٹر + {0} فی کیوبک میٹر + + + کیوبک سینٹی میٹر + {0} کیوبک سینٹی میٹر + {0} فی کیوبک سینٹی میٹر + + + کیوبک میل + {0} کیوبک میل + + + کیوبک گز + {0} کیوبک گز + + + کیوبک فٹ + {0} کیوبک فٹ + + + کیوبک انچا + {0} کیوبک انچا + + + میگا لیٹر + {0} میگا لیٹر + + + ہیکٹو لیٹر + {0} ہیکٹو لیٹر + + + لیٹر + {0} لیٹر + {0} فی لیٹر + + + ڈیسی لیٹر + {0} ڈیسی لیٹر + + + سینٹی لیٹر + {0} سینٹی لیٹر + + + ملی لیٹر + {0} ملی لیٹر + + + میٹرک پائنٹ + {0} میٹرک پائنٹ + + + میٹرک کپ + {0} میٹرک کپ + + + ایکڑ فٹ + {0} ایکڑ فٹ + + + بوشیل + {0} بوشیل + + + گیلن + {0} گیلن + {0} فی گیلن + + + امپیریل گیلن + {0} امپیریل گیلن + {0} فی امپیریل گیلن + + + کوارٹ + {0} کوارٹ + + + پائنٹ + {0} پائنٹ + + + کپ + {0} کپ + + + فلوئڈ اونس + {0} فلوئڈ اونس + + + امپیریل فلوئڈ اونس + {0} امپیریئل فلوئڈ اونس + + + ٹیبل سپون + {0} ٹیبل سپون + + + ٹی سپون + {0} ٹی سپون + + + بیرلز + {0} بیرل + + + dstspn + {0} dstspn + + + dstspn Imp + {0} dstspn Imp + + + ٹیگیل + {0} ٹیگیل + + + dram fluid + {0} dram fl + + + jigger + {0} jigger + + + پینچ + {0} پینچ + + + qt Imp + {0} qt Imp. + + + کارڈینل ڈائریکشن + {0} مشرق + {0} شمال + {0} جنوب + {0} مغرب + + + + + ڈی۔ {0} + + + سی۔ {0} + + + می۔ {0} + + + نے۔ {0} + + + پی۔{0} + + + فے۔{0} + + + ا۔{0} + + + ز۔{0} + + + یوکٹو{0} + + + ڈے۔{0} + + + ہے۔{0} + + + کی{0} + + + مے۔{0} + + + گی۔{0} + + + ٹے۔{0} + + + پے۔{0} + + + ای۔{0} + + + زے{0} + + + یو{0} + + + {0}⋅{1} + + + جی-فورس + + + ڈگری + {0} ڈگری + + + آرک منٹ + {0} آرک منٹ + + + آرک سیکنڈ + {0} آرک سیکنڈ + + + km² + {0} km² + {0}/km² + + + ہیکٹر + {0} ہیکٹر + + + مربع میٹر + {0} m² + {0}/m² + + + cm² + {0} cm² + {0}/cm² + + + مربع میل + {0} sq mi + {0}/mi² + + + ایکڑ + {0} ایکڑ + + + مربع گز + {0} yd² + + + مربع فٹ + {0} مربع فٹ + + + مربع انچا + {0} in² + {0}/in² + + + دُنامز + {0} دُنام + + + قیراط + {0} kt + + + ملی مول/لیٹر + + + حصے/ملین + + + فیصد + + + فی ملی + {0} فی ملی + + + پرمرئیڈ + {0}‱ + + + مول + {0} مول + + + لیٹر/100 کلو میٹر + {0} L/100km + + + mpg + {0} mpg + + + miles/gal Imp. + {0} mpg Imp. + + + پی بائٹ + {0} پی بی + + + Tbit + + + Gbit + + + MByte + + + kByte + + + kbit + + + بائٹ + {0} byte + + + قرن + {0} قرن + + + دہائی + {0} دہائی + + + کال + {0} کال + + + ما + {0} ما + فی ما {0} + + + ہفتہ + {0} ہفتہ + {0} فی ہفتہ + + + دی + {0} دی + {0} فی دی + + + گینٹہ + {0} گینٹہ + {0} فی گینٹہ + + + میلٹ + {0} میلٹ + {0} فی میلٹ + + + سیکنڈ + {0} سیکنڈ + {0} فی سیکنڈ + + + ملی سیکنڈ + {0} ملی سیکنڈ + + + مائیکرو سیکنڈ + {0} مائیکرو سیکنڈ + + + نینو سیکنڈز + {0} نینو سیکنڈ + + + اوہم + + + وولٹ + + + kcal + {0} kcal + + + الیکٹرون وولٹ + + + امریکی تھرم + {0} امریکی تھرمز + + + پاؤنڈ قوت + + + نیوٹن + + + پکسلز + + + میگا پکسلز + + + ppcm + {0} ppcm + + + ppi + {0} ppi + + + ڈاٹ + {0} ڈاٹ + + + کلو میٹر + {0} کلو میٹر + {0} فی کلو میٹر + + + میٹر + {0} میٹر + {0}/m + + + dm + {0} dm + + + سینٹی میٹر + {0} سینٹی میٹر + {0}/سینٹی میٹر + + + ملی میٹر + {0} ملی میٹر + + + μm + {0} μm + + + nm + {0} nm + + + پیکو میٹر + {0} پیکو میٹر + + + میل + {0} میل + + + گز + {0} گز + + + فٹ + {0} فٹ + {0}/فٹ + + + انچا + {0} انچا + {0}/انچا + + + پارسیک + {0} پارسیک + + + نوری کال + {0} نوری کال + + + au + {0} au + + + فرلانگ + {0} فرلانگ + + + فیتھامز + {0} فیتھامز + + + بحری میل + {0} بحری میل + + + smi + {0} smi + + + پوائنٹس + {0} پوائنٹس + + + شمسی رداس + {0} شمسی رداس + + + lux + {0} lx + + + گرام + {0}/g + + + ٹن + + + پاؤنڈ + + + قیراط + + + ڈالٹنز + + + زمینی کمیتیں + + + شمسی کمیتیں + + + گرین + {0} گرین + + + {0} کلو واٹ + + + واٹ + {0} واٹ + + + mm Hg + {0} mm Hg + + + {0} psi + + + بار + {0} بارز + + + کلومیٹر/گھنٹہ + {0} kph + + + میٹر فی سیکنڈ + + + میل فی گینٹہ + {0} mph + + + ڈگری سیلسیس + {0}‎°C + + + ڈگری فارن ہائیٹ + + + km³ + {0} km³ + + + + {0} m³ + {0}/m³ + + + کیوبک سینٹی میٹر + {0} cm³ + {0}/cm³ + + + کیوبک میل + {0} کیوبک میل + + + کیوبک گز + {0} yd³ + + + کیوبک فٹ + {0} ft³ + + + کیوبک انچا + {0} in³ + + + ML + {0} ML + + + لیٹر + {0} لیٹر + {0} فی لیٹر + + + ڈیسی لیٹر + + + سینٹی لیٹر + + + ایکڑ فٹ + + + بوشیل + + + gal + {0} gal + {0}/gal + + + Imp. gal + + + qts + {0} qt + + + کپ + + + fl oz + {0} fl oz + + + بیرل + + + ٹیگیل + {0} ٹیگیل + + + پینچ + {0} پینچ + + + ڈائریکشن + {0}E + {0}N + + + + + ڈیسی {0} + + + سینٹی {0} + + + ملی {0} + + + μ{0} + + + نینو {0} + + + پکو{0} + + + فیمٹو{0} + + + اٹو{0} + + + زپٹو{0} + + + یوکٹو{0} + + + ڈیکا{0} + + + ہیکٹو{0} + + + کلو{0} + + + میگا{0} + + + گیگا {0} + + + ٹیرا{0} + + + پیٹا{0} + + + اکسا{0} + + + زیٹا{0} + + + یوٹا{0} + + + کیبی{0} + + + Mi{0} + + + Gi{0} + + + Ti{0} + + + Pi{0} + + + Ei{0} + + + Zi{0} + + + Yi{0} + + + {0}/{1} + + + {0}² + + + {0}³ + + + {0}⋅{1} + + + ہیکٹر + {0} ہیکٹر + + + مربع میٹر + {0} m² + {0}/m² + + + cm² + {0} cm² + {0}/cm² + + + مربع میل + {0} sq mi + {0}/mi² + + + ایکڑ + {0} ایکڑ + + + مربع گز + {0} yd² + + + مربع فٹ + {0} مربع فٹ + + + مربع انچا + + + دُنامز + {0} دُنام + + + فیصد + {0}% + + + لیٹر/100 کلو میٹر + {0} L/100km + + + قرن + {0} قرن + + + دہائی + {0} دہائی + + + کال + {0} کال + + + ما + {0} ما + فی ما {0} + + + ہفتہ + {0} ہفتہ + {0} فی ہفتہ + + + دی + {0} دی + + + گینٹہ + {0} گینٹہ + {0} فی گینٹہ + + + میلٹ + {0} میلٹ + {0} فی میلٹ + + + سیکنڈ + {0} سیکنڈ + {0} فی سیکنڈ + + + ملی سیکنڈ + {0} ملی س + + + مائیکرو سیکنڈ + {0} م س + + + نینو سیکنڈز + {0} ن س + + + پکسلز + + + میگا پکسلز + + + ڈاٹ + {0} ڈاٹ + + + کلو میٹر + {0} کلو میٹر + {0} فی کلو میٹر + + + میٹر + {0} میٹر + + + سینٹی میٹر + {0}cm + {0}/سینٹی میٹر + + + ملی میٹر + {0} ملی میٹر + + + پیکو میٹر + {0} پیکو میٹر + + + میل + {0} میل + + + گز + {0} گز + + + فٹ + {0} فٹ + {0}/فٹ + + + انچا + {0} انچا + {0}/انچا + + + پارسیک + {0} پارسیک + + + نوری کال + {0} نوری کال + + + فرلانگ + {0} فرلانگ + + + فیتھامز + {0} فیتھامز + + + بحری میل + {0} بحری میل + + + پوائنٹس + {0} پوائنٹس + + + شمسی رداس + {0} شمسی ر + + + kg + {0} kg + + + گرام + {0} گرام + + + km/hr + {0}kph + + + ڈگری سیلسیس + {0}‎°C + + + لیٹر + {0} لیٹر + + + ڈائریکشن + {0}E + {0}N + {0}S + {0}W + + + + + + {0}،{1} + {0}،{1} + {0} ،آں {1} + {0} آں {1} + + + {0}،{1} + {0}،{1} + {0}، یا {1} + {0} یا {1} + + + {0}،{1} + {0}،{1} + {0}، یا {1} + {0} یا {1} + + + {0}،{1} + {0}،{1} + {0}، یا {1} + {0} یا {1} + + + {0}،{1} + {0}،{1} + {0}،{1} + {0}،{1} + + + {0}،{1} + {0}،{1} + {0} ،آں {1} + {0} آں {1} + + + {0}،{1} + {0}،{1} + {0} ،آں {1} + {0} آں {1} + + + {0}،{1} + {0}،{1} + {0} ،آں {1} + {0} آں {1} + + + {0}،{1} + {0}،{1} + {0} ،آں {1} + {0} آں {1} + + + + + ہاں:ہاں + نأ:نأ + + + diff --git a/make/data/cldr/common/main/trw_PK.xml b/make/data/cldr/common/main/trw_PK.xml new file mode 100644 index 00000000000..c7ddcf83557 --- /dev/null +++ b/make/data/cldr/common/main/trw_PK.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/ts.xml b/make/data/cldr/common/main/ts.xml new file mode 100644 index 00000000000..062cc30c7f6 --- /dev/null +++ b/make/data/cldr/common/main/ts.xml @@ -0,0 +1,579 @@ + + + + + + + + + + + Xi Czech + Xi Danish + Xi Jarimani + Xi Giriki + Xi Nghezi + Xi spain + hi xi Estonia + Xi Finnish + Xi Furwa + XiHeberu + hi xi Hungary + hi xi Iceland + Xi Ithali + Xi Japani + Xikorea + hi xi Lithuania + hi xi Latvia + Xi bunu + Xi Norway + Xi Polixi + Putukezi + hi xi Romania + Xi Rhaxiya + Xi Swiden + Xitsonga + + + + [a b c d e f g h i j k l m n o p q r s t u v w x y z] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + Sun + Yan + Kul + Dzi + Mud + Kho + Maw + Mha + Ndz + Nhl + Huk + N’w + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Sunguti + Nyenyenyani + Nyenyankulu + Dzivamisoko + Mudyaxihi + Khotavuxika + Mawuwani + Mhawuri + Ndzhati + Nhlangula + Hukuri + N’wendzamhala + + + + + Sun + Yan + Kul + Dzi + Mud + Kho + Maw + Mha + Ndz + Nhl + Huk + N’w + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + + + Sunguti + Nyenyenyani + Nyenyankulu + Dzivamisoko + Mudyaxihi + Khotavuxika + Mawuwani + Mhawuri + Ndzhati + Nhlangula + Hukuri + N’wendzamhala + + + + + + + Son + Mus + Bir + Har + Ne + Tlh + Mug + + + S + M + T + W + T + F + S + + + Son + Mus + Bir + Har + Ne + Tlh + Mug + + + Sonta + Musumbhunuku + Ravumbirhi + Ravunharhu + Ravumune + Ravuntlhanu + Mugqivela + + + + + Son + Mus + Bir + Har + Ne + Tlh + Mug + + + S + M + T + W + T + F + S + + + Son + Mus + Bir + Har + Ne + Tlh + Mug + + + Sonta + Musumbhunuku + Ravumbirhi + Ravunharhu + Ravumune + Ravuntlhanu + Mugqivela + + + + + + + K1 + K2 + K3 + K4 + + + 1 + 2 + 3 + 4 + + + Kotara yo sungula + Kotara ya vumbirhi + Kotara ya vunharhu + Kotara ya vumune + + + + + K1 + K2 + K3 + K4 + + + 1 + 2 + 3 + 4 + + + Kotara yo sungula + Kotara ya vumbirhi + Kotara ya vunharhu + Kotara ya vumune + + + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + AM + PM + + + AM + PM + + + AM + PM + + + + + + BC + BCE + CE + + + + + + y MMMM d, EEEE + yMMMMEEEEd + + + + + y MMMM d + yMMMMd + + + + + y MMM d + yMMMd + + + + + y-MM-dd + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + + {1} {0} + + + + d + ccc + d, E + E h:mm a + E HH:mm + E h:mm:ss a + E HH:mm:ss + G y + G y MMM + G y MMM d + G y MMM d, E + h a + HH + h:mm a + HH:mm + h:mm:ss a + HH:mm:ss + h:mm:ss a v + HH:mm:ss v + h:mm a v + HH:mm v + L + MM-dd + MM-dd, E + LLL + MMM d + MMM d, E + MMMM d + 'week' W 'of' MMM + 'week' W 'of' MMM + mm:ss + y + y-MM + y-MM-dd + y-MM-dd, E + y MMM + y MMM d + y MMM d, E + y MMMM + y QQQ + y QQQQ + 'week' w 'of' Y + 'week' w 'of' Y + + + {0} {1} + + + {0} – {1} + + d–d + + + h a – h a + h–h a + + + HH–HH + + + h:mm a – h:mm a + h:mm–h:mm a + h:mm–h:mm a + + + HH:mm–HH:mm + HH:mm–HH:mm + + + h:mm a – h:mm a v + h:mm–h:mm a v + h:mm–h:mm a v + + + HH:mm–HH:mm v + HH:mm–HH:mm v + + + h a – h a v + h–h a v + + + HH–HH v + + + MM–MM + + + MM-dd – MM-dd + MM-dd – MM-dd + + + MM-dd, E – MM-dd, E + MM-dd, E – MM-dd, E + + + LLL–LLL + + + MMM d–d + MMM d – MMM d + + + MMM d, E – MMM d, E + MMM d, E – MMM d, E + + + y–y + + + y-MM – y-MM + y-MM – y-MM + + + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + y-MM-dd – y-MM-dd + + + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + y-MM-dd, E – y-MM-dd, E + + + y MMM–MMM + y MMM – y MMM + + + y MMM d–d + y MMM d – MMM d + y MMM d – y MMM d + + + y MMM d, E – MMM d, E + y MMM d, E – MMM d, E + y MMM d, E – y MMM d, E + + + y MMMM–MMMM + y MMMM – y MMMM + + + + + + + + 1 + + , +   + % + + + - + E + × + + + NaN + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤ #,##0.00 + + + ¤ #,##0.00 + + + {0} {1} + {0} {1} + + + + R + + + + ≥{0} + {0}–{1} + + + diff --git a/make/data/cldr/common/main/ts_ZA.xml b/make/data/cldr/common/main/ts_ZA.xml new file mode 100644 index 00000000000..4cb6219d8d8 --- /dev/null +++ b/make/data/cldr/common/main/ts_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/tt.xml b/make/data/cldr/common/main/tt.xml index 2851a33c039..5d642d1b6d3 100644 --- a/make/data/cldr/common/main/tt.xml +++ b/make/data/cldr/common/main/tt.xml @@ -1,6 +1,6 @@ - + + + + + + + + Tshivenḓa + + + + [a b d ḓ e f g h i k l ḽ m n ṅ ṋ o p r s t ṱ u v w x y z] + [c j q] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + + + + + + + + + + + + + + Pha + Luh + Ṱhf + Lam + Shu + Lwi + Lwa + Ṱha + Khu + Tsh + Ḽar + Nye + + + Phando + Luhuhi + Ṱhafamuhwe + Lambamai + Shundunthule + Fulwi + Fulwana + Ṱhangule + Khubvumedzi + Tshimedzi + Ḽara + Nyendavhusiku + + + + + + + Swo + Mus + Vhi + Rar + Ṋa + Ṱan + Mug + + + Swondaha + Musumbuluwo + Ḽavhuvhili + Ḽavhuraru + Ḽavhuṋa + Ḽavhuṱanu + Mugivhela + + + + + + + K1 + K2 + K3 + K4 + + + Kotara ya u thoma + Kotara ya vhuvhili + Kotara ya vhuraru + Kotara ya vhuṋa + + + + + + + + + , +   + + + + + #,##0.### + + + + + + + #E0 + + + + + + + #,##0% + + + + + + + ¤#,##0.00 + + + + + + R + + + + diff --git a/make/data/cldr/common/main/ve_ZA.xml b/make/data/cldr/common/main/ve_ZA.xml new file mode 100644 index 00000000000..d55f653225d --- /dev/null +++ b/make/data/cldr/common/main/ve_ZA.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/vec.xml b/make/data/cldr/common/main/vec.xml new file mode 100644 index 00000000000..32e6fceec46 --- /dev/null +++ b/make/data/cldr/common/main/vec.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + abcazo + achineze + adangme + adiga + afregan + aghem + ainu + akan + aleutian + amàrego + aragoneze + angika + àrabo + àrabo moderno + arapaho + albaneze + Veneto + + + Lengua: {0} + Scritura: {0} + Rejon: {0} + + + + [a à b c d e é è f g h i ì j l m n o ó ò p r s t u ù v x z] + [ª á ć ç ḑ ʣ ǵ í k ł º q ş ţ ʦ ú w y {z\u0327}] + [\- ‐ ‑ ‒ – — ― ⁓ , ; \: ! ? . … · ' ‘ ’ " “ ” « » ( ) \[ \] \{ \} 〈 〉 @ * / \\ \& # + = ⁄] + + diff --git a/make/data/cldr/common/main/vec_IT.xml b/make/data/cldr/common/main/vec_IT.xml new file mode 100644 index 00000000000..ee6861ddd28 --- /dev/null +++ b/make/data/cldr/common/main/vec_IT.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/vi.xml b/make/data/cldr/common/main/vi.xml index 5c88443c07f..6b6dd420fc9 100644 --- a/make/data/cldr/common/main/vi.xml +++ b/make/data/cldr/common/main/vi.xml @@ -1,6 +1,6 @@ - + + + + + + + + Deutänapük + Linglänapük + Sperantapük + Spanyänapük + Fransänapük + Litaliyänapük + Yapänapük + Portugänapük + Rusänapük + Volapük + Tsyinänapük + + + Brasilän + Tsyinän + Deutän + Spanyän + Fransän + Regän Pebalöl + Grusiyän + Grikän + Lindän + Litaliyän + Yapän + Mäxikän + Naureän + Portugän + Palauäns + Rusän + Lamerikän + + + Pük: {0} + Topäd: {0} + + + + [a ä b c d e f g h i j k l m n o ö p r s t u ü v x y z] + [q w] + [A Ä B C D E F G H I J K L M N O Ö P R S T U Ü V X Y Z] + [\- ‐ ‑ – — , ; \: ! ? . … ' ‘ ’ " “ ” « » ( ) \[ \] \{ \} § @ * / \& #] + {0}… + … {0} + {0} … {1} + + + + + + + + + + + + + + G y MMMM'a' 'd'. d'id' + GyMMMMd + + + + + G y MMMM d + GyMMMMd + + + + + G y MMM. d + GyMMMd + + + + + GGGGG y-MM-dd + GGGGGyMMdd + + + + + + + + + yan + feb + mäz + prl + may + yun + yul + gst + set + ton + nov + dek + + + Y + F + M + P + M + Y + Y + G + S + T + N + D + + + yanul + febul + mäzul + prilul + mayul + yunul + yulul + gustul + setul + tobul + novul + dekul + + + + + yan + feb + mäz + prl + may + yun + yul + gst + set + tob + nov + dek + + + Y + F + M + P + M + Y + Y + G + S + T + N + D + + + yanul + febul + mäzul + prilul + mayul + yunul + yulul + gustul + setul + tobul + novul + dekul + + + + + + + su. + mu. + tu. + ve. + dö. + fr. + zä. + + + sudel + mudel + tudel + vedel + dödel + fridel + zädel + + + + + Su + Mu + Tu + Ve + + Fr + + + + S + M + T + V + D + F + Z + + + sudel + mudel + tudel + vedel + dödel + fridel + zädel + + + + + + + Yf1 + Yf2 + Yf3 + Yf4 + + + 1 + 2 + 3 + 4 + + + 1id yelafoldil + 2id yelafoldil + 3id yelafoldil + 4id yelafoldil + + + + + + b. t. kr. + p. t. kr. + + + b. t. kr. + p. t. kr. + + + + + + y MMMM'a' 'd'. d'id' + yMMMMd + + + + + y MMMM d + yMMMMd + + + + + y MMM. d + yMMMd + + + + + y-MM-dd + yMMdd + + + + + + + HH:mm:ss zzzz + HHmmsszzzz + + + + + HH:mm:ss z + HHmmssz + + + + + HH:mm:ss + HHmmss + + + + + HH:mm + HHmm + + + + + + + + Epoche + + + yel + äyelo + ayelo + oyelo + + + mul + ämulo + amulo + omulo + + + vig + ävigo + avigo + ovigo + + + Tag + edelo + ädelo + adelo + odelo + udelo + + + vodabel + + + delalaf + + + düp + + + minut + + + sekun + + + zon + + + + + + + yels + yel {0} + yels {0} + + + muls + mul {0} + muls {0} + + + vigs + + + dels + + + + + + si:s + no:n + + + diff --git a/make/data/cldr/common/main/vo_001.xml b/make/data/cldr/common/main/vo_001.xml new file mode 100644 index 00000000000..93848d5accd --- /dev/null +++ b/make/data/cldr/common/main/vo_001.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/vun.xml b/make/data/cldr/common/main/vun.xml index 9e3b3db51d4..65b2413a02e 100644 --- a/make/data/cldr/common/main/vun.xml +++ b/make/data/cldr/common/main/vun.xml @@ -1,6 +1,6 @@ - + + + + + + + + walon + + + + [a à â å æ b c ç d e é è ê ë f g h i î ï j k l m n o ô œ p q r s t u ù û ü v w x y ÿ z] + [á ä ã ā ē í ì ī ñ ó ò ö ø ú ǔ] + [A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + [\- ‐ ‑ – — , ; \: ! ? . … ’ " “ ” « » ( ) \[ \] § @ * / \& # † ‡] + + diff --git a/make/data/cldr/common/main/wa_BE.xml b/make/data/cldr/common/main/wa_BE.xml new file mode 100644 index 00000000000..1b6bab96e0c --- /dev/null +++ b/make/data/cldr/common/main/wa_BE.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/wae.xml b/make/data/cldr/common/main/wae.xml index 346980341d8..8bf9305ca7b 100644 --- a/make/data/cldr/common/main/wae.xml +++ b/make/data/cldr/common/main/wae.xml @@ -1,6 +1,6 @@ - + + + + + + + + ዐርቢኛ + ጀርመን + እንግሊዝኛ + ስፓኒሽ + ፈረንሳይኛ + ሐንድኛ + ጣሊያንኛ + ጃፓንኛ + ፖርቱጋሊኛ + ራሽኛ + ወላይታቱ + ቻይንኛ + + + + + + አንዶራ + የተባበሩት አረብ ኤምሬትስ + አልባኒያ + አርሜኒያ + አርጀንቲና + ኦስትሪያ + አውስትሬሊያ + አዘርባጃን + ቦስኒያ እና ሄርዞጎቪኒያ + ባርቤዶስ + ቤልጄም + ቡልጌሪያ + ባህሬን + ቤርሙዳ + ቦሊቪያ + ብራዚል + ቡህታን + ቤላሩስ + ቤሊዘ + ኮንጎ + የመካከለኛው አፍሪካ ሪፐብሊክ + ስዊዘርላንድ + ቺሊ + ካሜሩን + ቻይና + ኮሎምቢያ + ኬፕ ቬርዴ + ሳይፕረስ + ቼክ ሪፑብሊክ + ጀርመን + ዴንማርክ + ዶሚኒካ + ዶሚኒክ ሪፑብሊክ + አልጄሪያ + ኢኳዶር + ኤስቶኒያ + ግብጽ + ምዕራባዊ ሳህራ + ኤርትራ + ስፔን + ኢትዮጵያ + ፊንላንድ + ፊጂ + ሚክሮኔዢያ + ፈረንሳይ + እንግሊዝ + ጆርጂያ + የፈረንሳይ ጉዊአና + ጋምቢያ + ጊኒ + ኢኳቶሪያል ጊኒ + ግሪክ + ቢሳዎ + ጉያና + ሆንግ ኮንግ + ክሮኤሽያ + ሀይቲ + ሀንጋሪ + ኢንዶኔዢያ + አየርላንድ + እስራኤል + ህንድ + ኢራቅ + አይስላንድ + ጣሊያን + ጃማይካ + ጆርዳን + ጃፓን + ካምቦዲያ + ኮሞሮስ + ሰሜን ኮሪያ + ደቡብ ኮሪያ + ክዌት + ሊባኖስ + ሊቱዌኒያ + ላትቪያ + ሊቢያ + ሞሮኮ + ሞልዶቫ + ማከዶኒያ + ሞንጎሊያ + ማካዎ + ሞሪቴኒያ + ማልታ + ማሩሸስ + ሜክሲኮ + ማሌዢያ + ናሚቢያ + ኒው ካሌዶኒያ + ናይጄሪያ + ኔዘርላንድ + ኖርዌ + ኔፓል + ኒው ዚላንድ + ፔሩ + የፈረንሳይ ፖሊኔዢያ + ፓፑዋ ኒው ጊኒ + ፖላንድ + ፖርታ ሪኮ + ሮሜኒያ + ራሺያ + ሳውድአረቢያ + ሱዳን + ስዊድን + ሲንጋፖር + ስሎቬኒያ + ስሎቫኪያ + ሴኔጋል + ሱማሌ + ሲሪያ + ቻድ + የፈረንሳይ ደቡባዊ ግዛቶች + ታይላንድ + ታጃኪስታን + ምስራቅ ቲሞር + ቱኒዚያ + ቱርክ + ትሪኒዳድ እና ቶባጎ + ታንዛኒያ + ዩጋንዳ + አሜሪካ + ዩዝበኪስታን + ቬንዙዌላ + የእንግሊዝ ድንግል ደሴቶች + የአሜሪካ ቨርጂን ደሴቶች + የመን + ደቡብ አፍሪካ + ዛምቢያ + + + + [\u135F ᎐-᎙ ሀ-ሏ ⶀ ሐ-ሟ ᎀ-ᎃ ⶁ ሠ-ሯ ⶂ ሰ-ሷ ⶃ ሸ-ሿ ⶄ ቀ-ቈ ቊ-ቍ ቐ-ቖ ቘ ቚ-ቝ በ-ቧ ᎄ-ᎇ ⶅ ቨ-ቷ ⶆ ቸ-ቿ ⶇ ኀ-ኈ ኊ-ኍ ነ-ኗ ⶈ ኘ-ኟ ⶉ አ-ኧ ⶊ ከ-ኰ ኲ-ኵ ኸ-ኾ ዀ ዂ-ዅ ወ-ዖ ዘ-ዟ ⶋ ዠ-ዷ ⶌ ዸ-ዿ ⶍ ጀ-ጇ ⶎ ገ-ጐ ጒ-ጕ ጘ-ጟ ⶓ-ⶖ ጠ-ጧ ⶏ ጨ-ጯ ⶐ ጰ-ጷ ⶑ ጸ-ፏ ᎈ-ᎋ ፐ-ፗ ᎌ-ᎏ ⶒ ፘ-ፚ ⶠ-ⶦ ⶨ-ⶮ ⶰ-ⶶ ⶸ-ⶾ ⷀ-ⷆ ⷈ-ⷎ ⷐ-ⷖ ⷘ-ⷞ] + [ሀ ለ ⶀ መ ᎀ ᎁ ᎃ ⶁ ረ ⶂ ሰ ሸ ⶄ ቈ ቐ ቘ ᎄ ᎅ ᎇ ⶅ ቨ ⶆ ቸ ኀ ኈ ነ ኘ ⶉ ⶊ ከ ኰ ዀ ወ ዐ ⶋ ዠ ደ ⶌ ዸ ጀ ⶎ ጐ ጘ ⶓ ⶕ ⶖ ⶏ ጨ ⶐ ⶑ ጸ ፈ ᎈ ᎉ ᎋ ፐ ᎍ ᎎ ᎏ ፘ ⶠ ⶢ ⶣ ⶤ ⶦ ⶨ ⶩ ⶫ ⶬ ⶮ ⶰ ⶱ ⶳ ⶴ ⶶ ⶸ ⶹ ⶻ ⶼ ⶾ ⷀ ⷁ ⷃ ⷄ ⷆ ⷈ ⷉ ⷋ ⷌ ⷎ ⷐ ⷑ ⷓ ⷔ ⷖ ⷘ ⷙ ⷛ ⷜ ⷝ] + + + + + + + + EEEE፥ dd MMMM ጋላሳ y G + GyMMMMEEEEdd + + + + + dd MMMM y G + GyMMMMdd + + + + + dd-MMM-y G + GyMMMdd + + + + + dd/MM/yy GGGGG + GGGGGyyMMdd + + + + + + + + + ጃንዩ + ፌብሩ + ማርች + ኤፕረ + ሜይ + ጁን + ጁላይ + ኦገስ + ሴፕቴ + ኦክተ + ኖቬም + ዲሴም + + + ጃንዩወሪ + ፌብሩወሪ + ማርች + ኤፕረል + ሜይ + ጁን + ጁላይ + ኦገስት + ሴፕቴምበር + ኦክተውበር + ኖቬምበር + ዲሴምበር + + + + + + + + + + + + + + + + + + + + + + + ወጋ + ሳይኖ + ማቆሳኛ + አሩዋ + ሃሙሳ + አርባ + ቄራ + + + + + + + + + + + + + + + + + + ማለዶ + ቃማ + + + ማለዶ + ቃማ + + + + + + አዳ ዎዴ + ግሮተታ ላይታ + + + + + + EEEE፥ dd MMMM ጋላሳ y G + GyMMMMEEEEdd + + + + + dd MMMM y + yMMMMdd + + + + + dd-MMM-y + yMMMdd + + + + + dd/MM/yy + yyMMdd + + + + + + + h:mm:ss a zzzz + ahmmsszzzz + + + + + h:mm:ss a z + ahmmssz + + + + + h:mm:ss a + ahmmss + + + + + h:mm a + ahmm + + + + + + + + latn + + latn + ethi + + + + + + + + ¤#,##0.00 + + + + + + የብራዚል ሪል + + + የቻይና ዩአን ረንሚንቢ + + + የኢትዮጵያ ብር + Br + + + አውሮ + + + የእንግሊዝ ፓውንድ ስተርሊንግ + + + የሕንድ ሩፒ + + + የጃፓን የን + + + የራሻ ሩብል + + + የአሜሪካን ዶላር + + + + diff --git a/make/data/cldr/common/main/wal_ET.xml b/make/data/cldr/common/main/wal_ET.xml new file mode 100644 index 00000000000..6c199c58faf --- /dev/null +++ b/make/data/cldr/common/main/wal_ET.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/wbp.xml b/make/data/cldr/common/main/wbp.xml new file mode 100644 index 00000000000..9058e0b31e5 --- /dev/null +++ b/make/data/cldr/common/main/wbp.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + Yinkirliji + Warlpiri + + + + + left-to-right + top-to-bottom + + + + [a d g i j k l m n p r t u w y] + [b c e f h o q s v x z] + [J K L {LY} M N {NG} {NY} P R {RD} {RL} {RN} {RR} {RT} T W Y] + + diff --git a/make/data/cldr/common/main/wbp_AU.xml b/make/data/cldr/common/main/wbp_AU.xml new file mode 100644 index 00000000000..04068cc1078 --- /dev/null +++ b/make/data/cldr/common/main/wbp_AU.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/make/data/cldr/common/main/wo.xml b/make/data/cldr/common/main/wo.xml index 6406df14ba0..0676fddae95 100644 --- a/make/data/cldr/common/main/wo.xml +++ b/make/data/cldr/common/main/wo.xml @@ -1,6 +1,6 @@ - - af agq ak am ann ar as asa ast az + af agq ak am ann apc ar as asa ast az bas be bem bez bg bgc bho bm bn bo br brx bs ca ccp ce ceb cgg chr ckb cs cu cv cy da dav de dje doi dsb dua dyo dz @@ -22,13 +22,13 @@ ia id ig ii is it ja jgo jmc jv ka kab kam kde kea kgp khq ki kk kkj kl kln km kn ko kok ks ksb ksf ksh ku kw ky - lag lb lg lij lkt ln lo lrc lt lu luo luy lv + lag lb lg lij lkt lmo ln lo lrc lt lu luo luy lv mai mas mer mfe mg mgh mgo mi mk ml mn mni mr ms mt mua my mzn naq nb nd nds ne nl nmg nn nnh no nus nyn om or os - pa pcm pis pl prg ps pt + pa pap pcm pis pl prg ps pt qu - raj rm rn ro rof + raj rif rm rn ro rof und ru rw rwk sa sah saq sat sbp sc sd se seh ses sg shi si sk sl smn sms sn so sq sr su sv sw @@ -57,7 +57,7 @@ mad mag mak mdf men mh mic min moe moh mos mus mwl myv na nap new ng nia niu nog nqo nr nso nv ny oc ojb ojc ojs ojw oka - pag pam pap pau pqm + pag pam pau pqm rap rar rhg rup sad sba scn sco shn slh sm snk srn ss st str suk swb syr tce tem tet tgx tht tig tlh tli tn tpi trv ts ttm tum tvl ty tyv diff --git a/make/data/cldr/common/supplemental/languageGroup.xml b/make/data/cldr/common/supplemental/languageGroup.xml index 5bdb5ebe8d1..a854fd4de46 100644 --- a/make/data/cldr/common/supplemental/languageGroup.xml +++ b/make/data/cldr/common/supplemental/languageGroup.xml @@ -1,6 +1,6 @@ - - - + + @@ -287,7 +287,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -961,7 +961,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -972,6 +972,28 @@ not be patched by hand, as any changes made in that fashion may be lost. + + + + + + + + + + + + + + + + + + + + + + @@ -1199,7 +1221,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -1325,7 +1347,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -1387,11 +1409,11 @@ not be patched by hand, as any changes made in that fashion may be lost. - + - + @@ -1529,7 +1551,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -1928,8 +1950,6 @@ not be patched by hand, as any changes made in that fashion may be lost. - - @@ -1984,8 +2004,8 @@ not be patched by hand, as any changes made in that fashion may be lost. - - + + @@ -2084,10 +2104,8 @@ not be patched by hand, as any changes made in that fashion may be lost. - - - - + + @@ -2168,10 +2186,10 @@ not be patched by hand, as any changes made in that fashion may be lost. - - + + @@ -2297,7 +2315,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -2481,9 +2499,9 @@ not be patched by hand, as any changes made in that fashion may be lost. - + - + @@ -2709,7 +2727,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -2717,9 +2735,9 @@ not be patched by hand, as any changes made in that fashion may be lost. - + - + @@ -2877,7 +2895,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3299,7 +3317,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3370,8 +3388,8 @@ not be patched by hand, as any changes made in that fashion may be lost. - - + + @@ -3407,7 +3425,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3417,9 +3435,9 @@ not be patched by hand, as any changes made in that fashion may be lost. - + - + @@ -3439,7 +3457,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3481,7 +3499,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3511,7 +3529,7 @@ not be patched by hand, as any changes made in that fashion may be lost. - + @@ -3550,6 +3568,24 @@ not be patched by hand, as any changes made in that fashion may be lost. + + + + + + + + + + + + + + + + + + @@ -3599,9 +3635,9 @@ not be patched by hand, as any changes made in that fashion may be lost. - + - + @@ -3780,5 +3816,6147 @@ not be patched by hand, as any changes made in that fashion may be lost. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/make/data/cldr/common/supplemental/supplementalData.xml b/make/data/cldr/common/supplemental/supplementalData.xml index 8c390b5477c..cc5d5342568 100644 --- a/make/data/cldr/common/supplemental/supplementalData.xml +++ b/make/data/cldr/common/supplemental/supplementalData.xml @@ -546,7 +546,7 @@ The printed version of ISO-4217:2001 - + @@ -958,7 +958,7 @@ The printed version of ISO-4217:2001 - + @@ -1238,7 +1238,7 @@ XXX Code for transations where no currency is involved - + @@ -1311,6 +1311,7 @@ XXX Code for transations where no currency is involved + @@ -1532,7 +1533,7 @@ XXX Code for transations where no currency is involved - + @@ -1847,6 +1848,7 @@ XXX Code for transations where no currency is involved + @@ -2804,6 +2806,9 @@ XXX Code for transations where no currency is involved + + + @@ -3209,6 +3214,7 @@ XXX Code for transations where no currency is involved + @@ -3346,6 +3352,7 @@ XXX Code for transations where no currency is involved + @@ -3358,7 +3365,6 @@ XXX Code for transations where no currency is involved - @@ -3372,6 +3378,7 @@ XXX Code for transations where no currency is involved + @@ -3449,6 +3456,7 @@ XXX Code for transations where no currency is involved + @@ -3517,7 +3525,7 @@ XXX Code for transations where no currency is involved - + @@ -3732,7 +3740,7 @@ XXX Code for transations where no currency is involved - + @@ -3882,6 +3890,7 @@ XXX Code for transations where no currency is involved + @@ -4102,6 +4111,7 @@ XXX Code for transations where no currency is involved + @@ -4177,10 +4187,11 @@ XXX Code for transations where no currency is involved - + + @@ -4398,14 +4409,15 @@ XXX Code for transations where no currency is involved - - + + + @@ -4639,101 +4651,101 @@ XXX Code for transations where no currency is involved - - - - - + + + + + - + - + - + - + - + - + - + - + - - + + - + - + - - + + - + - + - - + + @@ -4868,7 +4880,7 @@ XXX Code for transations where no currency is involved + regions="AD AM AO AT AW BE BF BJ BL BR CG CI CV CW DE EE FR GA GF GN GP GW HR IL IT KZ MC MD MF MQ MZ NC NL PM PT RE RO SI SR ST TG TR WF YT"/> @@ -5407,11 +5419,24 @@ XXX Code for transations where no currency is involved - + + + + + + + + + + + + + + und hu ja km ko mn si ta te vi yue zh @@ -5584,11 +5609,14 @@ XXX Code for transations where no currency is involved Dutch is spoken as a mother tongue by about 60% of the Surinamese, while most others speak it as a second or third language. main language of trade and comm. in Isan region, except ... media where it gives way to Thai; now largely an unwritten language. 10% writing pop estimated in absence of other data - primarily written using an Arabic-derived alphabet + and https://islandstudies.com/files/2016/11/Guernsey-Herm-Sark.pdf - extrapolated GDP from per capita x population understood by 10 million, perhaps. Figure is questionable writing pop artificially set to 5% see also: http://en.wikipedia.org/wiki/Low_German (understood by 10 million people, and native to about 3 million people all around northern Germany) [missing] See the 2006 language survey data for 2nd langs = Shimaore See the 2006 language survey data for 2nd langs Common lingua franca, widely used. High literacy. + but subtracting 270,000 per https://en.wikipedia.org/wiki/Swiss_Italian + [missing] [missing] [missing] 98.8% speak Spanish. Also, https://www.cia.gov/library/publications/the-world-factbook/geos/sp.html diff --git a/make/data/cldr/common/supplemental/supplementalMetadata.xml b/make/data/cldr/common/supplemental/supplementalMetadata.xml index 064239d81b6..e704136950f 100644 --- a/make/data/cldr/common/supplemental/supplementalMetadata.xml +++ b/make/data/cldr/common/supplemental/supplementalMetadata.xml @@ -830,7 +830,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -1129,7 +1129,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -1799,13 +1799,13 @@ For terms of use, see http://www.unicode.org/copyright.html hectare acre + + square-meter + square-foot + millimole-per-liter milligram-ofglucose-per-deciliter @@ -443,6 +447,15 @@ For terms of use, see http://www.unicode.org/copyright.html kilometer-per-hour mile-per-hour + + millimeter-per-hour + centimeter-per-hour + inch-per-hour + + + centimeter-per-hour + inch-per-hour + kilometer-per-hour meter-per-second diff --git a/make/data/cldr/common/supplemental/windowsZones.xml b/make/data/cldr/common/supplemental/windowsZones.xml index 75b7dff71b0..b49266ef9e3 100644 --- a/make/data/cldr/common/supplemental/windowsZones.xml +++ b/make/data/cldr/common/supplemental/windowsZones.xml @@ -70,13 +70,13 @@ For terms of use, see http://www.unicode.org/copyright.html - - + + - + @@ -98,7 +98,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + @@ -108,7 +108,7 @@ For terms of use, see http://www.unicode.org/copyright.html - + diff --git a/make/jdk/src/classes/build/tools/cldrconverter/OtherCommonLocales.properties b/make/jdk/src/classes/build/tools/cldrconverter/OtherCommonLocales.properties index b7bb73388a4..354bcd13c15 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/OtherCommonLocales.properties +++ b/make/jdk/src/classes/build/tools/cldrconverter/OtherCommonLocales.properties @@ -135,6 +135,3 @@ xog=Soga yav=Yangben yi=Yiddish zgh=Standard Moroccan Tamazight - -# Not listed, but existed -sr-Latn=Serbian (Latin) diff --git a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java index 11547ccb38e..a2b5bd39ae2 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -70,6 +70,9 @@ class SupplementDataParseHandler extends AbstractLDMLHandler { // Map<"preferred"/"allowed", Map<"skeleton", SortedSet<"regions">>> private final Map>> inputSkeletonMap; + // "component" specific to this parent locale chain + private String currentParentLocaleComponent; + SupplementDataParseHandler() { firstDayMap = new HashMap<>(); minDaysMap = new HashMap<>(); @@ -163,11 +166,19 @@ class SupplementDataParseHandler extends AbstractLDMLHandler { minDaysMap.put(attributes.getValue("territories"), attributes.getValue("count")); } break; + case "parentLocales": + currentParentLocaleComponent = attributes.getValue("component"); + pushContainer(qName, attributes); + break; case "parentLocale": if (!isIgnored(attributes)) { - parentLocalesMap.put( - attributes.getValue("parent").replaceAll("_", "-"), - attributes.getValue("locales").replaceAll("_", "-")); + // Ignore component for now, otherwise "zh-Hant" falling back to "zh" would happen + // https://github.com/unicode-org/cldr/pull/2664 + if (currentParentLocaleComponent == null) { + parentLocalesMap.put( + attributes.getValue("parent").replaceAll("_", "-"), + attributes.getValue("locales").replaceAll("_", "-")); + } } break; case "hours": diff --git a/src/java.base/share/legal/cldr.md b/src/java.base/share/legal/cldr.md index 55ce9e1b93c..1660bd5d0cd 100644 --- a/src/java.base/share/legal/cldr.md +++ b/src/java.base/share/legal/cldr.md @@ -1,4 +1,4 @@ -## Unicode Common Local Data Repository (CLDR) v42 +## Unicode Common Local Data Repository (CLDR) v43 ### CLDR License diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java index 8bf189e8375..f1da3cb3806 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java @@ -135,7 +135,8 @@ public final class IncludeLocalesPlugin extends AbstractPlugin implements Resour .forEach(children::add); return new AbstractMap.SimpleEntry>(parent, children); }) - ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, + (l1, l2) -> Stream.concat(l1.stream(), l2.stream()).distinct().toList())); // Special COMPAT provider locales private static final String jaJPJPTag = "ja-JP-JP"; diff --git a/src/jdk.localedata/share/legal/cldr.md b/src/jdk.localedata/share/legal/cldr.md index 55ce9e1b93c..1660bd5d0cd 100644 --- a/src/jdk.localedata/share/legal/cldr.md +++ b/src/jdk.localedata/share/legal/cldr.md @@ -1,4 +1,4 @@ -## Unicode Common Local Data Repository (CLDR) v42 +## Unicode Common Local Data Repository (CLDR) v43 ### CLDR License diff --git a/test/jdk/java/time/test/java/time/format/TestUnicodeExtension.java b/test/jdk/java/time/test/java/time/format/TestUnicodeExtension.java index feba348b6cd..9a4cebbdc48 100644 --- a/test/jdk/java/time/test/java/time/format/TestUnicodeExtension.java +++ b/test/jdk/java/time/test/java/time/format/TestUnicodeExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8176841 8202537 8244245 8265315 8284840 + * @bug 8176841 8202537 8244245 8265315 8284840 8296248 * @summary Tests java.time classes deals with Unicode extensions * correctly. * @modules jdk.localedata @@ -610,6 +610,7 @@ public class TestUnicodeExtension { {"mwblz", "Africa/Blantyre"}, {"mxchi", "America/Chihuahua"}, {"mxcun", "America/Cancun"}, + {"mxcjs", "America/Ciudad_Juarez"}, {"mxhmo", "America/Hermosillo"}, {"mxmam", "America/Matamoros"}, {"mxmex", "America/Mexico_City"}, diff --git a/test/jdk/sun/text/resources/LocaleData.cldr b/test/jdk/sun/text/resources/LocaleData.cldr index 754c2251767..21f1d016cfc 100644 --- a/test/jdk/sun/text/resources/LocaleData.cldr +++ b/test/jdk/sun/text/resources/LocaleData.cldr @@ -3154,7 +3154,7 @@ LocaleNames/ms/ST=Sao Tome dan Principe LocaleNames/ms/TC=Kepulauan Turks dan Caicos LocaleNames/ms/TD=Chad LocaleNames/ms/TJ=Tajikistan -LocaleNames/ms/TR=Turki +LocaleNames/ms/TR=Turkiye LocaleNames/ms/TT=Trinidad dan Tobago LocaleNames/ms/US=Amerika Syarikat LocaleNames/ms/VC=Saint Vincent dan Grenadines @@ -6151,7 +6151,7 @@ CurrencyNames/fr/khr=riel cambodgien CurrencyNames/fr/kmf=franc comorien CurrencyNames/fr/kwd=dinar kowe\u00eftien CurrencyNames/fr/kzt=tenge kazakh -CurrencyNames/fr/lak=kip loatien +CurrencyNames/fr/lak=kip laotien CurrencyNames/fr/lkr=roupie srilankaise CurrencyNames/fr/lsl=loti lesothan CurrencyNames/fr/mga=ariary malgache diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index 46bba2400a0..ce758915f41 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -42,6 +42,7 @@ import tests.Result; * @test * @bug 8152143 8152704 8155649 8165804 8185841 8176841 8190918 * 8179071 8202537 8221432 8222098 8251317 8258794 8265315 + * 8296248 * @summary IncludeLocalesPlugin tests * @author Naoto Sato * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) @@ -146,7 +147,7 @@ public class IncludeLocalesPluginTest { "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class", "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"), List.of( - "(root)", "en", "en_US", "en_US_#Latn", "en_US_POSIX", "en_001", "en_150", "en_AG", "en_AI", + "(root)", "en", "en_001", "en_150", "en_AG", "en_AI", "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE", "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM", @@ -157,7 +158,7 @@ public class IncludeLocalesPluginTest { "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PK", "en_PN", "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH", "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO", - "en_TT", "en_TV", "en_TZ", "en_UG", "en_VC", "en_VG", "en_VU", "en_WS", + "en_TT", "en_TV", "en_TZ", "en_UG", "en_US", "en_US_#Latn", "en_US_POSIX", "en_VC", "en_VG", "en_VU", "en_WS", "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR", "es_BZ", "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN", "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", From 497f9e760da6342c611a2f542090c5cf4428b9fd Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 17 Apr 2023 16:45:56 +0000 Subject: [PATCH 010/288] 8305755: [JVMCI] missing barriers in CompilerToVM.readFieldValue for Reference.referent Reviewed-by: eosterlund, dnsimon --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 16 +++++++++------- src/hotspot/share/jvmci/jvmciRuntime.cpp | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 5811cc3f778..74672c4ee30 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2050,14 +2050,14 @@ static jobject read_field_value(Handle obj, long displacement, jchar type_char, // folding Unsafe.get* methods with volatile semantics. switch (basic_type) { - case T_BOOLEAN: value = obj->bool_field_acquire(displacement); break; - case T_BYTE: value = obj->byte_field_acquire(displacement); break; - case T_SHORT: value = obj->short_field_acquire(displacement); break; - case T_CHAR: value = obj->char_field_acquire(displacement); break; + case T_BOOLEAN: value = HeapAccess::load(obj->field_addr(displacement)); break; + case T_BYTE: value = HeapAccess::load(obj->field_addr(displacement)); break; + case T_SHORT: value = HeapAccess::load(obj->field_addr(displacement)); break; + case T_CHAR: value = HeapAccess::load(obj->field_addr(displacement)); break; case T_FLOAT: - case T_INT: value = obj->int_field_acquire(displacement); break; + case T_INT: value = HeapAccess::load(obj->field_addr(displacement)); break; case T_DOUBLE: - case T_LONG: value = obj->long_field_acquire(displacement); break; + case T_LONG: value = HeapAccess::load(obj->field_addr(displacement)); break; case T_OBJECT: { if (displacement == java_lang_Class::component_mirror_offset() && java_lang_Class::is_instance(obj()) && @@ -2067,7 +2067,9 @@ static jobject read_field_value(Handle obj, long displacement, jchar type_char, return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER()); } - oop value = obj->obj_field_acquire(displacement); + // Perform the read including any barriers required to make the reference strongly reachable + // since it will be wrapped as a JavaConstant. + oop value = obj->obj_field_access(displacement); if (value == nullptr) { return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER()); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index f93fdddf806..eb1fe403575 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -939,7 +939,9 @@ int JVMCIRuntime::release_cleared_oop_handles() { // Example: to_release: 2 // Bulk release the handles with a null referent - object_handles()->release(_oop_handles.adr_at(num_alive), to_release); + if (to_release != 0) { + object_handles()->release(_oop_handles.adr_at(num_alive), to_release); + } // Truncate oop handles to only those with a non-null referent JVMCI_event_1("compacted oop handles in JVMCI runtime %d from %d to %d", _id, _oop_handles.length(), num_alive); From 6831f9db8b978a441ef38d3602779c3a5f521413 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 17 Apr 2023 18:03:29 +0000 Subject: [PATCH 011/288] 8278583: Open source SwingMark - Swing performance benchmark Reviewed-by: serb, aghaisas, avu --- .../jdk/performance/client/SwingMark/Makefile | 106 +++++ test/jdk/performance/client/SwingMark/README | 112 +++++ .../SwingMark/src/AbstractSwingTest.java | 226 ++++++++++ .../SwingMark/src/AdvancedTextAreaTest.java | 244 +++++++++++ .../SwingMark/src/InternalFrameTest.java | 331 +++++++++++++++ .../client/SwingMark/src/JMTest_01.java | 195 +++++++++ .../client/SwingMark/src/JMTest_02.java | 185 +++++++++ .../client/SwingMark/src/JMTest_03.java | 172 ++++++++ .../client/SwingMark/src/JMTest_04.java | 226 ++++++++++ .../client/SwingMark/src/JMTest_05.java | 203 +++++++++ .../client/SwingMark/src/LabelTest.java | 126 ++++++ .../client/SwingMark/src/ListTest.java | 125 ++++++ .../client/SwingMark/src/MenuTest.java | 169 ++++++++ .../client/SwingMark/src/NullRunnable.java | 42 ++ .../client/SwingMark/src/SliderTest.java | 111 +++++ .../client/SwingMark/src/SwingMark.java | 311 ++++++++++++++ .../client/SwingMark/src/SwingMarkPanel.java | 168 ++++++++ .../SwingMark/src/TableColMoveTest.java | 103 +++++ .../client/SwingMark/src/TableColTest.java | 210 ++++++++++ .../client/SwingMark/src/TableRowTest.java | 234 +++++++++++ .../client/SwingMark/src/TableScrollTest.java | 149 +++++++ .../client/SwingMark/src/TextAreaTest.java | 131 ++++++ .../client/SwingMark/src/TextPaneTest.java | 114 +++++ .../client/SwingMark/src/TreeTest.java | 388 ++++++++++++++++++ .../client/SwingMark/src/TypingTest.java | 85 ++++ .../src/resources/JMTest_04.properties | 34 ++ .../src/resources/JMTest_04_ja.properties | 34 ++ .../src/resources/ListTest.properties | 32 ++ .../src/resources/ListTest_ja.properties | 32 ++ .../SwingMark/src/resources/TableRowTest.java | 94 +++++ .../src/resources/TableRowTest_ja.java | 90 ++++ .../SwingMark/src/resources/TestList.txt | 6 + .../src/resources/TextAreaTest.properties | 32 ++ .../src/resources/TextAreaTest_ja.properties | 32 ++ 34 files changed, 4852 insertions(+) create mode 100644 test/jdk/performance/client/SwingMark/Makefile create mode 100644 test/jdk/performance/client/SwingMark/README create mode 100644 test/jdk/performance/client/SwingMark/src/AbstractSwingTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/AdvancedTextAreaTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/InternalFrameTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/JMTest_01.java create mode 100644 test/jdk/performance/client/SwingMark/src/JMTest_02.java create mode 100644 test/jdk/performance/client/SwingMark/src/JMTest_03.java create mode 100644 test/jdk/performance/client/SwingMark/src/JMTest_04.java create mode 100644 test/jdk/performance/client/SwingMark/src/JMTest_05.java create mode 100644 test/jdk/performance/client/SwingMark/src/LabelTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/ListTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/MenuTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/NullRunnable.java create mode 100644 test/jdk/performance/client/SwingMark/src/SliderTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/SwingMark.java create mode 100644 test/jdk/performance/client/SwingMark/src/SwingMarkPanel.java create mode 100644 test/jdk/performance/client/SwingMark/src/TableColMoveTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TableColTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TableRowTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TableScrollTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TextAreaTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TextPaneTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TreeTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/TypingTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/resources/JMTest_04.properties create mode 100644 test/jdk/performance/client/SwingMark/src/resources/JMTest_04_ja.properties create mode 100644 test/jdk/performance/client/SwingMark/src/resources/ListTest.properties create mode 100644 test/jdk/performance/client/SwingMark/src/resources/ListTest_ja.properties create mode 100644 test/jdk/performance/client/SwingMark/src/resources/TableRowTest.java create mode 100644 test/jdk/performance/client/SwingMark/src/resources/TableRowTest_ja.java create mode 100644 test/jdk/performance/client/SwingMark/src/resources/TestList.txt create mode 100644 test/jdk/performance/client/SwingMark/src/resources/TextAreaTest.properties create mode 100644 test/jdk/performance/client/SwingMark/src/resources/TextAreaTest_ja.properties diff --git a/test/jdk/performance/client/SwingMark/Makefile b/test/jdk/performance/client/SwingMark/Makefile new file mode 100644 index 00000000000..ea4ae1ce256 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/Makefile @@ -0,0 +1,106 @@ +# +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +SOURCEPATH=src +CLASSES=build +DIST=dist +RESOURCES=resources + +SWINGMARK_CLASSES = \ + $(CLASSES)/AbstractSwingTest.class \ + $(CLASSES)/AdvancedTextAreaTest.class \ + $(CLASSES)/InternalFrameTest.class \ + $(CLASSES)/JMTest_01.class \ + $(CLASSES)/JMTest_02.class \ + $(CLASSES)/JMTest_03.class \ + $(CLASSES)/JMTest_04.class \ + $(CLASSES)/JMTest_05.class \ + $(CLASSES)/LabelTest.class \ + $(CLASSES)/ListTest.class \ + $(CLASSES)/MenuTest.class \ + $(CLASSES)/NullRunnable.class \ + $(CLASSES)/SliderTest.class \ + $(CLASSES)/SwingMark.class \ + $(CLASSES)/SwingMarkPanel.class \ + $(CLASSES)/TableColMoveTest.class \ + $(CLASSES)/TableColTest.class \ + $(CLASSES)/TableRowTest.class \ + $(CLASSES)/TableScrollTest.class \ + $(CLASSES)/TextAreaTest.class \ + $(CLASSES)/TextPaneTest.class \ + $(CLASSES)/TreeTest.class \ + $(CLASSES)/TypingTest.class \ + $(CLASSES)/resources/TableRowTest.class \ + $(CLASSES)/resources/TableRowTest_ja.class + +SWINGMARK_RESOURCES = \ + $(CLASSES)/resources/TestList.txt \ + $(CLASSES)/resources/JMTest_04.properties \ + $(CLASSES)/resources/JMTest_04_ja.properties \ + $(CLASSES)/resources/ListTest.properties \ + $(CLASSES)/resources/ListTest_ja.properties \ + $(CLASSES)/resources/TextAreaTest.properties \ + $(CLASSES)/resources/TextAreaTest_ja.properties + +all: mkdirs SwingMark.jar + +run: mkdirs SwingMark.jar + cd $(DIST) && java -jar SwingMark.jar -q + +SwingMark.jar: \ + $(SWINGMARK_CLASSES) \ + $(SWINGMARK_RESOURCES) \ + $(CLASSES)/swingmark.manifest + jar cvmf $(CLASSES)/swingmark.manifest $(DIST)/SwingMark.jar -C $(CLASSES) . + +$(CLASSES)/swingmark.manifest: + echo "Main-Class: SwingMark" > $@ + +$(DIST): + mkdir $(DIST) + +$(CLASSES): + mkdir $(CLASSES) + +mkdirs: $(DIST) $(CLASSES) + +$(CLASSES)/%.class: $(SOURCEPATH)/%.java + javac -d $(CLASSES) -sourcepath $(SOURCEPATH) $< + +$(CLASSES)/resources/%.properties: $(SOURCEPATH)/resources/%.properties + cp -r $< $@ + +$(CLASSES)/resources/TestList.txt: $(SOURCEPATH)/resources/TestList.txt + cp -r $< $@ + +clean: + rm -rf $(CLASSES) + rm -rf $(DIST) diff --git a/test/jdk/performance/client/SwingMark/README b/test/jdk/performance/client/SwingMark/README new file mode 100644 index 00000000000..3862cd3169c --- /dev/null +++ b/test/jdk/performance/client/SwingMark/README @@ -0,0 +1,112 @@ +A Basic Performance Benchmark for Swing components. +================================================== + +Introduction +------------ +SwingMark is a small suite of automated benchmark tests created to test +the speed of the Swing components. It is designed to be extensible so that +it is easy to add new tests. Each test can be run inside the SwingMarkPanel +test harness, or as a stand alone application. + +Getting Started +--------------- + +To build and run, add make, java and javac to your PATH and just type +% make run + +This will build if needed, then execute + +% java -jar dist/SwingMark.jar -q + +Results will be output to the console. +The "-q" causes SwingMark to exit when it is finished. + +If you run directly as below without -q you can click on the close item of the SwingMark window. + +% java -jar dist/SwingMark.jar + +In addition the tests can be run individually. +For example, you could type the following: + +% java -cp SwingMark.jar SliderTest + +This will run the SliderTest as a stand alone application. + +Command Line Options +==================== + +There are several command line options you can use to control the harness. +These include: + +* Repeat (-r) +------------- +The repeat option can be used to run the test suite multiple times inside the +same VM invocation. For example: + +% java -jar SwingMark.jar -r 5 + +will run the suite 5 times in succession. + +* LookAndFeel (-lf) +----------------- + +You can use the -lf option to choose the Swing L&F with which to run the test. +For example: + +% java SwingMark -lf com.sun.java.swing.plaf.motif.MotifLookAndFeel + +will run the suite using the Motif L&F. + +Quit (-q) +------------ + +The -q option will cause the suite to automatically exit when the run is completed. + +Version (-version) +------------------ + +The -version option will cause a string to be printed to the console +which indicates the version of the suite you are running. + +Generate Report File (-f) +------------------------- + +The -f option will cause a text file to be generate containing information +about the time it took to execute each test. +This is a simple XML file which contains run times for each test. +For example: +% java -jar SwingMark.jar -f TestTimes.txt + +Generate Memory Report (-m) +-------------------------- + +The -m option will cause a text file to be generate containing information +the amount of memory used during the test. +For example: +% java -jar SwingMark.jar -m MemoryData.txt + +Note that all these options can be combined in any order desired. +For example: +% java SwingMark -q -r 4 -lf com.me.MyLookAndFeel -f Test.txt + +Test Selection +============== + +A file called TestList.txt in the CWD can be used to over-ride which sets of tests are run. +A default file is built-in to SwingMark as a resource. + +The default file content looks like this :- +JMTest_04 +TextAreaTest +SliderTest +ListTest +TableRowTest +TreeTest + +Creating New Tests +================== + +To create a new test, you'll need to extend AbstractSwingTest. +See the JavaDoc for details on what each method does. +Then add the name of your class to the "TestList.txt" file. +This makes it easy to run arbitrary combinations of tests. diff --git a/test/jdk/performance/client/SwingMark/src/AbstractSwingTest.java b/test/jdk/performance/client/SwingMark/src/AbstractSwingTest.java new file mode 100644 index 00000000000..52394054f29 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/AbstractSwingTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.ActiveEvent; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.PaintEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * Derive from this abstract base class when ever + * you want to create a new benchmark test which + * will be run in the SwingMark harness + *. + * The SwingMarkPanel class requires that tests subclass AbstractSwingTest. + * + * @see SwingMarkPanel + * + */ + +public abstract class AbstractSwingTest { + + public int paintCount = 0; + + /** + * Override this when subclassing AbstractSwingTest. + * + * @return A very short description of the test + */ + public abstract String getTestName(); + + /** + * Override this when subclassing AbstractSwingTest. + * Here you create and initialize the component, or + * group of components, which will be exercised by + * your test. + * + * Typically you will create a JPanel and insert + * components into the panel. + * + * @return The JComponent which will be made visible for your test + */ + public abstract JComponent getTestComponent(); + + /** + * Override this when subclassing AbstractSwingTest. + * Here you create the code to automate your test, + * This code can be written in many ways. For example, you + * could directly modify the component, or its' model. + * You could also post events to the EventQueue. + * It's up to you + */ + public abstract void runTest(); + + /** + * This method is used to determine if a test can be run from within + * an applet. If your test will cause security exceptions when run as + * an applet then you should return false from this method. + */ + public boolean canRunInApplet() { + return true; + } + + public int getPaintCount() { + return paintCount; + } + /** + * This static method is used to run your test as a stand-alone + * application. Just pass an instance of your test to this function. + * This is especially useful when you're developing your test, or + * when you want to concentrate on a single area. + * + * To allow your test to be run stand-alone, you need to add a main() that + * looks like this + * + * public static void main(String[] args) { + * runStandAloneTest( new MyTestName() ); + * } + */ + @SuppressWarnings("deprecation") + public static void runStandAloneTest(AbstractSwingTest test) { + long startTime = System.currentTimeMillis(); + JFrame f = new JFrame(); + f.addWindowListener( new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + System.exit(0);}} ); + f.getContentPane().add( test.getTestComponent() ); + f.pack(); + f.show(); + rest(); + syncRam(); + long endStartup = System.currentTimeMillis(); + test.runTest(); + rest(); + long endTests = System.currentTimeMillis(); + System.out.println("Startup Time: " + (endStartup - startTime)); + System.out.println("Test Time: " + (endTests - endStartup)); + + if (test.getPaintCount() > 0) { + System.out.println("Called Paint: " + test.getPaintCount() + " times"); + } else { + System.out.println("Painting calls not counted."); + } + + } + + @SuppressWarnings("removal") + public static void syncRam() { + System.gc(); + System.runFinalization(); + System.gc(); + try { + Thread.sleep(100); + } catch (Exception e) { + System.out.println( "failed sleeping " + e); + } + } + + private static Component BOGUS_COMPONENT = new JPanel(); + private static EventQueue Q = Toolkit.getDefaultToolkit().getSystemEventQueue(); + + // Invoked during tests to wait until the current event has finished + // processing. At the time of this writing AWT's EventQueue has 3 + // queues: LOW, NORMAL and HIGH. Swing's repaint events end up on + // the NORMAL queue, AWT's paint events end up on the LOW queue. Runnable + // events end up on the NORMAL queue. The code to rest blocks until ALL + // queues are empty. This is accomplished by adding an event + // (NotifyingPaintEvent) to the EventQueue. When the event is dispatched + // the EventQueue is checked, if the EQ is empty rest exits, otherwise + // rest loops through adding another event to the EQ. + + public static void rest() { + Thread.yield(); + boolean qEmpty = false; + while (!qEmpty) { + NotifyingPaintEvent e = new NotifyingPaintEvent(BOGUS_COMPONENT); + Q.postEvent(e); + synchronized(e) { + // Wait until the event has been dispatched + while (!e.isDispatched()) { + try { + e.wait(); + } catch (InterruptedException ie) { + System.out.println("IE: " + ie); + } + } + // Check if the q is empty + qEmpty = e.qEmpty(); + } + } + Toolkit.getDefaultToolkit().sync(); + } + + + private static class NotifyingPaintEvent extends PaintEvent + implements ActiveEvent { + private static int nextLocation; + + boolean dispatched = false; + boolean qEmpty; + private int location; + + NotifyingPaintEvent(Component x) { + super(x, PaintEvent.UPDATE, null); + synchronized(NotifyingPaintEvent.class) { + location = nextLocation++; + } + } + + // 1.3 uses this for coalescing. To avoid having these events + // coalesce return a new location for each event. + public Rectangle getUpdateRect() { + return new Rectangle(location, location, 1, 1); + } + + public synchronized boolean isDispatched() { + return dispatched; + } + + public synchronized boolean qEmpty() { + return qEmpty; + } + + public void dispatch() { + qEmpty = (Q.peekEvent() == null); + synchronized(this) { + dispatched = true; + notifyAll(); + } + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/AdvancedTextAreaTest.java b/test/jdk/performance/client/SwingMark/src/AdvancedTextAreaTest.java new file mode 100644 index 00000000000..898bc586de8 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/AdvancedTextAreaTest.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Random; +import java.awt.Color; +import java.awt.Font; +import java.awt.Toolkit; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTextArea + * It creates a JTextArea and then perform the following + * behavios : + * (1) Append text + * (2) Change Font with random size and type + * (3) Cut with random selection + * (4) Copy with random selection + * (5) Paste with random selection + * + */ + +public class AdvancedTextAreaTest extends AbstractSwingTest { + + JTextArea textArea1; + final int repeat = 100; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + textArea1 = new JTextArea(10, 30); + textArea1.setLineWrap(true); + JScrollPane scroller = new JScrollPane(textArea1); + panel.add(scroller); + return panel; + } + + public String getTestName() { + return "Adv TextArea"; + } + + public void runTest() { + testTextArea(textArea1, "Swing is Fast! "); + } + + public void testTextArea(JTextArea currentTextArea, String appendThis) { + TextAppender appender = new TextAppender(currentTextArea, appendThis); + TextSelector selector = new TextSelector(currentTextArea); + TextCutter cutter = new TextCutter (currentTextArea); + TextPaster paster = new TextPaster (currentTextArea); + CaretSetter caretSetter = new CaretSetter(currentTextArea); + TextCopier copier = new TextCopier(currentTextArea); + TextFontSetter fonter = new TextFontSetter(currentTextArea); + + for (int i = 0; i < repeat; i++) { + try { + SwingUtilities.invokeLater(appender); + currentTextArea.repaint(); + rest(); + } catch (Exception e) {System.out.println(e);} + } + + + for (int i = 0; i < repeat; i++) { + try { + // Change font + SwingUtilities.invokeAndWait(fonter); + + // Cut + selector.setSelection(); + SwingUtilities.invokeAndWait(selector); + SwingUtilities.invokeAndWait(cutter); + + // Copy + caretSetter.setCaretPosition(); + SwingUtilities.invokeAndWait(caretSetter); + SwingUtilities.invokeAndWait(copier); + + // Paste + caretSetter.setCaretPosition(); + SwingUtilities.invokeAndWait(caretSetter); + SwingUtilities.invokeAndWait(paster); + + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new AdvancedTextAreaTest()); + } + + static class TextAppender implements Runnable { + JTextArea area; + String appendString; + + + public TextAppender(JTextArea textArea, String appendThis) { + area = textArea; + appendString = appendThis; + } + + public void run() { + area.append(appendString); + } + } + + static class TextCutter implements Runnable { + JTextArea area; + + public TextCutter(JTextArea textArea) { + area = textArea; + } + + public void run() { + area.cut(); + } + } + + static class TextCopier implements Runnable { + JTextArea area; + + public TextCopier(JTextArea textArea) { + area = textArea; + } + + public void run() { + area.copy(); + } + } + + static class TextFontSetter implements Runnable { + JTextArea area; + String[] fonts; + Random random; + int index = 0; + + @SuppressWarnings("deprecation") + public TextFontSetter(JTextArea textArea) { + area = textArea; + random = new Random(); + fonts = Toolkit.getDefaultToolkit().getFontList(); + } + + public void run() { + area.setFont(new Font( fonts[index], + Math.abs(random.nextInt()) % 3, + Math.abs(random.nextInt()) % 20)); + area.repaint(); + index ++ ; + index = index % fonts.length ; + } + } + + static class TextPaster implements Runnable { + JTextArea area; + + public TextPaster(JTextArea textArea) { + area = textArea; + } + + public void run() { + area.paste(); + } + } + + static class TextSelector implements Runnable { + JTextArea area; + int start; + int end; + Random random; + + public TextSelector(JTextArea textArea) { + area = textArea; + random = new Random(); + } + + public void setSelection() { + int length = area.getText().length(); + start = Math.abs( random.nextInt()) % length; + end = start + 50; + + if ( end >= length ) { + end = length - 1 ; + } + } + + public void run() { + area.setSelectionStart(start); + area.setSelectionEnd(end); + area.setSelectionColor(new Color(Math.abs(random.nextInt()) % 256, + Math.abs(random.nextInt()) % 256, + Math.abs(random.nextInt()) % 256)); + } + } + + static class CaretSetter implements Runnable { + JTextArea area; + int position; + Random random; + + public CaretSetter(JTextArea textArea) { + area = textArea; + random = new Random(); + } + + public void setCaretPosition() { + position =Math.abs( random.nextInt()) % area.getText().length(); + } + + public void run() { + area.setCaretPosition(position); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/InternalFrameTest.java b/test/jdk/performance/client/SwingMark/src/InternalFrameTest.java new file mode 100644 index 00000000000..b3cb2dd1bf8 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/InternalFrameTest.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Rectangle; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JLayeredPane; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/** + * A SwingMark to test two different aspects of InternalFrames. + * -repaint Brings each internal frame to the front of the + * other internal frames and message each widget to repaint. + * -move Moves each of the internal frames around the desktop. + * + * If you you do not specify one the default is to do both. + * The following options are also available: + * -numLevels Number of levels to create, default is 1. + * -numInternalFrames Number of internal frames to create per level, + default is 10. + * -numButtons Number of widgets to create, default is 10. + * -laf Look and feel to use, default is metal. + * + */ + +public class InternalFrameTest extends AbstractSwingTest { + + JDesktopPane desktop; + JFrame frame; + int numInternalFrames; + int numButtons; + int numLevels; + JInternalFrame[][] frames; + int whatTest; + + JComponent widget; + + public InternalFrameTest(int numLevels, int numInternalFrames, + int numButtons, int whatTest) { + this.numLevels = numLevels; + this.numInternalFrames = numInternalFrames; + this.numButtons = numButtons; + this.whatTest = whatTest; + frames = new JInternalFrame[numLevels][]; + createDesktopPane(); + createInternalFrames(); + } + + public InternalFrameTest() { + this( 1, 10, 10, 3); + } + + public String getTestName() { + return "InternalFrame"; + } + + public JComponent getTestComponent() { + return desktop; + } + + public void runTest() { + if ((whatTest & 1) != 0) { + testMove(); + } + if ((whatTest & 2) != 0) { + testRepaint(); + } + } + + protected void createDesktopPane() { + desktop = new JDesktopPane(); + desktop.setPreferredSize(new Dimension(425, 425)); + desktop.setMinimumSize(new Dimension(425, 425)); + } + + protected void createInternalFrames() { + Container parent = desktop; + + for (int counter = 0; counter < numLevels; counter++) { + Integer level = Integer.valueOf(JLayeredPane.DEFAULT_LAYER. + intValue() + counter); + + frames[counter] = new JInternalFrame[numInternalFrames]; + for (int iCounter = 0; iCounter < numInternalFrames; iCounter++) { + JInternalFrame internalFrame; + + internalFrame = createInternalFrame(level, iCounter); + parent.add(internalFrame); + frames[counter][iCounter] = internalFrame; + } + } + } + + protected JInternalFrame createInternalFrame(Integer id, int number) { + JInternalFrame jif; + + jif = new JInternalFrame("Internal Frame " + id + " " + number, + true, true, true, true); + createWidgets(jif); + + jif.setBounds((number * 50) % 220, (number * 50) % 220, + 100 + (number * 50) % 125, + 100 + (number * 25) % 125); + + return jif; + } + + protected void createWidgets(JInternalFrame jif) { + Container parent = jif.getContentPane(); + JComponent child = null; + + parent.setLayout(new FlowLayout()); + for (int counter = 0; counter < numButtons; counter++) { + switch (counter % 4) { + case 0: + child = new JButton("Button " + counter); + break; + case 1: + child = new JCheckBox("CheckBox " + counter); + break; + case 2: + child = new JTextField("TF " + counter); + break; + case 3: + child = new JLabel("Label " + counter); + break; + } + parent.add(child); + } + if (widget == null) { + widget = child; + } + } + + protected void slide(MoveRunnable mv, JInternalFrame frame, + int x, int y, int newX, int newY) { + int xInc = (newX - x) / 10; + int yInc = (newY - y) / 10; + + mv.jif = frame; + mv.moveToFront = true; + if (xInc != 0 || yInc != 0) { + mv.jif = frame; + for (int counter = 0; counter < 10; counter++) { + x += xInc; + y += yInc; + mv.newX = x; + mv.newY = y; + try { + SwingUtilities.invokeLater(mv); + rest(); + } + catch (Exception ex) { + System.out.println("--> " + ex); + } + } + } + } + + protected void testMove() { + Rectangle tempRect = new Rectangle(); + int width = desktop.getWidth(); + int height = desktop.getHeight(); + int tempWidth; + int tempHeight; + MoveRunnable mv = new MoveRunnable(); + + + for (int counter = frames.length - 1; counter >= 0; counter--) { + for (int iCounter = frames[counter].length - 1; iCounter >= 0; + iCounter--) { + JInternalFrame iFrame = frames[counter][iCounter]; + + iFrame.getBounds(tempRect); + tempWidth = width - tempRect.width; + tempHeight = height - tempRect.height; + // Slide to origin + slide(mv, iFrame, tempRect.x, tempRect.y, 0, 0); + // Slide to the right + slide(mv, iFrame, 0, 0, tempWidth, 0); + // Slide down + slide(mv, iFrame, tempWidth, 0, tempWidth, tempHeight); + // Slide to the left + slide(mv, iFrame, tempWidth, tempHeight, 0, tempHeight); + // Slide to original spot. + slide(mv, iFrame, 0, tempHeight, tempRect.x, tempRect.y); + } + } + } + + public void testRepaint() { + MoveRunnable mr = new MoveRunnable(); + Rectangle tempRect = new Rectangle(); + + for (int counter = frames.length - 1; counter >= 0; counter--) { + for (int iCounter = frames[counter].length - 1; iCounter >= 0; + iCounter--) { + JInternalFrame iFrame = frames[counter][iCounter]; + Container c = iFrame.getContentPane(); + + iFrame.getBounds(tempRect); + + mr.moveToFront = true; + mr.newX = tempRect.x; + mr.newY = tempRect.y; + mr.jif = iFrame; + try { + SwingUtilities.invokeLater(mr); + rest(); + } + catch (Exception ex) { + System.out.println("--> " + ex); + } + + iFrame.repaint(); + rest(); + for (int cCounter = c.getComponentCount() - 1; + cCounter >= 0; cCounter--) { + JComponent comp = (JComponent)c.getComponent(cCounter); + + comp.getBounds(tempRect); + comp.repaint(); + rest(); + } + } + } + } + + public static void main(String args[]) { + int whatTest = 0; + int numInternalFrames = 10; + int numButtons = 10; + int numLevels = 1; + + for (int counter = args.length - 1; counter >= 0; counter--) { + if (args[counter].equals("-repaint")) { + whatTest |= 2; + } + else if (args[counter].equals("-move")) { + whatTest |= 1; + } + else if (args[counter].equals("-numButtons")) { + try { + numButtons = Integer.parseInt(args[counter + 1]); + } + catch (NumberFormatException nfe) {} + } + else if (args[counter].equals("-numInternalFrames")) { + try { + numInternalFrames =Integer.parseInt(args[counter + 1]); + } + catch (NumberFormatException nfe) {} + } + else if (args[counter].equals("-numLevels")) { + try { + numLevels = Integer.parseInt(args[counter + 1]); + } + catch (NumberFormatException nfe) {} + } + else if (args[counter].equals("-laf")) { + try { + UIManager.setLookAndFeel(args[counter + 1]); + } + catch (Exception lafEX) { + System.out.println("Couldn't laf: " + lafEX); + } + } + } + if (whatTest == 0) { + whatTest = 3; + } + final InternalFrameTest test = + new InternalFrameTest(numLevels, numInternalFrames, numButtons, whatTest); + + runStandAloneTest(test); + System.exit(1); + } + + static class MoveRunnable implements Runnable { + int newX; + int newY; + JInternalFrame jif; + boolean moveToFront; + + public void run() { + if (moveToFront) { + moveToFront = false; + jif.moveToFront(); + } + jif.setLocation(newX, newY); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/JMTest_01.java b/test/jdk/performance/client/SwingMark/src/JMTest_01.java new file mode 100644 index 00000000000..83127e3bc21 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/JMTest_01.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected ActionEvent/MenuEvent is generated + * and that event causes the menu text to be appended to a JList + * + */ + +public class JMTest_01 extends AbstractSwingTest { + + JList list; + JMenuBar jmenubar = null; + + int nMenuCount = 2; + int nMenuItemCount = 4; + int ENTER = 10; + int LEFT = 37; + int RIGHT = 39; + int DOWN = 40; + int UP = 38; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + + JMenu jmenu; + JMenuItem jmenuitem; + + panel.setLayout(new BorderLayout()); + + jmenubar = new JMenuBar(); + for (int i = 0; i < nMenuCount; i ++) { + jmenu = new JMenu("JMenu" + i); + jmenu.setMnemonic('0' + i); + jmenu.addMenuListener(new MyMenuListener()); + jmenubar.add(jmenu); + + for (int j = 0; j < nMenuItemCount; j ++) { + jmenuitem = new JMenuItem("JMenuItem" + i + j); + jmenuitem.setMnemonic('0' + j); + jmenu.add(jmenuitem); + } + } + + panel.add("North", jmenubar); + + list = new JList(new DefaultListModel()); + list.setFont(new Font("Serif", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(list); + panel.add("Center", scrollPane); + + return panel; + } + + public String getTestName() { + return "JMTest_01"; + } + + public void runTest() { + for (int i = 0; i < 10; i++) { + testMenu(); + } + } + + @SuppressWarnings("deprecation") + public void testMenu() { + JMenu menu; + KeyEvent key; + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + int direction = RIGHT; + + int nCount = jmenubar.getMenuCount(); + + menu = jmenubar.getMenu(0); + int firstMnem = menu.getMnemonic(); + + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), KeyEvent.ALT_DOWN_MASK, firstMnem); + queue.postEvent(key); + + for (int i = 1; i < nCount; i ++) { + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + rest(); + + menu = jmenubar.getMenu(i); + + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + + direction = LEFT; + for (int i = 1; i < nCount; i ++) { + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + + menu = jmenubar.getMenu(i); + + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + } + + public static void main(String[] args) { + runStandAloneTest(new JMTest_01()); + } + + public class MyMenuListener implements MenuListener { + public void menuCanceled(MenuEvent e) { + } + + public void menuDeselected(MenuEvent e) { + } + + public void menuSelected(MenuEvent e) { + JMenu comp = (JMenu) e.getSource(); + Display(comp.getText()); + } + } + + public void Display(String str) { + DefaultListModel lm = (DefaultListModel) list.getModel(); + lm.addElement(str); + int nSize = lm.getSize(); + list.setSelectedIndex(nSize - 1); + list.requestFocus(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/JMTest_02.java b/test/jdk/performance/client/SwingMark/src/JMTest_02.java new file mode 100644 index 00000000000..b77844162ab --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/JMTest_02.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.DefaultListModel; +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected ActionEvent/MenuEvent is generated + * and that event causes the menu text to be appended to a JList + */ + +public class JMTest_02 extends AbstractSwingTest { + JList list; + JMenuBar jmenubar = null; + + int nMenuCount = 3; + int nMenuItemCount = 4; + int ENTER = 10; + int LEFT = 37; + int RIGHT = 39; + int DOWN = 40; + int UP = 38; + + int repeat = 15; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + + JMenu jmenu; + JMenuItem jmenuitem; + + panel.setLayout(new BorderLayout()); + + jmenubar = new JMenuBar(); + for (int i = 0; i < nMenuCount; i ++) { + jmenu = new JMenu("JMenu" + i); + jmenu.setMnemonic('0' + i); + jmenubar.add(jmenu); + + for (int j = 0; j < nMenuItemCount; j ++) { + jmenuitem = new JMenuItem("JMenuItem" + i + j); + jmenuitem.setMnemonic('0' + j); + jmenuitem.addActionListener(new MyActionListener()); + jmenu.add(jmenuitem); + } + } + + panel.add("North", jmenubar); + + list = new JList(new DefaultListModel()); + list.setFont(new Font("Serif", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(list); + panel.add("Center", scrollPane); + + return panel; + } + + public String getTestName() { + return "Menus"; + } + + public void runTest() { + for (int i = 0; i < repeat; i++) { + testMenu(); + } + } + + public void testMenu() { + int direction = DOWN; + FireEvents(direction); + } + + @SuppressWarnings("deprecation") + public void FireEvents(int direction) { + int nCount = jmenubar.getMenuCount(); + JMenuItem menuitem; + KeyEvent key; + int firstMnem; + JMenu menu; + + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + for (int i = 0; i < nCount; i++) { + menu = jmenubar.getMenu(i); + int nItemCount = menu.getItemCount(); + + for (int j = 0; j < nItemCount; j ++) { + firstMnem = menu.getMnemonic(); + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), KeyEvent.ALT_MASK, firstMnem); + queue.postEvent(key); + rest(); + + for (int k = 0; k < j; k++) { + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, new Date().getTime(), 0, ENTER); + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + } + } + + public static void main(String[] args) { + runStandAloneTest(new JMTest_02()); + } + + public class MyActionListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + AbstractButton comp = (AbstractButton) e.getSource(); + Display(comp.getText()); + } + } + + public void Display(String str) { + DefaultListModel lm = (DefaultListModel) list.getModel(); + lm.addElement(str); + int nSize = lm.getSize(); + list.setSelectedIndex(nSize - 1); + list.requestFocus(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/JMTest_03.java b/test/jdk/performance/client/SwingMark/src/JMTest_03.java new file mode 100644 index 00000000000..eed96da1e93 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/JMTest_03.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.AbstractButton; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected ActionEvent/MenuEvent is generated + * and that event causes the menu text to be appended to a JList + */ + +public class JMTest_03 extends AbstractSwingTest { + JList list; + JMenuBar jmenubar = null; + + int nMenuCount = 2; + int nMenuItemCount = 4; + int ENTER = 10; + int LEFT = 37; + int RIGHT = 39; + int DOWN = 40; + int UP = 38; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + + JMenu jmenu; + JMenuItem jmenuitem; + + panel.setLayout(new BorderLayout()); + + jmenubar = new JMenuBar(); + for (int i = 0; i < nMenuCount; i ++) { + jmenu = new JMenu("JMenu" + i); + jmenu.setMnemonic('0' + i); + jmenubar.add(jmenu); + + for (int j = 0; j < nMenuItemCount; j ++) { + jmenuitem = new JMenuItem("JMenuItem" + i + j); + jmenuitem.setMnemonic('0' + j); + jmenuitem.addActionListener(new MyActionListener()); + jmenu.add(jmenuitem); + } + } + + panel.add("North", jmenubar); + + list = new JList(new DefaultListModel()); + list.setFont(new Font("Serif", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(list); + panel.add("Center", scrollPane); + return panel; + } + + public String getTestName() { + return "JMTest_03"; + } + + public void runTest() { + for (int i = 0; i < 10; i++) { + testMenu(); + } + } + + public void testMenu() { + FireEvents(); + } + + @SuppressWarnings("deprecation") + public void FireEvents() { + int nCount = jmenubar.getMenuCount(); + JMenuItem menuitem; + KeyEvent key; + int firstMnem; + JMenu menu; + + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + for (int i = 0; i < nCount; i++) { + menu = jmenubar.getMenu(i); + int nItemCount = menu.getItemCount(); + + for (int j = 0; j < nItemCount; j ++) { + firstMnem = menu.getMnemonic(); + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), KeyEvent.ALT_DOWN_MASK, firstMnem); + queue.postEvent(key); + rest(); + + int mnem = menu.getItem(j).getMnemonic(); + + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, new Date().getTime(), 0, mnem); + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + } + } + + public static void main(String[] args) { + runStandAloneTest(new JMTest_03()); + } + + public class MyActionListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + AbstractButton comp = (AbstractButton) e.getSource(); + Display(comp.getText()); + } + } + + public void Display(String str) { + DefaultListModel lm = (DefaultListModel) list.getModel(); + lm.addElement(str); + int nSize = lm.getSize(); + list.setSelectedIndex(nSize - 1); + list.requestFocus(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/JMTest_04.java b/test/jdk/performance/client/SwingMark/src/JMTest_04.java new file mode 100644 index 00000000000..4c4c7f65d32 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/JMTest_04.java @@ -0,0 +1,226 @@ +import java.util.Date; +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.ResourceBundle; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.AbstractButton; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected ActionEvent/MenuEvent is generated + * and that event causes the menu text to be appended to a JList + */ + +public class JMTest_04 extends AbstractSwingTest { + JList list; + JMenuBar jmenubar = null; + + int nMenuCount = 2; + int nMenuItemCount = 4; + int ENTER = 10; + int LEFT = 37; + int RIGHT = 39; + int DOWN = 40; + int UP = 38; + + String MENU_STRING = "JMenu"; + String MENU_ITEM_STRING = "JMenuItem"; + String SUB_MENU_STRING = "SubMenu"; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + loadBundle(); + JPanel panel = new JPanel(); + + JMenu jmenu; + JMenuItem jmenuitem; + JMenu jsubmenu; + + panel.setLayout(new BorderLayout()); + + jmenubar = new JMenuBar(); + for (int i = 0; i < nMenuCount; i ++) { + jmenu = new JMenu(MENU_STRING + i); + jmenu.setMnemonic('0' + i); + jmenubar.add(jmenu); + + for (int j = 0; j < nMenuItemCount; j ++) { + int mn = 'A'; + mn = mn + j; + jsubmenu = new JMenu(SUB_MENU_STRING + String.valueOf((char) mn)); + jsubmenu.setMnemonic('A' + j); + jmenu.add(jsubmenu); + for (int k = 0; k <= j; k ++) { + jmenuitem = new JMenuItem(SUB_MENU_STRING+" - "+MENU_ITEM_STRING + i + (char) mn + k); + jmenuitem.setMnemonic('0' + k); + jmenuitem.addActionListener(new MyActionListener()); + jsubmenu.add(jmenuitem); + } + } + } + + + panel.add("North", jmenubar); + + list = new JList(new DefaultListModel()); + list.setFont(new Font("Serif", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(list); + panel.add("Center", scrollPane); + + return panel; + } + + private void loadBundle() { + ResourceBundle bundle = ResourceBundle.getBundle("resources.JMTest_04"); + MENU_STRING = bundle.getString("MenuString"); + MENU_ITEM_STRING = bundle.getString("MenuItemString"); + SUB_MENU_STRING = bundle.getString("SubMenuString"); + } + + public String getTestName() { + return "Sub-Menus"; + } + + public void runTest() { + for (int i = 0; i < 4; i++) { + testMenu(); + } + } + + public void testMenu() { + FireEvents(); + } + + + @SuppressWarnings("deprecation") + public void FireEvents() { + int nMenuCount = jmenubar.getMenuCount(); + + KeyEvent key; + int firstMnem; + int direction; + + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + jmenubar.requestFocus(); + for (int i = 0; i < nMenuCount; i ++) { + JMenu currentmenu = jmenubar.getMenu(i); + int currentmenuMnem = currentmenu.getMnemonic(); + + int nMenuItemCount = currentmenu.getItemCount(); + + for (int j = 0; j < nMenuItemCount; j ++) { + JMenuItem tempmenuitem = currentmenu.getItem(j); + if (tempmenuitem instanceof JMenu) { + JMenu targetmenu = (JMenu) tempmenuitem; + int iTargetMenuCount = targetmenu.getItemCount(); + + for (int k = 0; k < iTargetMenuCount; k ++) { + key = new KeyEvent(currentmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), KeyEvent.ALT_MASK, currentmenuMnem); + queue.postEvent(key); + + rest(); + + direction = DOWN; + for (int iTemp = 0; iTemp < j; iTemp ++) { + key = new KeyEvent(currentmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + rest(); + } + + + direction = RIGHT; + key = new KeyEvent(currentmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + rest(); + + direction = DOWN; + for (int iTemp = 0; iTemp < k; iTemp ++) { + key = new KeyEvent(targetmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, direction); + queue.postEvent(key); + rest(); + } + + key = new KeyEvent(targetmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, ENTER); + queue.postEvent(key); + rest(); + } + } + } + } + } + + + public static void main(String[] args) { + runStandAloneTest(new JMTest_04()); + } + + public class MyActionListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + AbstractButton comp = (AbstractButton) e.getSource(); + Display(comp.getText()); + } + } + + public void Display(String str) { + DefaultListModel lm = (DefaultListModel) list.getModel(); + lm.addElement(str); + int nSize = lm.getSize(); + list.setSelectedIndex(nSize - 1); + list.requestFocus(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/JMTest_05.java b/test/jdk/performance/client/SwingMark/src/JMTest_05.java new file mode 100644 index 00000000000..bd4eea45f9b --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/JMTest_05.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.AbstractButton; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected ActionEvent/MenuEvent is generated + * and that event causes the menu text to be appended to a JList + */ + +public class JMTest_05 extends AbstractSwingTest { + JList list; + JMenuBar jmenubar = null; + + int nMenuCount = 2; + int nMenuItemCount = 4; + int ENTER = 10; + int LEFT = 37; + int RIGHT = 39; + int DOWN = 40; + int UP = 38; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + + JMenu jmenu; + JMenuItem jmenuitem; + JMenu jsubmenu; + + panel.setLayout(new BorderLayout()); + + jmenubar = new JMenuBar(); + + for (int i = 0; i < nMenuCount; i ++) { + jmenu = new JMenu("JMenu" + i); + jmenu.setMnemonic('0' + i); + jmenubar.add(jmenu); + + for (int j = 0; j < nMenuItemCount; j ++) { + int mn = 'A'; + mn = mn + j; + jsubmenu = new JMenu("SubMenu" + String.valueOf((char) mn)); + jsubmenu.setMnemonic('A' + j); + jmenu.add(jsubmenu); + for (int k = 0; k <= j; k ++) { + jmenuitem = new JMenuItem("SubMenu - JMenuItem" + i + (char) mn + k); + jmenuitem.setMnemonic('0' + k); + jmenuitem.addActionListener(new MyActionListener()); + jsubmenu.add(jmenuitem); + } + } + } + panel.add("North", jmenubar); + list = new JList(new DefaultListModel()); + list.setFont(new Font("Serif", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(list); + panel.add("Center", scrollPane); + + return panel; + } + + public String getTestName() { + return "JMTest_05"; + } + + public void runTest() { + for (int i = 0; i < 10; i++) { + testMenu(); + } + } + + public void testMenu() { + FireEvents(); + } + + @SuppressWarnings("deprecation") + public void FireEvents() { + int nCount = jmenubar.getMenuCount(); + int mnem; + JMenuItem menuitem; + KeyEvent key; + int firstMnem; + JMenu menu; + + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + for (int i = 0; i < nCount; i++) { + menu = jmenubar.getMenu(i); + int nItemCount = menu.getItemCount(); + + for (int j = 0; j < nItemCount; j ++) { + JMenuItem mi = menu.getItem(j); + + if (mi instanceof JMenu) { + JMenu targetmenu = (JMenu) mi; + + int nC = targetmenu.getItemCount(); + for (int k = 0; k < nC; k ++) { + firstMnem = menu.getMnemonic(); + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), KeyEvent.ALT_DOWN_MASK, firstMnem); + queue.postEvent(key); + rest(); + + mnem = mi.getMnemonic(); + key = new KeyEvent(menu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, mnem); + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + + JMenuItem menui = targetmenu.getItem(k); + mnem = menui.getMnemonic(); + key = new KeyEvent(targetmenu, KeyEvent.KEY_PRESSED, + new Date().getTime(), 0, mnem); + + queue.postEvent(key); + try { + Thread.sleep(10); + } catch (Exception e) { + System.out.println(e); + } + } + } + } + } + } + + + public static void main(String[] args) { + runStandAloneTest(new JMTest_05()); + } + + public class MyActionListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + AbstractButton comp = (AbstractButton) e.getSource(); + Display(comp.getText()); + } + } + + public void Display(String str) { + DefaultListModel lm = (DefaultListModel) list.getModel(); + lm.addElement(str); + int nSize = lm.getSize(); + list.setSelectedIndex(nSize - 1); + list.requestFocus(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/LabelTest.java b/test/jdk/performance/client/SwingMark/src/LabelTest.java new file mode 100644 index 00000000000..870c45df6f7 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/LabelTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.GridLayout; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/** + * This test is mean to isolate the speed of JLabel painting + * It creates a grid of JLabels (some with icons) and + * proceeds to change their color and repaint them. + */ + +public class LabelTest extends AbstractSwingTest { + + JLabel[] labels; + final int repeat = 255; + final int gridDimension = 6; + JPanel panel; + + public JComponent getTestComponent() { + panel = new JPanel(); + panel.setLayout(new GridLayout( gridDimension, gridDimension) ); + labels = new JLabel[gridDimension*gridDimension]; + for (int i = 0; i < labels.length; i++) { + labels[i] = new CounterLabel( "Label #" + i); + if (i % 2 == 0) { + labels[i].setOpaque(true); + } else { + labels[i].setOpaque(false); + } + panel.add(labels[i]); + } + labels[0].setIcon(UIManager.getIcon("Tree.openIcon")); + labels[5].setIcon(UIManager.getIcon("Tree.closedIcon")); + labels[10].setIcon(UIManager.getIcon("Tree.leafIcon")); + labels[15].setIcon(UIManager.getIcon("Tree.expandedIcon")); + labels[20].setIcon(UIManager.getIcon("Tree.collapsedIcon")); + + return panel; + } + + public String getTestName() { + return "Labels"; + } + + public void runTest() { + LabelChanger changer = new LabelChanger(labels); + for (int i = 0; i < repeat; i++) { + try { + changer.setColor( new Color( i,i,i) ); + SwingUtilities.invokeLater(changer); + //panel.repaint(); + rest(); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new LabelTest()); + } + + + class CounterLabel extends JLabel { + CounterLabel(String s) { + super(s); + } + public void paint(Graphics g) { + paintCount++; + super.paint(g); + } + } +} + +class LabelChanger implements Runnable { + JLabel[] labels; + Color color; + + + public LabelChanger(JLabel[] labelsToChange) { + labels = labelsToChange; + } + + public void setColor(Color newColor) { + color = newColor; + } + + public void run() { + for (int i = 0; i < labels.length; i++) { + labels[i].setForeground(color); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/ListTest.java b/test/jdk/performance/client/SwingMark/src/ListTest.java new file mode 100644 index 00000000000..bd9a262a1d9 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/ListTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.ResourceBundle; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JList. + * It creates a JList and adds many items to it. It then + * scrolls through the list. + */ + +public class ListTest extends AbstractSwingTest { + JList list1; + final int list1ItemCount = 250; + String DISPLAY_STRING = "List Item "; + + public JComponent getTestComponent() { + loadBundle(); + JPanel panel = new JPanel(); + String[] list1Data = new String[list1ItemCount]; + for ( int i = 0; i < list1ItemCount; i++) { + list1Data[i] = DISPLAY_STRING+" " + i; + } + list1 = new CountList(list1Data); + JScrollPane scrollPane = new JScrollPane(list1); + if (SwingMark.useBlitScrolling) { + scrollPane.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE); + } + panel.add(scrollPane); + return panel; + } + + private void loadBundle() { + ResourceBundle bundle = ResourceBundle.getBundle("resources.ListTest"); + DISPLAY_STRING = bundle.getString("DisplayString"); + } + + public String getTestName() { + return "Lists"; + } + + public void runTest() { + testList(list1, 1); + } + + public void testList(JList currentList, int scrollBy) { + ListScroller scroll = new ListScroller(currentList, scrollBy); + for (int i = currentList.getSelectedIndex() ; + i < currentList.getModel().getSize(); + i++) { + try { + SwingUtilities.invokeLater(scroll); + rest(); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new ListTest()); + } + + class CountList extends JList { + public CountList(String[] s) { + super(s); + } + + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } + +} + + +class ListScroller implements Runnable { + JList list; + int scrollAmount = 1; + + + public ListScroller(JList listToScroll, int scrollBy) { + list = listToScroll; + scrollAmount = scrollBy; + } + + public void run() { + int currentVal = list.getSelectedIndex(); + list.setSelectedIndex(currentVal+scrollAmount); + list.ensureIndexIsVisible(currentVal+scrollAmount); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/MenuTest.java b/test/jdk/performance/client/SwingMark/src/MenuTest.java new file mode 100644 index 00000000000..9d9d8751d3e --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/MenuTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +/** + * This tests Swing Menus by posting key events to the EventQueue + * Each time a menu is selected and ActionEvent is generated + * and that event causes some text to be appended to a JTextArea + * + * note: this test has been replaced by JMTest_02 + */ + +public class MenuTest extends AbstractSwingTest { + + JMenuBar menuBar; + JMenu menu1; + JMenu menu2; + JMenu menu3; + JMenu menu4; + + JMenu subMenu; + + JTextArea textArea; + + ActionListener listener; + + int repeat = 50; + + /** + * This test cannot run as an applet because it + * posts events to the event queue + */ + public boolean canRunInApplet() { + return false; + } + + public JComponent getTestComponent() { + listener = new MyListener(); + + JPanel panel = new JPanel(); + panel.setLayout( new BorderLayout() ); + menuBar = new JMenuBar(); + panel.add(menuBar, BorderLayout.NORTH); + + menu1 = new JMenu("Menu1"); + menu1.setMnemonic('M'); + menuBar.add(menu1); + loadMenu(menu1, 5); + + menu2 = new JMenu("Menu2"); + menu2.setMnemonic('e'); + menuBar.add(menu2); + loadMenu(menu2, 4); + + menu3 = new JMenu("Menu3"); + menu3.setMnemonic('n'); + menuBar.add(menu3); + loadMenu(menu3, 6); + + menu4 = new JMenu("Menu4"); + menu4.setMnemonic('u'); + menuBar.add(menu4); + + textArea = new JTextArea(10,10); + textArea.setLineWrap(true); + JScrollPane scroll = new JScrollPane(textArea); + panel.add(scroll, BorderLayout.CENTER); + return panel; + } + + private void loadMenu(JMenu menu, int numItems) { + for (int i = 0; i < numItems; i++) { + JMenuItem item = new JMenuItem("Item " + i, String.valueOf(i).toCharArray()[0]); + menu.add(item); + item.addActionListener(listener); + } + } + + public String getTestName() { + return "Menus"; + } + + public void runTest() { + for (int i = 0; i < repeat; i++) { + testMenu(menu1); + testMenu(menu2); + testMenu(menu3); + } + } + + @SuppressWarnings("deprecation") + public void testMenu(JMenu currentMenu) { + int c = currentMenu.getMnemonic(); + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + + for (int i = 0; i < currentMenu.getItemCount(); i++) { + + KeyEvent key = new KeyEvent(currentMenu, + KeyEvent.KEY_PRESSED, + new Date().getTime(), + KeyEvent.ALT_DOWN_MASK, + c); + queue.postEvent(key); + + rest(); + key = new KeyEvent(currentMenu, + KeyEvent.KEY_PRESSED, + new Date().getTime(), + 0, + currentMenu.getItem(i).getMnemonic() ); + queue.postEvent(key); + + } + } + + public static void main(String[] args) { + runStandAloneTest(new MenuTest()); + } + + class MyListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + JMenuItem item = (JMenuItem)e.getSource(); + textArea.append(item.getText() + " "); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/NullRunnable.java b/test/jdk/performance/client/SwingMark/src/NullRunnable.java new file mode 100644 index 00000000000..6d0f5605d39 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/NullRunnable.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** This is a simple class to be used as a "do nothing" + * it is part of the timing system. + * + * @see SwingMarkPanel#runTests + */ + +class NullRunnable implements Runnable { + static NullRunnable singleton = new NullRunnable(); + public void run() { + } +} diff --git a/test/jdk/performance/client/SwingMark/src/SliderTest.java b/test/jdk/performance/client/SwingMark/src/SliderTest.java new file mode 100644 index 00000000000..260e164944a --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/SliderTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of JSlider painting + * It creates a JList and then changes its value while repainting. + * + */ + +public class SliderTest extends AbstractSwingTest { + + JSlider slider1; + int values = 500; + + public SliderTest() { + } + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + slider1 = new CountSlider(JSlider.HORIZONTAL, 0, values, 0); + slider1.setMajorTickSpacing(values / 5); + slider1.setMinorTickSpacing(values / 10); + slider1.setPaintTicks(true); + slider1.setPaintLabels(true); + panel.add(slider1); + return panel; + } + + public String getTestName() { + return "Sliders"; + } + + public void runTest() { + testSlider(slider1, 1); // increment this slider by ones + } + + public void testSlider(JSlider currentSlider, int incrementBy) { + SliderInc inc = new SliderInc(currentSlider, incrementBy); + for (int i = currentSlider.getValue() ; i < currentSlider.getMaximum(); i++) { + try { + SwingUtilities.invokeLater(inc); + rest(); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new SliderTest()); + } + + class CountSlider extends JSlider { + + public CountSlider(int ori, int min, int max, int curr) { + super(ori, min, max, curr); + } + + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } + } + +class SliderInc implements Runnable { + JSlider slider; + int incAmount = 1; + + public SliderInc(JSlider sliderToIncrement, int incrementBy) { + slider = sliderToIncrement; + incAmount = incrementBy; + } + + public void run() { + int currentVal = slider.getValue(); + slider.setValue(currentVal+incAmount); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/SwingMark.java b/test/jdk/performance/client/SwingMark/src/SwingMark.java new file mode 100644 index 00000000000..845e4764756 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/SwingMark.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.Date; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JFrame; +import javax.swing.RepaintManager; +import javax.swing.UIManager; + +/** + * This class runs the SwingMark benchmarks as an application + * Simply invoke this class' main() to run the test suite. + * Optionally you can use the name of a subclass of LookAndFeel + * as an arguement to main(). This will use that L&F for the test. + */ + +public class SwingMark { + + static SwingMarkPanel mainPanel; + static Date startTime; + static Date startupCompleteTime; + static Date endTime; + static int numRepeats = 1; + static boolean autoQuit = false; + static boolean sleepBetweenRuns = false; + static boolean useBlitScrolling = false; + + static long[][] timeReport; + static long[][] memoryReport; + + static String reportFileName = null; + static String memoryReportFileName = null; + + + @SuppressWarnings("deprecation") + public static void initFrame(JFrame frame) { + mainPanel = new SwingMarkPanel(); + prepReports(); + frame.getContentPane().add(mainPanel); + frame.pack(); + frame.show(); + } + + protected static void prepReports() { + if (timeReport == null) { + timeReport = new long[numRepeats][mainPanel.tests.length]; + } + if (memoryReport == null) { + memoryReport = new long[numRepeats][2]; + } + } + + public static void main(String[] args) { + + System.out.println("Starting SwingMark"); + startTime = new Date(); + System.out.println("SwingMark Test started at " + startTime); + + parseArgs(args); + + JFrame f = new JFrame("SwingMarks"); + Thread.currentThread().setPriority(Thread.NORM_PRIORITY-1); + f.addWindowListener( new Closer() ); + + initFrame(f); + Date startupCompleteTime = new Date(); + long elapsedTime = startupCompleteTime.getTime() - startTime.getTime(); + System.out.println("Startup Time: "+elapsedTime); + + + //int repeat = 15; + for (int i = 0; i < numRepeats; i++) { + mainPanel.runTests(i); + if (i < numRepeats - 1) { + f.setVisible(false); + f.dispose(); + AbstractSwingTest.rest(); + f = new JFrame("SwingMarks " + (i+2)); + initFrame(f); + f.addWindowListener( new Closer() ); + System.out.println(" **** Starting run " + (i+2) + "****"); + maybeSleep(); + } + } + + Date endTime = new Date(); + elapsedTime = endTime.getTime() - startTime.getTime(); + System.out.println("Score: "+elapsedTime); + + writeReport(); + writeMemoryReport(); + + if (autoQuit) { + System.exit(0); + } + } + + static void maybeSleep() { + if (sleepBetweenRuns) { + for (int i = 0; i < 10; i++) { + Toolkit.getDefaultToolkit().beep(); + try { + AbstractSwingTest.syncRam(); + Thread.sleep(900); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + static class Closer extends WindowAdapter { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + } + + @SuppressWarnings("deprecation") + private static void parseArgs(String[] args) { + String lafName = UIManager.getCrossPlatformLookAndFeelClassName(); + int lfOpts = 0; + int nOpts = 0; + + for (int i = 0; i < args.length; i++) { + + if (args[i].indexOf("-lf") == 0) { + lafName = args[i+1];//.substring(3); + lfOpts = 1; + i++; + } else if (args[i].indexOf("-n") == 0) { + // use native look and feel + lafName = UIManager.getSystemLookAndFeelClassName(); + nOpts++; + } else if (args[i].indexOf("-r") == 0) { + String repeatString = args[i+1];//.substring(2); + numRepeats = Integer.parseInt(repeatString); + System.out.println("Will run test " + numRepeats + " times in the same VM"); + i++; + } else if (args[i].equals("-q")) { + autoQuit = true; + System.out.println("Program will automatically terminate after last run"); + } else if (args[i].equals("-f")) { + reportFileName = args[i+1]; + if (reportFileName.indexOf("-mmdd") != -1) { + Date date = new Date(); + int startpos = reportFileName.indexOf("-mmdd"); + reportFileName = + reportFileName.substring(0,startpos)+(date.getMonth()+1)+"-"+ + date.getDate()+reportFileName.substring(startpos+5); + } + i++; + System.out.println("Will write test report to file: "+ reportFileName); + } else if (args[i].equals("-m")) { + memoryReportFileName = args[i+1]; + i++; + System.out.println("Will write memory report to file: "+ memoryReportFileName); + } else if (args[i].equals("-db=off")) { + RepaintManager.currentManager(null).setDoubleBufferingEnabled(false); + System.out.println("Will run without double buffering"); + } else if (args[i].equals("-sleep")) { + sleepBetweenRuns = true; + System.out.println("Will sleep for 5 seconds between runs"); + } else if (args[i].equals("-blit")) { + useBlitScrolling = true; + System.out.println("Will use fast window blitting"); + } else if (args[i].equals("-version")) { + System.out.println("SwingMark build Oct 28, 2005"); + } else { + System.out.println("Unexpected Argument: " + args[i]); + System.exit(1); + } + } + if (lfOpts + nOpts > 1) { + System.out.println("-lf and -n are mutually exclusive\n"); + System.exit(1); + } + switchLookAndFeel(lafName); + } + + private static void switchLookAndFeel(String lafName) { + try { + System.out.println("Setting L&F to: "+ lafName); + UIManager.setLookAndFeel(lafName); + + } catch (Exception e) { + System.out.println(e); + System.exit(1); + } + } + + protected static void writeReportHeader(PrintWriter writer) { + writer.println(""); + + writer.println("SwingMark"); + writer.println(); + writer.println("" + startTime + ""); + writer.println("" + System.getProperty("java.version") + ""); + writer.println("" + System.getProperty("java.vendor") + ""); + writer.println("" + System.getProperty("java.home") + ""); + + String vmName = System.getProperty("java.vm.name"); + String vmVersion = System.getProperty("java.vm.info"); + + String vmString = "Undefined"; + if (vmName != null && vmVersion != null) { + vmString = vmName + " " + vmVersion; + } + writer.println("" + vmString + ""); + + writer.print("" + System.getProperty("os.name") ); + writer.println(" version " + System.getProperty("os.version")+ ""); + + int bits = java.awt.Toolkit.getDefaultToolkit().getColorModel().getPixelSize(); + writer.println("" + bits + ""); + + writer.println(); + } + + protected static void writeReportFooter(PrintWriter writer) { + writer.println(""); + } + + protected static void writeReport() { + if (reportFileName != null) { + try { + System.out.println("Writing report to file: "+ reportFileName); + FileWriter fileWriter = new FileWriter(reportFileName); + PrintWriter writer = new PrintWriter(fileWriter); + + writeReportHeader(writer); + + writer.println(""); + for (int testNumber =0; testNumber < mainPanel.tests.length; testNumber++) { + writer.print(mainPanel.tests[testNumber].getTestName() + "\t"); + for (int runNumber = 0; runNumber < numRepeats; runNumber++) { + writer.print(timeReport[runNumber][testNumber]); + if (runNumber < numRepeats -1) { + writer.print("\t"); + } + } + writer.println(); + } + + writer.println(""); + + writer.println(); + writeReportFooter(writer); + + writer.close(); + fileWriter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + protected static void writeMemoryReport() { + if (memoryReportFileName != null) { + try { + System.out.println("Writing memory report to file: "+ memoryReportFileName); + FileWriter fileWriter = new FileWriter(memoryReportFileName); + PrintWriter writer = new PrintWriter(fileWriter); + writeReportHeader(writer); + writer.println("Used Memory\tHeapSize"); + for (int runNumber = 0; runNumber < numRepeats; runNumber++) { + writer.print(memoryReport[runNumber][0]); + writer.print("\t"); + writer.println(memoryReport[runNumber][1]); + } + writer.println(); + writeReportFooter(writer); + writer.close(); + fileWriter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/SwingMarkPanel.java b/test/jdk/performance/client/SwingMark/src/SwingMarkPanel.java new file mode 100644 index 00000000000..02b07e61aa8 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/SwingMarkPanel.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.Date; +import java.util.Vector; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; + +/** + * This class is the center point for running the automated + * test suite. + * It creates a number of instances of AbstractSwingTest. It + * gets a component from each test and inserts it into a JTabbedPane. + * It then sequentially selects each tab and runs the coresponding test + */ + +public class SwingMarkPanel extends JTabbedPane { + + AbstractSwingTest[] tests; + + public SwingMarkPanel() { + tests = getTests(); + for (int i = 0; i < tests.length; i++) { + addTab(tests[i].getTestName(), tests[i].getTestComponent() ); + } + setSelectedIndex(0); + } + + /** + * add new tests to the suite by adding objects + * to the array returned by this function + */ + @SuppressWarnings("deprecation") + public AbstractSwingTest[] getTests() { + + Vector testVector = new Vector(); + try { + + String testList = "TestList.txt"; + + FileReader file = null; + LineNumberReader reader = null; + + try { + file = new FileReader(testList); + reader = new LineNumberReader(file); + } catch (FileNotFoundException e) { + InputStream is = getClass().getResourceAsStream("/resources/" + testList); + reader = new LineNumberReader(new InputStreamReader(is)); + } + + String testName = reader.readLine();; + + while (testName != null ) { + + if (testName.indexOf("//") != 0) { + + try { + Class testClass = Class.forName(testName); + AbstractSwingTest test = (AbstractSwingTest)testClass.newInstance(); + testVector.addElement(test); + } catch (Exception e) { + System.out.println("Error instantiating test: " + testName); + System.out.println("Test must be subclass of AbstractSwingTest."); + e.printStackTrace(); + } + testName = reader.readLine(); + } + } + reader.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + + AbstractSwingTest[] tests = new AbstractSwingTest[testVector.size()]; + testVector.copyInto(tests); + return tests; + } + + /** + * run each test and print the elapsed time + */ + public void runTests(int runNumber) { + TabSelecter selecter = new TabSelecter(); + for (int testNumber = 0; testNumber < tests.length; testNumber++) { + selecter.setSelection(testNumber); + try { + // select the next tab + SwingUtilities.invokeAndWait(selecter); + AbstractSwingTest.rest(); + } catch (Exception e) { + System.out.println(e); + } + Date start = new Date(); // mark the start time + tests[testNumber].runTest(); + try { + // wait for event queue to clear + SwingUtilities.invokeAndWait(NullRunnable.singleton); + AbstractSwingTest.syncRam(); + AbstractSwingTest.rest(); + } catch (Exception e) { + System.out.println(e); + } + Date end = new Date(); // mark the completion time + long elapsedTime = end.getTime() - start.getTime(); + + Runtime runtime = Runtime.getRuntime(); + long heapSize = runtime.totalMemory(); + long freeMemory = runtime.freeMemory(); + long usedMemory = heapSize - freeMemory; + SwingMark.memoryReport[runNumber][0] = usedMemory; + SwingMark.memoryReport[runNumber][1] = heapSize; + + SwingMark.timeReport[runNumber][testNumber] = elapsedTime; + + System.out.println(tests[testNumber].getTestName() + + " = " + elapsedTime + + " (Paint = " + tests[testNumber].getPaintCount() + ")"); + } + } + + class TabSelecter implements Runnable { + int selection; + + void setSelection(int tabToSelect) { + selection = tabToSelect; + } + + public void run() { + SwingMarkPanel.this.setSelectedIndex(selection); + SwingMarkPanel.this.repaint(); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TableColMoveTest.java b/test/jdk/performance/client/SwingMark/src/TableColMoveTest.java new file mode 100644 index 00000000000..0e168f706a0 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TableColMoveTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTable. + * It creates a JTable and moves columns. + */ + +public class TableColMoveTest extends AbstractSwingTest { + JTable table; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + TableModel dataModel = new DefaultTableModel() { + public int getColumnCount(){ return 25; } + public int getRowCount() { return 20;} + public Object getValueAt(int row, int col) { return Integer.valueOf(col) ;} + }; + + table = new JTable(dataModel); + JScrollPane scrollPane = new JScrollPane(table); + panel.add(scrollPane); + return panel; + } + + public String getTestName() { + return "Table Column Move Test"; + } + + public void runTest() { + testTable(table, 1); + } + + public void testTable(JTable currentTable, int scrollBy) { + + TableColMover colmover = new TableColMover(currentTable); + // Column Selection Test + currentTable.clearSelection(); + + for (int i = 0 ; i < currentTable.getColumnCount(); i++) { + try { + SwingUtilities.invokeAndWait(colmover); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new TableColMoveTest()); + } +} + + +class TableColMover implements Runnable { + JTable table; + + public TableColMover(JTable table) { + this.table = table; + } + + public void run() { + table.moveColumn(0, table.getColumnCount()-1 ); + Rectangle cellBound = table.getCellRect(0, table.getColumnCount()-1, true); + table.scrollRectToVisible(cellBound); + table.repaint(); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TableColTest.java b/test/jdk/performance/client/SwingMark/src/TableColTest.java new file mode 100644 index 00000000000..0d2efae3a36 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TableColTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTable. + * It creates a JTable and performs the following scenarios : + * 1) Remove columns + * 2) Add columns + * 3) Select columns + * -Single Selection mode + * -Single Selection Interval + * -Multiple Selection Intervas + */ + +public class TableColTest extends AbstractSwingTest { + JTable table; + TableModel dataModel; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + dataModel = new DefaultTableModel() { + public int getColumnCount(){ return 30; } + public int getRowCount() { return 40;} + public Object getValueAt(int row, int col) { return Integer.valueOf(col) ;} + }; + + table = new JTable(dataModel); + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + JScrollPane scrollPane = new JScrollPane(table); + panel.add(scrollPane); + return panel; + } + + public String getTestName() { + return "Table Column Test"; + } + + public void runTest() { + testTable(table, 1); + } + + public void testTable(JTable currentTable, int scrollBy) { + currentTable.setColumnSelectionAllowed(true); + + // remove column + System.out.println("1)Removing Columns"); + TableColAdder colRemover = new TableColAdder(currentTable,false); + while(currentTable.getColumnCount() > 0 ) { + try { + SwingUtilities.invokeAndWait(colRemover); + } catch (Exception e) {System.out.println(e);} + } + + // add row + System.out.println("2)Adding Columns"); + TableColAdder colAdder = new TableColAdder(currentTable,true); + for ( int i = 0 ; i < dataModel.getColumnCount(); i++ ) { + + try { + colAdder.setModelIndex(i); + SwingUtilities.invokeAndWait(colAdder); + } catch (Exception e) {System.out.println(e);} + } + + + + // Selection Mode test + System.out.println("3)Selection Mode Test"); + for ( int m = 0 ; m < 3 ; m ++ ) { // m represents selection mode + System.out.println(" --------- Selection Mode :" + m ); + + TableColScroller colScroll = new TableColScroller(currentTable, scrollBy, m); + + // Column Selection Test + currentTable.clearSelection(); + + for (int i = 0 ; + i <= currentTable.getColumnCount(); + i= currentTable.getSelectedColumn()) { + try { + SwingUtilities.invokeAndWait(colScroll); + } catch (Exception e) {System.out.println(e);} + } + } + } + + public static void main(String[] args) { + runStandAloneTest(new TableColTest()); + } + +} + + +class TableColScroller implements Runnable { + JTable table; + int scrollAmount = 1; + int currentColSelection = 0; + + public TableColScroller(JTable tableToScroll, int scrollBy, int selectionMode) { + table = tableToScroll; + scrollAmount = scrollBy; + table.setSelectionMode( selectionMode); + } + + public void run() { + + int endInterval = 0; + + switch ( table.getSelectionModel().getSelectionMode() ) { + + case ListSelectionModel.SINGLE_SELECTION: + endInterval = currentColSelection; + table.addColumnSelectionInterval(currentColSelection, endInterval); + currentColSelection ++; + break; + + case ListSelectionModel.SINGLE_INTERVAL_SELECTION: + endInterval = ((currentColSelection + 2) >= table.getColumnCount()-1 ) ? + table.getColumnCount()-1 : currentColSelection+2 ; + table.addColumnSelectionInterval(currentColSelection, endInterval); + currentColSelection++; + break; + + case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION: + endInterval = (currentColSelection >= table.getColumnCount()-1 ) ? + table.getColumnCount()-1 :currentColSelection+1; + + table.addColumnSelectionInterval(currentColSelection, endInterval); + currentColSelection += 3; + break; + + default: + break; + } + + Rectangle cellBound = table.getCellRect(0, endInterval, true); + table.scrollRectToVisible(cellBound); + table.repaint(); + } +} + +class TableColAdder implements Runnable { + JTable table; + int currentRowSelection = 0; + int index = 0; + boolean add = true; // false for "remove" + int rowCount=40; + + + public TableColAdder(JTable table, boolean add) { + this.table = table; + this.add = add; + } + + public void setModelIndex(int i) { + this.index = i ; + } + + public void run() { + Rectangle cellBound; + + if (add) { + table.addColumn( new TableColumn(index)); + cellBound = table.getCellRect(0,table.getColumnCount()-1,true); + } else { + table.removeColumn( table.getColumn( table.getColumnName(0))); + cellBound = table.getCellRect(0,0,true); + } + table.scrollRectToVisible(cellBound); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TableRowTest.java b/test/jdk/performance/client/SwingMark/src/TableRowTest.java new file mode 100644 index 00000000000..92a52c18d0b --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TableRowTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.ResourceBundle; +import java.util.Vector; +import java.awt.Graphics; +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTable. + * It creates a JTable and performs the following scenarios : + * 1) Remove rows + * 2) Add rows + * 3) Select rows + * -Single Selection mode + * -Single Selection Interval + * -Multiple Selection Intervas + */ + +public class TableRowTest extends AbstractSwingTest { + + JTable table; + DefaultTableModel dataModel; + static boolean backingStoreEnabled = true; + + final String[] names = {"First Name", "Last Name", "Favorite Color", + "Favorite Number", "Vegetarian"}; + + Object[][] data = {{}}; + + public JComponent getTestComponent() { + loadBundle(); + JPanel panel = new JPanel(); + dataModel = new DefaultTableModel(data, names); + + table = new CountTable(dataModel); + JScrollPane scrollPane = new JScrollPane(table); + + if (SwingMark.useBlitScrolling) { + scrollPane.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE); + } + + panel.add(scrollPane); + return panel; + } + + private void loadBundle() { + ResourceBundle bundle = ResourceBundle.getBundle("resources.TableRowTest"); + data = (Object[][])bundle.getObject("TableData"); + } + + public String getTestName() { + return "Table Rows"; + } + + public void runTest() { + testTable(table, 1); + } + + public void testTable(JTable currentTable, int scrollBy) { + // remove row + TableRowAdder rowRemover = new TableRowAdder(currentTable, data, false); + while (dataModel.getRowCount() > 0 ) { + try { + SwingUtilities.invokeLater(rowRemover); + rest(); + } + catch (Exception e) {e.printStackTrace();} + } + + // add row + TableRowAdder rowAdder = new TableRowAdder(currentTable, data, true); + while (dataModel.getRowCount() < data.length ) { + try { + SwingUtilities.invokeAndWait(rowAdder); + } + catch (Exception e) {e.printStackTrace();} + } + + + + // Selection Test + for ( int m = 0 ; m < 3 ; m ++ ) { // m represents selection mode + // System.out.println(" --------- Selection Mode :" + m ); + + TableScroller scroll = new TableScroller(currentTable, scrollBy, m); + + currentTable.clearSelection(); + for (int i = 0 ; i < currentTable.getRowCount()-1; i++ ) { + try { + SwingUtilities.invokeAndWait(scroll); + } + catch (Exception e) {e.printStackTrace();} + } + } + + } + + public static void main(String[] args) { + if (args.length > 0) { + if (args[0].equals("-bs=off")) { + backingStoreEnabled = false; + System.out.println("BackingStore is off"); + } + } + runStandAloneTest(new TableRowTest()); + } + + class CountTable extends JTable { + public CountTable(TableModel tm) { + super(tm); + } + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } + +} + + +class TableScroller implements Runnable { + JTable table; + int scrollAmount = 1; + int currentRowSelection = 0; + + + public TableScroller(JTable tableToScroll, int scrollBy, int selectionMode) { + table = tableToScroll; + scrollAmount = scrollBy; + table.setSelectionMode( selectionMode); + } + + public void run() { + int ensureToSeeRow = 0; + + switch ( table.getSelectionModel().getSelectionMode() ) { + case ListSelectionModel.SINGLE_SELECTION: + table.addRowSelectionInterval(currentRowSelection, currentRowSelection); + currentRowSelection++; + ensureToSeeRow = currentRowSelection; + break; + case ListSelectionModel.SINGLE_INTERVAL_SELECTION: + currentRowSelection = Math.min(currentRowSelection, table.getRowCount()-1); + int maxRow = table.getRowCount()-1; + table.addRowSelectionInterval(currentRowSelection, + Math.min(currentRowSelection+5, maxRow)); + currentRowSelection++; + ensureToSeeRow = table.getSelectionModel().getAnchorSelectionIndex() + 4; + break; + case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION: + table.addRowSelectionInterval(Math.min(currentRowSelection, table.getRowCount()-1), + Math.min(currentRowSelection+3, table.getRowCount()-1)); + currentRowSelection = currentRowSelection + 5; + ensureToSeeRow = table.getSelectionModel().getAnchorSelectionIndex() + 3; + break; + default: + break; + } + + Rectangle cellBound = table.getCellRect(ensureToSeeRow, 0, true); + table.scrollRectToVisible(cellBound); + } +} + +class TableRowAdder implements Runnable { + JTable table; + int currentRowSelection = 0; + Vector dataVector; + int index = 0; + Object [][] data; + boolean add = true; // false for "remove" + + + public TableRowAdder(JTable table, Object[][] data, boolean add) { + this.table = table; + this.data = data; + this.add = add; + } + + public void run() { + DefaultTableModel model = (DefaultTableModel)table.getModel(); + Rectangle cellBound; + + if ( add ) { + model.addRow(data[index]); + index++; + cellBound = table.getCellRect(table.getRowCount()-1, 0, true); + } + else { + model.removeRow(0 ); + cellBound = table.getCellRect(0,0,true); + } + + table.scrollRectToVisible(cellBound); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TableScrollTest.java b/test/jdk/performance/client/SwingMark/src/TableScrollTest.java new file mode 100644 index 00000000000..453fb7ecfb2 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TableScrollTest.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.Graphics; +import java.awt.Rectangle; +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JViewport; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableModel; +import javax.swing.SwingUtilities; + +public class TableScrollTest extends AbstractSwingTest { + + static JTable table; + TableScroller tableScroller; + JScrollPane scroller; + static boolean backingStoreEnabled = true; + static int rendererCount = 0; + + public JComponent getTestComponent() { + + TableModel model = new AbstractTableModel() { + String[] data = { "1", "2", "3", "4", "5", "6", + "8", "9", "10", "11" }; + + public int getColumnCount() { return 10;} + public int getRowCount() { return 1000;} + public Object getValueAt(int row, int col) { + return data[(row*col)%data.length]; + } + }; + + table = new CountTable(model); + scroller = new JScrollPane(table); + tableScroller = new TableScroller(table, 1); + + return scroller; + } + + public String getTestName() { + return "Table Scroll"; + } + + public void runTest() { + for (int i = 0; i < 200; i++) { + try { + SwingUtilities.invokeLater( tableScroller ); + rest(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @SuppressWarnings("deprecation") + public static void main(String[] args) { + if (args.length > 0) { + if (args[0].equals("-bs=off")) { + backingStoreEnabled = false; + System.out.println("BackingStore is off"); + } + } + + runStandAloneTest(new TableScrollTest()); + System.out.println("Renderer painted :" + rendererCount); + System.out.println( "Backing store is:" + ((JViewport)table.getParent()).isBackingStoreEnabled() ); + } + + class TableScroller implements Runnable { + + JTable table; + int scrollAmount = 1; + int currentVis = 10; + + public TableScroller(JTable tableToScroll, int scrollBy) { + table = tableToScroll; + scrollAmount = scrollBy; + } + + public void run() { + int ensureToSeeRow = currentVis += scrollAmount; + Rectangle cellBound = table.getCellRect(ensureToSeeRow, 0, true); + table.scrollRectToVisible(cellBound); + } + } + + static class CountRenderer extends DefaultTableCellRenderer { + + public void paint(Graphics g) { + super.paint(g); + TableScrollTest.rendererCount++; + } + } + + class CountTable extends JTable { + TableCellRenderer rend = new CountRenderer(); + + public CountTable(TableModel tm) { + super(tm); + } + + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + + public TableCellRenderer getCellRenderer(int row, int column) { + return rend; + } + + @SuppressWarnings("deprecation") + public void addNotify() { + super.addNotify(); + ((JViewport)getParent()).setBackingStoreEnabled(backingStoreEnabled); + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TextAreaTest.java b/test/jdk/performance/client/SwingMark/src/TextAreaTest.java new file mode 100644 index 00000000000..63c0d94abe9 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TextAreaTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.util.ResourceBundle; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.awt.event.KeyEvent; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTextArea + * It creates a JTextArea and then continuously appends text + * to that string. + */ + +public class TextAreaTest extends AbstractSwingTest { + + JTextArea textArea1; + final int repeat = 300; + final int breakIncrement = 12; + + String DISPLAY_STRING = "Swing is Fast! "; + + public JComponent getTestComponent() { + loadBundle(); + JPanel panel = new JPanel(); + textArea1 = new CountTextArea(10, 30); + textArea1.setLineWrap(true); + JScrollPane scroller = new JScrollPane(textArea1); + + if (SwingMark.useBlitScrolling) { + scroller.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE); + } + + panel.add(scroller); + return panel; + } + + public String getTestName() { + return "TextArea"; + } + + public void runTest() { + testTextArea(textArea1, DISPLAY_STRING); + } + + private void loadBundle() { + ResourceBundle bundle = ResourceBundle.getBundle("resources.TextAreaTest"); + DISPLAY_STRING = bundle.getString("DisplayString"); + } + + + public void testTextArea(JTextArea currentTextArea, String appendThis) { + + TextAppender appender = new TextAppender(currentTextArea, appendThis); + for (int i = 0; i < repeat; i++) { + appender.appendString = appendThis; + if ( i % breakIncrement == breakIncrement -1) { + appender.appendString = appendThis + "\n"; + } + try { + SwingUtilities.invokeLater(appender); + rest(); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new TextAreaTest()); + } + + class CountTextArea extends JTextArea { + + public CountTextArea(int h, int w) { + super(h, w); + } + + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } +} + +class TextAppender implements Runnable { + + JTextArea area; + String appendString; + + public TextAppender(JTextArea textArea, String appendThis) { + area = textArea; + appendString = appendThis; + } + + public void run() { + area.append(appendString); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TextPaneTest.java b/test/jdk/performance/client/SwingMark/src/TextPaneTest.java new file mode 100644 index 00000000000..dbd6eeb5abb --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TextPaneTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.text.Document; + +/** + * This test is mean to isolate the speed of the JTextArea + * It creates a JTextArea and then continuously appends text + * to that string. + * + */ + +public class TextPaneTest extends AbstractSwingTest { + + JTextPane textArea1; + final int repeat = 250; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + panel.setPreferredSize(new Dimension(200,200)); + panel.setLayout(new BorderLayout()); + textArea1 = new CountTextArea(10, 30); + JScrollPane scroller = new JScrollPane(textArea1); + panel.add(scroller, BorderLayout.CENTER); + return panel; + } + + public String getTestName() { + return "TextPane"; + } + + public void runTest() { + testTextArea(textArea1, "Swing is Fast! "); + } + + public void testTextArea(JTextPane currentTextArea, String appendThis) { + TextAppender appender = new TextAppender(currentTextArea, appendThis); + for (int i = 0; i < repeat; i++) { + try { + SwingUtilities.invokeLater(appender); + rest(); + } catch (Exception e) {System.out.println(e);} + } + } + + public static void main(String[] args) { + runStandAloneTest(new TextPaneTest()); + } + + class CountTextArea extends JTextPane { + public CountTextArea(int h, int w) { + super(); + } + + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } + + static class TextAppender implements Runnable { + JTextPane area; + String appendString; + + public TextAppender(JTextPane textArea, String appendThis) { + area = textArea; + appendString = appendThis; + } + + public void run() { + try { + Document doc = area.getDocument(); + doc.insertString(doc.getLength(), appendString, null); + } catch (Exception e) { + } + } + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TreeTest.java b/test/jdk/performance/client/SwingMark/src/TreeTest.java new file mode 100644 index 00000000000..175a01ce733 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TreeTest.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Enumeration; +import java.util.Vector; +import java.awt.BorderLayout; +import java.awt.Graphics; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreeSelectionModel; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import javax.swing.SwingUtilities; + +/** + * This test is mean to isolate the speed of the JTree. + * It creates a JTree and performs the following scenarios : + * 1) Recursively adding node to the tree + * 2) Recursively expand all nodes + * 3) Selection Test + * -SINGLE_TREE_SELECTION mode + * -CONTIGUOUS_TREE_SELECTION mode + * -DISCONTIGUOUS_TREE_SELECTION mode + * 4) Collapse all nodes + * 5) Recursively Remove all the nodes + */ + +public class TreeTest extends AbstractSwingTest { + JTree tree; + int totalChildCount = 0; + int targetChildCount = 200; + int interval = 5; + boolean useLargeModel = false; + boolean debug = false; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + + DefaultMutableTreeNode top = + new DefaultMutableTreeNode(Integer.valueOf(0)); + totalChildCount ++; + + DefaultTreeModel model = new DefaultTreeModel(top); + + tree = new CountTree(model); + tree.setLargeModel(useLargeModel); + if (useLargeModel) { + tree.setRowHeight(18); + } + JScrollPane scroller = new JScrollPane(tree); + + if (SwingMark.useBlitScrolling) { + scroller.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE); + } + + panel.add(scroller, BorderLayout.CENTER); + + return panel; + } + + public String getTestName() { + return "Tree"; + } + + public void runTest() { + testTree(); + } + + public void testTree() { + // Recursively add Nodes to the tree + if (debug) { + System.out.println("(1)Adding nodes..."); + } + + TreeNodeAdder adder = + new TreeNodeAdder( (DefaultTreeModel)tree.getModel(), true ); + Vector nodeList = new Vector(); + nodeList.addElement(tree.getModel().getRoot()); + + addChild(nodeList, adder); + + // Recursively Expend all nodes + if (debug) { + System.out.println("(2)Recursively Expending all nodes..."); + } + + TreeExpender expender = new TreeExpender(tree, true); + TreePath path = tree.getPathForRow(0); + DefaultMutableTreeNode root = + (DefaultMutableTreeNode)path.getLastPathComponent(); + expandNodes(root, expender); + + // Selection Test + + // 1) SINGLE_TREE_SELECTION + if (debug) { + System.out.println("(3)Selection Test ....."); + System.out.println(" -SINGLE_TREE_SELECTION ....."); + + } + TreeSelector selector = + new TreeSelector(tree,TreeSelectionModel.SINGLE_TREE_SELECTION); + int [] rows = new int[1]; + + for (int i=0; i < tree.getRowCount() ; i ++ ) { + rows[0] = i; + selector.addSelectionRows(rows); + try { + SwingUtilities.invokeLater(selector); + rest(); + } catch (Exception e) {System.out.println(e);} + } + + + // 2) CONTIGUOUS_TREE_SELECTION + if (debug) { + System.out.println(" -CONTIGUOUS_TREE_SELECTION ....."); + } + + selector = + new TreeSelector(tree,TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); + rows = new int[3]; + int count = tree.getRowCount()/4 ; + + for (int i=0; i < count ;i ++) { + rows[0]=i*4; rows[1] = rows[0]+1; rows[2] = rows[0]+2; + selector.addSelectionRows(rows); + try { + SwingUtilities.invokeAndWait(selector); + } catch (Exception e) {System.out.println(e);} + } + + // 3) CONTIGUOUS_TREE_SELECTION + if (debug) { + System.out.println(" -DISCONTIGUOUS_TREE_SELECTION ....."); + } + new TreeSelector(tree,TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + count = tree.getRowCount()/5 ; + + for (int i=0; i < count ; i ++) { + rows[0]=i*5; rows[1] = rows[0]+1; rows[2] = rows[0]+2; + selector.addSelectionRows(rows); + try { + SwingUtilities.invokeAndWait(selector); + } catch (Exception e) {System.out.println(e);} + } + + // + // Collapse all the nodes + // + if (debug) { + System.out.println("(4)Collapsing all nodes ....."); + + } + TreeExpender collapser = new TreeExpender(tree, false); + TreePath[] paths = new TreePath[ tree.getRowCount()]; + + for ( int rowcount = 0 ; rowcount < tree.getRowCount() ; rowcount ++ ) { + paths[rowcount] = tree.getPathForRow(rowcount ); + } + + for ( int i = paths.length - 1 ; i >=0 ; i-- ) { + try { + collapser.setPath(paths[i]); + SwingUtilities.invokeAndWait(collapser); + } catch (Exception e) {System.out.println(e);} + } + + // Recursively remove Nodes from the tree + // + if (debug) { + System.out.println("(5)Removing nodes..."); + } + + TreeNodeAdder remover = + new TreeNodeAdder( (DefaultTreeModel)tree.getModel(), false); + + removeNodes((DefaultMutableTreeNode)tree.getModel().getRoot(),remover); + tree.repaint(); + } + + + public void addChild(Vector nodeList, TreeNodeAdder adder){ + DefaultMutableTreeNode node; + Vector newVec = new Vector(); + + for ( int i=0; i < nodeList.size() ; i++ ) { + + node = (DefaultMutableTreeNode)nodeList.elementAt(i); + + while ( node.getChildCount() < interval ) { + if ( totalChildCount >= targetChildCount ) return; + + adder.setNode(node, totalChildCount); + try { + SwingUtilities.invokeAndWait(adder); + totalChildCount ++; + } catch (Exception e) {System.out.println(e);} + + newVec.addElement(node.getChildAt(node.getChildCount()-1)); + } + } + addChild(newVec, adder); + } + + public void expandNodes(DefaultMutableTreeNode node, TreeExpender expender){ + try { + expender.setPath(new TreePath ( node.getPath())); + SwingUtilities.invokeAndWait(expender); + } catch (Exception e) {System.out.println(e);} + + for (Enumeration e = node.children() ; e.hasMoreElements() ;) { + DefaultMutableTreeNode childNode = + (DefaultMutableTreeNode)e.nextElement(); + expandNodes(childNode, expender); + } + } + + public void removeNodes(DefaultMutableTreeNode node, TreeNodeAdder remover){ + Vector nodeList = new Vector(); + for (Enumeration e = node.depthFirstEnumeration() ; e.hasMoreElements() ;) { + nodeList.addElement(e.nextElement()); + } + + for ( int i=0; i < nodeList.size(); i ++ ) { + DefaultMutableTreeNode nodeToRemove = + (DefaultMutableTreeNode)nodeList.elementAt(i); + + try { + remover.setNode(nodeToRemove, -1); + SwingUtilities.invokeAndWait(remover); + } catch (Exception exp) {System.out.println(exp); + } + } + } + + public static void main(String[] args) { + TreeTest test = new TreeTest(); + test.debug = true; + if (args.length > 0) { + test.targetChildCount = Integer.parseInt(args[0]); + System.out.println("Setting nodes to: " + test.targetChildCount); + } + if (args.length > 1) { + if (args[1].equals("-l")) { + System.out.println("Large Model On"); + test.useLargeModel = true; + } + } + runStandAloneTest(test); + } + + class CountTree extends JTree { + public CountTree(TreeModel tm) { + super(tm); + } + public void paint(Graphics g) { + super.paint(g); + paintCount++; + } + } +} + +class TreeNodeAdder implements Runnable { + DefaultTreeModel treeModel; + DefaultMutableTreeNode currentNode; + int totalChildCount = 0; + boolean add = true; + + public TreeNodeAdder(DefaultTreeModel treeModel, boolean add ) { + this.treeModel = treeModel; + this.add = add; + } + + public void setNode(DefaultMutableTreeNode node, int totalCount){ + currentNode = node; + totalChildCount = totalCount; + } + + public void run() { + if ( add ) { + // add a new node to the currentNode's child list + DefaultMutableTreeNode newNode = + new DefaultMutableTreeNode(Integer.valueOf(totalChildCount)); + treeModel.insertNodeInto(newNode, currentNode, currentNode.getChildCount()); + } else { + // remove the current Node from its parent + if ( currentNode.getParent() != null ) { + treeModel.removeNodeFromParent(currentNode); + } + } + } +} + +class TreeExpender implements Runnable { + JTree tree; + boolean expand = true; + TreePath currentPath; + + public TreeExpender(JTree tree, boolean expand ) { + this.tree = tree; + this.expand = expand; + } + + public void setPath(TreePath path){ + currentPath = path; + } + + public void run() { + if ( expand ) { + // Expand the current Path + if ( tree.isExpanded(currentPath)) tree.expandPath(currentPath); + tree.scrollPathToVisible(currentPath); + } else { + // Collapse the node + if ( !tree.isCollapsed(currentPath) ) { + tree.scrollPathToVisible(currentPath); + tree.collapsePath(currentPath); + } + } + } +} + +class TreeSelector implements Runnable { + JTree tree; + DefaultMutableTreeNode currentNode ; + TreePath currentPath; + int selectionMode = 0; + int [] rows; + + public TreeSelector(JTree tree, int mode ) { + this.tree = tree; + + selectionMode = mode; + DefaultTreeSelectionModel selectionModel = new DefaultTreeSelectionModel(); + selectionModel.setSelectionMode(mode); + tree.setSelectionModel( selectionModel ); + int [] rows; + } + + public void addSelectionRows( int[] rows ){ + this.rows = rows; + } + + public void setNode(TreePath path ) { + currentPath = path; + currentNode = (DefaultMutableTreeNode)path.getLastPathComponent(); + } + + public void run() { + tree.addSelectionRows(rows); + tree.scrollRowToVisible( rows[ rows.length -1 ]); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/TypingTest.java b/test/jdk/performance/client/SwingMark/src/TypingTest.java new file mode 100644 index 00000000000..0019f7bd2c4 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/TypingTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.Date; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class TypingTest extends AbstractSwingTest { + + JTextArea textArea1; + final int repeat = 100; + + public JComponent getTestComponent() { + JPanel panel = new JPanel(); + textArea1 = new JTextArea(10, 30); + textArea1.setLineWrap(true); + JScrollPane scroller = new JScrollPane(textArea1); + panel.add(scroller); + return panel; + } + + public boolean canRunInApplet() { + return false; + } + + public String getTestName() { + return "Typing"; + } + + public void runTest() { + testTyping(textArea1, "Write once, run anywhere! "); + } + + public void testTyping(JTextArea currentTextArea, String stuff) { + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + + int n = stuff.length(); + for (int i = 0; i < repeat; i++) + for (int j = 0; j < n; j++) { + char c = stuff.charAt(j); + KeyEvent key = new KeyEvent(currentTextArea, + KeyEvent.KEY_TYPED, new Date().getTime(), + 0, KeyEvent.VK_UNDEFINED, c); + queue.postEvent(key); + rest(); + } + } + + public static void main(String[] args) { + runStandAloneTest(new TypingTest()); + } +} diff --git a/test/jdk/performance/client/SwingMark/src/resources/JMTest_04.properties b/test/jdk/performance/client/SwingMark/src/resources/JMTest_04.properties new file mode 100644 index 00000000000..a5674cde149 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/JMTest_04.properties @@ -0,0 +1,34 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for Menu Test +MenuString=JMenu +SubMenuString=SubMenu +MenuItemString=JMenuItem diff --git a/test/jdk/performance/client/SwingMark/src/resources/JMTest_04_ja.properties b/test/jdk/performance/client/SwingMark/src/resources/JMTest_04_ja.properties new file mode 100644 index 00000000000..b3d79c809c3 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/JMTest_04_ja.properties @@ -0,0 +1,34 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for Menu Test +MenuString=\uff2a\uff2d\uff45\uff4e\uff55 +SubMenuString=\uff33\uff55\uff42\uff2d\uff45\uff4e\uff55 +MenuItemString=\uff2a\uff2d\uff45\uff4e\uff55\uff29\uff54\uff45\uff4d diff --git a/test/jdk/performance/client/SwingMark/src/resources/ListTest.properties b/test/jdk/performance/client/SwingMark/src/resources/ListTest.properties new file mode 100644 index 00000000000..b731243643d --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/ListTest.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for List Test +DisplayString=ListItem diff --git a/test/jdk/performance/client/SwingMark/src/resources/ListTest_ja.properties b/test/jdk/performance/client/SwingMark/src/resources/ListTest_ja.properties new file mode 100644 index 00000000000..9e70ac633a1 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/ListTest_ja.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for List Test +DisplayString=\uff2c\uff49\uff53\uff54\uff29\uff54\uff45\uff4d diff --git a/test/jdk/performance/client/SwingMark/src/resources/TableRowTest.java b/test/jdk/performance/client/SwingMark/src/resources/TableRowTest.java new file mode 100644 index 00000000000..0fbbf676030 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/TableRowTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package resources; + +import java.util.ListResourceBundle; + + + public class TableRowTest extends ListResourceBundle { + public Object[][] getContents() { + return contents; + } + + // LOCALIZE THIS + // note: probably don't need to localize integers and booleans + static Object[][] data = { + {"Mark", "Andrews", "Red", Integer.valueOf(2), Boolean.valueOf(true)}, + {"Tom", "Ball", "Blue", Integer.valueOf(99), Boolean.valueOf(false)}, + {"Alan", "Chung", "Green", Integer.valueOf(838), Boolean.valueOf(false)}, + {"Jeff", "Dinkins", "Turquois", Integer.valueOf(8), Boolean.valueOf(true)}, + {"Amy", "Fowler", "Yellow", Integer.valueOf(3), Boolean.valueOf(false)}, + {"Brian", "Gerhold", "Green", Integer.valueOf(0), Boolean.valueOf(false)}, + {"James", "Gosling", "Pink", Integer.valueOf(21), Boolean.valueOf(false)}, + {"David", "Karlton", "Red", Integer.valueOf(1), Boolean.valueOf(false)}, + {"Dave", "Kloba", "Yellow", Integer.valueOf(14), Boolean.valueOf(false)}, + {"Peter", "Korn", "Purple", Integer.valueOf(12), Boolean.valueOf(false)}, + {"Phil", "Milne", "Purple", Integer.valueOf(3), Boolean.valueOf(false)}, + {"Dave", "Moore", "Green", Integer.valueOf(88), Boolean.valueOf(false)}, + {"Hans", "Muller", "Maroon", Integer.valueOf(5), Boolean.valueOf(false)}, + {"Rick", "Levenson", "Blue", Integer.valueOf(2), Boolean.valueOf(false)}, + {"Tim", "Prinzing", "Blue", Integer.valueOf(22), Boolean.valueOf(false)}, + {"Chester", "Rose", "Black", Integer.valueOf(0), Boolean.valueOf(false)}, + {"Ray", "Ryan", "Gray", Integer.valueOf(77), Boolean.valueOf(false)}, + {"Georges", "Saab", "Red", Integer.valueOf(4), Boolean.valueOf(false)}, + {"Willie", "Walker", "Phthalo Blue", Integer.valueOf(4), Boolean.valueOf(false)}, + {"Kathy", "Walrath", "Blue", Integer.valueOf(8), Boolean.valueOf(false)}, + {"Arnaud", "Weber", "Green", Integer.valueOf(44), Boolean.valueOf(false)}, + {"Mark", "Andrews", "Red", Integer.valueOf(2), Boolean.valueOf(true)}, + {"Tom", "Ball", "Blue", Integer.valueOf(99), Boolean.valueOf(false)}, + {"Alan", "Chung", "Green", Integer.valueOf(838), Boolean.valueOf(false)}, + {"Jeff", "Dinkins", "Turquois", Integer.valueOf(8), Boolean.valueOf(true)}, + {"Amy", "Fowler", "Yellow", Integer.valueOf(3), Boolean.valueOf(false)}, + {"Brian", "Gerhold", "Green", Integer.valueOf(0), Boolean.valueOf(false)}, + {"James", "Gosling", "Pink", Integer.valueOf(21), Boolean.valueOf(false)}, + {"David", "Karlton", "Red", Integer.valueOf(1), Boolean.valueOf(false)}, + {"Dave", "Kloba", "Yellow", Integer.valueOf(14), Boolean.valueOf(false)}, + {"Peter", "Korn", "Purple", Integer.valueOf(12), Boolean.valueOf(false)}, + {"Phil", "Milne", "Purple", Integer.valueOf(3), Boolean.valueOf(false)}, + {"Dave", "Moore", "Green", Integer.valueOf(88), Boolean.valueOf(false)}, + {"Hans", "Muller", "Maroon", Integer.valueOf(5), Boolean.valueOf(false)}, + {"Rick", "Levenson", "Blue", Integer.valueOf(2), Boolean.valueOf(false)}, + {"Tim", "Prinzing", "Blue", Integer.valueOf(22), Boolean.valueOf(false)}, + {"Chester", "Rose", "Black", Integer.valueOf(0), Boolean.valueOf(false)}, + {"Ray", "Ryan", "Gray", Integer.valueOf(77), Boolean.valueOf(false)}, + {"Georges", "Saab", "Red", Integer.valueOf(4), Boolean.valueOf(false)}, + {"Willie", "Walker", "Phthalo Blue", Integer.valueOf(4), Boolean.valueOf(false)}, + {"Kathy", "Walrath", "Blue", Integer.valueOf(8), Boolean.valueOf(false)}, + {"Arnaud", "Weber", "Green", Integer.valueOf(44), Boolean.valueOf(false)} + }; + // END OF MATERIAL TO LOCALIZE + + static final Object[][] contents = { + {"TableData", data } // array for table data + }; + } + diff --git a/test/jdk/performance/client/SwingMark/src/resources/TableRowTest_ja.java b/test/jdk/performance/client/SwingMark/src/resources/TableRowTest_ja.java new file mode 100644 index 00000000000..42b165c459f --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/TableRowTest_ja.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package resources; + +import java.util.ListResourceBundle; + +public class TableRowTest_ja extends ListResourceBundle { + + public Object[][] getContents() { + return contents; + } + + static Object[][] data = { + {"\uff2d\uff41\uff52\uff4b", "\uff21\uff4e\uff44\uff52\uff45\uff57\uff53", "\uff32\uff45\uff44", Integer.valueOf(2), Boolean.valueOf(true)}, + {"\uff34\uff4f\uff4d", "\uff22\uff41\uff4c\uff4c", "\uff22\uff4c\uff55\uff45", Integer.valueOf(99), Boolean.valueOf(false)}, + {"\uff21\uff4c\uff41\uff4e", "\uff23\uff48\uff55\uff4e\uff47", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(838), Boolean.valueOf(false)}, + {"\uff2a\uff45\uff46\uff46", "\uff24\uff49\uff4e\uff4b\uff49\uff4e\uff53", "\uff34\uff55\uff52\uff51\uff55\uff4f\uff49\uff53", Integer.valueOf(8), Boolean.valueOf(true)}, + {"\uff21\uff4d\uff59", "\uff26\uff4f\uff57\uff4c\uff45\uff52", "\uff39\uff45\uff4c\uff4c\uff4f\uff57", Integer.valueOf(3), Boolean.valueOf(false)}, + {"\uff22\uff52\uff49\uff41\uff4e", "\uff27\uff45\uff52\uff48\uff4f\uff4c\uff44", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(0), Boolean.valueOf(false)}, + {"\uff2a\uff41\uff4d\uff45\uff53", "\uff27\uff4f\uff53\uff4c\uff49\uff4e\uff47", "\uff30\uff49\uff4e\uff4b", Integer.valueOf(21), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff49\uff44", "\uff2b\uff41\uff52\uff4c\uff54\uff4f\uff4e", "\uff32\uff45\uff44", Integer.valueOf(1), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff45", "\uff2b\uff4c\uff4f\uff42\uff41", "\uff39\uff45\uff4c\uff4c\uff4f\uff57", Integer.valueOf(14), Boolean.valueOf(false)}, + {"\uff30\uff45\uff54\uff45\uff52", "\uff2b\uff4f\uff52\uff4e", "\uff30\uff55\uff52\uff50\uff4c\uff45", Integer.valueOf(12), Boolean.valueOf(false)}, + {"\uff30\uff48\uff49\uff4c", "\uff2d\uff49\uff4c\uff4e\uff45", "\uff30\uff55\uff52\uff50\uff4c\uff45", Integer.valueOf(3), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff45", "\uff2d\uff4f\uff4f\uff52\uff45", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(88), Boolean.valueOf(false)}, + {"\uff28\uff41\uff4e\uff53", "\uff2d\uff55\uff4c\uff4c\uff45\uff52", "\uff2d\uff41\uff52\uff4f\uff4f\uff4e", Integer.valueOf(5), Boolean.valueOf(false)}, + {"\uff32\uff49\uff43\uff4b", "\uff2c\uff45\uff56\uff45\uff4e\uff53\uff4f\uff4e", "\uff22\uff4c\uff55\uff45", Integer.valueOf(2), Boolean.valueOf(false)}, + {"\uff34\uff49\uff4d", "\uff30\uff52\uff49\uff4e\uff5a\uff49\uff4e\uff47", "\uff22\uff4c\uff55\uff45", Integer.valueOf(22), Boolean.valueOf(false)}, + {"\uff23\uff48\uff45\uff53\uff54\uff45\uff52", "\uff32\uff4f\uff53\uff45", "\uff22\uff4c\uff41\uff43\uff4b", Integer.valueOf(0), Boolean.valueOf(false)}, + {"\uff32\uff41\uff59", "\uff32\uff59\uff41\uff4e", "\uff27\uff52\uff41\uff59", Integer.valueOf(77), Boolean.valueOf(false)}, + {"\uff27\uff45\uff4f\uff52\uff47\uff45\uff53", "\uff33\uff41\uff41\uff42", "\uff32\uff45\uff44", Integer.valueOf(4), Boolean.valueOf(false)}, + {"\uff37\uff49\uff4c\uff4c\uff49\uff45", "\uff37\uff41\uff4c\uff4b\uff45\uff52", "\uff30\uff48\uff54\uff48\uff41\uff4c\uff4f\u3000\uff42\uff4c\uff55\uff45", Integer.valueOf(4), Boolean.valueOf(false)}, + {"\uff2b\uff41\uff54\uff48\uff59", "\uff37\uff41\uff4c\uff52\uff41\uff54\uff48", "\uff22\uff4c\uff55\uff45", Integer.valueOf(8), Boolean.valueOf(false)}, + {"\uff21\uff52\uff4e\uff41\uff55\uff44", "\uff37\uff45\uff42\uff45\uff52", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(44), Boolean.valueOf(false)}, + {"\uff2d\uff41\uff52\uff4b", "\uff21\uff4e\uff44\uff52\uff45\uff57\uff53", "\uff32\uff45\uff44", Integer.valueOf(2), Boolean.valueOf(true)}, + {"\uff34\uff4f\uff4d", "\uff22\uff41\uff4c\uff4c", "\uff22\uff4c\uff55\uff45", Integer.valueOf(99), Boolean.valueOf(false)}, + {"\uff21\uff4c\uff41\uff4e", "\uff23\uff48\uff55\uff4e\uff47", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(838), Boolean.valueOf(false)}, + {"\uff2a\uff45\uff46\uff46", "\uff24\uff49\uff4e\uff4b\uff49\uff4e\uff53", "\uff34\uff55\uff52\uff51\uff55\uff4f\uff49\uff53", Integer.valueOf(8), Boolean.valueOf(true)}, + {"\uff21\uff4d\uff59", "\uff26\uff4f\uff57\uff4c\uff45\uff52", "\uff39\uff45\uff4c\uff4c\uff4f\uff57", Integer.valueOf(3), Boolean.valueOf(false)}, + {"\uff22\uff52\uff49\uff41\uff4e", "\uff27\uff45\uff52\uff48\uff4f\uff4c\uff44", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(0), Boolean.valueOf(false)}, + {"\uff2a\uff41\uff4d\uff45\uff53", "\uff27\uff4f\uff53\uff4c\uff49\uff4e\uff47", "\uff30\uff49\uff4e\uff4b", Integer.valueOf(21), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff49\uff44", "\uff2b\uff41\uff52\uff4c\uff54\uff4f\uff4e", "\uff32\uff45\uff44", Integer.valueOf(1), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff45", "\uff2b\uff4c\uff4f\uff42\uff41", "\uff39\uff45\uff4c\uff4c\uff4f\uff57", Integer.valueOf(14), Boolean.valueOf(false)}, + {"\uff30\uff45\uff54\uff45\uff52", "\uff2b\uff4f\uff52\uff4e", "\uff30\uff55\uff52\uff50\uff4c\uff45", Integer.valueOf(12), Boolean.valueOf(false)}, + {"\uff30\uff48\uff49\uff4c", "\uff2d\uff49\uff4c\uff4e\uff45", "\uff30\uff55\uff52\uff50\uff4c\uff45", Integer.valueOf(3), Boolean.valueOf(false)}, + {"\uff24\uff41\uff56\uff45", "\uff2d\uff4f\uff4f\uff52\uff45", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(88), Boolean.valueOf(false)}, + {"\uff28\uff41\uff4e\uff53", "\uff2d\uff55\uff4c\uff4c\uff45\uff52", "\uff2d\uff41\uff52\uff4f\uff4f\uff4e", Integer.valueOf(5), Boolean.valueOf(false)}, + {"\uff32\uff49\uff43\uff4b", "\uff2c\uff45\uff56\uff45\uff4e\uff53\uff4f\uff4e", "\uff22\uff4c\uff55\uff45", Integer.valueOf(2), Boolean.valueOf(false)}, + {"\uff34\uff49\uff4d", "\uff30\uff52\uff49\uff4e\uff5a\uff49\uff4e\uff47", "\uff22\uff4c\uff55\uff45", Integer.valueOf(22), Boolean.valueOf(false)}, + {"\uff23\uff48\uff45\uff53\uff54\uff45\uff52", "\uff32\uff4f\uff53\uff45", "\uff22\uff4c\uff41\uff43\uff4b", Integer.valueOf(0), Boolean.valueOf(false)}, + {"\uff32\uff41\uff59", "\uff32\uff59\uff41\uff4e", "\uff27\uff52\uff41\uff59", Integer.valueOf(77), Boolean.valueOf(false)}, + {"\uff27\uff45\uff4f\uff52\uff47\uff45\uff53", "\uff33\uff41\uff41\uff42", "\uff32\uff45\uff44", Integer.valueOf(4), Boolean.valueOf(false)}, + {"\uff37\uff49\uff4c\uff4c\uff49\uff45", "\uff37\uff41\uff4c\uff4b\uff45\uff52", "\uff30\uff48\uff54\uff48\uff41\uff4c\uff4f\u3000\uff42\uff4c\uff55\uff45", Integer.valueOf(4), Boolean.valueOf(false)}, + {"\uff2b\uff41\uff54\uff48\uff59", "\uff37\uff41\uff4c\uff52\uff41\uff54\uff48", "\uff22\uff4c\uff55\uff45", Integer.valueOf(8), Boolean.valueOf(false)}, + {"\uff21\uff52\uff4e\uff41\uff55\uff44", "\uff37\uff45\uff42\uff45\uff52", "\uff27\uff52\uff45\uff45\uff4e", Integer.valueOf(44), Boolean.valueOf(false)} + }; + + static final Object[][] contents = { + {"TableData", data } // array for table data + }; +} diff --git a/test/jdk/performance/client/SwingMark/src/resources/TestList.txt b/test/jdk/performance/client/SwingMark/src/resources/TestList.txt new file mode 100644 index 00000000000..45b03ba4e80 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/TestList.txt @@ -0,0 +1,6 @@ +JMTest_04 +TextAreaTest +SliderTest +ListTest +TableRowTest +TreeTest diff --git a/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest.properties b/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest.properties new file mode 100644 index 00000000000..07df149851b --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for Menu Test +DisplayString=Swing is Fast!!! diff --git a/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest_ja.properties b/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest_ja.properties new file mode 100644 index 00000000000..2b757c03447 --- /dev/null +++ b/test/jdk/performance/client/SwingMark/src/resources/TextAreaTest_ja.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Resource bundle for Menu Test +DisplayString=\uff33\uff57\uff49\uff4e\uff47\u3000\uff49\uff53\u3000\uff26\uff41\uff53\uff54\uff01\uff01\uff01\u3000\u3000\u3000 From 525a91e3fac892c26b09cc1705d0909afe80c8f9 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 17 Apr 2023 19:04:31 +0000 Subject: [PATCH 012/288] 8305673: Convert DocCommentParser to use enhanced switch Reviewed-by: hannesw --- .../tools/javac/parser/DocCommentParser.java | 206 ++++++++---------- 1 file changed, 92 insertions(+), 114 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java index 2bd8617062b..73d7a7b09a8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java @@ -25,6 +25,7 @@ package com.sun.tools.javac.parser; +import java.io.Serial; import java.util.HashMap; import java.util.Map; @@ -62,6 +63,7 @@ import static com.sun.tools.javac.util.LayoutCharacters.EOI; */ public class DocCommentParser { static class ParseException extends Exception { + @Serial private static final long serialVersionUID = 0; final int pos; @@ -117,10 +119,6 @@ public class DocCommentParser { this(fac, diagSource, comment, false); } - public DocCommentParser(ParserFactory fac) { - this(fac, null, null, false); - } - public DCDocComment parse() { String c = comment.getText(); buf = new char[c.length() + 1]; @@ -147,8 +145,7 @@ public class DocCommentParser { void nextChar() { ch = buf[bp < buflen ? ++bp : buflen]; switch (ch) { - case '\f': case '\n': case '\r': - newline = true; + case '\f', '\n', '\r' -> newline = true; } } @@ -186,7 +183,7 @@ public class DocCommentParser { newline = false; if (isFileContent) { switch (phase) { - case PREAMBLE: + case PREAMBLE -> { if (isEndPreamble()) { trees.add(html()); if (textStart == -1) { @@ -197,15 +194,15 @@ public class DocCommentParser { newline = true; break loop; } - break; - case BODY: + } + case BODY -> { if (isEndBody()) { addPendingText(trees, lastNonWhite); break loop; } - break; - default: - // fallthrough + } + + default -> { } } } addPendingText(trees, bp - 1); @@ -389,52 +386,48 @@ public class DocCommentParser { /** * Read plain text content of an inline tag. - * Matching pairs of { } are skipped; the text is terminated by the first - * unmatched }. It is an error if the beginning of the next tag is detected. + * Matching pairs of '{' '}' are skipped; the text is terminated by the first + * unmatched '}'. It is an error if the beginning of the next tag is detected. */ private DCText inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException { switch (whitespacePolicy) { - case REMOVE_ALL: + case REMOVE_ALL -> { skipWhitespace(); - break; - case REMOVE_FIRST_SPACE: + } + + case REMOVE_FIRST_SPACE -> { if (ch == ' ') nextChar(); - break; - case RETAIN_ALL: - default: - // do nothing - break; + } + case RETAIN_ALL -> { } } int pos = bp; int depth = 1; - loop: while (bp < buflen) { switch (ch) { - case '\n': case '\r': case '\f': - case ' ': case '\t': - break; + case '\n', '\r', '\f', ' ', '\t' -> { + } - case '{': + case '{' -> { newline = false; lastNonWhite = bp; depth++; - break; + } - case '}': + case '}' -> { if (--depth == 0) { return m.at(pos).newTextTree(newString(pos, bp)); } newline = false; lastNonWhite = bp; - break; + } - default: + default -> { newline = false; lastNonWhite = bp; - break; + } } nextChar(); } @@ -444,10 +437,9 @@ public class DocCommentParser { /** * Read Java class name, possibly followed by member * Matching pairs of {@literal < >} are skipped. The text is terminated by the first - * unmatched }. It is an error if the beginning of the next tag is detected. + * unmatched '}'. It is an error if the beginning of the next tag is detected. */ // TODO: improve quality of parse to forbid bad constructions. - @SuppressWarnings("fallthrough") protected DCReference reference(ReferenceParser.Mode mode) throws ParseException { int pos = bp; int depth = 0; @@ -457,37 +449,37 @@ public class DocCommentParser { loop: while (bp < buflen) { switch (ch) { - case '\n': case '\r': case '\f': - case ' ': case '\t': + + case '\n', '\r', '\f', ' ', '\t' -> { if (depth == 0) break loop; - break; + } - case '(': - case '<': + case '(', '<' -> { newline = false; depth++; - break; + } - case ')': - case '>': + case ')', '>' -> { newline = false; --depth; - break; + } - case '}': + case '}' -> { if (bp == pos) return null; newline = false; break loop; + } - case '@': + case '@' -> { if (newline) break loop; - // fallthrough + } - default: + default -> { newline = false; + } } nextChar(); @@ -534,19 +526,18 @@ public class DocCommentParser { loop: while (bp < buflen) { switch (ch) { - case '\n': case '\r': case '\f': - case ' ': case '\t': - break; + case '\n', '\r', '\f', ' ', '\t' -> { } - case '"': + case '"' -> { nextChar(); // trim trailing white-space? return m.at(pos).newTextTree(newString(pos, bp)); + } - case '@': + case '@' -> { if (newline) break loop; - + } } nextChar(); } @@ -563,24 +554,24 @@ public class DocCommentParser { loop: while (bp < buflen) { switch (ch) { - case '\n': - case '\r': case '\f': case ' ': case '\t': + case '\n', '\r', '\f', ' ', '\t' -> { return m.at(pos).newTextTree(newString(pos, bp)); + } - case '@': + case '@' -> { if (newline) break loop; - break; + } - case '{': + case '{' -> { depth++; - break; + } - case '}': + case '}' -> { if (depth == 0) return m.at(pos).newTextTree(newString(pos, bp)); depth--; - break; + } } newline = false; nextChar(); @@ -590,8 +581,8 @@ public class DocCommentParser { /** * Reads general text content of an inline tag, including HTML entities and elements. - * Matching pairs of { } are skipped; the text is terminated by the first - * unmatched }. It is an error if the beginning of the next tag is detected. + * Matching pairs of '{' '}' are skipped; the text is terminated by the first + * unmatched '}'. It is an error if the beginning of the next tag is detected. */ @SuppressWarnings("fallthrough") private List inlineContent() { @@ -751,7 +742,7 @@ public class DocCommentParser { if (isIdentifierStart(ch)) { String name = StringUtils.toLowerCase(readIdentifier().toString()); switch (name) { - case "body": + case "body" -> { // Check if also followed by
// 1. skip rest of while (bp < buflen && ch != '>') { @@ -777,10 +768,12 @@ public class DocCommentParser { // if is _not_ followed by
then this is the // end of the preamble return true; + } - case "main": + case "main" -> { //
is unconditionally the end of the preamble return true; + } } } return false; @@ -808,9 +801,9 @@ public class DocCommentParser { if (isIdentifierStart(ch)) { String name = StringUtils.toLowerCase(readIdentifier().toString()); switch (name) { - case "body": - case "main": + case "body", "main" -> { return true; + } } } } @@ -867,8 +860,7 @@ public class DocCommentParser { } if (ch == '>') { nextChar(); - DCTree dctree = m.at(p).newStartElementTree(name, attrs, selfClosing).setEndPos(bp); - return dctree; + return m.at(p).newStartElementTree(name, attrs, selfClosing).setEndPos(bp); } } } else if (ch == '/') { @@ -1011,16 +1003,9 @@ public class DocCommentParser { protected void attrValueChar(ListBuffer list) { switch (ch) { - case '&': - entity(list); - break; - - case '{': - inlineTag(list); - break; - - default: - nextChar(); + case '&' -> entity(list); + case '{' -> inlineTag(list); + default -> nextChar(); } } @@ -1064,13 +1049,15 @@ public class DocCommentParser { loop: while (i > pos) { switch (buf[i]) { - case '\f': case '\n': case '\r': + case '\f', '\n', '\r' -> { newline = true; - break; - case '\t': case ' ': - break; - default: + } + + case '\t', ' ' -> { } + + default -> { break loop; + } } i--; } @@ -1146,15 +1133,11 @@ public class DocCommentParser { } protected boolean isUnquotedAttrValueTerminator(char ch) { - switch (ch) { - case '\f': case '\n': case '\r': case '\t': - case ' ': - case '"': case '\'': case '`': - case '=': case '<': case '>': - return true; - default: - return false; - } + return switch (ch) { + case '\f', '\n', '\r', '\t', ' ', + '"', '\'', '`', '=', '<', '>' -> true; + default -> false; + }; } protected boolean isWhitespace(char ch) { @@ -1402,17 +1385,11 @@ public class DocCommentParser { new TagParser(TagParser.Kind.EITHER, DCTree.Kind.RETURN) { @Override public DCTree parse(int pos, Kind kind) { - List description; - switch (kind) { - case BLOCK: - description = blockContent(); - break; - case INLINE: - description = inlineContent(); - break; - default: - throw new IllegalArgumentException(kind.toString()); - } + List description = switch (kind) { + case BLOCK -> blockContent(); + case INLINE -> inlineContent(); + default -> throw new IllegalArgumentException(kind.toString()); + }; return m.at(pos).newReturnTree(kind == Kind.INLINE, description); } }, @@ -1423,7 +1400,7 @@ public class DocCommentParser { public DCTree parse(int pos) throws ParseException { skipWhitespace(); switch (ch) { - case '"': + case '"' -> { DCText string = quotedString(); if (string != null) { skipWhitespace(); @@ -1432,30 +1409,31 @@ public class DocCommentParser { return m.at(pos).newSeeTree(List.of(string)); } } - break; + } - case '<': + case '<' -> { List html = blockContent(); if (html != null) return m.at(pos).newSeeTree(html); - break; + } - case '@': + case '@' -> { if (newline) throw new ParseException("dc.no.content"); - break; + } - case EOI: + case EOI -> { if (bp == buf.length - 1) throw new ParseException("dc.no.content"); - break; + } - default: + default -> { if (isJavaIdentifierStart(ch) || ch == '#') { DCReference ref = reference(ReferenceParser.Mode.MEMBER_OPTIONAL); List description = blockContent(); return m.at(pos).newSeeTree(description.prepend(ref)); } + } } throw new ParseException("dc.unexpected.content"); } @@ -1613,7 +1591,7 @@ public class DocCommentParser { // {@summary summary-text} new TagParser(TagParser.Kind.INLINE, DCTree.Kind.SUMMARY) { @Override - public DCTree parse(int pos) throws ParseException { + public DCTree parse(int pos) { List summary = inlineContent(); return m.at(pos).newSummaryTree(summary); } From 8858d54342bc52c8a2a986e1d35bfa4ddf9470e6 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Mon, 17 Apr 2023 20:17:23 +0000 Subject: [PATCH 013/288] 8305811: (bf) Improve performance of CharBuffer::append(CharSequence[,int,int]) Reviewed-by: alanb --- .../java/nio/Heap-X-Buffer.java.template | 56 ++++++- .../classes/java/nio/X-Buffer.java.template | 9 ++ .../bench/java/nio/CharBufferAppend.java | 141 ++++++++++++++++++ 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java diff --git a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template index 2ead79fc86b..b77e45ee156 100644 --- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -278,6 +278,60 @@ class Heap$Type$Buffer$RW$ #if[char] + // + // Use getChars() to load chars directly into the heap buffer array. + // For a String or StringBuffer source this improves performance if + // a proper subsequence is being appended as copying to a new intermediate + // String object is avoided. For a StringBuilder where either a subsequence + // or the full sequence of chars is being appended, copying the chars to + // an intermedite String in StringBuilder::toString is avoided. + // + private $Type$Buffer appendChars(CharSequence csq, int start, int end) { + checkSession(); + + int length = end - start; + int pos = position(); + int lim = limit(); + int rem = (pos <= lim) ? lim - pos : 0; + if (length > rem) + throw new BufferOverflowException(); + + if (csq instanceof String str) { + str.getChars(start, end, hb, ix(pos)); + } else if (csq instanceof StringBuilder sb) { + sb.getChars(start, end, hb, ix(pos)); + } else if (csq instanceof StringBuffer sb) { + sb.getChars(start, end, hb, ix(pos)); + } + + position(pos + length); + + return this; + } + + public $Type$Buffer append(CharSequence csq) { +#if[rw] + if (csq instanceof StringBuilder) + return appendChars(csq, 0, csq.length()); + + return super.append(csq); +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + + public $Type$Buffer append(CharSequence csq, int start, int end) { +#if[rw] + if (csq instanceof String || csq instanceof StringBuffer || + csq instanceof StringBuilder) + return appendChars(csq, start, end); + + return super.append(csq, start, end); +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + public $Type$Buffer put(String src, int start, int end) { #if[rw] checkSession(); diff --git a/src/java.base/share/classes/java/nio/X-Buffer.java.template b/src/java.base/share/classes/java/nio/X-Buffer.java.template index 6bee52279ca..6c496667d25 100644 --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -2005,6 +2005,8 @@ public abstract sealed class $Type$Buffer public $Type$Buffer append(CharSequence csq) { if (csq == null) return put("null"); + else if (csq instanceof CharBuffer cb) + return put(cb); else return put(csq.toString()); } @@ -2042,6 +2044,13 @@ public abstract sealed class $Type$Buffer * @since 1.5 */ public $Type$Buffer append(CharSequence csq, int start, int end) { + if (csq instanceof CharBuffer cb) { + int pos = position(); + int length = end - start; + put(pos, cb, start, length); + position(pos + length); + return this; + } CharSequence cs = (csq == null ? "null" : csq); return put(cs.subSequence(start, end).toString()); } diff --git a/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java b/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java new file mode 100644 index 00000000000..ea3ef4ab0fe --- /dev/null +++ b/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.nio; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +/** + * Benchmark for {@code CharBuffer} implementations of the {@code Appendable} + * methods which accept a {@code CharSequence} source. + */ +@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Fork(1) +public class CharBufferAppend { + + static final int SIZE = 8192; + + static String str; + static StringBuffer strbuf; + static StringBuilder strbld; + static CharBuffer hbDst; + static CharBuffer hbSrc; + static CharBuffer dbSrc; + static CharBuffer dbDst; + + static { + char[] chars = new char[SIZE]; + Arrays.fill(chars, (char)27); + + strbld = new StringBuilder(SIZE); + strbld.append(chars); + + str = strbld.toString(); + + strbuf = new StringBuffer(SIZE); + strbuf.append(chars); + + hbDst = CharBuffer.allocate(SIZE); + hbSrc = CharBuffer.wrap(chars); + + dbDst = ByteBuffer.allocateDirect(2*SIZE).asCharBuffer(); + dbSrc = ByteBuffer.allocateDirect(2*SIZE).asCharBuffer(); + dbSrc.put(chars); + dbSrc.clear(); + }; + + @Benchmark + public CharBuffer appendDirectToDirect() { + dbDst.clear(); + dbSrc.clear(); + return dbDst.append(dbSrc); + } + + @Benchmark + public CharBuffer appendDirectToHeap() { + hbDst.clear(); + dbSrc.clear(); + return hbDst.append(dbSrc); + } + + @Benchmark + public CharBuffer appendHeapToHeap() { + hbDst.clear(); + hbSrc.clear(); + return hbDst.append(hbSrc); + } + + @Benchmark + public CharBuffer appendHeapToDirect() { + dbDst.clear(); + hbSrc.clear(); + return dbDst.append(hbSrc); + } + + @Benchmark + public CharBuffer appendString() { + hbDst.clear(); + return hbDst.append(str); + } + + @Benchmark + public CharBuffer appendStringBuffer() { + hbDst.clear(); + return hbDst.append(strbuf); + } + + @Benchmark + public CharBuffer appendStringBuilder() { + hbDst.clear(); + return hbDst.append(strbld); + } + + @Benchmark + public CharBuffer appendSubString() { + hbDst.clear(); + return hbDst.append(str, SIZE/4, 3*SIZE/4); + } + + @Benchmark + public CharBuffer appendSubStringBuffer() { + hbDst.clear(); + return hbDst.append(strbuf, SIZE/4, 3*SIZE/4); + } + + @Benchmark + public CharBuffer appendSubStringBuilder() { + hbDst.clear(); + return hbDst.append(strbld, SIZE/4, 3*SIZE/4); + } +} From bb1a7bb3e15096fbdb5d3cc28db09fd486a6ba03 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Mon, 17 Apr 2023 20:40:47 +0000 Subject: [PATCH 014/288] 8305762: FileInputStream and FileOutputStream implSpec should be corrected or removed Reviewed-by: kbarrett, alanb, bpb --- .../classes/java/io/FileInputStream.java | 24 +++++++------------ .../classes/java/io/FileOutputStream.java | 24 +++++++------------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/java.base/share/classes/java/io/FileInputStream.java b/src/java.base/share/classes/java/io/FileInputStream.java index e882946cf74..a1797cf1246 100644 --- a/src/java.base/share/classes/java/io/FileInputStream.java +++ b/src/java.base/share/classes/java/io/FileInputStream.java @@ -41,19 +41,13 @@ import sun.nio.ch.FileChannelImpl; * {@code FileReader}. * * @apiNote - * To release resources used by this stream {@link #close} should be called - * directly or by try-with-resources. Subclasses are responsible for the cleanup - * of resources acquired by the subclass. - * Subclasses that override {@link #finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms such as - * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * The {@link #close} method should be called to release resources used by this + * stream, either directly, or with the {@code try}-with-resources statement. * * @implSpec - * If this FileInputStream has been subclassed and the {@link #close} - * method has been overridden, the {@link #close} method will be - * called when the FileInputStream is unreachable. - * Otherwise, it is implementation specific how the resource cleanup described in - * {@link #close} is performed. + * Subclasses are responsible for the cleanup of resources acquired by the subclass. + * Subclasses requiring that resource cleanup take place after a stream becomes + * unreachable should use {@link java.lang.ref.Cleaner} or some other mechanism. * * @author Arthur van Hoff * @see java.io.File @@ -494,10 +488,10 @@ public class FileInputStream extends InputStream * @apiNote * Overriding {@link #close} to perform cleanup actions is reliable * only when called directly or when called by try-with-resources. - * Do not depend on finalization to invoke {@code close}; - * finalization is not reliable and is deprecated. - * If cleanup of native resources is needed, other mechanisms such as - * {@linkplain java.lang.ref.Cleaner} should be used. + * + * @implSpec + * Subclasses requiring that resource cleanup take place after a stream becomes + * unreachable should use the {@link java.lang.ref.Cleaner} mechanism. * * @throws IOException {@inheritDoc} * diff --git a/src/java.base/share/classes/java/io/FileOutputStream.java b/src/java.base/share/classes/java/io/FileOutputStream.java index 5d2dead569a..9aadf1f38be 100644 --- a/src/java.base/share/classes/java/io/FileOutputStream.java +++ b/src/java.base/share/classes/java/io/FileOutputStream.java @@ -46,19 +46,13 @@ import sun.nio.ch.FileChannelImpl; * {@code FileWriter}. * * @apiNote - * To release resources used by this stream {@link #close} should be called - * directly or by try-with-resources. Subclasses are responsible for the cleanup - * of resources acquired by the subclass. - * Subclasses that override {@link #finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms such as - * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * The {@link #close} method should be called to release resources used by this + * stream, either directly, or with the {@code try}-with-resources statement. * * @implSpec - * If this FileOutputStream has been subclassed and the {@link #close} - * method has been overridden, the {@link #close} method will be - * called when the FileInputStream is unreachable. - * Otherwise, it is implementation specific how the resource cleanup described in - * {@link #close} is performed. + * Subclasses are responsible for the cleanup of resources acquired by the subclass. + * Subclasses requiring that resource cleanup take place after a stream becomes + * unreachable should use {@link java.lang.ref.Cleaner} or some other mechanism. * * @author Arthur van Hoff * @see java.io.File @@ -387,10 +381,10 @@ public class FileOutputStream extends OutputStream * @apiNote * Overriding {@link #close} to perform cleanup actions is reliable * only when called directly or when called by try-with-resources. - * Do not depend on finalization to invoke {@code close}; - * finalization is not reliable and is deprecated. - * If cleanup of native resources is needed, other mechanisms such as - * {@linkplain java.lang.ref.Cleaner} should be used. + * + * @implSpec + * Subclasses requiring that resource cleanup take place after a stream becomes + * unreachable should use the {@link java.lang.ref.Cleaner} mechanism. * * @throws IOException if an I/O error occurs. * From e3ece365ce7dc92dd9d0a7ad9eb53ed9ea87f48d Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Mon, 17 Apr 2023 21:38:46 +0000 Subject: [PATCH 015/288] 8303422: Use common functions to exit the VM for -Xshare:dump and CDS errors Reviewed-by: iklam, coleenp, fparain --- src/hotspot/share/cds/archiveBuilder.cpp | 8 +-- src/hotspot/share/cds/archiveUtils.cpp | 9 ++-- src/hotspot/share/cds/dynamicArchive.cpp | 3 +- src/hotspot/share/cds/filemap.cpp | 54 +++++++------------ src/hotspot/share/cds/filemap.hpp | 2 - src/hotspot/share/cds/heapShared.cpp | 8 +-- src/hotspot/share/cds/metaspaceShared.cpp | 58 ++++++++++++++++----- src/hotspot/share/cds/metaspaceShared.hpp | 4 ++ src/hotspot/share/classfile/stringTable.cpp | 2 +- 9 files changed, 82 insertions(+), 66 deletions(-) diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index f69596dd41e..1a73c4ab2ac 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -331,7 +331,7 @@ address ArchiveBuilder::reserve_buffer() { ReservedSpace rs(buffer_size, MetaspaceShared::core_region_alignment(), os::vm_page_size()); if (!rs.is_reserved()) { log_error(cds)("Failed to reserve " SIZE_FORMAT " bytes of output buffer.", buffer_size); - os::_exit(0); + MetaspaceShared::unrecoverable_writing_error(); } // buffer_bottom is the lowest address of the 2 core regions (rw, ro) when @@ -381,7 +381,7 @@ address ArchiveBuilder::reserve_buffer() { log_error(cds)("my_archive_requested_top = " INTPTR_FORMAT, p2i(my_archive_requested_top)); log_error(cds)("SharedBaseAddress (" INTPTR_FORMAT ") is too high. " "Please rerun java -Xshare:dump with a lower value", p2i(_requested_static_archive_bottom)); - os::_exit(0); + MetaspaceShared::unrecoverable_writing_error(); } if (DumpSharedSpaces) { @@ -1269,8 +1269,8 @@ void ArchiveBuilder::report_out_of_space(const char* name, size_t needed_bytes) _rw_region.print_out_of_space_msg(name, needed_bytes); _ro_region.print_out_of_space_msg(name, needed_bytes); - vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name), - "Please reduce the number of shared classes."); + log_error(cds)("Unable to allocate from '%s' region: Please reduce the number of shared classes.", name); + MetaspaceShared::unrecoverable_writing_error(); } diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 260424fcb37..9f99d1d98fc 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -164,8 +164,8 @@ char* DumpRegion::expand_top_to(char* newtop) { // This is just a sanity check and should not appear in any real world usage. This // happens only if you allocate more than 2GB of shared objects and would require // millions of shared classes. - vm_exit_during_initialization("Out of memory in the CDS archive", - "Please reduce the number of shared classes."); + log_error(cds)("Out of memory in the CDS archive: Please reduce the number of shared classes."); + MetaspaceShared::unrecoverable_writing_error(); } } @@ -190,8 +190,9 @@ void DumpRegion::commit_to(char* newtop) { assert(commit <= uncommitted, "sanity"); if (!_vs->expand_by(commit, false)) { - vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes", - need_committed_size)); + log_error(cds)("Failed to expand shared space to " SIZE_FORMAT " bytes", + need_committed_size); + MetaspaceShared::unrecoverable_writing_error(); } const char* which; diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index e553f6598fd..36728e459c6 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -367,7 +367,8 @@ void DynamicArchive::check_for_dynamic_dump() { #define __THEMSG " is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info." if (RecordDynamicDumpInfo) { - vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo" __THEMSG, nullptr); + log_error(cds)("-XX:+RecordDynamicDumpInfo%s", __THEMSG); + MetaspaceShared::unrecoverable_loading_error(); } else { assert(ArchiveClassesAtExit != nullptr, "sanity"); log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG); diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index da3775d28e2..8a0d55fd105 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -80,29 +80,6 @@ #define O_BINARY 0 // otherwise do nothing. #endif -// Complain and stop. All error conditions occurring during the writing of -// an archive file should stop the process. Unrecoverable errors during -// the reading of the archive file should stop the process. - -static void fail_exit(const char *msg, va_list ap) { - // This occurs very early during initialization: tty is not initialized. - jio_fprintf(defaultStream::error_stream(), - "An error has occurred while processing the" - " shared archive file.\n"); - jio_vfprintf(defaultStream::error_stream(), msg, ap); - jio_fprintf(defaultStream::error_stream(), "\n"); - // Do not change the text of the below message because some tests check for it. - vm_exit_during_initialization("Unable to use shared archive.", nullptr); -} - - -void FileMapInfo::fail_stop(const char *msg, ...) { - va_list ap; - va_start(ap, msg); - fail_exit(msg, ap); // Never returns. - va_end(ap); // for completeness. -} - // Fill in the fileMapInfo structure with data about this VM instance. // This method copies the vm version info into header_version. If the version is too @@ -367,7 +344,8 @@ void SharedClassPathEntry::init(bool is_modules_image, // // If we can't access a jar file in the boot path, then we can't // make assumptions about where classes get loaded from. - FileMapInfo::fail_stop("Unable to open file %s.", cpe->name()); + log_error(cds)("Unable to open file %s.", cpe->name()); + MetaspaceShared::unrecoverable_loading_error(); } // No need to save the name of the module file, as it will be computed at run time @@ -1097,7 +1075,8 @@ bool FileMapInfo::validate_shared_path_table() { const char* hint_msg = log_is_enabled(Info, class, path) ? "" : " (hint: enable -Xlog:class+path=info to diagnose the failure)"; if (RequireSharedSpaces) { - fail_stop("%s%s", mismatch_msg, hint_msg); + log_error(cds)("%s%s", mismatch_msg, hint_msg); + MetaspaceShared::unrecoverable_loading_error(); } else { log_warning(cds)("%s%s", mismatch_msg, hint_msg); } @@ -1447,7 +1426,8 @@ bool FileMapInfo::init_from_file(int fd) { void FileMapInfo::seek_to_position(size_t pos) { if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) { - fail_stop("Unable to seek to position " SIZE_FORMAT, pos); + log_error(cds)("Unable to seek to position %ld", pos); + MetaspaceShared::unrecoverable_loading_error(); } } @@ -1493,8 +1473,9 @@ void FileMapInfo::open_for_write() { remove(_full_path); int fd = os::open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); if (fd < 0) { - fail_stop("Unable to create shared archive file %s: (%s).", _full_path, - os::strerror(errno)); + log_error(cds)("Unable to create shared archive file %s: (%s).", _full_path, + os::strerror(errno)); + MetaspaceShared::unrecoverable_writing_error(); } _fd = fd; _file_open = true; @@ -1731,11 +1712,12 @@ size_t FileMapInfo::write_heap_regions(GrowableArray* regions, int arr_len = regions == nullptr ? 0 : regions->length(); if (arr_len > max_num_regions) { - fail_stop("Unable to write archive heap memory regions: " - "number of memory regions exceeds maximum due to fragmentation. " - "Please increase java heap size " - "(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").", - MaxHeapSize, InitialHeapSize); + log_error(cds)("Unable to write archive heap memory regions: " + "number of memory regions exceeds maximum due to fragmentation. " + "Please increase java heap size " + "(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").", + MaxHeapSize, InitialHeapSize); + MetaspaceShared::unrecoverable_writing_error(); } size_t total_size = 0; @@ -1769,7 +1751,7 @@ void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) { // If the shared archive is corrupted, close it and remove it. close(); remove(_full_path); - fail_stop("Unable to write to shared archive file."); + MetaspaceShared::unrecoverable_writing_error("Unable to write to shared archive file."); } _file_offset += nbytes; } @@ -1810,7 +1792,7 @@ void FileMapInfo::write_bytes_aligned(const void* buffer, size_t nbytes) { void FileMapInfo::close() { if (_file_open) { if (::close(_fd) < 0) { - fail_stop("Unable to close the shared archive file."); + MetaspaceShared::unrecoverable_loading_error("Unable to close the shared archive file."); } _file_open = false; _fd = -1; @@ -2537,7 +2519,7 @@ void FileMapInfo::unmap_region(int i) { void FileMapInfo::assert_mark(bool check) { if (!check) { - fail_stop("Mark mismatch while restoring from shared file."); + MetaspaceShared::unrecoverable_loading_error("Mark mismatch while restoring from shared file."); } } diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 0a21613e300..b415ec6c0d3 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -482,8 +482,6 @@ public: // Remap the shared readonly space to shared readwrite, private. bool remap_shared_readonly_as_readwrite(); - // Errors. - static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2); static bool memory_mapping_failed() { CDS_ONLY(return _memory_mapping_failed;) NOT_CDS(return false;) diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 1ef4ea67734..cc04f61d0c2 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -735,7 +735,7 @@ void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) { ResourceMark rm; log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s", ik->external_name(), extra_msg); - os::_exit(1); + MetaspaceShared::unrecoverable_writing_error(); } bool KlassSubGraphInfo::is_non_early_klass(Klass* k) { @@ -1213,7 +1213,7 @@ bool HeapShared::archive_reachable_objects_from(int level, // these objects that are referenced (directly or indirectly) by static fields. ResourceMark rm; log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name()); - os::_exit(1); + MetaspaceShared::unrecoverable_writing_error(); } // java.lang.Class instances cannot be included in an archived object sub-graph. We only support @@ -1223,7 +1223,7 @@ bool HeapShared::archive_reachable_objects_from(int level, // object that is referenced (directly or indirectly) by static fields. if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _default_subgraph_info) { log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level); - os::_exit(1); + MetaspaceShared::unrecoverable_writing_error(); } if (has_been_seen_during_subgraph_recording(orig_obj)) { @@ -1252,7 +1252,7 @@ bool HeapShared::archive_reachable_objects_from(int level, // We don't know how to handle an object that has been archived, but some of its reachable // objects cannot be archived. Bail out for now. We might need to fix this in the future if // we have a real use case. - os::_exit(1); + MetaspaceShared::unrecoverable_writing_error(); } } } diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 2e762d29a31..a874668035f 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -267,8 +267,8 @@ void MetaspaceShared::initialize_for_static_dump() { size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M); _symbol_rs = ReservedSpace(symbol_rs_size); if (!_symbol_rs.is_reserved()) { - vm_exit_during_initialization("Unable to reserve memory for symbols", - err_msg(SIZE_FORMAT " bytes.", symbol_rs_size)); + log_error(cds)("Unable to reserve memory for symbols: %ld bytes.", symbol_rs_size); + MetaspaceShared::unrecoverable_writing_error(); } _symbol_region.init(&_symbol_rs, &_symbol_vs); } @@ -309,7 +309,8 @@ void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename) ResourceMark rm(current); if (utf8_length == 0x7fffffff) { // buf_len will overflown 32-bit value. - vm_exit_during_initialization(err_msg("string length too large: %d", utf8_length)); + log_error(cds)("string length too large: %d", utf8_length); + MetaspaceShared::unrecoverable_loading_error(); } int buf_len = utf8_length+1; char* utf8_buffer = NEW_RESOURCE_ARRAY(char, buf_len); @@ -564,10 +565,7 @@ void VM_PopulateDumpSharedSpace::doit() { "for testing purposes only and should not be used in a production environment"); } - // There may be pending VM operations. We have changed some global states - // (such as vmClasses::_klasses) that may cause these VM operations - // to fail. For safety, forget these operations and exit the VM directly. - os::_exit(0); + MetaspaceShared::exit_after_static_dump(); } class CollectCLDClosure : public CLDClosure { @@ -677,12 +675,13 @@ void MetaspaceShared::preload_and_dump() { preload_and_dump_impl(THREAD); if (HAS_PENDING_EXCEPTION) { if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) { - vm_direct_exit(-1, err_msg("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " - SIZE_FORMAT "M", MaxHeapSize/M)); + log_error(cds)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " + SIZE_FORMAT "M", MaxHeapSize/M); + MetaspaceShared::unrecoverable_writing_error(); } else { log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), java_lang_String::as_utf8_string(java_lang_Throwable::message(PENDING_EXCEPTION))); - vm_direct_exit(-1, "VM exits due to exception, use -Xlog:cds,exceptions=trace for detail"); + MetaspaceShared::unrecoverable_writing_error("VM exits due to exception, use -Xlog:cds,exceptions=trace for detail"); } } else { // On success, the VM_PopulateDumpSharedSpace op should have @@ -902,6 +901,37 @@ bool MetaspaceShared::is_shared_dynamic(void* p) { } } +// This function is called when the JVM is unable to load the specified archive(s) due to one +// of the following conditions. +// - There's an error that indicates that the archive(s) files were corrupt or otherwise damaged. +// - When -XX:+RequireSharedSpaces is specified, AND the JVM cannot load the archive(s) due +// to version or classpath mismatch. +void MetaspaceShared::unrecoverable_loading_error(const char* message) { + log_error(cds)("An error has occurred while processing the shared archive file."); + if (message != nullptr) { + log_error(cds)("%s", message); + } + vm_exit_during_initialization("Unable to use shared archive.", nullptr); +} + +// This function is called when the JVM is unable to write the specified CDS archive due to an +// unrecoverable error. +void MetaspaceShared::unrecoverable_writing_error(const char* message) { + log_error(cds)("An error has occurred while writing the shared archive file."); + if (message != nullptr) { + log_error(cds)("%s", message); + } + vm_exit(1); +} + +// We have finished dumping the static archive. At this point, there may be pending VM +// operations. We have changed some global states (such as vmClasses::_klasses) that +// may cause these VM operations to fail. For safety, forget these operations and +// exit the VM directly. +void MetaspaceShared::exit_after_static_dump() { + os::_exit(0); +} + void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled"); MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE; @@ -950,9 +980,9 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { DynamicDumpSharedSpaces = false; log_info(cds)("Unable to map shared spaces"); if (PrintSharedArchiveAndExit) { - vm_exit_during_initialization("Unable to use shared archive."); + MetaspaceShared::unrecoverable_loading_error("Unable to use shared archive."); } else if (RequireSharedSpaces) { - FileMapInfo::fail_stop("Unable to map shared spaces"); + MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces"); } } @@ -967,7 +997,7 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { delete dynamic_mapinfo; } if (RequireSharedSpaces && has_failed) { - FileMapInfo::fail_stop("Unable to map shared spaces"); + MetaspaceShared::unrecoverable_loading_error("Unable to map shared spaces"); } } @@ -995,7 +1025,7 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() { if (!mapinfo->initialize()) { delete(mapinfo); if (RequireSharedSpaces) { - FileMapInfo::fail_stop("Failed to initialize dynamic archive"); + MetaspaceShared::unrecoverable_loading_error("Failed to initialize dynamic archive"); } return nullptr; } diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index 9c79cb17a36..9e410b257c4 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -116,6 +116,10 @@ public: static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false); + static void unrecoverable_loading_error(const char* message = nullptr); + static void unrecoverable_writing_error(const char* message = nullptr); + static void exit_after_static_dump(); + static void serialize(SerializeClosure* sc) NOT_CDS_RETURN; // JVM/TI RedefineClasses() support: diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index f84491ce06a..8db4c08c966 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -797,7 +797,7 @@ void StringTable::allocate_shared_strings_array(TRAPS) { // refer to more than 16384 * 16384 = 26M interned strings! Not a practical concern // but bail out for safety. log_error(cds)("Too many strings to be archived: " SIZE_FORMAT, _items_count); - os::_exit(1); + MetaspaceShared::unrecoverable_writing_error(); } objArrayOop primary = oopFactory::new_objArray(vmClasses::Object_klass(), primary_array_length, CHECK); From 445ebef4371569b574af698138dccb159ce95602 Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Tue, 18 Apr 2023 06:59:51 +0000 Subject: [PATCH 016/288] 8305668: PPC: Non-Top Interpreted frames should be independent of ABI_ELFv2 Reviewed-by: mdoerr --- .../cpu/ppc/abstractInterpreter_ppc.cpp | 18 ++--- src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp | 4 +- src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp | 18 ++--- src/hotspot/cpu/ppc/continuationEntry_ppc.hpp | 4 +- .../ppc/continuationFreezeThaw_ppc.inline.hpp | 76 +++++++++---------- .../cpu/ppc/continuationHelper_ppc.inline.hpp | 6 +- src/hotspot/cpu/ppc/frame_ppc.cpp | 6 +- src/hotspot/cpu/ppc/frame_ppc.hpp | 74 +++++++++--------- .../ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp | 6 +- .../cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp | 6 +- src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp | 6 +- src/hotspot/cpu/ppc/macroAssembler_ppc.cpp | 10 +-- src/hotspot/cpu/ppc/macroAssembler_ppc.hpp | 4 +- src/hotspot/cpu/ppc/methodHandles_ppc.cpp | 6 +- src/hotspot/cpu/ppc/ppc.ad | 2 +- src/hotspot/cpu/ppc/runtime_ppc.cpp | 4 +- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 22 +++--- .../ppc/stackChunkFrameStream_ppc.inline.hpp | 6 +- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 12 +-- .../ppc/templateInterpreterGenerator_ppc.cpp | 4 +- .../share/runtime/continuationFreezeThaw.cpp | 2 +- 21 files changed, 148 insertions(+), 148 deletions(-) diff --git a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp index 3280330f1d0..56f8fce5ce9 100644 --- a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp +++ b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015 SAP SE. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -57,7 +57,7 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) { // Note: This returns the conservative size assuming maximum alignment. int AbstractInterpreter::size_top_interpreter_activation(Method* method) { const int max_alignment_size = 2; - const int abi_scratch = frame::abi_reg_args_size; + const int abi_scratch = frame::top_ijava_frame_abi_size; return method->max_locals() + method->max_stack() + frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch; } @@ -76,8 +76,8 @@ int AbstractInterpreter::size_activation(int max_stack, // in TemplateInterpreterGenerator::generate_fixed_frame. assert(Interpreter::stackElementWords == 1, "sanity"); const int max_alignment_space = StackAlignmentInBytes / Interpreter::stackElementSize; - const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) : - (frame::abi_minframe_size / Interpreter::stackElementSize); + const int abi_scratch = is_top_frame ? (frame::top_ijava_frame_abi_size / Interpreter::stackElementSize) : + (frame::parent_ijava_frame_abi_size / Interpreter::stackElementSize); const int size = max_stack + (callee_locals - callee_params) + @@ -122,20 +122,20 @@ void AbstractInterpreter::layout_activation(Method* method, bool is_top_frame, bool is_bottom_frame) { - const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) : - (frame::abi_minframe_size / Interpreter::stackElementSize); + const int abi_scratch = is_top_frame ? (frame::top_ijava_frame_abi_size / Interpreter::stackElementSize) : + (frame::parent_ijava_frame_abi_size / Interpreter::stackElementSize); intptr_t* locals_base = (caller->is_interpreted_frame()) ? caller->interpreter_frame_esp() + caller_actual_parameters : - caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize); + caller->sp() + method->max_locals() - 1 + (frame::java_abi_size / Interpreter::stackElementSize); intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize; intptr_t* monitor = monitor_base - (moncount * frame::interpreter_frame_monitor_size()); intptr_t* esp_base = monitor - 1; intptr_t* esp = esp_base - tempcount - popframe_extra_args; intptr_t* sp = (intptr_t *) (((intptr_t) (esp_base - callee_locals_count + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes); - intptr_t* sender_sp = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; - intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize; + intptr_t* sender_sp = caller->sp() + (frame::parent_ijava_frame_abi_size - frame::top_ijava_frame_abi_size) / Interpreter::stackElementSize; + intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::parent_ijava_frame_abi_size - frame::top_ijava_frame_abi_size) / Interpreter::stackElementSize; interpreter_frame->interpreter_frame_set_method(method); interpreter_frame->interpreter_frame_set_mirror(method->method_holder()->java_mirror()); diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index dd78a3d492f..4f48f7efe50 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -1834,7 +1834,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // Set up the arraycopy stub information. ArrayCopyStub* stub = op->stub(); - const int frame_resize = frame::abi_reg_args_size - sizeof(frame::jit_abi); // C calls need larger frame. + const int frame_resize = frame::native_abi_reg_args_size - sizeof(frame::java_abi); // C calls need larger frame. // Always do stub if no type information is available. It's ok if // the known type isn't loaded since the code sanity checks diff --git a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp index b3b68034e7a..348de609901 100644 --- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -153,7 +153,7 @@ static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs]; static int frame_size_in_bytes = -1; static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) { - assert(frame_size_in_bytes > frame::abi_reg_args_size, "init"); + assert(frame_size_in_bytes > frame::native_abi_reg_args_size, "init"); sasm->set_frame_size(frame_size_in_bytes / BytesPerWord); int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); OopMap* oop_map = new OopMap(frame_size_in_slots, 0); @@ -241,7 +241,7 @@ static void restore_live_registers(StubAssembler* sasm, Register result1, Regist void Runtime1::initialize_pd() { int i; - int sp_offset = frame::abi_reg_args_size; + int sp_offset = frame::native_abi_reg_args_size; for (i = 0; i < FrameMap::nof_cpu_regs; i++) { Register r = as_Register(i); @@ -487,9 +487,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ mflr(R0); __ std(R0, _abi0(lr), R1_SP); - __ push_frame(frame::abi_reg_args_size, R0); // Empty dummy frame (no callee-save regs). - sasm->set_frame_size(frame::abi_reg_args_size / BytesPerWord); - OopMap* oop_map = new OopMap(frame::abi_reg_args_size / sizeof(jint), 0); + __ push_frame(frame::native_abi_reg_args_size, R0); // Empty dummy frame (no callee-save regs). + sasm->set_frame_size(frame::native_abi_reg_args_size / BytesPerWord); + OopMap* oop_map = new OopMap(frame::native_abi_reg_args_size / sizeof(jint), 0); int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), R3_ARG1); oop_maps = new OopMapSet(); @@ -732,9 +732,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ set_info("unimplemented entry", dont_gc_arguments); __ mflr(R0); __ std(R0, _abi0(lr), R1_SP); - __ push_frame(frame::abi_reg_args_size, R0); // empty dummy frame - sasm->set_frame_size(frame::abi_reg_args_size / BytesPerWord); - OopMap* oop_map = new OopMap(frame::abi_reg_args_size / sizeof(jint), 0); + __ push_frame(frame::native_abi_reg_args_size, R0); // empty dummy frame + sasm->set_frame_size(frame::native_abi_reg_args_size / BytesPerWord); + OopMap* oop_map = new OopMap(frame::native_abi_reg_args_size / sizeof(jint), 0); __ load_const_optimized(R4_ARG2, (int)id); int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), R4_ARG2); diff --git a/src/hotspot/cpu/ppc/continuationEntry_ppc.hpp b/src/hotspot/cpu/ppc/continuationEntry_ppc.hpp index ae912b15cee..5928c2ef254 100644 --- a/src/hotspot/cpu/ppc/continuationEntry_ppc.hpp +++ b/src/hotspot/cpu/ppc/continuationEntry_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 SAP SE. All rights reserved. + * Copyright (c) 2022, 2023 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 @@ -29,7 +29,7 @@ class ContinuationEntryPD { // This is needed to position the ContinuationEntry at the unextended sp of the entry frame - frame::abi_reg_args _abi; + frame::native_abi_reg_args _abi; }; #endif // CPU_PPC_CONTINUATIONENTRY_PPC_HPP diff --git a/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp index 0bef7b68d07..285ffcdaf0e 100644 --- a/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp @@ -131,7 +131,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // // Caller on entry New frame with resized Caller // -// | frame::abi_minframe | | | +// | frame::java_abi | | | // | |<- FP of caller | Caller's SP |<- FP of caller // ========================== ========================== // | ijava_state | | ijava_state | @@ -141,9 +141,9 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | : | | | : : | // | Pn |<- unext. SP | | : Pn |<- unext. SP // |------------------------| + metadata overlap | : | + metadata -// | frame::abi_minframe | | | Lm | +// | frame::java_abi | | | Lm | // | (metadata_words_at_top)|<- SP == unext. SP v |------------------------|<- unextended SP of caller (1) -// ========================== of caller ----- | frame::abi_minframe | +// ========================== of caller ----- | frame::java_abi | // | (metadata_words_at_top)|<- new SP of caller / FP of new frame // overlap = stack_argsize(f) ========================== ^ // + frame::metadata_words_at_top | ijava_state | | @@ -154,7 +154,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | : | | // | Growth | | Pi | v // v v |------------------------| --- -// | frame::abi_minframe | +// | frame::java_abi | // | (metadata_words_at_top)|<- unextended SP / // ========================== SP of new frame // ### Compiled Caller: No Overlap @@ -164,13 +164,13 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // // Caller on entry New frame with resized Caller // -// | frame::abi_minframe | | | +// | frame::java_abi | | | // | (metadata_words_at_top)|<- FP of caller | Caller's SP |<- FP of caller // ========================== ========================== // | | | | // | | | | // |------------------------| |------------------------| -// | frame::abi_minframe | | frame::abi_minframe | +// | frame::java_abi | | frame::java_abi | // | (metadata_words_at_top)|<- SP == unext. SP | (metadata_words_at_top)|<- unext. SP of caller // ========================== of caller |------------------------| // | L0 aka P0 | @@ -178,7 +178,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | : Pn | // overlap = 0 | Lm | // |------------------------| -// f is the frame to be relocated on the heap | frame::abi_minframe | +// f is the frame to be relocated on the heap | frame::java_abi | // | (metadata_words_at_top)|<- new SP of caller / FP of new frame // ========================== ^ // | ijava_state | | @@ -189,7 +189,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | : | | // | Pi | v // |------------------------| --- -// | frame::abi_minframe | +// | frame::java_abi | // | (metadata_words_at_top)|<- unextended SP / // ========================== SP of new frame // @@ -209,7 +209,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // // Caller on entry New frame with resized Caller // -// | frame::abi_minframe | | frame::abi_minframe | +// | frame::java_abi | | frame::java_abi | // | (metadata_words_at_top)|<- FP of caller | (metadata_words_at_top)|<- FP of caller // ========================== ========================== // | ijava_state | | ijava_state | @@ -219,19 +219,19 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | : | | : | // | Pn |<- unext. SP | Pn |<- unext. SP // |------------------------| + metadata |------------------------| + metadata -// | frame::abi_minframe | | frame::abi_minframe | +// | frame::java_abi | | frame::java_abi | // | (metadata_words_at_top)|<- SP == unext. SP | (metadata_words_at_top)|<- unextended SP of caller (1) // ========================== of caller |------------------------| // | Stack Args | // overlap = 0 | (if any) | // |------------------------| -// f is the frame to be relocated on the heap | frame::abi_minframe | +// f is the frame to be relocated on the heap | frame::java_abi | // | (metadata_words_at_top)|<- new SP of caller / FP of new frame // ========================== // | | // | Growth | | | // v v |------------------------| -// | frame::abi_minframe | +// | frame::java_abi | // | (metadata_words_at_top)|<- SP == unext. SP of new frame // ========================== // @@ -239,7 +239,7 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // // Caller on entry New frame with resized Caller // -// | frame::abi_minframe | | frame::abi_minframe | +// | frame::java_abi | | frame::java_abi | // | (metadata_words_at_top)|<- FP of caller | (metadata_words_at_top)|<- FP of caller // ========================== ========================== // | | | | @@ -248,13 +248,13 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) { // | Stack Args | ^ | Stack Args | // | (if any) | | | (if any) | // |------------------------| overlap |------------------------| -// | frame::abi_minframe | | | frame::abi_minframe | +// | frame::java_abi | | | frame::java_abi | // | (metadata_words_at_top)|<- SP == unext. SP v | (metadata_words_at_top)|<- SP == unext. SP of caller // ========================== of caller ----- ========================== / FP of new frame // | | // overlap = stack_argsize(f) | | // + frame::metadata_words_at_top |------------------------| -// | frame::abi_minframe | +// | frame::java_abi | // Where f is the frame to be relocated on the heap. | (metadata_words_at_top)|<- SP == unext. SP of new frame // See also StackChunkFrameStream::frame_size(). ========================== // @@ -346,7 +346,7 @@ inline void ThawBase::prefetch_chunk_pd(void* start, int size) { template inline void Thaw::patch_caller_links(intptr_t* sp, intptr_t* bottom) { for (intptr_t* callers_sp; sp < bottom; sp = callers_sp) { - address pc = (address)((frame::abi_minframe*) sp)->lr; + address pc = (address)((frame::java_abi*) sp)->lr; assert(pc != nullptr, ""); // see ThawBase::patch_return() which gets called just before bool is_entry_frame = pc == StubRoutines::cont_returnBarrier() || pc == _cont.entryPC(); @@ -357,7 +357,7 @@ inline void Thaw::patch_caller_links(intptr_t* sp, intptr_t* bottom) { callers_sp = sp + cb->frame_size(); } // set the back link - ((frame::abi_minframe*) sp)->callers_sp = (intptr_t) callers_sp; + ((frame::java_abi*) sp)->callers_sp = (intptr_t) callers_sp; } } @@ -376,29 +376,29 @@ inline frame ThawBase::new_entry_frame() { // // | | Non-Interpreted | | // | |<- bottom Caller |----------------------| -// |----------------------| ^ | frame::abi_minframe |<- unextended SP +// |----------------------| ^ | frame::java_abi |<- unextended SP // | L0 aka P0 | | --- ======================== // | : : | | ^ | L0 aka P0 | // | : Pn | | | | : : | Parameters do // | : | | | | : Pn | not overlap with // | Lm | | | | : | caller! // |----------------------| `fsize` | | : | -// | frame::abi_minframe | | | : | +// | frame::java_abi | | | : | // ======================== | `fsize` + padding | Lm | // | | | |----------------------| // | ijava_state | | | | Opt. Align. Padding | // | | | | |----------------------| -// |----------------------| | | | frame::abi_minframe |<- new SP of caller +// |----------------------| | | | frame::java_abi |<- new SP of caller // | L0 aka P0 | | | ======================== / FP of new frame // | : : | | | | | (aligned) // | : Pn |<- unext. SP + metadata | | ijava_state | // | : | | | | | // | Lm | | | |----------------------| // |----------------------| v | | P0 | -// | frame::abi_minframe |<- SP / unextended SP | | : | +// | frame::java_abi |<- SP / unextended SP | | : | // ======================== | | Pi |<- unextended SP + metadata // | |----------------------| -// | Growth | v | frame::abi_minframe |<- unextended SP / SP of new frame +// | Growth | v | frame::java_abi |<- unextended SP / SP of new frame // v v --- ======================== (not yet aligned(1)) // // @@ -415,13 +415,13 @@ inline frame ThawBase::new_entry_frame() { // | : | | | | : : | // | Pn |<- unextended SP overlap | | : Pn |<- unextended SP // |----------------------| + metadata_words_at_top | | | : | + metadata_words_at_top -// | frame::abi_minframe |<- unextended SP v | | : | (unaligned) +// | frame::java_abi |<- unextended SP v | | : | (unaligned) // ======================== / SP of new frame --- | | : | of caller // (not yet aligned(1)) | | Lm | // `fsize` |----------------------| // overlap = stack_argsize(hf) + padding| Opt. Align. Padding | // + frame::metadata_words_at_top | |----------------------| -// | | frame::abi_minframe |<- new SP of caller +// | | frame::java_abi |<- new SP of caller // | ======================== / FP of new frame // | | | (aligned) // | Growth | | | ijava_state | @@ -431,7 +431,7 @@ inline frame ThawBase::new_entry_frame() { // | | : | // | | Pi |<- unextended SP // | |----------------------| + metadata_words_at_top -// v | frame::abi_minframe |<- unextended SP / SP of new frame +// v | frame::java_abi |<- unextended SP / SP of new frame // --- ======================== (not yet aligned(1)) // // @@ -459,20 +459,20 @@ inline frame ThawBase::new_entry_frame() { // g l |----------------------| | | // i e | Stack Args | | | // n r | (if any) | |----------------------| -// a |----------------------| | frame::abi_minframe | -// l | frame::abi_minframe |<- unext. SP / SP | (unused) |<- unal.unext.SP +// a |----------------------| | frame::java_abi | +// l | frame::java_abi |<- unext. SP / SP | (unused) |<- unal.unext.SP // - - - ======================== - - - - - - - - - - |----------------------|- - - - - - - - - - - - - - - - - - - - - - - - - - - - // N | | | Opt. Align. Padding | // e | | |----------------------| // w |----------------------| | Stack Args | -// | frame::abi_minframe |<- unext. SP / SP | (if any) | +// | frame::java_abi |<- unext. SP / SP | (if any) | // F ======================== |----------------------| -// r | frame::abi_minframe |<- caller's SP +// r | frame::java_abi |<- caller's SP // a ======================== / new frame's FP // m | | (aligned) // e | | // |----------------------| -// | frame::abi_minframe |<- unext. SP / SP +// | frame::java_abi |<- unext. SP / SP // ======================== // // If the new frame is at the bottom just above the ContinuationEntry frame then the stackargs @@ -582,8 +582,8 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) { // - Note that unextended SP < SP // is possible on ppc. // -// | Minimal ABI | | Minimal ABI | | Minimal ABI | -// | (frame::abi_minframe)| | (frame::abi_minframe)| | (frame::abi_minframe)| +// | | | | | | +// | (frame::java_abi) | | (frame::java_abi) | | (frame::java_abi) | // | 4 words | | 4 words | | 4 words | // | Caller's SP |<- FP of caller | Caller's SP |<- FP of caller | Caller's SP |<- FP of caller // ======================== (aligned) ======================== ======================== @@ -599,13 +599,13 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) { // | Reserved Expr. Stack | |----------------------| |----------------------| // | | | Opt. Alignm. Padding | | Opt. Alignm. Padding | // | |<- ConstMethod |----------------------| |----------------------| -// |----------------------| ::_max_stack | Minimal ABI | | Minimal ABI | -// | Opt. Alignm. Padding | | (frame::abi_minframe)| | (frame::abi_minframe)| +// |----------------------| ::_max_stack | | | | +// | Opt. Alignm. Padding | | (frame::java_abi) | | (frame::java_abi) | // |----------------------| | 4 words | | 4 words | // | Large ABI | | Caller's SP |<- new SP of caller | Caller's SP |<- SP of caller / // | for C++ calls | ======================== (aligned) ======================== FP of callee -// | (frame::abi_reg_args)| | frame:: | (aligned) -// | | | ijava_state | +// | (frame:: | | frame:: | (aligned) +// | native_abi_reg_args)| | ijava_state | // | | | | // | | |----------------------| // | | | | @@ -621,8 +621,8 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) { // --------------------> ------------------------> |----------------------| // (ABI, expressions, locals) | Large ABI | // | for C++ calls | -// | (frame::abi_reg_args)| -// | | +// | (frame:: | +// | native_abi_reg_args)| // | Growth | | | // v v | | // | | diff --git a/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp b/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp index f2a1ef828c9..3fb56b6703b 100644 --- a/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp @@ -107,7 +107,7 @@ inline void ContinuationHelper::Frame::patch_pc(const frame& f, address pc) { } // | Minimal ABI | -// | (frame::abi_minframe)| +// | (frame::java_abi) | // | 4 words | // | Caller's SP |<- FP of f's caller // |======================| @@ -124,7 +124,7 @@ inline void ContinuationHelper::Frame::patch_pc(const frame& f, address pc) { // | SP alignment (opt.) | // |----------------------| // | Minimal ABI | -// | (frame::abi_minframe)| +// | (frame::java_abi) | // | 4 words | // | Caller's SP |<- SP of f's caller / FP of f // |======================| @@ -145,7 +145,7 @@ inline void ContinuationHelper::Frame::patch_pc(const frame& f, address pc) { // | SP alignment (opt.) | // |----------------------| // | Minimal ABI | -// | (frame::abi_minframe)| +// | (frame::java_abi) | // | 4 words | // | Caller's SP |<- SP of f / FP of f's callee // |======================| diff --git a/src/hotspot/cpu/ppc/frame_ppc.cpp b/src/hotspot/cpu/ppc/frame_ppc.cpp index 0657da07deb..90fcbad8f27 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.cpp +++ b/src/hotspot/cpu/ppc/frame_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -117,7 +117,7 @@ bool frame::safe_for_sender(JavaThread *thread) { return false; } - abi_minframe* sender_abi = (abi_minframe*) fp; + common_abi* sender_abi = (common_abi*) fp; intptr_t* sender_sp = (intptr_t*) fp; address sender_pc = (address) sender_abi->lr;; @@ -291,7 +291,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const { if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { return false; } - int min_frame_slots = (abi_minframe_size + ijava_state_size) / sizeof(intptr_t); + int min_frame_slots = (parent_ijava_frame_abi_size + ijava_state_size) / sizeof(intptr_t); if (fp() - min_frame_slots < sp()) { return false; } diff --git a/src/hotspot/cpu/ppc/frame_ppc.hpp b/src/hotspot/cpu/ppc/frame_ppc.hpp index 76a5d27a7a7..a4ec15d5aa0 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.hpp +++ b/src/hotspot/cpu/ppc/frame_ppc.hpp @@ -62,16 +62,16 @@ // ... // spill slot for FR // - // ABI_48: + // ABI_MINFRAME: // 0 caller's SP // 8 space for condition register (CR) for next call // 16 space for link register (LR) for next call - // 24 reserved - // 32 reserved + // 24 reserved (ABI_ELFv2 only) + // 32 reserved (ABI_ELFv2 only) // 40 space for TOC (=R2) register for next call // // ABI_REG_ARGS: - // 0 [ABI_48] + // 0 [ABI_MINFRAME] // 48 CARG_1: spill slot for outgoing arg 1. used by next callee. // ... ... // 104 CARG_8: spill slot for outgoing arg 8. used by next callee. @@ -82,11 +82,15 @@ // C frame layout static const int alignment_in_bytes = 16; - // ABI_MINFRAME: - struct abi_minframe { + // Common ABI. On top of all frames, C and Java + struct common_abi { uint64_t callers_sp; - uint64_t cr; //_16 + uint64_t cr; uint64_t lr; + }; + + // ABI_MINFRAME. Used for native C frames. + struct native_abi_minframe : common_abi { #if !defined(ABI_ELFv2) uint64_t reserved1; //_16 uint64_t reserved2; @@ -96,11 +100,7 @@ // aligned to frame::alignment_in_bytes (16) }; - enum { - abi_minframe_size = sizeof(abi_minframe) - }; - - struct abi_reg_args : abi_minframe { + struct native_abi_reg_args : native_abi_minframe { uint64_t carg_1; uint64_t carg_2; //_16 uint64_t carg_3; @@ -113,13 +113,14 @@ }; enum { - abi_reg_args_size = sizeof(abi_reg_args) + native_abi_minframe_size = sizeof(native_abi_minframe), + native_abi_reg_args_size = sizeof(native_abi_reg_args) }; #define _abi0(_component) \ - (offset_of(frame::abi_reg_args, _component)) + (offset_of(frame::native_abi_reg_args, _component)) - struct abi_reg_args_spill : abi_reg_args { + struct native_abi_reg_args_spill : native_abi_reg_args { // additional spill slots uint64_t spill_ret; uint64_t spill_fret; //_16 @@ -127,11 +128,11 @@ }; enum { - abi_reg_args_spill_size = sizeof(abi_reg_args_spill) + native_abi_reg_args_spill_size = sizeof(native_abi_reg_args_spill) }; - #define _abi_reg_args_spill(_component) \ - (offset_of(frame::abi_reg_args_spill, _component)) + #define _native_abi_reg_args_spill(_component) \ + (offset_of(frame::native_abi_reg_args_spill, _component)) // non-volatile GPRs: @@ -186,6 +187,10 @@ // Frame layout for the Java template interpreter on PPC64. // + // We differnetiate between TOP and PARENT frames. + // TOP frames allow for calling native C code. + // A TOP frame is trimmed to a PARENT frame when calling a Java method. + // // In these figures the stack grows upwards, while memory grows // downwards. Square brackets denote regions possibly larger than // single 64 bit slots. @@ -227,20 +232,23 @@ // [outgoing arguments] // [ENTRY_FRAME_LOCALS] - struct parent_ijava_frame_abi : abi_minframe { + // ABI for every Java frame, compiled and interpreted + struct java_abi : common_abi { + uint64_t toc; }; - enum { - parent_ijava_frame_abi_size = sizeof(parent_ijava_frame_abi) + struct parent_ijava_frame_abi : java_abi { }; #define _parent_ijava_frame_abi(_component) \ (offset_of(frame::parent_ijava_frame_abi, _component)) - struct top_ijava_frame_abi : abi_reg_args { + struct top_ijava_frame_abi : native_abi_reg_args { }; enum { + java_abi_size = sizeof(java_abi), + parent_ijava_frame_abi_size = sizeof(parent_ijava_frame_abi), top_ijava_frame_abi_size = sizeof(top_ijava_frame_abi) }; @@ -318,18 +326,10 @@ // [in_preserve] added / removed by prolog / epilog // - // JIT_ABI (TOP and PARENT) + // For JIT frames we don't differentiate between TOP and PARENT frames. + // Runtime calls go through stubs which push a new frame. - struct jit_abi { - uint64_t callers_sp; - uint64_t cr; - uint64_t lr; - uint64_t toc; - // Nothing to add here! - // NOT ALIGNED to frame::alignment_in_bytes (16). - }; - - struct jit_out_preserve : jit_abi { + struct jit_out_preserve : java_abi { // Nothing to add here! }; @@ -390,8 +390,8 @@ void mark_not_fully_initialized() const { DEBUG_ONLY(own_abi()->callers_sp = NOT_FULLY_INITIALIZED;) } // Accessors for ABIs - inline abi_minframe* own_abi() const { return (abi_minframe*) _sp; } - inline abi_minframe* callers_abi() const { return (abi_minframe*) _fp; } + inline common_abi* own_abi() const { return (common_abi*) _sp; } + inline common_abi* callers_abi() const { return (common_abi*) _fp; } private: @@ -439,14 +439,14 @@ // normal return address is 1 bundle past PC pc_return_offset = 0, // size, in words, of frame metadata (e.g. pc and link) - metadata_words = sizeof(abi_minframe) >> LogBytesPerWord, + metadata_words = sizeof(java_abi) >> LogBytesPerWord, // size, in words, of metadata at frame bottom, i.e. it is not part of the // caller/callee overlap metadata_words_at_bottom = 0, // size, in words, of frame metadata at the frame top, i.e. it is located // between a callee frame and its stack arguments, where it is part // of the caller/callee overlap - metadata_words_at_top = sizeof(abi_minframe) >> LogBytesPerWord, + metadata_words_at_top = sizeof(java_abi) >> LogBytesPerWord, // size, in words, of frame metadata at the frame top that needs // to be reserved for callee functions in the runtime frame_alignment = 16, diff --git a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp index ac988dcad1b..cd2fd355bbb 100644 --- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2021 SAP SE. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -54,7 +54,7 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm int spill_slots = 3; if (preserve1 != noreg) { spill_slots++; } if (preserve2 != noreg) { spill_slots++; } - const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes); + const int frame_size = align_up(frame::native_abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes); Label filtered; // Is marking active? @@ -98,7 +98,7 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve) { int spill_slots = (preserve != noreg) ? 1 : 0; - const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes); + const int frame_size = align_up(frame::native_abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes); __ save_LR_CR(R0); __ push_frame(frame_size, R0); diff --git a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp index 64c32337e1a..84042505089 100644 --- a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2021, 2022 SAP SE. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -411,7 +411,7 @@ class ZSaveLiveRegisters { const int register_save_size = iterate_over_register_mask(ACTION_COUNT_ONLY) * BytesPerWord; _frame_size = align_up(register_save_size, frame::alignment_in_bytes) - + frame::abi_reg_args_size; + + frame::native_abi_reg_args_size; __ save_LR_CR(R0); __ push_frame(_frame_size, R0); diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index be1611739c5..8dc0b627d93 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -1171,7 +1171,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, R // to meet the abi scratch requirements. // The max_stack pointer will get restored by means of the GR_Lmax_stack local in // the return entry of the interpreter. - addi(Rscratch2, R15_esp, Interpreter::stackElementSize - frame::abi_reg_args_size); + addi(Rscratch2, R15_esp, Interpreter::stackElementSize - frame::top_ijava_frame_abi_size); clrrdi(Rscratch2, Rscratch2, exact_log2(frame::alignment_in_bytes)); // round towards smaller address resize_frame_absolute(Rscratch2, Rscratch2, R0); @@ -2186,7 +2186,7 @@ void InterpreterMacroAssembler::save_interpreter_state(Register scratch) { void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool bcp_and_mdx_only, bool restore_top_frame_sp) { ld_ptr(scratch, _abi0(callers_sp), R1_SP); // Load frame pointer. if (restore_top_frame_sp) { - // After thawing the top frame of a continuation we reach here with frame::abi_minframe. + // After thawing the top frame of a continuation we reach here with frame::java_abi. // therefore we have to restore top_frame_sp before the assertion below. assert(!bcp_and_mdx_only, "chose other registers"); Register tfsp = R18_locals; @@ -2211,7 +2211,7 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool { Label Lok; subf(R0, R1_SP, scratch); - cmpdi(CCR0, R0, frame::abi_reg_args_size + frame::ijava_state_size); + cmpdi(CCR0, R0, frame::top_ijava_frame_abi_size + frame::ijava_state_size); bge(CCR0, Lok); stop("frame too small (restore istate)"); bind(Lok); diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index a27c208eafe..3ca2ed3ff69 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -730,7 +730,7 @@ void MacroAssembler::clobber_carg_stack_slots(Register tmp) { li(tmp, magic_number); for (int m = 0; m <= 7; m++) { - std(tmp, frame::abi_minframe_size + m * 8, R1_SP); + std(tmp, frame::native_abi_minframe_size + m * 8, R1_SP); } } @@ -976,16 +976,16 @@ void MacroAssembler::push_frame(unsigned int bytes, Register tmp) { } } -// Push a frame of size `bytes' plus abi_reg_args on top. +// Push a frame of size `bytes' plus native_abi_reg_args on top. void MacroAssembler::push_frame_reg_args(unsigned int bytes, Register tmp) { - push_frame(bytes + frame::abi_reg_args_size, tmp); + push_frame(bytes + frame::native_abi_reg_args_size, tmp); } // Setup up a new C frame with a spill area for non-volatile GPRs and // additional space for local variables. void MacroAssembler::push_frame_reg_args_nonvolatiles(unsigned int bytes, Register tmp) { - push_frame(bytes + frame::abi_reg_args_size + frame::spill_nonvolatiles_size, tmp); + push_frame(bytes + frame::native_abi_reg_args_size + frame::spill_nonvolatiles_size, tmp); } // Pop current C frame. diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp index 732d35b33a2..cedc764fdbd 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -316,7 +316,7 @@ class MacroAssembler: public Assembler { // Push a frame of size `bytes'. No abi space provided. void push_frame(unsigned int bytes, Register tmp); - // Push a frame of size `bytes' plus abi_reg_args on top. + // Push a frame of size `bytes' plus native_abi_reg_args on top. void push_frame_reg_args(unsigned int bytes, Register tmp); // Setup up a new C frame with a spill area for non-volatile GPRs and additional diff --git a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp index eee918e7bb0..923eb44cf17 100644 --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -506,11 +506,11 @@ void trace_method_handle_stub(const char* adaptername, ResourceMark rm; LogStream ls(lt); ls.print_cr("Registers:"); - const int abi_offset = frame::abi_reg_args_size / 8; + const int abi_offset = frame::native_abi_reg_args_size / 8; for (int i = R3->encoding(); i <= R12->encoding(); i++) { Register r = as_Register(i); int count = i - R3->encoding(); - // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, abi_reg_args_size)). + // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, native_abi_reg_args_size)). ls.print("%3s=" PTR_FORMAT, r->name(), saved_regs[abi_offset + count]); if ((count + 1) % 4 == 0) { ls.cr(); diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index bc7f6a3afe6..461c2c161a4 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -3799,7 +3799,7 @@ frame %{ // out_preserve_stack_slots for calls to C. Supports the var-args // backing area for register parms. // - varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); + varargs_C_out_slots_killed(((frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); // The after-PROLOG location of the return address. Location of // return address specifies a type (REG or STACK) and a number diff --git a/src/hotspot/cpu/ppc/runtime_ppc.cpp b/src/hotspot/cpu/ppc/runtime_ppc.cpp index 7f2d3e627eb..8c3bfd4f37b 100644 --- a/src/hotspot/cpu/ppc/runtime_ppc.cpp +++ b/src/hotspot/cpu/ppc/runtime_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -77,7 +77,7 @@ void OptoRuntime::generate_exception_blob() { address start = __ pc(); - int frame_size_in_bytes = frame::abi_reg_args_size; + int frame_size_in_bytes = frame::native_abi_reg_args_size; OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); // Exception pc is 'return address' for stack walker. diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 71842f33dfd..9cc2e988815 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -272,7 +272,7 @@ OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssemble : 0; const int register_save_size = regstosave_num * reg_size + vsregstosave_num * vs_reg_size; const int frame_size_in_bytes = align_up(register_save_size, frame::alignment_in_bytes) - + frame::abi_reg_args_size; + + frame::native_abi_reg_args_size; *out_frame_size_in_bytes = frame_size_in_bytes; const int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); @@ -790,7 +790,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt, int i; VMReg reg; // Leave room for C-compatible ABI_REG_ARGS. - int stk = (frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size; + int stk = (frame::native_abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size; int arg = 0; int freg = 0; @@ -1951,7 +1951,7 @@ static void gen_continuation_yield(MacroAssembler* masm, int& compiled_entry_offset) { Register tmp = R10_ARG8; - const int framesize_bytes = (int)align_up((int)frame::abi_reg_args_size, frame::alignment_in_bytes); + const int framesize_bytes = (int)align_up((int)frame::native_abi_reg_args_size, frame::alignment_in_bytes); framesize_words = framesize_bytes / wordSize; address start = __ pc(); @@ -2480,7 +2480,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // disallows any pending_exception. // Save argument registers and leave room for C-compatible ABI_REG_ARGS. - int frame_size = frame::abi_reg_args_size + align_up(total_c_args * wordSize, frame::alignment_in_bytes); + int frame_size = frame::native_abi_reg_args_size + align_up(total_c_args * wordSize, frame::alignment_in_bytes); __ mr(R11_scratch1, R1_SP); RegisterSaver::push_frame_and_save_argument_registers(masm, R12_scratch2, frame_size, total_c_args, out_regs, out_regs2); @@ -2950,7 +2950,7 @@ void SharedRuntime::generate_deopt_blob() { OopMapSet *oop_maps = new OopMapSet(); // size of ABI112 plus spill slots for R3_RET and F1_RET. - const int frame_size_in_bytes = frame::abi_reg_args_spill_size; + const int frame_size_in_bytes = frame::native_abi_reg_args_spill_size; const int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); int first_frame_size_in_bytes = 0; // frame size of "unpack frame" for call to fetch_unroll_info. @@ -3119,8 +3119,8 @@ void SharedRuntime::generate_deopt_blob() { // ...). // Spill live volatile registers since we'll do a call. - __ std( R3_RET, _abi_reg_args_spill(spill_ret), R1_SP); - __ stfd(F1_RET, _abi_reg_args_spill(spill_fret), R1_SP); + __ std( R3_RET, _native_abi_reg_args_spill(spill_ret), R1_SP); + __ stfd(F1_RET, _native_abi_reg_args_spill(spill_fret), R1_SP); // Let the unpacker layout information in the skeletal frames just // allocated. @@ -3132,8 +3132,8 @@ void SharedRuntime::generate_deopt_blob() { __ reset_last_Java_frame(); // Restore the volatiles saved above. - __ ld( R3_RET, _abi_reg_args_spill(spill_ret), R1_SP); - __ lfd(F1_RET, _abi_reg_args_spill(spill_fret), R1_SP); + __ ld( R3_RET, _native_abi_reg_args_spill(spill_ret), R1_SP); + __ lfd(F1_RET, _native_abi_reg_args_spill(spill_fret), R1_SP); // Pop the unpack frame. __ pop_frame(); @@ -3179,7 +3179,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { Register r_return_pc = R27_tmp7; OopMapSet* oop_maps = new OopMapSet(); - int frame_size_in_bytes = frame::abi_reg_args_size; + int frame_size_in_bytes = frame::native_abi_reg_args_size; OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); // stack: (deoptee, optional i2c, caller_of_deoptee, ...). diff --git a/src/hotspot/cpu/ppc/stackChunkFrameStream_ppc.inline.hpp b/src/hotspot/cpu/ppc/stackChunkFrameStream_ppc.inline.hpp index e4489660f46..f8d60ed9f93 100644 --- a/src/hotspot/cpu/ppc/stackChunkFrameStream_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/stackChunkFrameStream_ppc.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -54,14 +54,14 @@ inline frame StackChunkFrameStream::to_frame() const { template inline address StackChunkFrameStream::get_pc() const { assert(!is_done(), ""); - return (address)((frame::abi_minframe*) _sp)->lr; + return (address)((frame::common_abi*) _sp)->lr; } template inline intptr_t* StackChunkFrameStream::fp() const { // See FreezeBase::patch_pd() and frame::setup() assert((frame_kind == ChunkFrames::Mixed && is_interpreted()), ""); - intptr_t* fp_addr = (intptr_t*)&((frame::abi_minframe*)_sp)->callers_sp; + intptr_t* fp_addr = (intptr_t*)&((frame::common_abi*)_sp)->callers_sp; assert(*(intptr_t**)fp_addr != nullptr, ""); // derelativize return fp_addr + *fp_addr; diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index 170c77890b3..d194eb16875 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2022 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -91,8 +91,8 @@ class StubGenerator: public StubCodeGenerator { address start = __ function_entry(); // some sanity checks - assert((sizeof(frame::abi_minframe) % 16) == 0, "unaligned"); - assert((sizeof(frame::abi_reg_args) % 16) == 0, "unaligned"); + assert((sizeof(frame::native_abi_minframe) % 16) == 0, "unaligned"); + assert((sizeof(frame::native_abi_reg_args) % 16) == 0, "unaligned"); assert((sizeof(frame::spill_nonvolatiles) % 16) == 0, "unaligned"); assert((sizeof(frame::parent_ijava_frame_abi) % 16) == 0, "unaligned"); assert((sizeof(frame::entry_frame_locals) % 16) == 0, "unaligned"); @@ -540,7 +540,7 @@ class StubGenerator: public StubCodeGenerator { MacroAssembler* masm = new MacroAssembler(&code); OopMapSet* oop_maps = new OopMapSet(); - int frame_size_in_bytes = frame::abi_reg_args_size; + int frame_size_in_bytes = frame::native_abi_reg_args_size; OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0); address start = __ pc(); @@ -4553,7 +4553,7 @@ class StubGenerator: public StubCodeGenerator { __ mtctr(tmp1); __ bctr(); __ bind(thaw_success); - __ addi(R3_RET, R3_RET, frame::abi_reg_args_size); // Large abi required for C++ calls. + __ addi(R3_RET, R3_RET, frame::native_abi_reg_args_size); // Large abi required for C++ calls. __ neg(R3_RET, R3_RET); // align down resulting in a smaller negative offset __ clrrdi(R3_RET, R3_RET, exact_log2(frame::alignment_in_bytes)); @@ -4617,7 +4617,7 @@ class StubGenerator: public StubCodeGenerator { Register tmp1 = R10_ARG8; Register tmp2 = R9_ARG7; - int framesize = frame::abi_reg_args_size / VMRegImpl::stack_slot_size; + int framesize = frame::native_abi_reg_args_size / VMRegImpl::stack_slot_size; address start = __ pc(); __ mflr(tmp1); __ std(tmp1, _abi0(lr), R1_SP); // save return pc diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 42c179b05d1..d8747a1c981 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -978,10 +978,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist } // Compute top frame size. - __ addi(Rtop_frame_size, Rtop_frame_size, frame::abi_reg_args_size + frame::ijava_state_size); + __ addi(Rtop_frame_size, Rtop_frame_size, frame::top_ijava_frame_abi_size + frame::ijava_state_size); // Cut back area between esp and max_stack. - __ addi(Rparent_frame_resize, Rparent_frame_resize, frame::abi_minframe_size - Interpreter::stackElementSize); + __ addi(Rparent_frame_resize, Rparent_frame_resize, frame::parent_ijava_frame_abi_size - Interpreter::stackElementSize); __ round_to(Rtop_frame_size, frame::alignment_in_bytes); __ round_to(Rparent_frame_resize, frame::alignment_in_bytes); diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index b09a0090644..ab9fa9535b3 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -487,7 +487,7 @@ FreezeBase::FreezeBase(JavaThread* thread, ContinuationWrapper& cont, intptr_t* #if !defined(PPC64) || defined(ZERO) static const int doYield_stub_frame_size = frame::metadata_words; #else - static const int doYield_stub_frame_size = frame::abi_reg_args_size >> LogBytesPerWord; + static const int doYield_stub_frame_size = frame::native_abi_reg_args_size >> LogBytesPerWord; #endif assert(SharedRuntime::cont_doYield_stub()->frame_size() == doYield_stub_frame_size, ""); From 49726ee3a95023a912aacad0e3714eae146eed21 Mon Sep 17 00:00:00 2001 From: Guoxiong Li Date: Tue, 18 Apr 2023 08:01:32 +0000 Subject: [PATCH 017/288] 8305690: [X86] Do not emit two REX prefixes in Assembler::prefix Reviewed-by: kvn, thartmann --- src/hotspot/cpu/x86/assembler_x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index ccf3b236afc..78ef74fa31a 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -12547,7 +12547,7 @@ void Assembler::prefix(Register dst, Address adr, Prefix p) { if (adr.index_needs_rex()) { assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X"); } else { - prefix(REX_B); + p = (Prefix)(p | REX_B); } } else { if (adr.index_needs_rex()) { From 8ecb5dfa34ebd2ef7717994522fbb4bd7a14e0c9 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Tue, 18 Apr 2023 08:54:55 +0000 Subject: [PATCH 018/288] 8305781: compiler/c2/irTests/TestVectorizationMultiInvar.java failed with "IRViolationException: There were one or multiple IR rule failures." Reviewed-by: thartmann, kvn --- .../c2/irTests/TestVectorizationMultiInvar.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMultiInvar.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMultiInvar.java index c5b5e691a5c..6b5c886cf86 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMultiInvar.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMultiInvar.java @@ -25,6 +25,7 @@ package compiler.c2.irTests; import compiler.lib.ir_framework.*; import jdk.test.lib.Utils; +import jdk.test.whitebox.WhiteBox; import jdk.internal.misc.Unsafe; import java.util.Objects; import java.util.Random; @@ -36,14 +37,20 @@ import java.util.Random; * @summary C2: vectorization fails on some simple Memory Segment loops * @modules java.base/jdk.internal.misc * @library /test/lib / - * @run driver compiler.c2.irTests.TestVectorizationMultiInvar + * @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 compiler.c2.irTests.TestVectorizationMultiInvar */ public class TestVectorizationMultiInvar { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + private final static WhiteBox wb = WhiteBox.getWhiteBox(); public static void main(String[] args) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); + Object alignVector = wb.getVMFlag("AlignVector"); + if (alignVector != null && !((Boolean)alignVector)) { + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); + } } static int size = 1024; From 54f7b6ca34986cc26c5b91c6724b9a1754c94391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Tue, 18 Apr 2023 08:59:31 +0000 Subject: [PATCH 019/288] 8301497: Replace NULL with nullptr in cpu/s390 Reviewed-by: amitkumar, coleenp --- .../cpu/s390/abstractInterpreter_s390.cpp | 10 +- src/hotspot/cpu/s390/assembler_s390.hpp | 4 +- src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp | 4 +- src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 150 +++++++++--------- src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp | 46 +++--- .../cpu/s390/c1_MacroAssembler_s390.cpp | 6 +- .../cpu/s390/c1_MacroAssembler_s390.hpp | 4 +- src/hotspot/cpu/s390/c1_Runtime1_s390.cpp | 20 +-- .../cpu/s390/c2_MacroAssembler_s390.cpp | 4 +- src/hotspot/cpu/s390/compiledIC_s390.cpp | 24 +-- .../continuationFreezeThaw_s390.inline.hpp | 4 +- .../s390/continuationHelper_s390.inline.hpp | 24 +-- src/hotspot/cpu/s390/disassembler_s390.hpp | 4 +- src/hotspot/cpu/s390/frame_s390.cpp | 16 +- src/hotspot/cpu/s390/frame_s390.inline.hpp | 12 +- .../s390/gc/g1/g1BarrierSetAssembler_s390.cpp | 26 +-- .../s390/gc/g1/g1BarrierSetAssembler_s390.hpp | 6 +- .../gc/shared/barrierSetAssembler_s390.cpp | 6 +- .../gc/shared/barrierSetAssembler_s390.hpp | 4 +- .../cardTableBarrierSetAssembler_s390.cpp | 4 +- src/hotspot/cpu/s390/globals_s390.hpp | 2 +- src/hotspot/cpu/s390/interp_masm_s390.cpp | 38 ++--- src/hotspot/cpu/s390/interpreterRT_s390.cpp | 6 +- src/hotspot/cpu/s390/javaFrameAnchor_s390.hpp | 12 +- src/hotspot/cpu/s390/jniFastGetField_s390.cpp | 6 +- .../cpu/s390/jvmciCodeInstaller_s390.cpp | 4 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 144 ++++++++--------- src/hotspot/cpu/s390/macroAssembler_s390.hpp | 24 +-- src/hotspot/cpu/s390/matcher_s390.hpp | 8 +- src/hotspot/cpu/s390/methodHandles_s390.cpp | 10 +- src/hotspot/cpu/s390/nativeInst_s390.cpp | 42 ++--- src/hotspot/cpu/s390/nativeInst_s390.hpp | 16 +- src/hotspot/cpu/s390/registerMap_s390.hpp | 6 +- src/hotspot/cpu/s390/relocInfo_s390.cpp | 4 +- src/hotspot/cpu/s390/runtime_s390.cpp | 6 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 38 ++--- .../cpu/s390/smallRegisterMap_s390.inline.hpp | 6 +- .../stackChunkFrameStream_s390.inline.hpp | 10 +- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 12 +- src/hotspot/cpu/s390/stubRoutines_s390.cpp | 12 +- .../templateInterpreterGenerator_s390.cpp | 42 ++--- src/hotspot/cpu/s390/templateTable_s390.cpp | 52 +++--- src/hotspot/cpu/s390/vm_version_s390.cpp | 8 +- src/hotspot/cpu/s390/vtableStubs_s390.cpp | 18 +-- 44 files changed, 452 insertions(+), 452 deletions(-) diff --git a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp index 98f441452cf..c24c2b56bf7 100644 --- a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp +++ b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -121,17 +121,17 @@ int AbstractInterpreter::size_activation(int max_stack, // // Parameters: // -// interpreter_frame != NULL: +// interpreter_frame isn't null: // set up the method, locals, and monitors. -// The frame interpreter_frame, if not NULL, is guaranteed to be the +// The frame interpreter_frame, if not null, is guaranteed to be the // right size, as determined by a previous call to this method. // It is also guaranteed to be walkable even though it is in a skeletal state // -// is_top_frame == true: +// is_top_frame is true: // We're processing the *oldest* interpreter frame! // // pop_frame_extra_args: -// If this is != 0 we are returning to a deoptimized frame by popping +// If this isn't 0 we are returning to a deoptimized frame by popping // off the callee frame. We want to re-execute the call that called the // callee interpreted, but since the return to the interpreter would pop // the arguments off advance the esp by dummy popframe_extra_args slots. diff --git a/src/hotspot/cpu/s390/assembler_s390.hpp b/src/hotspot/cpu/s390/assembler_s390.hpp index 0a138151ace..1e2152ad718 100644 --- a/src/hotspot/cpu/s390/assembler_s390.hpp +++ b/src/hotspot/cpu/s390/assembler_s390.hpp @@ -137,7 +137,7 @@ class RelAddr { assert(((uint64_t)target & 0x0001L) == 0, "target of a relative address must be aligned"); assert(((uint64_t)pc & 0x0001L) == 0, "origin of a relative address must be aligned"); - if ((target == NULL) || (target == pc)) { + if ((target == nullptr) || (target == pc)) { return 0; // Yet unknown branch destination. } else { guarantee(is_in_range_of_RelAddr(target, pc, shortForm), "target not within reach"); @@ -295,7 +295,7 @@ class AddressLiteral { protected: // creation - AddressLiteral() : _address(NULL), _rspec() {} + AddressLiteral() : _address(nullptr), _rspec() {} public: AddressLiteral(address addr, RelocationHolder const& rspec) diff --git a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp index b99027f09d5..200f7ee978d 100644 --- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp +++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -375,7 +375,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { address entry = __ pc(); NativeGeneralJump::insert_unconditional((address)_pc_start, entry); - address target = NULL; + address target = nullptr; relocInfo::relocType reloc_type = relocInfo::none; switch (_id) { case access_field_id: target = Runtime1::entry_for (Runtime1::access_field_patching_id); break; diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index 4fef086bc8e..2f945837dfc 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -143,7 +143,7 @@ void LIR_Assembler::osr_entry() { for (int i = 0; i < number_of_locks; i++) { int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); // Verify the interpreter's monitor has a non-null object. - __ asm_assert_mem8_isnot_zero(slot_offset + 1*BytesPerWord, OSR_buf, "locked object is NULL", __LINE__); + __ asm_assert_mem8_isnot_zero(slot_offset + 1*BytesPerWord, OSR_buf, "locked object is null", __LINE__); // Copy the lock field into the compiled activation. __ z_lg(Z_R1_scratch, slot_offset + 0, OSR_buf); __ z_stg(Z_R1_scratch, frame_map()->address_for_monitor_lock(i)); @@ -158,7 +158,7 @@ void LIR_Assembler::osr_entry() { address LIR_Assembler::emit_call_c(address a) { __ align_call_far_patchable(__ pc()); address call_addr = __ call_c_opt(a); - if (call_addr == NULL) { + if (call_addr == nullptr) { bailout("const section overflow"); } return call_addr; @@ -167,7 +167,7 @@ address LIR_Assembler::emit_call_c(address a) { int LIR_Assembler::emit_exception_handler() { // Generate code for exception handler. address handler_base = __ start_a_stub(exception_handler_size()); - if (handler_base == NULL) { + if (handler_base == nullptr) { // Not enough space left for the handler. bailout("exception handler overflow"); return -1; @@ -213,7 +213,7 @@ int LIR_Assembler::emit_unwind_handler() { } // Perform needed unlocking. - MonitorExitStub* stub = NULL; + MonitorExitStub* stub = nullptr; if (method()->is_synchronized()) { // Runtime1::monitorexit_id expects lock address in Z_R1_scratch. LIR_Opr lock = FrameMap::as_opr(Z_R1_scratch); @@ -248,7 +248,7 @@ int LIR_Assembler::emit_unwind_handler() { __ z_br(Z_R5); // Emit the slow path assembly. - if (stub != NULL) { + if (stub != nullptr) { stub->emit_code(this); } @@ -258,7 +258,7 @@ int LIR_Assembler::emit_unwind_handler() { int LIR_Assembler::emit_deopt_handler() { // Generate code for exception handler. address handler_base = __ start_a_stub(deopt_handler_size()); - if (handler_base == NULL) { + if (handler_base == nullptr) { // Not enough space left for the handler. bailout("deopt handler overflow"); return -1; @@ -273,7 +273,7 @@ int LIR_Assembler::emit_deopt_handler() { } void LIR_Assembler::jobject2reg(jobject o, Register reg) { - if (o == NULL) { + if (o == nullptr) { __ clear_reg(reg, true/*64bit*/, false/*set cc*/); // Must not kill cc set by cmove. } else { AddressLiteral a = __ allocate_oop_address(o); @@ -286,12 +286,12 @@ void LIR_Assembler::jobject2reg(jobject o, Register reg) { void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) { // Allocate a new index in table to hold the object once it's been patched. - int oop_index = __ oop_recorder()->allocate_oop_index(NULL); + int oop_index = __ oop_recorder()->allocate_oop_index(nullptr); PatchingStub* patch = new PatchingStub(_masm, patching_id(info), oop_index); AddressLiteral addrlit((intptr_t)0, oop_Relocation::spec(oop_index)); assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc"); - // The NULL will be dynamically patched later so the sequence to + // The null will be dynamically patched later so the sequence to // load the address literal must not be optimized. __ load_const(reg, addrlit); @@ -308,11 +308,11 @@ void LIR_Assembler::metadata2reg(Metadata* md, Register reg) { void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo *info) { // Allocate a new index in table to hold the klass once it's been patched. - int index = __ oop_recorder()->allocate_metadata_index(NULL); + int index = __ oop_recorder()->allocate_metadata_index(nullptr); PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, index); AddressLiteral addrlit((intptr_t)0, metadata_Relocation::spec(index)); assert(addrlit.rspec().type() == relocInfo::metadata_type, "must be an metadata reloc"); - // The NULL will be dynamically patched later so the sequence to + // The null will be dynamically patched later so the sequence to // load the address literal must not be optimized. __ load_const(reg, addrlit); @@ -353,18 +353,18 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) { void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { #ifdef ASSERT - assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); - if (op->block() != NULL) { _branch_target_blocks.append(op->block()); } - if (op->ublock() != NULL) { _branch_target_blocks.append(op->ublock()); } + assert(op->block() == nullptr || op->block()->label() == op->label(), "wrong label"); + if (op->block() != nullptr) { _branch_target_blocks.append(op->block()); } + if (op->ublock() != nullptr) { _branch_target_blocks.append(op->ublock()); } #endif if (op->cond() == lir_cond_always) { - if (op->info() != NULL) { add_debug_info_for_branch(op->info()); } + if (op->info() != nullptr) { add_debug_info_for_branch(op->info()); } __ branch_optimized(Assembler::bcondAlways, *(op->label())); } else { Assembler::branch_condition acond = Assembler::bcondZero; if (op->code() == lir_cond_float_branch) { - assert(op->ublock() != NULL, "must have unordered successor"); + assert(op->ublock() != nullptr, "must have unordered successor"); __ branch_optimized(Assembler::bcondNotOrdered, *(op->ublock()->label())); } switch (op->cond()) { @@ -504,7 +504,7 @@ void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { } void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { - address virtual_call_oop_addr = NULL; + address virtual_call_oop_addr = nullptr; AddressLiteral empty_ic((address) Universe::non_oop_word()); virtual_call_oop_addr = __ pc(); bool success = __ load_const_from_toc(Z_inline_cache, empty_ic); @@ -546,7 +546,7 @@ void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { case T_OBJECT: dest_addr = frame_map()->address_for_slot(dest->single_stack_ix()); - if (c->as_jobject() == NULL) { + if (c->as_jobject() == nullptr) { __ store_const(dest_addr, (int64_t)NULL_WORD, 8, 8); } else { jobject2reg(c->as_jobject(), Z_R1_scratch); @@ -596,7 +596,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi case T_OBJECT: // fall through case T_ARRAY: - if (c->as_jobject() == NULL) { + if (c->as_jobject() == nullptr) { if (UseCompressedOops && !wide) { __ clear_reg(Z_R1_scratch, false); store_offset = __ reg2mem_opt(Z_R1_scratch, addr, false); @@ -666,7 +666,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi case T_OBJECT: // fall through case T_ARRAY: - if (c->as_jobject() == NULL) { + if (c->as_jobject() == nullptr) { if (UseCompressedOops && !wide) { store_offset = __ store_const(addr, (int32_t)NULL_WORD, 4, 4); } else { @@ -709,7 +709,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi } } - if (info != NULL) { + if (info != nullptr) { add_debug_info_for_null_check(store_offset, info); } } @@ -760,7 +760,7 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod Register toc_reg = Z_R1_scratch; __ load_toc(toc_reg); address const_addr = __ float_constant(c->as_jfloat()); - if (const_addr == NULL) { + if (const_addr == nullptr) { bailout("const section overflow"); break; } @@ -778,7 +778,7 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod Register toc_reg = Z_R1_scratch; __ load_toc(toc_reg); address const_addr = __ double_constant(c->as_jdouble()); - if (const_addr == NULL) { + if (const_addr == nullptr) { bailout("const section overflow"); break; } @@ -881,7 +881,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P __ verify_oop(src, FILE_AND_LINE); } - PatchingStub* patch = NULL; + PatchingStub* patch = nullptr; if (needs_patching) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); assert(!to_reg->is_double_cpu() || @@ -969,10 +969,10 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P default : ShouldNotReachHere(); } - if (patch != NULL) { + if (patch != nullptr) { patching_epilog(patch, patch_code, src, info); } - if (info != NULL) add_debug_info_for_null_check(offset, info); + if (info != nullptr) add_debug_info_for_null_check(offset, info); } void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { @@ -1074,7 +1074,7 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, __ verify_oop(dest, FILE_AND_LINE); } - PatchingStub* patch = NULL; + PatchingStub* patch = nullptr; if (needs_patching) { patch = new PatchingStub(_masm, PatchingStub::access_field_id); assert(!from->is_double_cpu() || @@ -1176,11 +1176,11 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, default: ShouldNotReachHere(); } - if (patch != NULL) { + if (patch != nullptr) { patching_epilog(patch, patch_code, dest, info); } - if (info != NULL) add_debug_info_for_null_check(offset, info); + if (info != nullptr) add_debug_info_for_null_check(offset, info); } @@ -1211,7 +1211,7 @@ void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { const Register poll_addr = tmp->as_register_lo(); __ z_lg(poll_addr, Address(Z_thread, JavaThread::polling_page_offset())); - guarantee(info != NULL, "Shouldn't be NULL"); + guarantee(info != nullptr, "Shouldn't be null"); add_debug_info_for_branch(info); int offset = __ offset(); __ relocate(relocInfo::poll_type); @@ -1226,7 +1226,7 @@ void LIR_Assembler::emit_static_call_stub() { address call_pc = __ pc(); address stub = __ start_a_stub(call_stub_size()); - if (stub == NULL) { + if (stub == nullptr) { bailout("static call stub overflow"); return; } @@ -1236,7 +1236,7 @@ void LIR_Assembler::emit_static_call_stub() { __ relocate(static_stub_Relocation::spec(call_pc)); // See also Matcher::interpreter_method_reg(). - AddressLiteral meta = __ allocate_metadata_address(NULL); + AddressLiteral meta = __ allocate_metadata_address(nullptr); bool success = __ load_const_from_toc(Z_method, meta); __ set_inst_mark(); @@ -1289,10 +1289,10 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, __ z_cfi(reg1, c->as_jint()); } } else if (c->type() == T_METADATA) { - // We only need, for now, comparison with NULL for metadata. + // We only need, for now, comparison with null for metadata. assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); Metadata* m = c->as_metadata(); - if (m == NULL) { + if (m == nullptr) { __ z_cghi(reg1, 0); } else { ShouldNotReachHere(); @@ -1300,7 +1300,7 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, } else if (is_reference_type(c->type())) { // In 64bit oops are single register. jobject o = c->as_jobject(); - if (o == NULL) { + if (o == nullptr) { __ z_ltgr(reg1, reg1); } else { jobject2reg(o, Z_R1_scratch); @@ -1311,7 +1311,7 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, } // cpu register - address } else if (opr2->is_address()) { - if (op->info() != NULL) { + if (op->info() != nullptr) { add_debug_info_for_null_check_here(op->info()); } if (unsigned_comp) { @@ -1449,7 +1449,7 @@ void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, L } else if (opr1->is_stack()) { stack2reg(opr1, result, result->type()); } else if (opr1->is_constant()) { - const2reg(opr1, result, lir_patch_none, NULL); + const2reg(opr1, result, lir_patch_none, nullptr); } else { ShouldNotReachHere(); } @@ -1478,7 +1478,7 @@ void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, L } else if (opr2->is_stack()) { stack2reg(opr2, result, result->type()); } else if (opr2->is_constant()) { - const2reg(opr2, result, lir_patch_none, NULL); + const2reg(opr2, result, lir_patch_none, nullptr); } else { ShouldNotReachHere(); } @@ -1488,7 +1488,7 @@ void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, L void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) { - assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method"); + assert(info == nullptr, "should never be used, idiv/irem and ldiv/lrem not handled by this method"); if (left->is_single_cpu()) { assert(left == dest, "left and dest must be equal"); @@ -1935,14 +1935,14 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { CodeStub* stub = op->stub(); int flags = op->flags(); - BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; + BasicType basic_type = default_type != nullptr ? default_type->element_type()->basic_type() : T_ILLEGAL; if (basic_type == T_ARRAY) basic_type = T_OBJECT; // If we don't know anything, just go through the generic arraycopy. - if (default_type == NULL) { + if (default_type == nullptr) { address copyfunc_addr = StubRoutines::generic_arraycopy(); - if (copyfunc_addr == NULL) { + if (copyfunc_addr == nullptr) { // Take a slow path for generic arraycopy. __ branch_optimized(Assembler::bcondAlways, *stub->entry()); __ bind(*stub->continuation()); @@ -2007,7 +2007,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { return; } - assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point"); + assert(default_type != nullptr && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point"); int elem_size = type2aelembytes(basic_type); int shift_amount; @@ -2037,7 +2037,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // Length and pos's are all sign extended at this point on 64bit. - // test for NULL + // test for null if (flags & LIR_OpArrayCopy::src_null_check) { __ compareU64_and_branch(src, (intptr_t)0, Assembler::bcondZero, *stub->entry()); } @@ -2115,7 +2115,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ load_klass(src_klass, src); __ load_klass(dst_klass, dst); - __ check_klass_subtype_fast_path(src_klass, dst_klass, tmp, &cont, &slow, NULL); + __ check_klass_subtype_fast_path(src_klass, dst_klass, tmp, &cont, &slow, nullptr); store_parameter(src_klass, 0); // sub store_parameter(dst_klass, 1); // super @@ -2127,7 +2127,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ bind(slow); address copyfunc_addr = StubRoutines::checkcast_arraycopy(); - if (copyfunc_addr != NULL) { // use stub if available + if (copyfunc_addr != nullptr) { // use stub if available // Src is not a sub class of dst so we have to do a // per-element check. @@ -2456,17 +2456,17 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L assert(!op->tmp3()->is_valid(), "tmp3's not needed"); // Check if it needs to be profiled. - ciMethodData* md = NULL; - ciProfileData* data = NULL; + ciMethodData* md = nullptr; + ciProfileData* data = nullptr; if (op->should_profile()) { ciMethod* method = op->profiled_method(); - assert(method != NULL, "Should have method"); + assert(method != nullptr, "Should have method"); int bci = op->profiled_bci(); md = method->method_data_or_null(); - assert(md != NULL, "Sanity"); + assert(md != nullptr, "Sanity"); data = md->bci_to_data(bci); - assert(data != NULL, "need data for type check"); + assert(data != nullptr, "need data for type check"); assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); } @@ -2527,8 +2527,8 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L __ load_klass(klass_RInfo, obj); // Perform the fast part of the checking logic. __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, - (need_slow_path ? success_target : NULL), - failure_target, NULL, + (need_slow_path ? success_target : nullptr), + failure_target, nullptr, RegisterOrConstant(super_check_offset)); if (need_slow_path) { // Call out-of-line instance of __ check_klass_subtype_slow_path(...): @@ -2572,19 +2572,19 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { CodeStub* stub = op->stub(); // Check if it needs to be profiled. - ciMethodData* md = NULL; - ciProfileData* data = NULL; + ciMethodData* md = nullptr; + ciProfileData* data = nullptr; assert_different_registers(value, k_RInfo, klass_RInfo); if (op->should_profile()) { ciMethod* method = op->profiled_method(); - assert(method != NULL, "Should have method"); + assert(method != nullptr, "Should have method"); int bci = op->profiled_bci(); md = method->method_data_or_null(); - assert(md != NULL, "Sanity"); + assert(md != nullptr, "Sanity"); data = md->bci_to_data(bci); - assert(data != NULL, "need data for type check"); + assert(data != nullptr, "need data for type check"); assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); } NearLabel profile_cast_success, profile_cast_failure, done; @@ -2613,7 +2613,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { // Get instance klass (it's already uncompressed). __ z_lg(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset())); // Perform the fast part of the checking logic. - __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, nullptr); // Call out-of-line instance of __ check_klass_subtype_slow_path(...): address a = Runtime1::entry_for (Runtime1::slow_subtype_check_id); store_parameter(klass_RInfo, 0); // sub @@ -2723,7 +2723,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register hdr = op->hdr_opr()->as_register(); Register lock = op->lock_opr()->as_register(); if (UseHeavyMonitors) { - if (op->info() != NULL) { + if (op->info() != nullptr) { add_debug_info_for_null_check_here(op->info()); __ null_check(obj); } @@ -2731,7 +2731,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) { } else if (op->code() == lir_lock) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); // Add debug info for NullPointerException only if one is possible. - if (op->info() != NULL) { + if (op->info() != nullptr) { add_debug_info_for_null_check_here(op->info()); } __ lock_object(hdr, obj, lock, *op->stub()->entry()); @@ -2750,7 +2750,7 @@ void LIR_Assembler::emit_load_klass(LIR_OpLoadKlass* op) { Register result = op->result_opr()->as_pointer_register(); CodeEmitInfo* info = op->info(); - if (info != NULL) { + if (info != nullptr) { add_debug_info_for_null_check_here(info); } @@ -2768,9 +2768,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { // Update counter for all call types. ciMethodData* md = method->method_data_or_null(); - assert(md != NULL, "Sanity"); + assert(md != nullptr, "Sanity"); ciProfileData* data = md->bci_to_data(bci); - assert(data != NULL && data->is_CounterData(), "need CounterData for calls"); + assert(data != nullptr && data->is_CounterData(), "need CounterData for calls"); assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); Register mdo = op->mdo()->as_register(); assert(op->tmp1()->is_double_cpu(), "tmp1 must be allocated"); @@ -2786,7 +2786,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { assert_different_registers(mdo, tmp1, recv); assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); ciKlass* known_klass = op->known_holder(); - if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { + if (C1OptimizeVirtualCallProfiling && known_klass != nullptr) { // We know the type that will be seen at this call site; we can // statically update the MethodData* rather than needing to do // dynamic tests on the receiver type. @@ -2811,7 +2811,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { // VirtualCallData rather than just the first time. for (i = 0; i < VirtualCallData::row_limit(); i++) { ciKlass* receiver = vc_data->receiver(i); - if (receiver == NULL) { + if (receiver == nullptr) { Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); metadata2reg(known_klass->constant_encoding(), tmp1); __ z_stg(tmp1, recv_addr); @@ -2865,7 +2865,7 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, assert(!tmp->is_valid(), "don't need temporary"); emit_call_c(dest); CHECK_BAILOUT(); - if (info != NULL) { + if (info != nullptr) { add_call_info_here(info); } } @@ -2962,7 +2962,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { Label update, next, none, null_seen, init_klass; bool do_null = !not_null; - bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; + bool exact_klass_set = exact_klass != nullptr && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; assert(do_null || do_update, "why are we here?"); @@ -2991,7 +2991,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { if (do_update) { #ifdef ASSERT - if (exact_klass != NULL) { + if (exact_klass != nullptr) { __ load_klass(tmp1, tmp1); metadata2reg(exact_klass->constant_encoding(), tmp2); __ z_cgr(tmp1, tmp2); @@ -3003,8 +3003,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ z_lg(tmp2, mdo_addr); if (!no_conflict) { - if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { - if (exact_klass != NULL) { + if (exact_klass == nullptr || TypeEntries::is_type_none(current_klass)) { + if (exact_klass != nullptr) { metadata2reg(exact_klass->constant_encoding(), tmp1); } else { __ load_klass(tmp1, tmp1); @@ -3027,7 +3027,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ compareU64_and_branch(Z_R0_scratch, (intptr_t)0, Assembler::bcondEqual, init_klass); } } else { - assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && + assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr && ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); // Already unknown: Nothing to do anymore. @@ -3040,7 +3040,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ z_bru(do_update); } else { // There's a single possible klass at this profile point. - assert(exact_klass != NULL, "should be"); + assert(exact_klass != nullptr, "should be"); if (TypeEntries::is_type_none(current_klass)) { metadata2reg(exact_klass->constant_encoding(), tmp1); __ z_lgr(Z_R0_scratch, tmp2); @@ -3060,7 +3060,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { #endif } else { - assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && + assert(ciTypeEntries::valid_ciklass(current_klass) != nullptr && ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); // Already unknown: Nothing to do anymore. diff --git a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp index d5e5c01ebde..c216897d68f 100644 --- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -103,11 +103,11 @@ LIR_Opr LIRGenerator::rlock_byte(BasicType type) { // z/Architecture cannot inline all constants. bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { - if (v->type()->as_IntConstant() != NULL) { + if (v->type()->as_IntConstant() != nullptr) { return Immediate::is_simm16(v->type()->as_IntConstant()->value()); - } else if (v->type()->as_LongConstant() != NULL) { + } else if (v->type()->as_LongConstant() != nullptr) { return Immediate::is_simm16(v->type()->as_LongConstant()->value()); - } else if (v->type()->as_ObjectConstant() != NULL) { + } else if (v->type()->as_ObjectConstant() != nullptr) { return v->type()->as_ObjectConstant()->value()->is_null_object(); } else { return false; @@ -115,9 +115,9 @@ bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { } bool LIRGenerator::can_inline_as_constant(Value i, int bits) const { - if (i->type()->as_IntConstant() != NULL) { + if (i->type()->as_IntConstant() != nullptr) { return Assembler::is_simm(i->type()->as_IntConstant()->value(), bits); - } else if (i->type()->as_LongConstant() != NULL) { + } else if (i->type()->as_LongConstant() != nullptr) { return Assembler::is_simm(i->type()->as_LongConstant()->value(), bits); } else { return can_store_as_constant(i, as_BasicType(i->type())); @@ -267,7 +267,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { // "lock" stores the address of the monitor stack slot, so this is not an oop. LIR_Opr lock = new_register(T_INT); - CodeEmitInfo* info_for_exception = NULL; + CodeEmitInfo* info_for_exception = nullptr; if (x->needs_null_check()) { info_for_exception = state_for (x); } @@ -326,7 +326,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) { default: ShouldNotReachHere(); } - LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), NULL); + LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), nullptr); set_result(x, result); } else { LIR_Opr reg = rlock(x); @@ -387,7 +387,7 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0)); __ branch(lir_cond_equal, new DivByZeroStub(info)); // Idiv/irem cannot trap (passing info would generate an assertion). - info = NULL; + info = nullptr; } if (x->op() == Bytecodes::_lrem) { @@ -408,7 +408,7 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { left.load_item(); right.load_nonconstant(32); rlock_result(x); - arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL); + arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), nullptr); } } @@ -463,7 +463,7 @@ void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { __ cmp(lir_cond_equal, right.result(), LIR_OprFact::intConst(0)); __ branch(lir_cond_equal, new DivByZeroStub(info)); // Idiv/irem cannot trap (passing info would generate an assertion). - info = NULL; + info = nullptr; } if (x->op() == Bytecodes::_irem) { @@ -519,7 +519,7 @@ void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { // If an operand with use count 1 is the left operand, then it is // likely that no move for 2-operand-LIR-form is necessary. - if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { + if (x->is_commutative() && x->y()->as_Constant() == nullptr && x->x()->use_count() > x->y()->use_count()) { x->swap_operands(); } @@ -558,7 +558,7 @@ void LIRGenerator::do_ShiftOp(ShiftOp* x) { void LIRGenerator::do_LogicOp(LogicOp* x) { // IF an operand with use count 1 is the left operand, then it is // likely that no move for 2-operand-LIR-form is necessary. - if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) { + if (x->is_commutative() && x->y()->as_Constant() == nullptr && x->x()->use_count() > x->y()->use_count()) { x->swap_operands(); } @@ -659,7 +659,7 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { case vmIntrinsics::_dexp: { assert(x->number_of_arguments() == 1, "wrong type"); - address runtime_entry = NULL; + address runtime_entry = nullptr; switch (x->id()) { case vmIntrinsics::_dsin: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); @@ -683,14 +683,14 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { ShouldNotReachHere(); } - LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL); + LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), nullptr); set_result(x, result); break; } case vmIntrinsics::_dpow: { assert(x->number_of_arguments() == 2, "wrong type"); address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); - LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL); + LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), nullptr); set_result(x, result); break; } @@ -795,7 +795,7 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { CodeEmitInfo* info = state_for (x, x->state()); // In case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction // and therefore provide the state before the parameters have been consumed. - CodeEmitInfo* patching_info = NULL; + CodeEmitInfo* patching_info = nullptr; if (!x->klass()->is_loaded() || PatchALot) { patching_info = state_for (x, x->state_before()); } @@ -826,14 +826,14 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { void LIRGenerator::do_NewMultiArray(NewMultiArray* x) { Values* dims = x->dims(); int i = dims->length(); - LIRItemList* items = new LIRItemList(i, i, NULL); + LIRItemList* items = new LIRItemList(i, i, nullptr); while (i-- > 0) { LIRItem* size = new LIRItem(dims->at(i), this); items->at_put(i, size); } // Evaluate state_for early since it may emit code. - CodeEmitInfo* patching_info = NULL; + CodeEmitInfo* patching_info = nullptr; if (!x->klass()->is_loaded() || PatchALot) { patching_info = state_for (x, x->state_before()); @@ -882,7 +882,7 @@ void LIRGenerator::do_BlockBegin(BlockBegin* x) { void LIRGenerator::do_CheckCast(CheckCast* x) { LIRItem obj(x->obj(), this); - CodeEmitInfo* patching_info = NULL; + CodeEmitInfo* patching_info = nullptr; if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) { // Must do this before locking the destination register as an oop register, // and before the obj is loaded (the latter is for deoptimization). @@ -897,10 +897,10 @@ void LIRGenerator::do_CheckCast(CheckCast* x) { CodeStub* stub; if (x->is_incompatible_class_change_check()) { - assert(patching_info == NULL, "can't patch this"); + assert(patching_info == nullptr, "can't patch this"); stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); } else if (x->is_invokespecial_receiver_check()) { - assert(patching_info == NULL, "can't patch this"); + assert(patching_info == nullptr, "can't patch this"); stub = new DeoptimizeStub(info_for_exception, Deoptimization::Reason_class_check, Deoptimization::Action_none); @@ -920,7 +920,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) { void LIRGenerator::do_InstanceOf(InstanceOf* x) { LIRItem obj(x->obj(), this); - CodeEmitInfo* patching_info = NULL; + CodeEmitInfo* patching_info = nullptr; if (!x->klass()->is_loaded() || PatchALot) { patching_info = state_for (x, x->state_before()); } diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp index d74be71fe9c..91f8fe16be8 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -130,7 +130,7 @@ void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hd load_const_optimized(Z_R0_scratch, (~(os::vm_page_size()-1) | markWord::lock_mask_in_place)); z_ngr(hdr, Z_R0_scratch); // AND sets CC (result eq/ne 0). // For recursive locking, the result is zero. => Save it in the displaced header - // location (NULL in the displaced hdr location indicates recursive locking). + // location (null in the displaced hdr location indicates recursive locking). z_stg(hdr, Address(disp_hdr, (intptr_t)0)); // Otherwise we don't care about the result and handle locking via runtime call. branch_optimized(Assembler::bcondNotZero, slow_case); @@ -146,7 +146,7 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_ // Load displaced header. z_ltg(hdr, Address(disp_hdr, (intptr_t)0)); - // If the loaded hdr is NULL we had recursive locking, and we are done. + // If the loaded hdr is null we had recursive locking, and we are done. z_bre(done); // Load object. z_lg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); diff --git a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp index 6afbeebec6f..1ff914b7b71 100644 --- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -96,6 +96,6 @@ Register preserve3 = noreg) PRODUCT_RETURN; // This platform only uses signal-based null checks. The Label is not needed. - void null_check(Register r, Label *Lnull = NULL) { MacroAssembler::null_check(r); } + void null_check(Register r, Label *Lnull = nullptr) { MacroAssembler::null_check(r); } #endif // CPU_S390_C1_MACROASSEMBLER_S390_HPP diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index 77329cdefd9..1a3ce714e32 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -66,10 +66,10 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre // ARG1 must hold thread address. z_lgr(Z_ARG1, Z_thread); - address return_pc = NULL; + address return_pc = nullptr; align_call_far_patchable(this->pc()); return_pc = call_c_opt(entry_point); - assert(return_pc != NULL, "const section overflow"); + assert(return_pc != nullptr, "const section overflow"); reset_last_Java_frame(); @@ -282,7 +282,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { // deoptmized, return to the deoptimization handler entry that will // cause re-execution of the current bytecode. DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); - assert(deopt_blob != NULL, "deoptimization blob must have been created"); + assert(deopt_blob != nullptr, "deoptimization blob must have been created"); __ z_ltr(Z_RET, Z_RET); // return value == 0 @@ -311,7 +311,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { bool save_fpu_registers = true; // Stub code and info for the different stubs. - OopMapSet* oop_maps = NULL; + OopMapSet* oop_maps = nullptr; switch (id) { case forward_exception_id: { @@ -527,7 +527,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { const Register Rarray_ptr = Z_ARG5; // Current value from cache array. if (UseCompressedOops) { - assert(Universe::heap() != NULL, "java heap must be initialized to generate partial_subtype_check stub"); + assert(Universe::heap() != nullptr, "java heap must be initialized to generate partial_subtype_check stub"); } const int frame_size = 4*BytesPerWord + frame::z_abi_160_size; @@ -547,7 +547,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ z_lg(Rsubklass, 0*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP); __ z_lg(Rsuperklass, 1*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP); - __ check_klass_subtype_slow_path(Rsubklass, Rsuperklass, Rarray_ptr, Rlength, NULL, &miss); + __ check_klass_subtype_slow_path(Rsubklass, Rsuperklass, Rarray_ptr, Rlength, nullptr, &miss); // Match falls through here. i = 0; @@ -627,7 +627,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { oop_maps->add_gc_map(call_offset, oop_map); restore_live_registers(sasm); DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); - assert(deopt_blob != NULL, "deoptimization blob must have been created"); + assert(deopt_blob != nullptr, "deoptimization blob must have been created"); AddressLiteral dest(deopt_blob->unpack_with_reexecution()); __ load_const_optimized(Z_R1_scratch, dest); __ z_br(Z_R1_scratch); @@ -761,7 +761,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { restore_live_registers(sasm); DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); - assert(deopt_blob != NULL, "deoptimization blob must have been created"); + assert(deopt_blob != nullptr, "deoptimization blob must have been created"); __ load_const_optimized(Z_R1_scratch, deopt_blob->unpack_with_reexecution()); __ z_br(Z_R1_scratch); @@ -784,7 +784,7 @@ OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { // Save registers if required. OopMapSet* oop_maps = new OopMapSet(); - OopMap* oop_map = NULL; + OopMap* oop_map = nullptr; Register reg_fp = Z_R1_scratch; switch (id) { diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp index 6fac285f738..62c1bd943b6 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1016,7 +1016,7 @@ unsigned int C2_MacroAssembler::array_equals(bool is_array_equ, Register ary1, R // Return true if the same array. compareU64_and_branch(ary1, ary2, Assembler::bcondEqual, Ldone_true); - // Return false if one of them is NULL. + // Return false if one of them is null. compareU64_and_branch(ary1, (intptr_t)0, Assembler::bcondEqual, Ldone_false); compareU64_and_branch(ary2, (intptr_t)0, Assembler::bcondEqual, Ldone_false); diff --git a/src/hotspot/cpu/s390/compiledIC_s390.cpp b/src/hotspot/cpu/s390/compiledIC_s390.cpp index 6660a34aeff..09822425e12 100644 --- a/src/hotspot/cpu/s390/compiledIC_s390.cpp +++ b/src/hotspot/cpu/s390/compiledIC_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -40,34 +40,34 @@ #undef __ #define __ _masm. -address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark/* = NULL*/) { +address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark/* = nullptr*/) { #ifdef COMPILER2 // Stub is fixed up when the corresponding call is converted from calling // compiled code to calling interpreted code. - if (mark == NULL) { + if (mark == nullptr) { // Get the mark within main instrs section which is set to the address of the call. mark = cbuf.insts_mark(); } - assert(mark != NULL, "mark must not be NULL"); + assert(mark != nullptr, "mark must not be null"); // Note that the code buffer's insts_mark is always relative to insts. // That's why we must use the macroassembler to generate a stub. MacroAssembler _masm(&cbuf); address stub = __ start_a_stub(CompiledStaticCall::to_interp_stub_size()); - if (stub == NULL) { - return NULL; // CodeBuffer::expand failed. + if (stub == nullptr) { + return nullptr; // CodeBuffer::expand failed. } __ relocate(static_stub_Relocation::spec(mark)); - AddressLiteral meta = __ allocate_metadata_address(NULL); + AddressLiteral meta = __ allocate_metadata_address(nullptr); bool success = __ load_const_from_toc(as_Register(Matcher::inline_cache_reg_encode()), meta); __ set_inst_mark(); AddressLiteral a((address)-1); success = success && __ load_const_from_toc(Z_R1, a); if (!success) { - return NULL; // CodeCache is full. + return nullptr; // CodeCache is full. } __ z_br(Z_R1); @@ -75,7 +75,7 @@ address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark/* return stub; #else ShouldNotReachHere(); - return NULL; + return nullptr; #endif } @@ -93,7 +93,7 @@ int CompiledStaticCall::reloc_to_interp_stub() { void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) { address stub = find_stub(); - guarantee(stub != NULL, "stub not found"); + guarantee(stub != nullptr, "stub not found"); if (TraceICs) { ResourceMark rm; @@ -118,7 +118,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) { // Reset stub. address stub = static_stub->addr(); - assert(stub != NULL, "stub not found"); + assert(stub != nullptr, "stub not found"); assert(CompiledICLocker::is_safe(stub), "mt unsafe call"); // Creation also verifies the object. NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeCall::get_IC_pos_in_java_to_interp_stub()); @@ -138,7 +138,7 @@ void CompiledDirectStaticCall::verify() { // Verify stub. address stub = find_stub(); - assert(stub != NULL, "no stub found for static call"); + assert(stub != nullptr, "no stub found for static call"); // Creation also verifies the object. NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeCall::get_IC_pos_in_java_to_interp_stub()); NativeJump* jump = nativeJump_at(method_holder->next_instruction_address()); diff --git a/src/hotspot/cpu/s390/continuationFreezeThaw_s390.inline.hpp b/src/hotspot/cpu/s390/continuationFreezeThaw_s390.inline.hpp index 5b9c5d9a8bd..91fb850a286 100644 --- a/src/hotspot/cpu/s390/continuationFreezeThaw_s390.inline.hpp +++ b/src/hotspot/cpu/s390/continuationFreezeThaw_s390.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,7 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& caller, bool bottom) { Unimplemented(); - return NULL; + return nullptr; } inline void ThawBase::patch_pd(frame& f, const frame& caller) { diff --git a/src/hotspot/cpu/s390/continuationHelper_s390.inline.hpp b/src/hotspot/cpu/s390/continuationHelper_s390.inline.hpp index 6c1a152339f..4cea0459551 100644 --- a/src/hotspot/cpu/s390/continuationHelper_s390.inline.hpp +++ b/src/hotspot/cpu/s390/continuationHelper_s390.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ template static inline intptr_t** link_address(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } inline int ContinuationHelper::frame_align_words(int size) { @@ -42,7 +42,7 @@ inline int ContinuationHelper::frame_align_words(int size) { inline intptr_t* ContinuationHelper::frame_align_pointer(intptr_t* sp) { Unimplemented(); - return NULL; + return nullptr; } template @@ -75,18 +75,18 @@ inline bool ContinuationHelper::Frame::assert_frame_laid_out(frame f) { inline intptr_t** ContinuationHelper::Frame::callee_link_address(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } template static inline intptr_t* real_fp(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } inline address* ContinuationHelper::InterpretedFrame::return_pc_address(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } inline void ContinuationHelper::InterpretedFrame::patch_sender_sp(frame& f, const frame& caller) { @@ -95,12 +95,12 @@ inline void ContinuationHelper::InterpretedFrame::patch_sender_sp(frame& f, cons inline address* ContinuationHelper::Frame::return_pc_address(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } inline address ContinuationHelper::Frame::real_pc(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } inline void ContinuationHelper::Frame::patch_pc(const frame& f, address pc) { @@ -109,22 +109,22 @@ inline void ContinuationHelper::Frame::patch_pc(const frame& f, address pc) { inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f, InterpreterOopMap* mask) { // inclusive; this will be copied with the frame Unimplemented(); - return NULL; + return nullptr; } inline intptr_t* ContinuationHelper::InterpretedFrame::frame_bottom(const frame& f) { // exclusive; this will not be copied with the frame Unimplemented(); - return NULL; + return nullptr; } inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f, int callee_argsize, bool callee_interpreted) { Unimplemented(); - return NULL; + return nullptr; } inline intptr_t* ContinuationHelper::InterpretedFrame::callers_sp(const frame& f) { Unimplemented(); - return NULL; + return nullptr; } #endif // CPU_S390_CONTINUATIONHELPER_S390_INLINE_HPP diff --git a/src/hotspot/cpu/s390/disassembler_s390.hpp b/src/hotspot/cpu/s390/disassembler_s390.hpp index 53019c2f0d7..4549bc3611b 100644 --- a/src/hotspot/cpu/s390/disassembler_s390.hpp +++ b/src/hotspot/cpu/s390/disassembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,7 +39,7 @@ // the perfect job. In those cases, decode_instruction0 may kick in // and do it right. // If nothing had to be done, just return "here", otherwise return "here + instr_len(here)" - static address decode_instruction0(address here, outputStream* st, address virtual_begin = NULL); + static address decode_instruction0(address here, outputStream* st, address virtual_begin = nullptr); // platform-specific instruction annotations (like value of loaded constants) static void annotate(address pc, outputStream* st); diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index 72d78d23d33..37683bdac8e 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp @@ -82,7 +82,7 @@ bool frame::safe_for_sender(JavaThread *thread) { // construct the sender and do some validation of it. This goes a long way // toward eliminating issues when we get in frame construction code - if (_cb != NULL ) { + if (_cb != nullptr ) { // First check if the frame is complete and the test is reliable. // Unfortunately we can only check frame completeness for runtime stubs. @@ -111,7 +111,7 @@ bool frame::safe_for_sender(JavaThread *thread) { } // At this point, there still is a chance that fp_safe is false. - // In particular, (fp == NULL) might be true. So let's check and + // In particular, fp might be null. So let's check and // bail out before we actually dereference from fp. if (!fp_safe) { return false; @@ -123,7 +123,7 @@ bool frame::safe_for_sender(JavaThread *thread) { // We must always be able to find a recognizable pc. CodeBlob* sender_blob = CodeCache::find_blob(sender_pc); - if (sender_blob == NULL) { + if (sender_blob == nullptr) { return false; } @@ -196,7 +196,7 @@ intptr_t* frame::interpreter_frame_sender_sp() const { } frame frame::sender_for_entry_frame(RegisterMap *map) const { - assert(map != NULL, "map must be set"); + assert(map != nullptr, "map must be set"); // Java frame called from C. Skip all C frames and return top C // frame of that chunk as the sender. JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); @@ -208,7 +208,7 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const { assert(map->include_argument_oops(), "should be set by clear"); - if (jfa->last_Java_pc() != NULL) { + if (jfa->last_Java_pc() != nullptr) { frame fr(jfa->last_Java_sp(), jfa->last_Java_pc()); return fr; } @@ -249,7 +249,7 @@ void frame::patch_pc(Thread* thread, address pc) { own_abi()->return_pc = (uint64_t)pc; _pc = pc; // must be set before call to get_deopt_original_pc address original_pc = CompiledMethod::get_deopt_original_pc(this); - if (original_pc != NULL) { + if (original_pc != nullptr) { // assert(original_pc == _pc, "expected original to be stored before patching"); _deopt_state = is_deoptimized; _pc = original_pc; @@ -403,12 +403,12 @@ void frame::back_trace(outputStream* st, intptr_t* start_sp, intptr_t* top_pc, u st->print("#%-3d ", num); const char* type_name = " "; - const char* function_name = NULL; + const char* function_name = nullptr; // Detect current frame's frame_type, default to 'C frame'. frame_type = 0; - CodeBlob* blob = NULL; + CodeBlob* blob = nullptr; if (Interpreter::contains(current_pc)) { frame_type = 1; diff --git a/src/hotspot/cpu/s390/frame_s390.inline.hpp b/src/hotspot/cpu/s390/frame_s390.inline.hpp index ef2a1aa1a66..dfa68940bac 100644 --- a/src/hotspot/cpu/s390/frame_s390.inline.hpp +++ b/src/hotspot/cpu/s390/frame_s390.inline.hpp @@ -124,7 +124,7 @@ inline void frame::interpreter_frame_set_monitors(BasicObjectLock* monitors) { // Accessors // Return unique id for this frame. The id must have a value where we -// can distinguish identity and younger/older relationship. NULL +// can distinguish identity and younger/older relationship. null // represents an invalid (incomparable) frame. inline intptr_t* frame::id(void) const { // Use _fp. _sp or _unextended_sp wouldn't be correct due to resizing. @@ -134,7 +134,7 @@ inline intptr_t* frame::id(void) const { // Return true if this frame is older (less recent activation) than // the frame represented by id. inline bool frame::is_older(intptr_t* id) const { - assert(this->id() != NULL && id != NULL, "NULL frame id"); + assert(this->id() != nullptr && id != nullptr, "null frame id"); // Stack grows towards smaller addresses on z/Architecture. return this->id() > id; } @@ -304,17 +304,17 @@ inline intptr_t* frame::real_fp() const { } inline const ImmutableOopMap* frame::get_oop_map() const { - if (_cb == NULL) return NULL; - if (_cb->oop_maps() != NULL) { + if (_cb == nullptr) return nullptr; + if (_cb->oop_maps() != nullptr) { NativePostCallNop* nop = nativePostCallNop_at(_pc); - if (nop != NULL && nop->displacement() != 0) { + if (nop != nullptr && nop->displacement() != 0) { int slot = ((nop->displacement() >> 24) & 0xff); return _cb->oop_map_for_slot(slot, _pc); } const ImmutableOopMap* oop_map = OopMapSet::find_map(this); return oop_map; } - return NULL; + return nullptr; } inline int frame::compiled_frame_stack_argsize() const { diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index 8cb4b444ab7..d8243e5aa96 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -107,13 +107,13 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool on_reference = on_weak || on_phantom; Label done; - if (on_oop && on_reference && L_handle_null == NULL) { L_handle_null = &done; } + if (on_oop && on_reference && L_handle_null == nullptr) { L_handle_null = &done; } ModRefBarrierSetAssembler::load_at(masm, decorators, type, src, dst, tmp1, tmp2, L_handle_null); if (on_oop && on_reference) { // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. g1_write_barrier_pre(masm, decorators | IS_NOT_NULL, - NULL /* obj */, + nullptr /* obj */, dst /* pre_val */, noreg/* preserve */ , tmp1, tmp2 /* tmp */, @@ -132,7 +132,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator ) { bool not_null = (decorators & IS_NOT_NULL) != 0, - preloaded = obj == NULL; + preloaded = obj == nullptr; const Register Robj = obj ? obj->base() : noreg, Roff = obj ? obj->index() : noreg; @@ -170,7 +170,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator } } - // Is the previous value NULL? + // Is the previous value null? // If so, we don't need to record it and we're done. // Note: pre_val is loaded, decompressed and stored (directly or via runtime call). // Register contents is preserved across runtime call if caller requests to do so. @@ -181,12 +181,12 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator #endif } else { __ z_ltgr(Rpre_val, Rpre_val); - __ z_bre(filtered); // previous value is NULL, so we don't need to record it. + __ z_bre(filtered); // previous value is null, so we don't need to record it. } - // Decode the oop now. We know it's not NULL. + // Decode the oop now. We know it's not null. if (Robj != noreg && UseCompressedOops) { - __ oop_decoder(Rpre_val, Rpre_val, /*maybeNULL=*/false); + __ oop_decoder(Rpre_val, Rpre_val, /*maybenullptr=*/false); } // OK, it's not filtered, so we'll need to call enqueue. @@ -285,7 +285,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato __ z_srag(Rtmp1, Rtmp1, HeapRegion::LogOfHRGrainBytes); __ z_bre(filtered); - // Crosses regions, storing NULL? + // Crosses regions, storing null? if (not_null) { #ifdef ASSERT __ z_ltgr(Rnew_val, Rnew_val); @@ -298,7 +298,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato Rnew_val = noreg; // end of lifetime - // Storing region crossing non-NULL, is card already dirty? + // Storing region crossing non-null, is card already dirty? assert_different_registers(Rtmp1, Rtmp2, Rtmp3); // Make sure not to use Z_R0 for any of these registers. Register Rcard_addr = (Rtmp1 != Z_R0_scratch) ? Rtmp1 : Rtmp3; @@ -320,7 +320,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato __ z_cli(0, Rcard_addr, G1CardTable::dirty_card_val()); // Reload after membar. __ z_bre(filtered); - // Storing a region crossing, non-NULL oop, card is clean. + // Storing a region crossing, non-null oop, card is clean. // Dirty card and log. __ z_mvi(0, Rcard_addr, G1CardTable::dirty_card_val()); @@ -380,7 +380,7 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - // No need for post barrier if storing NULL + // No need for post barrier if storing null if (val != noreg) { const Register base = dst.base(), idx = dst.index(); @@ -395,7 +395,7 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) { NearLabel Ldone, Lnot_weak; __ z_ltgr(tmp1, value); - __ z_bre(Ldone); // Use NULL result as-is. + __ z_bre(Ldone); // Use null result as-is. __ z_nill(value, ~JNIHandles::tag_mask); __ z_lg(value, 0, value); // Resolve (untagged) jobject. @@ -404,7 +404,7 @@ void G1BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value __ z_braz(Lnot_weak); __ verify_oop(value, FILE_AND_LINE); DecoratorSet decorators = IN_NATIVE | ON_PHANTOM_OOP_REF; - g1_write_barrier_pre(masm, decorators, (const Address*)NULL, value, noreg, tmp1, tmp2, true); + g1_write_barrier_pre(masm, decorators, (const Address*)nullptr, value, noreg, tmp1, tmp2, true); __ bind(Lnot_weak); __ verify_oop(value, FILE_AND_LINE); __ bind(Ldone); diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp index e13de5708a6..cc1d51d2fa1 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -42,7 +42,7 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { bool do_return); void g1_write_barrier_pre(MacroAssembler* masm, DecoratorSet decorators, - const Address* obj, // Address of oop or NULL if pre-loaded. + const Address* obj, // Address of oop or null if pre-loaded. Register Rpre_val, // Ideally, this is a non-volatile register. Register Rval, // Will be preserved. Register Rtmp1, // If Rpre_val is volatile, either Rtmp1 @@ -65,7 +65,7 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler { #endif virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - const Address& src, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = NULL); + const Address& src, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = nullptr); virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2); }; diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index 31fb02ebc66..9613de903d9 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -53,7 +53,7 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, case T_OBJECT: { if (UseCompressedOops && in_heap) { __ z_llgf(dst, addr); - if (L_handle_null != NULL) { // Label provided. + if (L_handle_null != nullptr) { // Label provided. __ compareU32_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null); __ oop_decoder(dst, dst, false); } else { @@ -61,7 +61,7 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, } } else { __ z_lg(dst, addr); - if (L_handle_null != NULL) { + if (L_handle_null != nullptr) { __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null); } } @@ -108,7 +108,7 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) { NearLabel Ldone; __ z_ltgr(tmp1, value); - __ z_bre(Ldone); // Use NULL result as-is. + __ z_bre(Ldone); // Use null result as-is. __ z_nill(value, ~JNIHandles::tag_mask); __ z_lg(value, 0, value); // Resolve (untagged) jobject. diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp index 1590268aac8..b0f7233812b 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -40,7 +40,7 @@ public: Register dst, Register count, bool do_return = false); virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = NULL); + const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = nullptr); virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, const Address& addr, Register val, Register tmp1, Register tmp2, Register tmp3); diff --git a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp index 0124868e46a..760f77951fa 100644 --- a/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/cardTableBarrierSetAssembler_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -160,7 +160,7 @@ void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorS BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3); - // No need for post barrier if storing NULL + // No need for post barrier if storing null if (val != noreg) { const Register base = dst.base(), idx = dst.index(); diff --git a/src/hotspot/cpu/s390/globals_s390.hpp b/src/hotspot/cpu/s390/globals_s390.hpp index a3923147185..df38f3133d7 100644 --- a/src/hotspot/cpu/s390/globals_s390.hpp +++ b/src/hotspot/cpu/s390/globals_s390.hpp @@ -34,7 +34,7 @@ define_pd_global(bool, ImplicitNullChecks, true); // Generate code for implicit null checks. define_pd_global(bool, TrapBasedNullChecks, true); -define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap NULLs passed to check cast. +define_pd_global(bool, UncommonNullCast, true); // Uncommon-trap nulls passed to check cast. define_pd_global(bool, DelayCompilerStubsGeneration, COMPILER2_OR_JVMCI); diff --git a/src/hotspot/cpu/s390/interp_masm_s390.cpp b/src/hotspot/cpu/s390/interp_masm_s390.cpp index b4a7a041725..576f69e7e4d 100644 --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp @@ -57,7 +57,7 @@ #endif void InterpreterMacroAssembler::jump_to_entry(address entry, Register Rscratch) { - assert(entry != NULL, "Entry must have been generated by now"); + assert(entry != nullptr, "Entry must have been generated by now"); assert(Rscratch != Z_R0, "Can't use R0 for addressing"); branch_optimized(Assembler::bcondAlways, entry); } @@ -93,7 +93,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, bo verify_FPU(1, state); #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { Label OK; // Check if the frame pointer in Z_fp is correct. z_cg(Z_fp, 0, Z_SP); @@ -274,7 +274,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg) Register jvmti_thread_state = Z_ARG2; Register tmp = Z_ARG3; load_and_test_long(jvmti_thread_state, Address(Z_thread, JavaThread::jvmti_thread_state_offset())); - z_bre(L); // if (thread->jvmti_thread_state() == NULL) exit; + z_bre(L); // if (thread->jvmti_thread_state() == nullptr) exit; // Initiate earlyret handling only if it is not already being processed. // If the flag has the earlyret_processing bit set, it means that this code @@ -617,7 +617,7 @@ void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register void InterpreterMacroAssembler::verify_esp(Register Resp, Register Rtemp) { // About to read or write Resp[0]. // Make sure it is not in the monitors or the TOP_IJAVA_FRAME_ABI. - address reentry = NULL; + address reentry = nullptr; { // Check if the frame pointer in Z_fp is correct. @@ -995,7 +995,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { // // We stored the monitor address into the object's mark word. // } else if (THREAD->is_lock_owned((address)displaced_header)) // // Simple recursive case. - // monitor->lock()->set_displaced_header(NULL); + // monitor->lock()->set_displaced_header(nullptr); // } else { // // Slow path. // InterpreterRuntime::monitorenter(THREAD, monitor); @@ -1040,7 +1040,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { // } else if (THREAD->is_lock_owned((address)displaced_header)) // // Simple recursive case. - // monitor->lock()->set_displaced_header(NULL); + // monitor->lock()->set_displaced_header(nullptr); // We did not see an unlocked object so try the fast recursive case. @@ -1094,12 +1094,12 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) // else { // template code: // - // if ((displaced_header = monitor->displaced_header()) == NULL) { - // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. - // monitor->set_obj(NULL); + // if ((displaced_header = monitor->displaced_header()) == nullptr) { + // // Recursive unlock. Mark the monitor unlocked by setting the object field to null. + // monitor->set_obj(nullptr); // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { // // We swapped the unlocked mark in displaced_header into the object's mark word. - // monitor->set_obj(NULL); + // monitor->set_obj(nullptr); // } else { // // Slow path. // InterpreterRuntime::monitorexit(monitor); @@ -1120,9 +1120,9 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) assert_different_registers(monitor, object, displaced_header, current_header); - // if ((displaced_header = monitor->displaced_header()) == NULL) { - // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. - // monitor->set_obj(NULL); + // if ((displaced_header = monitor->displaced_header()) == nullptr) { + // // Recursive unlock. Mark the monitor unlocked by setting the object field to null. + // monitor->set_obj(nullptr); clear_mem(obj_entry, sizeof(oop)); @@ -1134,7 +1134,7 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { // // We swapped the unlocked mark in displaced_header into the object's mark word. - // monitor->set_obj(NULL); + // monitor->set_obj(nullptr); // If we still have a lightweight lock, unlock the object and be done. @@ -1176,7 +1176,7 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { Register method = Z_ARG5; get_method(method); - // Test MDO to avoid the call if it is NULL. + // Test MDO to avoid the call if it is null. load_and_test_long(mdp, method2_(method, method_data)); z_brz(set_mdp); @@ -1462,7 +1462,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( } // In the fall-through case, we found no matching receiver, but we - // observed the receiver[start_row] is NULL. + // observed the receiver[start_row] is null. // Fill in the receiver field and increment the count. int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); @@ -1478,13 +1478,13 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( // Example state machine code for three profile rows: // // main copy of decision tree, rooted at row[1] // if (row[0].rec == rec) { row[0].incr(); goto done; } -// if (row[0].rec != NULL) { +// if (row[0].rec != nullptr) { // // inner copy of decision tree, rooted at row[1] // if (row[1].rec == rec) { row[1].incr(); goto done; } -// if (row[1].rec != NULL) { +// if (row[1].rec != nullptr) { // // degenerate decision tree, rooted at row[2] // if (row[2].rec == rec) { row[2].incr(); goto done; } -// if (row[2].rec != NULL) { count.incr(); goto done; } // overflow +// if (row[2].rec != nullptr) { count.incr(); goto done; } // overflow // row[2].init(rec); goto done; // } else { // // remember row[1] is empty diff --git a/src/hotspot/cpu/s390/interpreterRT_s390.cpp b/src/hotspot/cpu/s390/interpreterRT_s390.cpp index 6d88d71b862..d1f4a48b93b 100644 --- a/src/hotspot/cpu/s390/interpreterRT_s390.cpp +++ b/src/hotspot/cpu/s390/interpreterRT_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -118,10 +118,10 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { as_Register(int_arg_nr) + Z_ARG1->encoding() : Z_R0; // The handle for a receiver will never be null. - bool do_NULL_check = offset() != 0 || is_static(); + bool do_nullptr_check = offset() != 0 || is_static(); Label do_null; - if (do_NULL_check) { + if (do_nullptr_check) { __ clear_reg(r, true, false); __ load_and_test_long(Z_R0, locals_j_arg_at(offset())); __ z_bre(do_null); diff --git a/src/hotspot/cpu/s390/javaFrameAnchor_s390.hpp b/src/hotspot/cpu/s390/javaFrameAnchor_s390.hpp index 9f401d89c28..ae8b8766159 100644 --- a/src/hotspot/cpu/s390/javaFrameAnchor_s390.hpp +++ b/src/hotspot/cpu/s390/javaFrameAnchor_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,11 +37,11 @@ inline void clear(void) { // Clearing _last_Java_sp must be first. OrderAccess::release(); - _last_Java_sp = NULL; + _last_Java_sp = nullptr; // Fence? OrderAccess::fence(); - _last_Java_pc = NULL; + _last_Java_pc = nullptr; } inline void set(intptr_t* sp, address pc) { @@ -55,12 +55,12 @@ // In order to make sure the transition state is valid for "this" // we must clear _last_Java_sp before copying the rest of the new data. // Hack Alert: Temporary bugfix for 4717480/4721647 - // To act like previous version (pd_cache_state) don't NULL _last_Java_sp + // To act like previous version (pd_cache_state) don't null _last_Java_sp // unless the value is changing. // if (_last_Java_sp != src->_last_Java_sp) { OrderAccess::release(); - _last_Java_sp = NULL; + _last_Java_sp = nullptr; OrderAccess::fence(); } _last_Java_pc = src->_last_Java_pc; @@ -77,7 +77,7 @@ public: // We don't have a frame pointer. - intptr_t* last_Java_fp(void) { return NULL; } + intptr_t* last_Java_fp(void) { return nullptr; } intptr_t* last_Java_sp() const { return _last_Java_sp; } void set_last_Java_sp(intptr_t* sp) { OrderAccess::release(); _last_Java_sp = sp; } diff --git a/src/hotspot/cpu/s390/jniFastGetField_s390.cpp b/src/hotspot/cpu/s390/jniFastGetField_s390.cpp index c58090b5a2f..01b0bd528a8 100644 --- a/src/hotspot/cpu/s390/jniFastGetField_s390.cpp +++ b/src/hotspot/cpu/s390/jniFastGetField_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -58,7 +58,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { case T_FLOAT: name = "jni_fast_GetFloatField"; break; case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; default: ShouldNotReachHere(); - name = NULL; // unreachable + name = nullptr; // unreachable } ResourceMark rm; BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); @@ -129,7 +129,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; default: ShouldNotReachHere(); - slow_case_addr = NULL; // unreachable + slow_case_addr = nullptr; // unreachable } __ load_const_optimized(Robj, slow_case_addr); __ z_br(Robj); // tail call diff --git a/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp b/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp index 8849c65c37d..4318703ad38 100644 --- a/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp +++ b/src/hotspot/cpu/s390/jvmciCodeInstaller_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -77,7 +77,7 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark) { // Convert JVMCI register indices (as used in oop maps) to HotSpot registers. VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) { - return NULL; + return nullptr; } bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) { diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index a1c72d69262..50a4f1bc438 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -887,7 +887,7 @@ void MacroAssembler::load_double_largeoffset(FloatRegister t, int64_t si20, Regi // Returns 0 (zero) if no consts section exists or if it has size zero. long MacroAssembler::toc_distance() { CodeSection* cs = code()->consts(); - return (long)((cs != NULL) ? cs->start()-pc() : 0); + return (long)((cs != nullptr) ? cs->start()-pc() : 0); } // Implementation on x86/sparc assumes that constant and instruction section are @@ -1142,9 +1142,9 @@ Address MacroAssembler::argument_address(RegisterOrConstant arg_slot, // referring to a position-fixed target location. // If not so, relocations and patching must be used. void MacroAssembler::load_absolute_address(Register d, address addr) { - assert(addr != NULL, "should not happen"); + assert(addr != nullptr, "should not happen"); BLOCK_COMMENT("load_absolute_address:"); - if (addr == NULL) { + if (addr == nullptr) { z_larl(d, pc()); // Dummy emit for size calc. return; } @@ -1795,27 +1795,27 @@ void MacroAssembler::compare_and_branch_optimized(Register r1, //=========================================================================== AddressLiteral MacroAssembler::allocate_metadata_address(Metadata* obj) { - assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + assert(oop_recorder() != nullptr, "this assembler needs an OopRecorder"); int index = oop_recorder()->allocate_metadata_index(obj); RelocationHolder rspec = metadata_Relocation::spec(index); return AddressLiteral((address)obj, rspec); } AddressLiteral MacroAssembler::constant_metadata_address(Metadata* obj) { - assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + assert(oop_recorder() != nullptr, "this assembler needs an OopRecorder"); int index = oop_recorder()->find_index(obj); RelocationHolder rspec = metadata_Relocation::spec(index); return AddressLiteral((address)obj, rspec); } AddressLiteral MacroAssembler::allocate_oop_address(jobject obj) { - assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + assert(oop_recorder() != nullptr, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->allocate_oop_index(obj); return AddressLiteral(address(obj), oop_Relocation::spec(oop_index)); } AddressLiteral MacroAssembler::constant_oop_address(jobject obj) { - assert(oop_recorder() != NULL, "this assembler needs an OopRecorder"); + assert(oop_recorder() != nullptr, "this assembler needs an OopRecorder"); int oop_index = oop_recorder()->find_index(obj); return AddressLiteral(address(obj), oop_Relocation::spec(oop_index)); } @@ -2172,7 +2172,7 @@ void MacroAssembler::call_VM_base(Register oop_result, // ARG1 must hold thread address. z_lgr(Z_ARG1, Z_thread); - address return_pc = NULL; + address return_pc = nullptr; if (allow_relocation) { return_pc = call_c(entry_point); } else { @@ -2377,7 +2377,7 @@ address MacroAssembler::call_c_static(address function_entry) { address MacroAssembler::call_c_opt(address function_entry) { bool success = call_far_patchable(function_entry, -2 /* emit relocation + constant */); - _last_calls_return_pc = success ? pc() : NULL; + _last_calls_return_pc = success ? pc() : nullptr; return _last_calls_return_pc; } @@ -2571,7 +2571,7 @@ address MacroAssembler::get_dest_of_call_far_patchable_at(address instruction_ad call_far_patchable_size()); Disassembler::decode(instruction_addr, instruction_addr+call_far_patchable_size()); ShouldNotReachHere(); - return NULL; + return nullptr; } } @@ -2632,7 +2632,7 @@ bool MacroAssembler::is_load_from_polling_page(address instr_loc) { // Extract poll address from instruction and ucontext. address MacroAssembler::get_poll_address(address instr_loc, void* ucontext) { - assert(ucontext != NULL, "must have ucontext"); + assert(ucontext != nullptr, "must have ucontext"); ucontext_t* uc = (ucontext_t*) ucontext; unsigned long z_instruction; unsigned int ilen = get_instruction(instr_loc, &z_instruction); @@ -2650,7 +2650,7 @@ address MacroAssembler::get_poll_address(address instr_loc, void* ucontext) { } ShouldNotReachHere(); - return NULL; + return nullptr; } // Extract poll register from instruction. @@ -2778,7 +2778,7 @@ void MacroAssembler::lookup_interface_method(Register recv_klass, bind(search); // Handle IncompatibleClassChangeError. - // If the entry is NULL then we've reached the end of the table + // If the entry is null then we've reached the end of the table // without finding the expected interface, so throw an exception. load_and_test_long(itable_interface, Address(itable_entry_addr)); z_bre(no_such_interface); @@ -2945,12 +2945,12 @@ void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, NearLabel L_fallthrough; int label_nulls = 0; - if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; } - if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; } - if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; } + if (L_success == nullptr) { L_success = &L_fallthrough; label_nulls++; } + if (L_failure == nullptr) { L_failure = &L_fallthrough; label_nulls++; } + if (L_slow_path == nullptr) { L_slow_path = &L_fallthrough; label_nulls++; } assert(label_nulls <= 1 || (L_slow_path == &L_fallthrough && label_nulls <= 2 && !need_slow_path), - "at most one NULL in the batch, usually"); + "at most one null in the batch, usually"); BLOCK_COMMENT("check_klass_subtype_fast_path {"); // If the pointers are equal, we are done (e.g., String[] elements). @@ -3031,9 +3031,9 @@ void MacroAssembler::check_klass_subtype_slow_path(Register Rsubklass, assert_different_registers(Z_R1, Rsubklass, Rsuperklass, Rarray_ptr, Rlength); NearLabel L_fallthrough; int label_nulls = 0; - if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; } - if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; } - assert(label_nulls <= 1, "at most one NULL in the batch"); + if (L_success == nullptr) { L_success = &L_fallthrough; label_nulls++; } + if (L_failure == nullptr) { L_failure = &L_fallthrough; label_nulls++; } + assert(label_nulls <= 1, "at most one null in the batch"); const int ss_offset = in_bytes(Klass::secondary_supers_offset()); const int sc_offset = in_bytes(Klass::secondary_super_cache_offset()); @@ -3100,20 +3100,20 @@ void MacroAssembler::check_klass_subtype(Register sub_klass, NearLabel failure; BLOCK_COMMENT(err_msg("check_klass_subtype(%s subclass of %s) {", sub_klass->name(), super_klass->name())); check_klass_subtype_fast_path(sub_klass, super_klass, temp1_reg, - &L_success, &failure, NULL); + &L_success, &failure, nullptr); check_klass_subtype_slow_path(sub_klass, super_klass, - temp1_reg, temp2_reg, &L_success, NULL); + temp1_reg, temp2_reg, &L_success, nullptr); BIND(failure); BLOCK_COMMENT("} check_klass_subtype"); } void MacroAssembler::clinit_barrier(Register klass, Register thread, Label* L_fast_path, Label* L_slow_path) { - assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required"); + assert(L_fast_path != nullptr || L_slow_path != nullptr, "at least one is required"); Label L_fallthrough; - if (L_fast_path == NULL) { + if (L_fast_path == nullptr) { L_fast_path = &L_fallthrough; - } else if (L_slow_path == NULL) { + } else if (L_slow_path == nullptr) { L_slow_path = &L_fallthrough; } @@ -3203,10 +3203,10 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis Register zero = temp; Register monitor_tagged = displacedHeader; // Tagged with markWord::monitor_value. bind(object_has_monitor); - // The object's monitor m is unlocked iff m->owner == NULL, + // The object's monitor m is unlocked iff m->owner is null, // otherwise m->owner may contain a thread or a stack address. // - // Try to CAS m->owner from NULL to current thread. + // Try to CAS m->owner from null to current thread. z_lghi(zero, 0); // If m->owner is null, then csg succeeds and sets m->owner=THREAD and CR=EQ. z_csg(zero, Z_thread, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), monitor_tagged); @@ -3306,7 +3306,7 @@ void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Ja } // When returning from calling out from Java mode the frame anchor's - // last_Java_pc will always be set to NULL. It is set here so that + // last_Java_pc will always be set to null. It is set here so that // if we are doing a call to native (not VM) that we capture the // known pc and don't have to rely on the native call having a // standard frame linkage where we can find the pc. @@ -3402,13 +3402,13 @@ void MacroAssembler::null_check(Register reg, Register tmp, int64_t offset) { bind(ok); } else { if (needs_explicit_null_check((intptr_t)offset)) { - // Provoke OS NULL exception if reg = NULL by + // Provoke OS null exception if reg is null by // accessing M[reg] w/o changing any registers. z_lg(tmp, 0, reg); } // else // Nothing to do, (later) access of M[reg + offset] - // will provoke OS NULL exception if reg = NULL. + // will provoke OS null exception if reg is null. } } @@ -3447,7 +3447,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) { current = dst; } - if (base != NULL) { + if (base != nullptr) { // Use scaled-down base address parts to match scaled-down klass pointer. unsigned int base_h = ((unsigned long)base)>>(32+shift); unsigned int base_l = (unsigned int)(((unsigned long)base)>>shift); @@ -3514,7 +3514,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) { // This function calculates the size of the code generated by // decode_klass_not_null(register dst, Register src) -// when (Universe::heap() != NULL). Hence, if the instructions +// when Universe::heap() isn't null. Hence, if the instructions // it generates change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { address base = CompressedKlassPointers::base(); @@ -3522,7 +3522,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() { int addbase_size = 0; assert(UseCompressedClassPointers, "only for compressed klass ptrs"); - if (base != NULL) { + if (base != nullptr) { unsigned int base_h = ((unsigned long)base)>>32; unsigned int base_l = (unsigned int)((unsigned long)base); if ((base_h != 0) && (base_l == 0) && VM_Version::has_HighWordInstr()) { @@ -3557,7 +3557,7 @@ void MacroAssembler::decode_klass_not_null(Register dst) { if (shift != 0) { // Shift required? z_sllg(dst, dst, shift); } - if (base != NULL) { + if (base != nullptr) { unsigned int base_h = ((unsigned long)base)>>32; unsigned int base_l = (unsigned int)((unsigned long)base); if ((base_h != 0) && (base_l == 0) && VM_Version::has_HighWordInstr()) { @@ -3604,7 +3604,7 @@ void MacroAssembler::decode_klass_not_null(Register dst, Register src) { lgr_if_needed(dst, src); } - if (base != NULL) { + if (base != nullptr) { unsigned int base_h = ((unsigned long)base)>>32; unsigned int base_l = (unsigned int)((unsigned long)base); if ((base_h != 0) && (base_l == 0) && VM_Version::has_HighWordInstr()) { @@ -3679,8 +3679,8 @@ void MacroAssembler::store_klass_gap(Register s, Register d) { // Rop1 - klass in register, always uncompressed. // disp - Offset of klass in memory, compressed/uncompressed, depending on runtime flag. // Rbase - Base address of cKlass in memory. -// maybeNULL - True if Rop1 possibly is a NULL. -void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybeNULL) { +// maybenull - True if Rop1 possibly is a null. +void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybenull) { BLOCK_COMMENT("compare klass ptr {"); @@ -3694,7 +3694,7 @@ void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rba // First encode register oop and then compare with cOop in memory. // This sequence saves an unnecessary cOop load and decode. - if (base == NULL) { + if (base == nullptr) { if (shift == 0) { z_cl(Rop1, disp, Rbase); // Unscaled } else { @@ -3709,7 +3709,7 @@ void MacroAssembler::compare_klass_ptr(Register Rop1, int64_t disp, Register Rba Register current = Rop1; Label done; - if (maybeNULL) { // NULL ptr must be preserved! + if (maybenull) { // null ptr must be preserved! z_ltgr(Z_R0, current); z_bre(done); current = Z_R0; @@ -3812,9 +3812,9 @@ int MacroAssembler::get_oop_base_complement(Register Rbase, uint64_t oop_base) { // Rop1 - Oop in register. // disp - Offset of cOop in memory. // Rbase - Base address of cOop in memory. -// maybeNULL - True if Rop1 possibly is a NULL. -// maybeNULLtarget - Branch target for Rop1 == NULL, if flow control shall NOT continue with compare instruction. -void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL) { +// maybenull - True if Rop1 possibly is a null. +// maybenulltarget - Branch target for Rop1 == nullptr, if flow control shall NOT continue with compare instruction. +void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybenull) { Register Rbase = mem.baseOrR0(); Register Rindex = mem.indexOrR0(); int64_t disp = mem.disp(); @@ -3823,7 +3823,7 @@ void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL address base = CompressedOops::base(); assert(UseCompressedOops, "must be on to call this method"); - assert(Universe::heap() != NULL, "java heap must be initialized to call this method"); + assert(Universe::heap() != nullptr, "java heap must be initialized to call this method"); assert((shift == 0) || (shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); assert_different_registers(Rop1, Z_R0); assert_different_registers(Rop1, Rbase, Z_R1); @@ -3833,7 +3833,7 @@ void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL // First encode register oop and then compare with cOop in memory. // This sequence saves an unnecessary cOop load and decode. - if (base == NULL) { + if (base == nullptr) { if (shift == 0) { z_cl(Rop1, disp, Rindex, Rbase); // Unscaled } else { @@ -3848,7 +3848,7 @@ void MacroAssembler::compare_heap_oop(Register Rop1, Address mem, bool maybeNULL Label done; int pow2_offset = get_oop_base_complement(Z_R1, ((uint64_t)(intptr_t)base)); - if (maybeNULL) { // NULL ptr must be preserved! + if (maybenull) { // null ptr must be preserved! z_ltgr(Z_R0, Rop1); z_bre(done); } @@ -3928,7 +3928,7 @@ void MacroAssembler::store_heap_oop(Register Roop, const Address &a, // // only32bitValid is set, if later code only uses the lower 32 bits. In this // case we must not fix the upper 32 bits. -void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, +void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybenull, Register Rbase, int pow2_offset, bool only32bitValid) { const address oop_base = CompressedOops::base(); @@ -3936,20 +3936,20 @@ void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, const bool disjoint = CompressedOops::base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); - assert(Universe::heap() != NULL, "java heap must be initialized to call this encoder"); + assert(Universe::heap() != nullptr, "java heap must be initialized to call this encoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); - if (disjoint || (oop_base == NULL)) { + if (disjoint || (oop_base == nullptr)) { BLOCK_COMMENT("cOop encoder zeroBase {"); if (oop_shift == 0) { - if (oop_base != NULL && !only32bitValid) { + if (oop_base != nullptr && !only32bitValid) { z_llgfr(Rdst, Rsrc); // Clear upper bits in case the register will be decoded again. } else { lgr_if_needed(Rdst, Rsrc); } } else { z_srlg(Rdst, Rsrc, oop_shift); - if (oop_base != NULL && !only32bitValid) { + if (oop_base != nullptr && !only32bitValid) { z_llgfr(Rdst, Rdst); // Clear upper bits in case the register will be decoded again. } } @@ -3963,7 +3963,7 @@ void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, BLOCK_COMMENT("cOop encoder general {"); assert_different_registers(Rdst, Z_R1); assert_different_registers(Rsrc, Rbase); - if (maybeNULL) { + if (maybenull) { Label done; // We reorder shifting and subtracting, so that we can compare // and shift in parallel: @@ -3990,7 +3990,7 @@ void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, } assert_different_registers(Rdst, Rbase); - // Check for NULL oop (must be left alone) and shift. + // Check for null oop (must be left alone) and shift. if (oop_shift != 0) { // Shift out alignment bits if (((intptr_t)oop_base&0xc000000000000000L) == 0L) { // We are sure: no single address will have the leftmost bit set. z_srag(Rdst, Rsrc, oop_shift); // Arithmetic shift sets the condition code. @@ -4001,7 +4001,7 @@ void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, // z_cghi(Rsrc, 0); } } else { - z_ltgr(Rdst, Rsrc); // Move NULL to result register. + z_ltgr(Rdst, Rsrc); // Move null to result register. } z_bre(done); @@ -4064,20 +4064,20 @@ void MacroAssembler::oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, // - avoid Z_R0 for any of the argument registers. // - keep Rdst and Rsrc distinct from Rbase. Rdst == Rsrc is ok for performance. // - avoid Z_R1 for Rdst if Rdst == Rbase. -void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, Register Rbase, int pow2_offset) { +void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybenull, Register Rbase, int pow2_offset) { const address oop_base = CompressedOops::base(); const int oop_shift = CompressedOops::shift(); const bool disjoint = CompressedOops::base_disjoint(); assert(UseCompressedOops, "must be on to call this method"); - assert(Universe::heap() != NULL, "java heap must be initialized to call this decoder"); + assert(Universe::heap() != nullptr, "java heap must be initialized to call this decoder"); assert((oop_shift == 0) || (oop_shift == LogMinObjAlignmentInBytes), "cOop encoder detected bad shift"); // cOops are always loaded zero-extended from memory. No explicit zero-extension necessary. - if (oop_base != NULL) { + if (oop_base != nullptr) { unsigned int oop_base_hl = ((unsigned int)((uint64_t)(intptr_t)oop_base >> 32)) & 0xffff; unsigned int oop_base_hh = ((unsigned int)((uint64_t)(intptr_t)oop_base >> 48)) & 0xffff; unsigned int oop_base_hf = ((unsigned int)((uint64_t)(intptr_t)oop_base >> 32)) & 0xFFFFffff; @@ -4088,7 +4088,7 @@ void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, R Label done; // Rsrc contains a narrow oop. Thus we are sure the leftmost bits will never be set. - if (maybeNULL) { // NULL ptr must be preserved! + if (maybenull) { // null ptr must be preserved! z_slag(Rdst, Rsrc, oop_shift); // Arithmetic shift sets the condition code. z_bre(done); } else { @@ -4148,9 +4148,9 @@ void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, R } if (base_preloaded) lgr_if_needed(Rbase_tmp, Rbase); - // Scale oop and check for NULL. + // Scale oop and check for null. // Rsrc contains a narrow oop. Thus we are sure the leftmost bits will never be set. - if (maybeNULL) { // NULL ptr must be preserved! + if (maybenull) { // null ptr must be preserved! z_slag(Rdst_tmp, Rsrc, oop_shift); // Arithmetic shift sets the condition code. z_bre(done); } else { @@ -4428,11 +4428,11 @@ int MacroAssembler::store_const_in_toc(AddressLiteral& val) { long value = val.value(); address tocPos = long_constant(value); - if (tocPos != NULL) { + if (tocPos != nullptr) { int tocOffset = (int)(tocPos - code()->consts()->start()); return tocOffset; } - // Address_constant returned NULL, so no constant entry has been created. + // Address_constant returned null, so no constant entry has been created. // In that case, we return a "fatal" offset, just in case that subsequently // generated access code is executed. return -1; @@ -4446,7 +4446,7 @@ int MacroAssembler::store_oop_in_toc(AddressLiteral& oop) { // where x is the address of the constant pool entry. address tocPos = address_constant((address)oop.value(), RelocationHolder::none); - if (tocPos != NULL) { + if (tocPos != nullptr) { int tocOffset = (int)(tocPos - code()->consts()->start()); RelocationHolder rsp = oop.rspec(); Relocation *rel = rsp.reloc(); @@ -4460,7 +4460,7 @@ int MacroAssembler::store_oop_in_toc(AddressLiteral& oop) { return tocOffset; } - // Address_constant returned NULL, so no constant entry has been created + // Address_constant returned null, so no constant entry has been created // in that case, we return a "fatal" offset, just in case that subsequently // generated access code is executed. return -1; @@ -4470,7 +4470,7 @@ bool MacroAssembler::load_const_from_toc(Register dst, AddressLiteral& a, Regist int tocOffset = store_const_in_toc(a); if (tocOffset == -1) return false; address tocPos = tocOffset + code()->consts()->start(); - assert((address)code()->consts()->start() != NULL, "Please add CP address"); + assert((address)code()->consts()->start() != nullptr, "Please add CP address"); relocate(a.rspec()); load_long_pcrelative(dst, tocPos); return true; @@ -4480,7 +4480,7 @@ bool MacroAssembler::load_oop_from_toc(Register dst, AddressLiteral& a, Register int tocOffset = store_oop_in_toc(a); if (tocOffset == -1) return false; address tocPos = tocOffset + code()->consts()->start(); - assert((address)code()->consts()->start() != NULL, "Please add CP address"); + assert((address)code()->consts()->start() != nullptr, "Please add CP address"); load_addr_pcrelative(dst, tocPos); return true; @@ -4494,7 +4494,7 @@ intptr_t MacroAssembler::get_const_from_toc(address pc) { assert(is_load_const_from_toc(pc), "must be load_const_from_pool"); long offset = get_load_const_from_toc_offset(pc); - address dataLoc = NULL; + address dataLoc = nullptr; if (is_load_const_from_toc_pcrelative(pc)) { dataLoc = pc + offset; } else { @@ -4513,12 +4513,12 @@ void MacroAssembler::set_const_in_toc(address pc, unsigned long new_data, CodeBl assert(is_load_const_from_toc(pc), "must be load_const_from_pool"); long offset = MacroAssembler::get_load_const_from_toc_offset(pc); - address dataLoc = NULL; + address dataLoc = nullptr; if (is_load_const_from_toc_pcrelative(pc)) { dataLoc = pc+offset; } else { nmethod* nm = CodeCache::find_nmethod(pc); - assert((cb == NULL) || (nm == (nmethod*)cb), "instruction address should be in CodeBlob"); + assert((cb == nullptr) || (nm == (nmethod*)cb), "instruction address should be in CodeBlob"); dataLoc = nm->ctable_begin() + offset; } if (*(unsigned long *)dataLoc != new_data) { // Prevent cache invalidation: update only if necessary. @@ -5534,7 +5534,7 @@ void MacroAssembler::stop(int type, const char* msg, int id) { // should be given for "hand-written" code, if all chain calls are in the same code blob. // Generated code must not undergo any transformation, e.g. ShortenBranches, to be safe. address MacroAssembler::stop_chain(address reentry, int type, const char* msg, int id, bool allow_relocation) { - BLOCK_COMMENT(err_msg("stop_chain(%s,%s): %s {", reentry==NULL?"init":"cont", allow_relocation?"reloc ":"static", msg)); + BLOCK_COMMENT(err_msg("stop_chain(%s,%s): %s {", reentry==nullptr?"init":"cont", allow_relocation?"reloc ":"static", msg)); // Setup arguments. if (allow_relocation) { @@ -5545,7 +5545,7 @@ address MacroAssembler::stop_chain(address reentry, int type, const char* msg, i load_absolute_address(Z_ARG1, (address)stop_types[type%stop_end]); load_absolute_address(Z_ARG2, (address)msg); } - if ((reentry != NULL) && RelAddr::is_in_range_of_RelAddr16(reentry, pc())) { + if ((reentry != nullptr) && RelAddr::is_in_range_of_RelAddr16(reentry, pc())) { BLOCK_COMMENT("branch to reentry point:"); z_brc(bcondAlways, reentry); } else { @@ -5554,7 +5554,7 @@ address MacroAssembler::stop_chain(address reentry, int type, const char* msg, i save_return_pc(); // Saves return pc Z_R14. push_frame_abi160(0); if (allow_relocation) { - reentry = NULL; // Prevent reentry if code relocation is allowed. + reentry = nullptr; // Prevent reentry if code relocation is allowed. call_VM_leaf(CAST_FROM_FN_PTR(address, stop_on_request), Z_ARG1, Z_ARG2); } else { call_VM_leaf_static(CAST_FROM_FN_PTR(address, stop_on_request), Z_ARG1, Z_ARG2); @@ -5569,7 +5569,7 @@ address MacroAssembler::stop_chain(address reentry, int type, const char* msg, i // Special version of stop() for code size reduction. // Assumes constant relative addresses for data and runtime call. void MacroAssembler::stop_static(int type, const char* msg, int id) { - stop_chain(NULL, type, msg, id, false); + stop_chain(nullptr, type, msg, id, false); } void MacroAssembler::stop_subroutine() { diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index f5181bbb6da..c4ba4562598 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -679,7 +679,7 @@ class MacroAssembler: public Assembler { // Test sub_klass against super_klass, with fast and slow paths. // The fast path produces a tri-state answer: yes / no / maybe-slow. - // One of the three labels can be NULL, meaning take the fall-through. + // One of the three labels can be null, meaning take the fall-through. // If super_check_offset is -1, the value is loaded up from super_klass. // No registers are killed, except temp_reg and temp2_reg. // If super_check_offset is not -1, temp1_reg is not used and can be noreg. @@ -713,8 +713,8 @@ class MacroAssembler: public Assembler { void clinit_barrier(Register klass, Register thread, - Label* L_fast_path = NULL, - Label* L_slow_path = NULL); + Label* L_fast_path = nullptr, + Label* L_slow_path = nullptr); // Increment a counter at counter_address when the eq condition code is set. // Kills registers tmp1_reg and tmp2_reg and preserves the condition code. @@ -747,9 +747,9 @@ class MacroAssembler: public Assembler { // Vm result is currently getting hijacked to for oop preservation. void set_vm_result(Register oop_result); - // Support for NULL-checks + // Support for null-checks // - // Generates code that causes a NULL OS exception if the content of reg is NULL. + // Generates code that causes a null OS exception if the content of reg is null. // If the accessed location is M[reg + offset] and the offset is known, provide the // offset. No explicit code generation is needed if the offset is within a certain // range (0 <= offset <= page_size). @@ -771,7 +771,7 @@ class MacroAssembler: public Assembler { // This function calculates the size of the code generated by // decode_klass_not_null(register dst) - // when (Universe::heap() != NULL). Hence, if the instructions + // when Universe::heap() isn't null. Hence, if the instructions // it generates change, then this method needs to be updated. static int instr_size_for_decode_klass_not_null(); @@ -781,8 +781,8 @@ class MacroAssembler: public Assembler { static int get_oop_base_pow2_offset(uint64_t oop_base); int get_oop_base(Register Rbase, uint64_t oop_base); int get_oop_base_complement(Register Rbase, uint64_t oop_base); - void compare_heap_oop(Register Rop1, Address mem, bool maybeNULL); - void compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybeNULL); + void compare_heap_oop(Register Rop1, Address mem, bool maybenull); + void compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybenull); // Access heap oop, handle encoding and GC barriers. private: @@ -791,20 +791,20 @@ class MacroAssembler: public Assembler { Register tmp1, Register tmp2, Register tmp3); void access_load_at(BasicType type, DecoratorSet decorators, const Address& addr, Register dst, - Register tmp1, Register tmp2, Label *is_null = NULL); + Register tmp1, Register tmp2, Label *is_null = nullptr); public: // tmp1 and tmp2 are used with decorators ON_PHANTOM_OOP_REF or ON_WEAK_OOP_REF. void load_heap_oop(Register dest, const Address &a, Register tmp1, Register tmp2, - DecoratorSet decorators = 0, Label *is_null = NULL); + DecoratorSet decorators = 0, Label *is_null = nullptr); void store_heap_oop(Register Roop, const Address &a, Register tmp1, Register tmp2, Register tmp3, DecoratorSet decorators = 0); - void oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL, + void oop_encoder(Register Rdst, Register Rsrc, bool maybenull, Register Rbase = Z_R1, int pow2_offset = -1, bool only32bitValid = false); - void oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, + void oop_decoder(Register Rdst, Register Rsrc, bool maybenull, Register Rbase = Z_R1, int pow2_offset = -1); void resolve_oop_handle(Register result); diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index d683f35a8a4..0ab944a5426 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -71,7 +71,7 @@ // Set this as clone_shift_expressions. static bool narrow_oop_use_complex_address() { - if (CompressedOops::base() == NULL && CompressedOops::shift() == 0) return true; + if (CompressedOops::base() == nullptr && CompressedOops::shift() == 0) return true; return false; } @@ -84,12 +84,12 @@ static bool const_oop_prefer_decode() { // Prefer ConN+DecodeN over ConP in simple compressed oops mode. - return CompressedOops::base() == NULL; + return CompressedOops::base() == nullptr; } static bool const_klass_prefer_decode() { // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. - return CompressedKlassPointers::base() == NULL; + return CompressedKlassPointers::base() == nullptr; } // Is it better to copy float constants, or load them directly from memory? diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp index 0841d22db72..318f51cf97e 100644 --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp @@ -180,7 +180,7 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth __ z_br(target); __ bind(L_no_such_method); - assert(StubRoutines::throw_AbstractMethodError_entry() != NULL, "not yet generated!"); + assert(StubRoutines::throw_AbstractMethodError_entry() != nullptr, "not yet generated!"); __ load_const_optimized(target, StubRoutines::throw_AbstractMethodError_entry()); __ z_br(target); } @@ -249,14 +249,14 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* // adapters via MethodHandleNatives.linkMethod. They all allow an // appendix argument. __ should_not_reach_here(); // Empty stubs make SG sick. - return NULL; + return nullptr; } // No need in interpreter entry for linkToNative for now. // Interpreter calls compiled entry through i2c. if (iid == vmIntrinsics::_linkToNative) { __ should_not_reach_here(); // Empty stubs make SG sick. - return NULL; + return nullptr; } // Z_R10: sender SP (must preserve; see prepare_to_jump_from_interprted) @@ -559,8 +559,8 @@ void trace_method_handle_stub(const char* adaptername, intptr_t* sender_sp, intptr_t* args, intptr_t* tracing_fp) { - bool has_mh = (strstr(adaptername, "/static") == NULL && - strstr(adaptername, "linkTo") == NULL); // Static linkers don't have MH. + bool has_mh = (strstr(adaptername, "/static") == nullptr && + strstr(adaptername, "linkTo") == nullptr); // Static linkers don't have MH. const char* mh_reg_name = has_mh ? "Z_R4_mh" : "Z_R4"; log_info(methodhandles)("MH %s %s=" INTPTR_FORMAT " sender_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, mh_reg_name, diff --git a/src/hotspot/cpu/s390/nativeInst_s390.cpp b/src/hotspot/cpu/s390/nativeInst_s390.cpp index c1c395b6697..95178e9ae74 100644 --- a/src/hotspot/cpu/s390/nativeInst_s390.cpp +++ b/src/hotspot/cpu/s390/nativeInst_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -55,7 +55,7 @@ void NativeInstruction::verify() { // Make sure code pattern is actually an instruction address. // Do not allow: - // - NULL + // - null // - any address in first page (0x0000 .. 0x0fff) // - odd address (will cause a "specification exception") address addr = addr_at(0); @@ -68,7 +68,7 @@ void NativeInstruction::verify() { // Print location and value (hex representation) of current NativeInstruction void NativeInstruction::print(const char* msg) const { int len = Assembler::instr_len(addr_at(0)); - if (msg == NULL) { // Output line without trailing blanks. + if (msg == nullptr) { // Output line without trailing blanks. switch (len) { case 2: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x", p2i(addr_at(0)), len, halfword_at(0)); break; case 4: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %4.4x", p2i(addr_at(0)), len, halfword_at(0), halfword_at(2)); break; @@ -89,20 +89,20 @@ void NativeInstruction::print(const char* msg) const { } } void NativeInstruction::print() const { - print(NULL); + print(nullptr); } // Hex-Dump of storage around current NativeInstruction. Also try disassembly. void NativeInstruction::dump(const unsigned int range, const char* msg) const { - Assembler::dump_code_range(tty, addr_at(0), range, (msg == NULL) ? "":msg); + Assembler::dump_code_range(tty, addr_at(0), range, (msg == nullptr) ? "":msg); } void NativeInstruction::dump(const unsigned int range) const { - dump(range, NULL); + dump(range, nullptr); } void NativeInstruction::dump() const { - dump(32, NULL); + dump(32, nullptr); } void NativeInstruction::set_halfword_at(int offset, short i) { @@ -176,7 +176,7 @@ bool NativeInstruction::is_sigill_not_entrant() { // (see implementation of is_illegal() for details). CodeBlob* cb = CodeCache::find_blob(addr_at(0)); - if (cb == NULL || !cb->is_nmethod()) { + if (cb == nullptr || !cb->is_nmethod()) { return false; } @@ -255,7 +255,7 @@ void NativeFarCall::verify() { address NativeFarCall::destination() { assert(MacroAssembler::is_call_far_patchable_at((address)this), "unexpected call type"); - address ctable = NULL; + address ctable = nullptr; return MacroAssembler::get_dest_of_call_far_patchable_at((address)this, ctable); } @@ -368,7 +368,7 @@ address NativeMovConstReg::next_instruction_address(int offset) const { #else guarantee(false, "Not a NativeMovConstReg site"); #endif - return NULL; + return nullptr; } intptr_t NativeMovConstReg::data() const { @@ -385,7 +385,7 @@ intptr_t NativeMovConstReg::data() const { #else ShouldNotReachHere(); #endif - return *(intptr_t *)NULL; + return *(intptr_t *)nullptr; } else { // Otherwise, assume data resides in TOC. Is asserted in called method. return MacroAssembler::get_const_from_toc(loc); @@ -481,15 +481,15 @@ void NativeMovConstReg::set_data(intptr_t data, relocInfo::relocType expected_ty address next_address = set_data_plain(data, cb); // 'RelocIterator' requires an nmethod - nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; - if (nm != NULL) { + nmethod* nm = cb ? cb->as_nmethod_or_null() : nullptr; + if (nm != nullptr) { RelocIterator iter(nm, instruction_address(), next_address); - oop* oop_addr = NULL; - Metadata** metadata_addr = NULL; + oop* oop_addr = nullptr; + Metadata** metadata_addr = nullptr; while (iter.next()) { if (iter.type() == relocInfo::oop_type) { oop_Relocation *r = iter.oop_reloc(); - if (oop_addr == NULL) { + if (oop_addr == nullptr) { oop_addr = r->oop_addr(); *oop_addr = cast_to_oop(data); } else { @@ -498,7 +498,7 @@ void NativeMovConstReg::set_data(intptr_t data, relocInfo::relocType expected_ty } if (iter.type() == relocInfo::metadata_type) { metadata_Relocation *r = iter.metadata_reloc(); - if (metadata_addr == NULL) { + if (metadata_addr == nullptr) { metadata_addr = r->metadata_addr(); *metadata_addr = (Metadata*)data; } else { @@ -507,8 +507,8 @@ void NativeMovConstReg::set_data(intptr_t data, relocInfo::relocType expected_ty } } assert(expected_type == relocInfo::none || - (expected_type == relocInfo::metadata_type && metadata_addr != NULL) || - (expected_type == relocInfo::oop_type && oop_addr != NULL), + (expected_type == relocInfo::metadata_type && metadata_addr != nullptr) || + (expected_type == relocInfo::oop_type && oop_addr != nullptr), "%s relocation not found", expected_type == relocInfo::oop_type ? "oop" : "metadata"); } } @@ -540,7 +540,7 @@ void NativeMovConstReg::set_narrow_klass(intptr_t data) { ICache::invalidate_range(start, range); } -void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passed_nm /* = NULL */) { +void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passed_nm /* = nullptr */) { address next_address; address loc = addr_at(0); @@ -565,7 +565,7 @@ void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passe } } -void NativeMovConstReg::set_pcrel_data(intptr_t newData, CompiledMethod *passed_nm /* = NULL */) { +void NativeMovConstReg::set_pcrel_data(intptr_t newData, CompiledMethod *passed_nm /* = nullptr */) { address next_address; address loc = addr_at(0); diff --git a/src/hotspot/cpu/s390/nativeInst_s390.hpp b/src/hotspot/cpu/s390/nativeInst_s390.hpp index 8cd03e0cfa0..65bfe499370 100644 --- a/src/hotspot/cpu/s390/nativeInst_s390.hpp +++ b/src/hotspot/cpu/s390/nativeInst_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -257,7 +257,7 @@ class NativeCall: public NativeInstruction { ((NativeCall*)iaddr)->print(); guarantee(false, "Not a NativeCall site"); - return NULL; + return nullptr; } address return_address() const { @@ -325,7 +325,7 @@ class NativeCall: public NativeInstruction { // instruction, is always prepended with a NOP. This measure avoids // ambiguities with load_const_from_toc_call. friend NativeCall* nativeCall_before(address return_address) { - NativeCall *call = NULL; + NativeCall *call = nullptr; // Make sure not to return garbage address instp = return_address - MacroAssembler::load_const_call_size(); @@ -486,8 +486,8 @@ class NativeMovConstReg: public NativeInstruction { // Patch narrow oop constant in code stream. void set_narrow_oop(intptr_t data); void set_narrow_klass(intptr_t data); - void set_pcrel_addr(intptr_t addr, CompiledMethod *nm = NULL); - void set_pcrel_data(intptr_t data, CompiledMethod *nm = NULL); + void set_pcrel_addr(intptr_t addr, CompiledMethod *nm = nullptr); + void set_pcrel_data(intptr_t data, CompiledMethod *nm = nullptr); void verify(); @@ -664,13 +664,13 @@ public: inline NativePostCallNop* nativePostCallNop_at(address address) { // Unimplemented(); - return NULL; + return nullptr; } class NativeDeoptInstruction: public NativeInstruction { public: - address instruction_address() const { Unimplemented(); return NULL; } - address next_instruction_address() const { Unimplemented(); return NULL; } + address instruction_address() const { Unimplemented(); return nullptr; } + address next_instruction_address() const { Unimplemented(); return nullptr; } void verify() { Unimplemented(); } diff --git a/src/hotspot/cpu/s390/registerMap_s390.hpp b/src/hotspot/cpu/s390/registerMap_s390.hpp index 74cf3855fa6..827e3b44e04 100644 --- a/src/hotspot/cpu/s390/registerMap_s390.hpp +++ b/src/hotspot/cpu/s390/registerMap_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,8 +33,8 @@ private: // This is the hook for finding a register in a "well-known" location, // such as a register block of a predetermined format. - // Since there is none, we just return NULL. - address pd_location(VMReg reg) const {return NULL;} + // Since there is none, we just return null. + address pd_location(VMReg reg) const {return nullptr;} address pd_location(VMReg base_reg, int slot_idx) const { return location(base_reg->next(slot_idx), nullptr); diff --git a/src/hotspot/cpu/s390/relocInfo_s390.cpp b/src/hotspot/cpu/s390/relocInfo_s390.cpp index 9fcefd77962..747ae9c535d 100644 --- a/src/hotspot/cpu/s390/relocInfo_s390.cpp +++ b/src/hotspot/cpu/s390/relocInfo_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -99,7 +99,7 @@ address Relocation::pd_call_destination(address orig_addr) { return (address)(-1); } NativeFarCall* call; - if (orig_addr == NULL) { + if (orig_addr == nullptr) { call = nativeFarCall_at(inst_addr); } else { // must access location (in CP) where destination is stored in unmoved code, because load from CP is pc-relative diff --git a/src/hotspot/cpu/s390/runtime_s390.cpp b/src/hotspot/cpu/s390/runtime_s390.cpp index 978c036316e..6e128d2c393 100644 --- a/src/hotspot/cpu/s390/runtime_s390.cpp +++ b/src/hotspot/cpu/s390/runtime_s390.cpp @@ -114,12 +114,12 @@ void OptoRuntime::generate_exception_blob() { // Pop the exception blob's C frame that has been pushed before. __ z_lgr(Z_SP, saved_sp); - // [Z_RET]!=NULL was possible in hotspot5 but not in sapjvm6. + // [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 // (unwind_initial_activation_pending_exception). #ifdef ASSERT __ z_ltgr(handle_exception, handle_exception); - __ asm_assert_ne("handler must not be NULL", 0x852); + __ asm_assert_ne("handler must not be null", 0x852); #endif // Handle_exception contains the handler address. If the associated frame @@ -145,6 +145,6 @@ void OptoRuntime::generate_exception_blob() { masm->flush(); // Set exception blob. - OopMapSet *oop_maps = NULL; + OopMapSet *oop_maps = nullptr; _exception_blob = ExceptionBlob::create(&buffer, oop_maps, frame_size/wordSize); } diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index c0ef3bb8c78..a1c0a6b1811 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -293,7 +293,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, RegisterSet reg OopMap* map = new OopMap(frame_size_in_slots, 0); int regstosave_num = 0; - const RegisterSaver::LiveRegType* live_regs = NULL; + const RegisterSaver::LiveRegType* live_regs = nullptr; switch (reg_set) { case all_registers: @@ -398,7 +398,7 @@ OopMap* RegisterSaver::generate_oop_map(MacroAssembler* masm, RegisterSet reg_se OopMap* map = new OopMap(frame_size_in_slots, 0); int regstosave_num = 0; - const RegisterSaver::LiveRegType* live_regs = NULL; + const RegisterSaver::LiveRegType* live_regs = nullptr; switch (reg_set) { case all_registers: @@ -448,7 +448,7 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, RegisterSet reg bool float_spilled = false; int regstosave_num = 0; - const RegisterSaver::LiveRegType* live_regs = NULL; + const RegisterSaver::LiveRegType* live_regs = nullptr; switch (reg_set) { case all_registers: @@ -762,7 +762,7 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt, VMRegPair *regs, VMRegPair *regs2, int total_args_passed) { - assert(regs2 == NULL, "second VMRegPair array not used on this platform"); + assert(regs2 == nullptr, "second VMRegPair array not used on this platform"); // Calling conventions for C runtime calls and calls to JNI native methods. const VMReg z_iarg_reg[5] = { @@ -1017,7 +1017,7 @@ static void object_move(MacroAssembler *masm, __ add2reg(rHandle, reg2offset(src.first())+frame_offset, Z_SP); __ load_and_test_long(Z_R0, Address(rHandle)); __ z_brne(skip); - // Use a NULL handle if oop is NULL. + // Use a null handle if oop is null. __ clear_reg(rHandle, true, false); __ bind(skip); @@ -1043,7 +1043,7 @@ static void object_move(MacroAssembler *masm, __ z_stg(rOop, oop_slot_offset, Z_SP); __ add2reg(rHandle, oop_slot_offset, Z_SP); - // If Oop == NULL, use a NULL handle. + // If Oop is null, use a null handle. __ compare64_and_branch(rOop, (RegisterOrConstant)0L, Assembler::bcondNotEqual, skip); __ clear_reg(rHandle, true, false); __ bind(skip); @@ -1324,7 +1324,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, stack_slots / VMRegImpl::slots_per_word, in_ByteSize(-1), in_ByteSize(-1), - (OopMapSet *) NULL); + (OopMapSet *) nullptr); } @@ -1335,7 +1335,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, /////////////////////////////////////////////////////////////////////// address native_func = method->native_function(); - assert(native_func != NULL, "must have function"); + assert(native_func != nullptr, "must have function"); //--------------------------------------------------------------------- // We have received a description of where all the java args are located @@ -1363,7 +1363,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, BasicType *out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); VMRegPair *out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); - BasicType* in_elem_bt = NULL; + BasicType* in_elem_bt = nullptr; // Create the signature for the C call: // 1) add the JNIEnv* @@ -1457,7 +1457,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // *_slot_offset indicates offset from SP in #stack slots // *_offset indicates offset from SP in #bytes - int stack_slots = c_calling_convention(out_sig_bt, out_regs, /*regs2=*/NULL, total_c_args) + // 1+2 + int stack_slots = c_calling_convention(out_sig_bt, out_regs, /*regs2=*/nullptr, total_c_args) + // 1+2 SharedRuntime::out_preserve_stack_slots(); // see c_calling_convention // Now the space for the inbound oop handle area. @@ -2075,7 +2075,7 @@ static address gen_c2i_adapter(MacroAssembler *masm, // Call patching needed? __ load_and_test_long(Z_R0_scratch, method_(code)); __ z_lg(ientry, method_(interpreter_entry)); // Preload interpreter entry (also if patching). - __ z_brne(patch_callsite); // Patch required if code != NULL (compiled target exists). + __ z_brne(patch_callsite); // Patch required if code isn't null (compiled target exists). __ bind(skip_fixup); // Return point from patch_callsite. @@ -2358,7 +2358,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm address c2i_entry = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = NULL; + address c2i_no_clinit_check_entry = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; @@ -2510,7 +2510,7 @@ void SharedRuntime::generate_deopt_blob() { CodeBuffer buffer("deopt_blob", 2048, 1024); InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer); Label exec_mode_initialized; - OopMap* map = NULL; + OopMap* map = nullptr; OopMapSet *oop_maps = new OopMapSet(); unsigned int start_off = __ offset(); @@ -2627,7 +2627,7 @@ void SharedRuntime::generate_deopt_blob() { // occur so we don't need an oopmap. the value of the pc in the // frame is not particularly important. it just needs to identify the blob. - // Don't set last_Java_pc anymore here (is implicitly NULL then). + // Don't set last_Java_pc anymore here (is implicitly null then). // the correct PC is retrieved in pd_last_frame() in that case. __ set_last_Java_frame(/*sp*/Z_SP, noreg); // With EscapeAnalysis turned on, this call may safepoint @@ -2844,7 +2844,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ z_br(Z_R14); masm->flush(); - _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, NULL, framesize_in_bytes/wordSize); + _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, nullptr, framesize_in_bytes/wordSize); } #endif // COMPILER2 @@ -2854,7 +2854,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // Generate a special Compile2Runtime blob that saves all registers, // and setup oopmap. SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { - assert(StubRoutines::forward_exception_entry() != NULL, + assert(StubRoutines::forward_exception_entry() != nullptr, "must be generated before"); ResourceMark rm; @@ -2866,7 +2866,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t MacroAssembler* masm = new MacroAssembler(&buffer); unsigned int start_off = __ offset(); - address call_pc = NULL; + address call_pc = nullptr; int frame_size_in_bytes; bool cause_return = (poll_type == POLL_AT_RETURN); @@ -2955,7 +2955,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t // must do any gc of the args. // RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) { - assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); + assert (StubRoutines::forward_exception_entry() != nullptr, "must be generated before"); // allocate space for the code ResourceMark rm; @@ -2964,7 +2964,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha MacroAssembler* masm = new MacroAssembler(&buffer); OopMapSet *oop_maps = new OopMapSet(); - OopMap* map = NULL; + OopMap* map = nullptr; unsigned int start_off = __ offset(); diff --git a/src/hotspot/cpu/s390/smallRegisterMap_s390.inline.hpp b/src/hotspot/cpu/s390/smallRegisterMap_s390.inline.hpp index aaef8670c50..8c74eb7dd6d 100644 --- a/src/hotspot/cpu/s390/smallRegisterMap_s390.inline.hpp +++ b/src/hotspot/cpu/s390/smallRegisterMap_s390.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -54,7 +54,7 @@ public: inline address location(VMReg reg, intptr_t* sp) const { Unimplemented(); - return NULL; + return nullptr; } inline void set_location(VMReg reg, address loc) { assert_is_rfp(reg); } @@ -77,7 +77,7 @@ public: bool should_skip_missing() const { return false; } VMReg find_register_spilled_here(void* p, intptr_t* sp) { Unimplemented(); - return NULL; + return nullptr; } void print() const { print_on(tty); } void print_on(outputStream* st) const { st->print_cr("Small register map"); } diff --git a/src/hotspot/cpu/s390/stackChunkFrameStream_s390.inline.hpp b/src/hotspot/cpu/s390/stackChunkFrameStream_s390.inline.hpp index 4f372c982d5..d94dea33e55 100644 --- a/src/hotspot/cpu/s390/stackChunkFrameStream_s390.inline.hpp +++ b/src/hotspot/cpu/s390/stackChunkFrameStream_s390.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -46,25 +46,25 @@ inline frame StackChunkFrameStream::to_frame() const { template inline address StackChunkFrameStream::get_pc() const { Unimplemented(); - return NULL; + return nullptr; } template inline intptr_t* StackChunkFrameStream::fp() const { Unimplemented(); - return NULL; + return nullptr; } template inline intptr_t* StackChunkFrameStream::derelativize(int offset) const { Unimplemented(); - return NULL; + return nullptr; } template inline intptr_t* StackChunkFrameStream::unextended_sp_for_interpreter_frame() const { Unimplemented(); - return NULL; + return nullptr; } template diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 5d6b836f1e2..26af54f75a3 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -483,7 +483,7 @@ class StubGenerator: public StubCodeGenerator { __ z_st(exception_line, thread_(exception_line)); // Complete return to VM. - assert(StubRoutines::_call_stub_return_address != NULL, "must have been generated before"); + assert(StubRoutines::_call_stub_return_address != nullptr, "must have been generated before"); // Continue in call stub. __ z_br(Z_ARG2); @@ -649,7 +649,7 @@ class StubGenerator: public StubCodeGenerator { RuntimeStub::new_runtime_stub(name, &code, frame_complete_pc - start, framesize_in_bytes/wordSize, - NULL /*oop_maps*/, false); + nullptr /*oop_maps*/, false); return stub->entry_point(); } @@ -685,12 +685,12 @@ class StubGenerator: public StubCodeGenerator { const Register Rarray_ptr = Z_ARG5; // Current value from cache array. if (UseCompressedOops) { - assert(Universe::heap() != NULL, "java heap must be initialized to generate partial_subtype_check stub"); + assert(Universe::heap() != nullptr, "java heap must be initialized to generate partial_subtype_check stub"); } // Always take the slow path. __ check_klass_subtype_slow_path(Rsubklass, Rsuperklass, - Rarray_ptr, Rlength, NULL, &miss); + Rarray_ptr, Rlength, nullptr, &miss); // Match falls through here. __ clear_reg(Z_RET); // Zero indicates a match. Set EQ flag in CC. @@ -3171,7 +3171,7 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_AES_encrypt("AES_encryptBlock_chaining"); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_AES_decrypt("AES_decryptBlock_chaining"); } else { - // In PRODUCT builds, the function pointers will keep their initial (NULL) value. + // In PRODUCT builds, the function pointers will keep their initial (null) value. // LibraryCallKit::try_to_inline() will return false then, preventing the intrinsic to be called. assert(VM_Version::has_Crypto_AES(), "Inconsistent settings. Check vm_version_s390.cpp"); } @@ -3181,7 +3181,7 @@ class StubGenerator: public StubCodeGenerator { if (VM_Version::has_Crypto_AES_CTR()) { StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt("counterMode_AESCrypt"); } else { - // In PRODUCT builds, the function pointers will keep their initial (NULL) value. + // In PRODUCT builds, the function pointers will keep their initial (null) value. // LibraryCallKit::try_to_inline() will return false then, preventing the intrinsic to be called. assert(VM_Version::has_Crypto_AES_CTR(), "Inconsistent settings. Check vm_version_s390.cpp"); } diff --git a/src/hotspot/cpu/s390/stubRoutines_s390.cpp b/src/hotspot/cpu/s390/stubRoutines_s390.cpp index eac2ccf5f20..67f96330837 100644 --- a/src/hotspot/cpu/s390/stubRoutines_s390.cpp +++ b/src/hotspot/cpu/s390/stubRoutines_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,12 +33,12 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::zarch::_partial_subtype_check = NULL; +address StubRoutines::zarch::_partial_subtype_check = nullptr; // Comapct string intrinsics: Translate table for string inflate intrinsic. Used by trot instruction. -address StubRoutines::zarch::_trot_table_addr = NULL; +address StubRoutines::zarch::_trot_table_addr = nullptr; -address StubRoutines::zarch::_nmethod_entry_barrier = NULL; +address StubRoutines::zarch::_nmethod_entry_barrier = nullptr; int StubRoutines::zarch::_atomic_memory_operation_lock = StubRoutines::zarch::unlocked; @@ -48,7 +48,7 @@ void StubRoutines::zarch::generate_load_absolute_address(MacroAssembler* masm, R __ load_absolute_address(table, table_addr); #ifdef ASSERT - assert(table_addr != NULL, "CRC lookup table address must be initialized by now"); + assert(table_addr != nullptr, "CRC lookup table address must be initialized by now"); assert(*((uint32_t*)(table_addr+4)) == (uint32_t)table_contents, "Bad CRC lookup table: 0x%8.8x, expected 0x%8.8x", *((uint32_t*)(table_addr+4)), (uint32_t)table_contents); { Label L; @@ -90,7 +90,7 @@ void StubRoutines::zarch::generate_load_trot_table_addr(MacroAssembler* masm, Re __ relocate(rspec); __ load_absolute_address(table, _trot_table_addr); #ifdef ASSERT - assert(_trot_table_addr != NULL, "Translate table address must be initialized by now"); + assert(_trot_table_addr != nullptr, "Translate table address must be initialized by now"); assert((p2i(_trot_table_addr) & (TROT_ALIGNMENT-1)) == 0, "Translate table alignment error"); for (int i = 0; i < 256; i++) { assert(i == *((jshort*)(_trot_table_addr+2*i)), "trot_table[%d] = %d", i, *((jshort*)(_trot_table_addr+2*i))); diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 60ca0020907..bea48e51544 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -281,7 +281,7 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() { // don't dereference it as in case of ints, floats, etc.. // UNBOX argument - // Load reference and check for NULL. + // Load reference and check for null. Label do_int_Entry4Boxed; __ bind(do_boxed); { @@ -589,7 +589,7 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() { } address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { - assert(!pass_oop || message == NULL, "either oop or message but not both"); + assert(!pass_oop || message == nullptr, "either oop or message but not both"); address entry = __ pc(); BLOCK_COMMENT("exception_handler_common {"); @@ -597,7 +597,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch // Expression stack must be empty before entering the VM if an // exception happened. __ empty_expression_stack(); - if (name != NULL) { + if (name != nullptr) { __ load_absolute_address(Z_ARG2, (address)name); } else { __ clear_reg(Z_ARG2, true, false); @@ -608,7 +608,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(const ch CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), Z_ARG2, Z_tos /*object (see TT::aastore())*/); } else { - if (message != NULL) { + if (message != nullptr) { __ load_absolute_address(Z_ARG3, (address)message); } else { __ clear_reg(Z_ARG3, true, false); @@ -638,7 +638,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for (TosState state, __ resize_frame_absolute(sp_before_i2c_extension, Z_locals/*tmp*/, true/*load_fp*/); // TODO(ZASM): necessary?? - // // and NULL it as marker that esp is now tos until next java call + // // and null it as marker that esp is now tos until next java call // __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); @@ -683,7 +683,7 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, BLOCK_COMMENT("deopt_entry {"); - // TODO(ZASM): necessary? NULL last_sp until next java call + // TODO(ZASM): necessary? null last_sp until next java call // __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ z_lg(Z_fp, _z_abi(callers_sp), Z_SP); // Restore frame pointer. __ restore_bcp(); @@ -701,7 +701,7 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, __ should_not_reach_here(); __ bind(L); } - if (continuation == NULL) { + if (continuation == nullptr) { __ dispatch_next(state, step); } else { __ jump_to_entry(continuation, Z_R1_scratch); @@ -780,8 +780,8 @@ void TemplateInterpreterGenerator::generate_counter_overflow(Label& do_continue) // InterpreterRuntime::frequency_counter_overflow takes two // arguments, the first (thread) is passed by call_VM, the second // indicates if the counter overflow occurs at a backwards branch - // (NULL bcp). We pass zero for it. The call returns the address - // of the verified entry point for the method or NULL if the + // (null bcp). We pass zero for it. The call returns the address + // of the verified entry point for the method or null if the // compilation did not complete (either went background or bailed // out). __ clear_reg(Z_ARG2); @@ -812,7 +812,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register frame_ // Get the stack base, and in debug, verify it is non-zero. __ z_lg(tmp1, thread_(stack_base)); #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; NearLabel base_not_zero; __ compareU64_and_branch(tmp1, (intptr_t)0L, Assembler::bcondNotEqual, base_not_zero); reentry = __ stop_chain_static(reentry, "stack base is zero in generate_stack_overflow_check"); @@ -850,7 +850,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register frame_ // Note also that the restored frame is not necessarily interpreted. // Use the shared runtime version of the StackOverflowError. - assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "stub not yet generated"); + assert(StubRoutines::throw_StackOverflowError_entry() != nullptr, "stub not yet generated"); AddressLiteral stub(StubRoutines::throw_StackOverflowError_entry()); __ load_absolute_address(tmp1, StubRoutines::throw_StackOverflowError_entry()); __ z_br(tmp1); @@ -875,7 +875,7 @@ void TemplateInterpreterGenerator::lock_method(void) { __ get_method(method); #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { Label L; __ testbit(method2_(method, access_flags), JVM_ACC_SYNCHRONIZED_BIT); @@ -909,7 +909,7 @@ void TemplateInterpreterGenerator::lock_method(void) { { NearLabel L; __ compare64_and_branch(object, (intptr_t) 0, Assembler::bcondNotEqual, L); - reentry = __ stop_chain_static(reentry, "synchronization object is NULL"); + reentry = __ stop_chain_static(reentry, "synchronization object is null"); __ bind(L); } #endif // ASSERT @@ -1132,12 +1132,12 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // z_ijava_state->locals = Z_esp + parameter_count bytes __ z_stg(Z_locals, _z_ijava_state_neg(locals), fp); - // z_ijava_state->oop_temp = NULL; + // z_ijava_state->oop_temp = nullptr; __ store_const(Address(fp, oop_tmp_offset), 0); // Initialize z_ijava_state->mdx. Register Rmdp = Z_bcp; - // native_call: assert that mdo == NULL + // native_call: assert that mdo is null const bool check_for_mdo = !native_call DEBUG_ONLY(|| native_call); if (ProfileInterpreter && check_for_mdo) { Label get_continue; @@ -1207,7 +1207,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M // Decide what to do: Use same platform specific instructions and runtime calls as compilers. bool use_instruction = false; - address runtime_entry = NULL; + address runtime_entry = nullptr; int num_args = 1; bool double_precision = true; @@ -1236,7 +1236,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M } // Use normal entry if neither instruction nor runtime call is used. - if (!use_instruction && runtime_entry == NULL) return NULL; + if (!use_instruction && runtime_entry == nullptr) return nullptr; address entry = __ pc(); @@ -1343,7 +1343,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { // Make sure method is native and not abstract. #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { Label L; __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_btrue(L); @@ -1711,7 +1711,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // Make sure method is not native and not abstract. // Rethink these assertions - they can be simplified and shared. #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { Label L; __ testbit(method_(access_flags), JVM_ACC_NATIVE_BIT); __ z_bfalse(L); @@ -2165,7 +2165,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // The member name argument must be restored if _invokestatic is // re-executed after a PopFrame call. Detect such a case in the // InterpreterRuntime function and return the member name - // argument, or NULL. + // argument, or null. __ z_lg(Z_ARG2, Address(Z_locals)); __ get_method(Z_ARG3); __ call_VM(Z_tmp_1, @@ -2378,7 +2378,7 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) { // The run-time runtime saves the right registers, depending on // the tosca in-state for the given template. address entry = Interpreter::trace_code(t->tos_in()); - guarantee(entry != NULL, "entry must have been generated"); + guarantee(entry != nullptr, "entry must have been generated"); __ call_stub(entry); } diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp index c072cf5fa70..c38a375849d 100644 --- a/src/hotspot/cpu/s390/templateTable_s390.cpp +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp @@ -138,7 +138,7 @@ static inline Address aaddress(int n) { return iaddress(n); } -// Pass NULL, if no shift instruction should be emitted. +// Pass null, if no shift instruction should be emitted. static inline Address iaddress(InterpreterMacroAssembler *masm, Register r) { if (masm) { masm->z_sllg(r, r, LogBytesPerWord); // index2bytes @@ -146,7 +146,7 @@ static inline Address iaddress(InterpreterMacroAssembler *masm, Register r) { return Address(Z_locals, r, Interpreter::local_offset_in_bytes(0)); } -// Pass NULL, if no shift instruction should be emitted. +// Pass null, if no shift instruction should be emitted. static inline Address laddress(InterpreterMacroAssembler *masm, Register r) { if (masm) { masm->z_sllg(r, r, LogBytesPerWord); // index2bytes @@ -464,7 +464,7 @@ void TemplateTable::fast_aldc(LdcType type) { __ z_ltgr(Z_tos, Z_tos); __ z_bre(L_do_resolve); - // Convert null sentinel to NULL. + // Convert null sentinel to null. __ load_const_optimized(Z_R1_scratch, (intptr_t)Universe::the_null_sentinel_addr()); __ resolve_oop_handle(Z_R1_scratch); __ z_cg(Z_tos, Address(Z_R1_scratch)); @@ -1167,7 +1167,7 @@ void TemplateTable::aastore() { // Address where the store goes to, i.e. &(Rarry[index]) __ load_address(Rstore_addr, Address(Rarray, Rindex, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); - // do array store check - check for NULL value first. + // do array store check - check for null value first. __ compareU64_and_branch(Rvalue, (intptr_t)0, Assembler::bcondEqual, is_null); Register Rsub_klass = Z_ARG4; @@ -1191,11 +1191,11 @@ void TemplateTable::aastore() { Register tmp3 = Rsub_klass; - // Have a NULL in Rvalue. + // Have a null in Rvalue. __ bind(is_null); __ profile_null_seen(tmp1); - // Store a NULL. + // Store a null. do_oop_store(_masm, Address(Rstore_addr, (intptr_t)0), noreg, tmp3, tmp2, tmp1, IS_ARRAY); __ z_bru(done); @@ -1937,7 +1937,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { const Address mask(mdo, MethodData::backedge_mask_offset()); __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, Z_ARG2, false, Assembler::bcondZero, - UseOnStackReplacement ? &backedge_counter_overflow : NULL); + UseOnStackReplacement ? &backedge_counter_overflow : nullptr); __ z_bru(dispatch); __ bind(no_mdo); } @@ -1948,7 +1948,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { __ increment_mask_and_jump(Address(m_counters, be_offset), increment, mask, Z_ARG2, false, Assembler::bcondZero, - UseOnStackReplacement ? &backedge_counter_overflow : NULL); + UseOnStackReplacement ? &backedge_counter_overflow : nullptr); __ bind(dispatch); } @@ -1972,7 +1972,7 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), Z_ARG2); - // Z_RET: osr nmethod (osr ok) or NULL (osr not possible). + // Z_RET: osr nmethod (osr ok) or null (osr not possible). __ compare64_and_branch(Z_RET, (intptr_t) 0, Assembler::bcondEqual, dispatch); // Nmethod may have been invalidated (VM may block upon call_VM return). @@ -2385,7 +2385,7 @@ void TemplateTable::resolve_cache_and_index(int byte_no, __ load_resolved_method_at_index(byte_no, cache, cpe_offset, method); __ load_method_holder(klass, method); - __ clinit_barrier(klass, Z_thread, NULL /*L_fast_path*/, &clinit_barrier_slow); + __ clinit_barrier(klass, Z_thread, nullptr /*L_fast_path*/, &clinit_barrier_slow); } BLOCK_COMMENT("} resolve_cache_and_index"); @@ -2547,12 +2547,12 @@ void TemplateTable::jvmti_post_field_access(Register cache, Register index, Z_ARG3, Z_R1_scratch); if (is_static) { - __ clear_reg(Z_ARG2, true, false); // NULL object reference. Don't set CC. + __ clear_reg(Z_ARG2, true, false); // null object reference. Don't set CC. } else { __ mem2reg_opt(Z_ARG2, at_tos()); // Get object pointer without popping it. __ verify_oop(Z_ARG2); } - // Z_ARG2: object pointer or NULL + // Z_ARG2: object pointer or null // Z_ARG3: cache entry pointer __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), @@ -2864,7 +2864,7 @@ void TemplateTable::jvmti_post_field_mod(Register cache, // object(tos) __ load_address(Z_ARG4, Address(Z_esp, Interpreter::stackElementSize)); - // Z_ARG2: object pointer set up above (NULL if static) + // Z_ARG2: object pointer set up above (null if static) // Z_ARG3: cache entry pointer // Z_ARG4: jvalue object on the stack __ call_VM(noreg, @@ -3786,7 +3786,7 @@ void TemplateTable::invokedynamic(int byte_no) { // spec jbb2005 shows no measurable performance degradation. void TemplateTable::_new() { transition(vtos, atos); - address prev_instr_address = NULL; + address prev_instr_address = nullptr; Register tags = Z_tmp_1; Register RallocatedObject = Z_tos; Register cpool = Z_ARG2; @@ -3930,7 +3930,7 @@ void TemplateTable::checkcast() { NearLabel done, is_null, ok_is_subtype, quicked, resolved; BLOCK_COMMENT("checkcast {"); - // If object is NULL, we are almost done. + // If object is null, we are almost done. __ compareU64_and_branch(Z_tos, (intptr_t) 0, Assembler::bcondZero, is_null); // Get cpool & tags index. @@ -3984,7 +3984,7 @@ void TemplateTable::checkcast() { __ z_lgr(Z_tos, receiver); // Restore object. - // Collect counts on whether this test sees NULLs a lot or not. + // Collect counts on whether this test sees nulls a lot or not. if (ProfileInterpreter) { __ z_bru(done); __ bind(is_null); @@ -4003,7 +4003,7 @@ void TemplateTable::instanceof() { NearLabel done, is_null, ok_is_subtype, quicked, resolved; BLOCK_COMMENT("instanceof {"); - // If object is NULL, we are almost done. + // If object is null, we are almost done. __ compareU64_and_branch(Z_tos, (intptr_t) 0, Assembler::bcondZero, is_null); // Get cpool & tags index. @@ -4054,7 +4054,7 @@ void TemplateTable::instanceof() { __ bind(ok_is_subtype); __ load_const_optimized(Z_tos, 1); - // Collect counts on whether this test sees NULLs a lot or not. + // Collect counts on whether this test sees nulls a lot or not. if (ProfileInterpreter) { __ z_bru(done); __ bind(is_null); @@ -4064,8 +4064,8 @@ void TemplateTable::instanceof() { } __ bind(done); - // tos = 0: obj == NULL or obj is not an instanceof the specified klass - // tos = 1: obj != NULL and obj is an instanceof the specified klass + // tos = 0: obj is null or obj is not an instanceof the specified klass + // tos = 1: obj isn't null and obj is an instanceof the specified klass BLOCK_COMMENT("} instanceof"); } @@ -4141,13 +4141,13 @@ void TemplateTable::monitorenter() { BLOCK_COMMENT("monitorenter {"); - // Check for NULL object. + // Check for null object. __ null_check(Z_tos); const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; NearLabel allocated; // Initialize entry pointer. const Register Rfree_slot = Z_tmp_1; - __ clear_reg(Rfree_slot, true, false); // Points to free slot or NULL. Don't set CC. + __ clear_reg(Rfree_slot, true, false); // Points to free slot or null. Don't set CC. // Find a free slot in the monitor block from top to bot (result in Rfree_slot). { @@ -4160,7 +4160,7 @@ void TemplateTable::monitorenter() { __ add2reg(Rbot, -frame::z_ijava_state_size, Z_fp); #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { NearLabel ok; __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotHigh, ok); reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors points below monitor block bottom"); @@ -4193,7 +4193,7 @@ void TemplateTable::monitorenter() { __ bind(exit); } - // Rfree_slot != NULL -> found one + // Rfree_slot isn't null -> found one __ compareU64_and_branch(Rfree_slot, (intptr_t)0L, Assembler::bcondNotEqual, allocated); // Allocate one if there's no free slot. @@ -4230,7 +4230,7 @@ void TemplateTable::monitorexit() { BLOCK_COMMENT("monitorexit {"); - // Check for NULL object. + // Check for null object. __ null_check(Z_tos); NearLabel found, not_found; @@ -4248,7 +4248,7 @@ void TemplateTable::monitorexit() { __ add2reg(Rbot, -frame::z_ijava_state_size, Z_fp); #ifdef ASSERT - address reentry = NULL; + address reentry = nullptr; { NearLabel ok; __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotHigh, ok); reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors points below monitor block bottom"); diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index e53d6fc5635..60f726edacc 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -717,7 +717,7 @@ void VM_Version::print_platform_virtualization_info(outputStream* st) { // - LPAR // - whole "Box" (CPUs ) // - z/VM / KVM (VM); this is not available in an LPAR-only setup - const char* kw[] = { "LPAR", "CPUs", "VM", NULL }; + const char* kw[] = { "LPAR", "CPUs", "VM", nullptr }; const char* info_file = "/proc/sysinfo"; if (!print_matching_lines_from_file(info_file, st, kw)) { @@ -842,7 +842,7 @@ void VM_Version::set_features_from(const char* march) { bool err = false; bool prt = false; - if ((march != NULL) && (march[0] != '\0')) { + if ((march != nullptr) && (march[0] != '\0')) { const int buf_len = 16; const int hdr_len = 5; char buf[buf_len]; @@ -909,10 +909,10 @@ void VM_Version::set_features_from(const char* march) { // < 0: failure: required number of feature bit string words (buffer too small). // == 0: failure: operation aborted. // -static long (*getFeatures)(unsigned long*, int, int) = NULL; +static long (*getFeatures)(unsigned long*, int, int) = nullptr; void VM_Version::set_getFeatures(address entryPoint) { - if (getFeatures == NULL) { + if (getFeatures == nullptr) { getFeatures = (long(*)(unsigned long*, int, int))entryPoint; } } diff --git a/src/hotspot/cpu/s390/vtableStubs_s390.cpp b/src/hotspot/cpu/s390/vtableStubs_s390.cpp index e89cf421f6c..6d6eb5ebf2a 100644 --- a/src/hotspot/cpu/s390/vtableStubs_s390.cpp +++ b/src/hotspot/cpu/s390/vtableStubs_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -49,9 +49,9 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. const int stub_code_length = code_size_limit(true); VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index); - // Can be NULL if there is no free space in the code cache. - if (s == NULL) { - return NULL; + // Can be null if there is no free space in the code cache. + if (s == nullptr) { + return nullptr; } // Count unused bytes in instruction sequences of variable size. @@ -82,7 +82,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { assert(VtableStub::receiver_location() == Z_R2->as_VMReg(), "receiver expected in Z_ARG1"); const Register rcvr_klass = Z_R1_scratch; - address npe_addr = __ pc(); // npe == NULL ptr exception + address npe_addr = __ pc(); // npe is short for null pointer exception // Get receiver klass. __ load_klass(rcvr_klass, Z_ARG1); @@ -152,9 +152,9 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. const int stub_code_length = code_size_limit(false); VtableStub* s = new(stub_code_length) VtableStub(false, itable_index); - // Can be NULL if there is no free space in the code cache. - if (s == NULL) { - return NULL; + // Can be null if there is no free space in the code cache. + if (s == nullptr) { + return nullptr; } // Count unused bytes in instruction sequences of variable size. @@ -193,7 +193,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // Get receiver klass. // Must do an explicit check if offset too large or implicit checks are disabled. - address npe_addr = __ pc(); // npe == NULL ptr exception + address npe_addr = __ pc(); // npe is short for null pointer exception __ load_klass(rcvr_klass, Z_ARG1); // Receiver subtype check against REFC. From 896207de144380e58584838382e0ec32fb0f9d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Tue, 18 Apr 2023 09:00:20 +0000 Subject: [PATCH 020/288] 8306077: Replace NEW_ARENA_ARRAY with NEW_RESOURCE_ARRAY when applicable in opto Reviewed-by: thartmann --- src/hotspot/share/opto/block.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/opto/block.cpp b/src/hotspot/share/opto/block.cpp index 2666e7a84cf..78774ff2fd1 100644 --- a/src/hotspot/share/opto/block.cpp +++ b/src/hotspot/share/opto/block.cpp @@ -1764,21 +1764,20 @@ void PhaseBlockLayout::merge_traces(bool fall_thru_only) { // Order the sequence of the traces in some desirable way void PhaseBlockLayout::reorder_traces(int count) { - ResourceArea *area = Thread::current()->resource_area(); - Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count); + Trace** new_traces = NEW_RESOURCE_ARRAY(Trace*, count); Block_List worklist; int new_count = 0; // Compact the traces. for (int i = 0; i < count; i++) { - Trace *tr = traces[i]; + Trace* tr = traces[i]; if (tr != nullptr) { new_traces[new_count++] = tr; } } // The entry block should be first on the new trace list. - Trace *tr = trace(_cfg.get_root_block()); + Trace* tr = trace(_cfg.get_root_block()); assert(tr == new_traces[0], "entry trace misplaced"); // Sort the new trace list by frequency @@ -1787,7 +1786,7 @@ void PhaseBlockLayout::reorder_traces(int count) { // Collect all blocks from existing Traces _cfg.clear_blocks(); for (int i = 0; i < new_count; i++) { - Trace *tr = new_traces[i]; + Trace* tr = new_traces[i]; if (tr != nullptr) { // push blocks onto the CFG list for (Block* b = tr->first_block(); b != nullptr; b = tr->next(b)) { @@ -1802,16 +1801,15 @@ PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) : Phase(BlockLayout) , _cfg(cfg) { ResourceMark rm; - ResourceArea *area = Thread::current()->resource_area(); // List of traces int size = _cfg.number_of_blocks() + 1; - traces = NEW_ARENA_ARRAY(area, Trace *, size); + traces = NEW_RESOURCE_ARRAY(Trace*, size); memset(traces, 0, size*sizeof(Trace*)); - next = NEW_ARENA_ARRAY(area, Block *, size); - memset(next, 0, size*sizeof(Block *)); - prev = NEW_ARENA_ARRAY(area, Block *, size); - memset(prev , 0, size*sizeof(Block *)); + next = NEW_RESOURCE_ARRAY(Block*, size); + memset(next, 0, size*sizeof(Block*)); + prev = NEW_RESOURCE_ARRAY(Block*, size); + memset(prev , 0, size*sizeof(Block*)); // List of edges edges = new GrowableArray; From 3bba89957439a8899f5c1f5089227519403f75fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 18 Apr 2023 09:43:08 +0000 Subject: [PATCH 021/288] 8299592: Fix and reenable warnings in java.desktop native code compilation Reviewed-by: ihse, aivanov --- .../java.desktop/lib/Awt2dLibraries.gmk | 14 +-- .../share/native/common/awt/debug/debug_mem.c | 16 ++-- .../native/common/awt/debug/debug_trace.c | 29 +----- .../native/common/java2d/opengl/OGLContext.c | 4 +- .../libawt/awt/medialib/awt_ImagingLib.c | 90 +------------------ .../native/libmlib_image/mlib_image_get.h | 50 +++++------ .../share/native/libmlib_image/safe_alloc.h | 6 +- .../native/libawt/java2d/d3d/D3DBlitLoops.cpp | 6 +- .../libawt/java2d/d3d/D3DVertexCacher.cpp | 18 ++-- .../native/libawt/windows/ThemeReader.cpp | 6 +- .../native/libawt/windows/awt_Font.cpp | 4 +- 11 files changed, 62 insertions(+), 181 deletions(-) diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index b2139188bfa..7b5c98d5cf0 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -120,12 +120,7 @@ ifeq ($(call isTargetOs, windows), true) LIBAWT_VERSIONINFO_RESOURCE := $(TOPDIR)/src/$(MODULE)/windows/native/libawt/windows/awt.rc endif -# Turn off all warnings for debug_mem.c This is needed because the specific warning -# about initializing a declared 'extern' cannot be turned off individually. Only -# applies to debug builds. This limitation in gcc is tracked in -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45977 ifeq ($(TOOLCHAIN_TYPE), gcc) - BUILD_LIBAWT_debug_mem.c_CFLAGS := -w # This option improves performance of MaskFill in Java2D by 20% for some gcc LIBAWT_CFLAGS += -fgcse-after-reload endif @@ -138,24 +133,17 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT, \ OPTIMIZATION := HIGHEST, \ CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_CFLAGS), \ EXTRA_HEADER_DIRS := $(LIBAWT_EXTRA_HEADER_DIRS), \ - DISABLED_WARNINGS_gcc_awt_ImagingLib.c := unused-function sign-compare, \ DISABLED_WARNINGS_gcc_awt_LoadLibrary.c := unused-result, \ - DISABLED_WARNINGS_gcc_awt_Mlib.c := unused-function, \ - DISABLED_WARNINGS_gcc_awt_parseImage.c := sign-compare unused-function, \ - DISABLED_WARNINGS_gcc_debug_trace.c := unused-function, \ DISABLED_WARNINGS_gcc_ProcessPath.c := maybe-uninitialized, \ DISABLED_WARNINGS_gcc_Region.c := maybe-uninitialized, \ DISABLED_WARNINGS_gcc_SurfaceData.c := unused-value, \ DISABLED_WARNINGS_gcc_TransformHelper.c := sign-compare, \ - DISABLED_WARNINGS_clang_awt_ImagingLib.c := sign-compare deprecated-non-prototype, \ - DISABLED_WARNINGS_clang_awt_parseImage.c := sign-compare, \ - DISABLED_WARNINGS_clang_debug_mem.c := extern-initializer format-nonliteral, \ + DISABLED_WARNINGS_clang_awt_ImagingLib.c := deprecated-non-prototype, \ DISABLED_WARNINGS_clang_debug_trace.c := format-nonliteral, \ DISABLED_WARNINGS_clang_Trace.c := format-nonliteral, \ DISABLED_WARNINGS_clang_TransformHelper.c := sign-compare, \ DISABLED_WARNINGS_microsoft := 4244 4996, \ DISABLED_WARNINGS_microsoft_awt_Toolkit.cpp := 4267, \ - DISABLED_WARNINGS_microsoft_OGLContext.c := 4267, \ LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \ LDFLAGS_windows := -delayload:user32.dll -delayload:gdi32.dll \ diff --git a/src/java.desktop/share/native/common/awt/debug/debug_mem.c b/src/java.desktop/share/native/common/awt/debug/debug_mem.c index 3cbe05327c2..dce59783c03 100644 --- a/src/java.desktop/share/native/common/awt/debug/debug_mem.c +++ b/src/java.desktop/share/native/common/awt/debug/debug_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -68,10 +68,10 @@ typedef struct MemoryListLink { /************************************************** * Global Data structures */ -static DMemState DMemGlobalState; -extern const DMemState * DMemStatePtr = &DMemGlobalState; -static MemoryListLink MemoryList = {NULL,NULL,FALSE}; -static dmutex_t DMemMutex = NULL; +static DMemState DMemGlobalState; +const DMemState * DMemStatePtr = &DMemGlobalState; +static MemoryListLink MemoryList = {NULL,NULL,FALSE}; +static dmutex_t DMemMutex = NULL; /**************************************************/ @@ -271,10 +271,10 @@ Exit: } static void DMem_DumpHeader(MemoryBlockHeader * header) { - char report[FILENAME_MAX+MAX_DECIMAL_DIGITS*3+1]; - static const char * reportFormat = + char report[FILENAME_MAX+MAX_DECIMAL_DIGITS*3+42]; + static const char * const reportFormat = "file: %s, line %d\n" - "size: %d bytes\n" + "size: %zd bytes\n" "order: %d\n" "-------"; diff --git a/src/java.desktop/share/native/common/awt/debug/debug_trace.c b/src/java.desktop/share/native/common/awt/debug/debug_trace.c index 31424fb6c3c..97abe77044b 100644 --- a/src/java.desktop/share/native/common/awt/debug/debug_trace.c +++ b/src/java.desktop/share/native/common/awt/debug/debug_trace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -25,9 +25,9 @@ #include "debug_util.h" +#if defined(DEBUG) static void JNICALL DTrace_PrintStdErr(const char *msg); -#if defined(DEBUG) enum { MAX_TRACES = 200, /* max number of defined trace points allowed */ MAX_TRACE_BUFFER = 512, /* maximum size of a given trace output */ @@ -292,8 +292,6 @@ void DTrace_SetOutputCallback(DTRACE_OUTPUT_CALLBACK pfn) { DMutex_Exit(DTraceMutex); } -#endif /* DEBUG */ - /********************************************************************************** * Support for Java tracing in release or debug mode builds */ @@ -302,28 +300,7 @@ static void JNICALL DTrace_PrintStdErr(const char *msg) { fprintf(stderr, "%s", msg); fflush(stderr); } - -static void DTrace_JavaPrint(const char * msg) { -#if defined(DEBUG) - DMutex_Enter(DTraceMutex); - DTrace_ClientPrint(msg); - DMutex_Exit(DTraceMutex); -#else - DTrace_PrintStdErr(msg); -#endif -} - -static void DTrace_JavaPrintln(const char * msg) { -#if defined(DEBUG) - DMutex_Enter(DTraceMutex); - DTrace_ClientPrint(msg); - DTrace_ClientPrint("\n"); - DMutex_Exit(DTraceMutex); -#else - DTrace_PrintStdErr(msg); - DTrace_PrintStdErr("\n"); -#endif -} +#endif /* DEBUG */ /********************************************************************************* * Native method implementations. Java print trace calls are functional in diff --git a/src/java.desktop/share/native/common/java2d/opengl/OGLContext.c b/src/java.desktop/share/native/common/java2d/opengl/OGLContext.c index cac3895703b..89c3af32b1d 100644 --- a/src/java.desktop/share/native/common/java2d/opengl/OGLContext.c +++ b/src/java.desktop/share/native/common/java2d/opengl/OGLContext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -1039,7 +1039,7 @@ JNIEXPORT jstring JNICALL Java_sun_java2d_opengl_OGLContext_getOGLIdString char *vendor, *renderer, *version; char *pAdapterId; jobject ret = NULL; - int len; + size_t len; J2dTraceLn(J2D_TRACE_INFO, "OGLContext_getOGLIdString"); diff --git a/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c b/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c index 0a934d5fff7..28da681aa97 100644 --- a/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c +++ b/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1801,49 +1801,6 @@ Java_sun_awt_image_ImagingLib_init(JNIEnv *env, jclass thisClass) { return JNI_TRUE; } -/* REMIND: How to specify border? */ -static void extendEdge(JNIEnv *env, BufImageS_t *imageP, - int *widthP, int *heightP) { - RasterS_t *rasterP = &imageP->raster; - int width; - int height; - /* Useful for convolution? */ - - jobject jbaseraster = (*env)->GetObjectField(env, rasterP->jraster, - g_RasterBaseRasterID); - width = rasterP->width; - height = rasterP->height; -#ifdef WORKING - if (! JNU_IsNull(env, jbaseraster) && - !(*env)->IsSameObject(env, rasterP->jraster, jbaseraster)) { - int xOff; - int yOff; - int baseWidth; - int baseHeight; - int baseXoff; - int baseYoff; - /* Not the same object so get the width and height */ - xOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterXOffsetID); - yOff = (*env)->GetIntField(env, rasterP->jraster, g_RasterYOffsetID); - baseWidth = (*env)->GetIntField(env, jbaseraster, g_RasterWidthID); - baseHeight = (*env)->GetIntField(env, jbaseraster, g_RasterHeightID); - baseXoff = (*env)->GetIntField(env, jbaseraster, g_RasterXOffsetID); - baseYoff = (*env)->GetIntField(env, jbaseraster, g_RasterYOffsetID); - - if (xOff + rasterP->width < baseXoff + baseWidth) { - /* Can use edge */ - width++; - } - if (yOff + rasterP->height < baseYoff + baseHeight) { - /* Can use edge */ - height++; - } - - } -#endif - -} - static int setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, int expandICM, int useAlpha, @@ -2016,47 +1973,6 @@ setImageHints(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP, return nbands; } - -static int -expandPacked(JNIEnv *env, BufImageS_t *img, ColorModelS_t *cmP, - RasterS_t *rasterP, int component, unsigned char *bdataP) { - - if (rasterP->rasterType == COMPONENT_RASTER_TYPE) { - switch (rasterP->dataType) { - case BYTE_DATA_TYPE: - if (expandPackedBCR(env, rasterP, component, bdataP) < 0) { - /* Must have been an error */ - return -1; - } - break; - - case SHORT_DATA_TYPE: - if (expandPackedICR(env, rasterP, component, bdataP) < 0) { - /* Must have been an error */ - return -1; - } - break; - - case INT_DATA_TYPE: - if (expandPackedICR(env, rasterP, component, bdataP) < 0) { - /* Must have been an error */ - return -1; - } - break; - - default: - /* REMIND: Return some sort of error */ - return -1; - } - } - else { - /* REMIND: Return some sort of error */ - return -1; - } - - return 0; -} - #define NUM_LINES 10 static int @@ -2445,8 +2361,8 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP, *dataPP = dataP; return 0; case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES: - if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands) && - SAFE_TO_ALLOC_2(rasterP->scanlineStride, height))) + if (!(SAFE_TO_ALLOC_3(width, rasterP->numBands, 1) && + SAFE_TO_ALLOC_3(rasterP->scanlineStride, height, 1))) { return -1; } diff --git a/src/java.desktop/share/native/libmlib_image/mlib_image_get.h b/src/java.desktop/share/native/libmlib_image/mlib_image_get.h index ce4241f3291..31979d51586 100644 --- a/src/java.desktop/share/native/libmlib_image/mlib_image_get.h +++ b/src/java.desktop/share/native/libmlib_image/mlib_image_get.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -32,136 +32,136 @@ extern "C" { #endif /* __cplusplus */ -static mlib_type mlib_ImageGetType(const mlib_image *img) +static inline mlib_type mlib_ImageGetType(const mlib_image *img) { return img->type; } -static mlib_s32 mlib_ImageGetChannels(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetChannels(const mlib_image *img) { return img->channels; } -static mlib_s32 mlib_ImageGetWidth(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetWidth(const mlib_image *img) { return img->width; } -static mlib_s32 mlib_ImageGetHeight(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetHeight(const mlib_image *img) { return img->height; } -static mlib_s32 mlib_ImageGetStride(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetStride(const mlib_image *img) { return img->stride; } -static void *mlib_ImageGetData(const mlib_image *img) +static inline void *mlib_ImageGetData(const mlib_image *img) { return img->data; } -static mlib_s32 mlib_ImageGetFlags(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetFlags(const mlib_image *img) { return img->flags; } -static mlib_u8 *mlib_ImageGetPaddings(const mlib_image *img) +static inline mlib_u8 *mlib_ImageGetPaddings(const mlib_image *img) { return (mlib_u8 *)img->paddings; } -static mlib_s32 mlib_ImageGetBitOffset(const mlib_image *img) +static inline mlib_s32 mlib_ImageGetBitOffset(const mlib_image *img) { return img->bitoffset; } -static mlib_format mlib_ImageGetFormat(const mlib_image *img) +static inline mlib_format mlib_ImageGetFormat(const mlib_image *img) { return img->format; } /* returns 0 if all conditions are satisfied, non-zero otherwise */ -static int mlib_ImageTestFlags(const mlib_image *img, mlib_s32 flags) +static inline int mlib_ImageTestFlags(const mlib_image *img, mlib_s32 flags) { return (img->flags & flags); } /* returns 0 if 64 byte aligned and non-zero if not aligned */ -static int mlib_ImageIsNotAligned64(const mlib_image *img) +static inline int mlib_ImageIsNotAligned64(const mlib_image *img) { return (img->flags & MLIB_IMAGE_ALIGNED64); } /* returns 0 if 8 byte aligned and non-zero if not aligned */ -static int mlib_ImageIsNotAligned8(const mlib_image *img) +static inline int mlib_ImageIsNotAligned8(const mlib_image *img) { return (img->flags & MLIB_IMAGE_ALIGNED8); } /* returns 0 if 4 byte aligned and non-zero if not aligned */ -static int mlib_ImageIsNotAligned4(const mlib_image *img) +static inline int mlib_ImageIsNotAligned4(const mlib_image *img) { return (img->flags & MLIB_IMAGE_ALIGNED4); } /* returns 0 if 2 byte aligned and non-zero if not aligned */ -static int mlib_ImageIsNotAligned2(const mlib_image *img) +static inline int mlib_ImageIsNotAligned2(const mlib_image *img) { return (img->flags & MLIB_IMAGE_ALIGNED2); } /* returns 0 if width is a multiple of 8, non-zero otherwise */ -static int mlib_ImageIsNotWidth8X(const mlib_image *img) +static inline int mlib_ImageIsNotWidth8X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_WIDTH8X); } /* returns 0 if width is a multiple of 4, non-zero otherwise */ -static int mlib_ImageIsNotWidth4X(const mlib_image *img) +static inline int mlib_ImageIsNotWidth4X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_WIDTH4X); } /* returns 0 if width is a multiple of 2, non-zero otherwise */ -static int mlib_ImageIsNotWidth2X(const mlib_image *img) +static inline int mlib_ImageIsNotWidth2X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_WIDTH2X); } /* returns 0 if height is a multiple of 8, non-zero otherwise */ -static int mlib_ImageIsNotHeight8X(const mlib_image *img) +static inline int mlib_ImageIsNotHeight8X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_HEIGHT8X); } /* returns 0 if height is a multiple of 4, non-zero otherwise */ -static int mlib_ImageIsNotHeight4X(const mlib_image *img) +static inline int mlib_ImageIsNotHeight4X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_HEIGHT4X); } /* returns 0 if height is a multiple of 2, non-zero otherwise */ -static int mlib_ImageIsNotHeight2X(const mlib_image *img) +static inline int mlib_ImageIsNotHeight2X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_HEIGHT2X); } /* returns 0 if stride is a multiple of 8, non-zero otherwise */ -static int mlib_ImageIsNotStride8X(const mlib_image *img) +static inline int mlib_ImageIsNotStride8X(const mlib_image *img) { return (img->flags & MLIB_IMAGE_STRIDE8X); } /* returns 0 if it can be treated as a 1-D vector, non-zero otherwise */ -static int mlib_ImageIsNotOneDvector(const mlib_image *img) +static inline int mlib_ImageIsNotOneDvector(const mlib_image *img) { return (img->flags & MLIB_IMAGE_ONEDVECTOR); } /* returns non-zero if data buffer is user allocated, 0 otherwise */ -static int mlib_ImageIsUserAllocated(const mlib_image *img) +static inline int mlib_ImageIsUserAllocated(const mlib_image *img) { return (img->flags & MLIB_IMAGE_USERALLOCATED); } diff --git a/src/java.desktop/share/native/libmlib_image/safe_alloc.h b/src/java.desktop/share/native/libmlib_image/safe_alloc.h index 11ed1b5e27e..e2defdbac3f 100644 --- a/src/java.desktop/share/native/libmlib_image/safe_alloc.h +++ b/src/java.desktop/share/native/libmlib_image/safe_alloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,10 +35,10 @@ */ #define SAFE_TO_ALLOC_2(c, sz) \ (((c) > 0) && ((sz) > 0) && \ - ((0x7fffffff / (c)) > (sz))) + ((0x7fffffffu / (c)) > (sz))) #define SAFE_TO_ALLOC_3(w, h, sz) \ (((w) > 0) && ((h) > 0) && ((sz) > 0) && \ - (((0x7fffffff / (w)) / (h)) > (sz))) + (((0x7fffffffu / (w)) / (h)) > (sz))) #endif // __SAFE_ALLOC_H__ diff --git a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBlitLoops.cpp b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBlitLoops.cpp index 3788cc27dff..ecf8100e87d 100644 --- a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBlitLoops.cpp +++ b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBlitLoops.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -441,8 +441,8 @@ D3DBlitTextureToSurface(D3DContext *d3dc, pSrc = srcOps->pResource->GetTexture(); RETURN_STATUS_IF_NULL(pSrc, E_FAIL); - if (FAILED(res = d3dc->BeginScene(STATE_TEXTUREOP) || - FAILED(res = d3dc->SetTexture(pSrc)))) + if (FAILED(res = d3dc->BeginScene(STATE_TEXTUREOP)) || + FAILED(res = d3dc->SetTexture(pSrc))) { J2dRlsTraceLn(J2D_TRACE_ERROR, "D3DBlitTextureToSurface: BeginScene or SetTexture failed"); diff --git a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DVertexCacher.cpp b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DVertexCacher.cpp index b37c3f4d393..c30676b0ba2 100644 --- a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DVertexCacher.cpp +++ b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DVertexCacher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -566,10 +566,10 @@ HRESULT D3DVertexCacher::FillParallelogramAA(float fx11, float fy11, ADJUST_PGRAM(py, dy21, ph); ADJUST_PGRAM(px, dx12, pw); ADJUST_PGRAM(py, dy12, ph); - float px1 = floor(px); - float py1 = floor(py); - float px2 = ceil(px + pw); - float py2 = ceil(py + ph); + float px1 = floorf(px); + float py1 = floorf(py); + float px2 = ceilf(px + pw); + float py2 = ceilf(py + ph); float u11, v11, u12, v12, u21, v21, u22, v22; TRANSFORM(om, u11, v11, px1, py1); TRANSFORM(om, u21, v21, px2, py1); @@ -615,10 +615,10 @@ HRESULT D3DVertexCacher::DrawParallelogramAA(float ox11, float oy11, ADJUST_PGRAM(oy, oy21, oh); ADJUST_PGRAM(ox, ox12, ow); ADJUST_PGRAM(oy, oy12, oh); - float ox11 = floor(ox); - float oy11 = floor(oy); - float ox22 = ceil(ox + ow); - float oy22 = ceil(oy + oh); + float ox11 = floorf(ox); + float oy11 = floorf(oy); + float ox22 = ceilf(ox + ow); + float oy22 = ceilf(oy + oh); float ou11, ov11, ou12, ov12, ou21, ov21, ou22, ov22; TRANSFORM(om, ou11, ov11, ox11, oy11); TRANSFORM(om, ou21, ov21, ox22, oy11); diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp index 037b2a92bf5..c5428aedda5 100644 --- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp +++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -83,8 +83,8 @@ typedef HRESULT (__stdcall *PFNGETTHEMEPOSITION)(HTHEME hTheme, int iPartId, typedef HRESULT(__stdcall *PFNSETWINDOWTHEME)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); -typedef HRESULT (__stdcall *PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT) - (HTHEME hTheme, int iPartId, int iStateId); +typedef BOOL (__stdcall *PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT) + (HTHEME hTheme, int iPartId, int iStateId); typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION) (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo, diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp index 73d81cec878..a310d417893 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -486,7 +486,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height, VERIFY(::DeleteObject(oldFont)); } avgWidth = tm.tmAveCharWidth; - logFont.lfWidth = (LONG) ScaleUpX((fabs) (avgWidth * awScale)); + logFont.lfWidth = (LONG) ScaleUpX((fabsf) (avgWidth * awScale)); hFont = ::CreateFontIndirect(&logFont); DASSERT(hFont != NULL); VERIFY(::ReleaseDC(0, hDC)); From 3c7ab80501d7935d6f65b18c1eb2b47b207ffcf9 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Tue, 18 Apr 2023 11:10:57 +0000 Subject: [PATCH 022/288] 8304054: Linux: NullPointerException from FontConfiguration.getVersion in case no fonts are installed Reviewed-by: lucy, aivanov --- .../share/classes/sun/awt/FontConfiguration.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java index 1ae63af83db..8daec86345f 100644 --- a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java +++ b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java @@ -1244,15 +1244,24 @@ public abstract class FontConfiguration { return filenamesMap.get(platformName); } + private static final String fontconfigErrorMessage = + "Fontconfig head is null, check your fonts or fonts configuration"; + /** * Returns a configuration specific path to be appended to the font * search path. */ public String getExtraFontPath() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_appendedfontpath]); } public String getVersion() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_version]); } From e97fe081adbcb3ef37d192aab3c889f54d192059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 18 Apr 2023 12:55:14 +0000 Subject: [PATCH 023/288] 8306279: Build failure after JDK-8299592 Reviewed-by: thartmann --- make/modules/java.desktop/lib/Awt2dLibraries.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk index 7b5c98d5cf0..a0d70333108 100644 --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk @@ -134,6 +134,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBAWT, \ CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_CFLAGS), \ EXTRA_HEADER_DIRS := $(LIBAWT_EXTRA_HEADER_DIRS), \ DISABLED_WARNINGS_gcc_awt_LoadLibrary.c := unused-result, \ + DISABLED_WARNINGS_gcc_debug_mem.c := format-nonliteral, \ DISABLED_WARNINGS_gcc_ProcessPath.c := maybe-uninitialized, \ DISABLED_WARNINGS_gcc_Region.c := maybe-uninitialized, \ DISABLED_WARNINGS_gcc_SurfaceData.c := unused-value, \ From 803680f17a0459be66c221ac019266f91d52fc3f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 18 Apr 2023 15:33:39 +0000 Subject: [PATCH 024/288] 8306289: 32-bit build failures after JDK-8303422 Reviewed-by: jiefu, zgu --- src/hotspot/share/cds/filemap.cpp | 2 +- src/hotspot/share/cds/metaspaceShared.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 8a0d55fd105..a0c82dcdcc2 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1426,7 +1426,7 @@ bool FileMapInfo::init_from_file(int fd) { void FileMapInfo::seek_to_position(size_t pos) { if (os::lseek(_fd, (long)pos, SEEK_SET) < 0) { - log_error(cds)("Unable to seek to position %ld", pos); + log_error(cds)("Unable to seek to position " SIZE_FORMAT, pos); MetaspaceShared::unrecoverable_loading_error(); } } diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index a874668035f..5d5ef2f4567 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -267,7 +267,7 @@ void MetaspaceShared::initialize_for_static_dump() { size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M); _symbol_rs = ReservedSpace(symbol_rs_size); if (!_symbol_rs.is_reserved()) { - log_error(cds)("Unable to reserve memory for symbols: %ld bytes.", symbol_rs_size); + log_error(cds)("Unable to reserve memory for symbols: " SIZE_FORMAT " bytes.", symbol_rs_size); MetaspaceShared::unrecoverable_writing_error(); } _symbol_region.init(&_symbol_rs, &_symbol_vs); From 0f3828dddd8d4a08677efcd15aa8dfde18540130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Tue, 18 Apr 2023 16:00:40 +0000 Subject: [PATCH 025/288] 8306282: Build failure linux-arm32-open-cmp-baseline after JDK-8257967 Reviewed-by: egahlin, iklam --- src/hotspot/share/prims/jvmtiAgent.hpp | 16 ++++++------- src/hotspot/share/prims/jvmtiAgentList.cpp | 5 ---- src/hotspot/share/prims/jvmtiAgentList.hpp | 28 +++++++++++----------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/hotspot/share/prims/jvmtiAgent.hpp b/src/hotspot/share/prims/jvmtiAgent.hpp index e51c45351b0..6eb646ee2d4 100644 --- a/src/hotspot/share/prims/jvmtiAgent.hpp +++ b/src/hotspot/share/prims/jvmtiAgent.hpp @@ -58,20 +58,20 @@ class JvmtiAgent : public CHeapObj { public: JvmtiAgent(const char* name, const char* options, bool is_absolute_path, bool dynamic = false); - const char* name() const; + const char* name() const NOT_JVMTI_RETURN_(nullptr); const char* options() const; - bool is_absolute_path() const; - void* os_lib() const; + bool is_absolute_path() const NOT_JVMTI_RETURN_(false); + void* os_lib() const NOT_JVMTI_RETURN_(nullptr); void set_os_lib(void* os_lib); const char* os_lib_path() const; - void set_os_lib_path(const char* path); - bool is_static_lib() const; - void set_static_lib(); + void set_os_lib_path(const char* path) NOT_JVMTI_RETURN; + bool is_static_lib() const NOT_JVMTI_RETURN_(false); + void set_static_lib() NOT_JVMTI_RETURN; bool is_dynamic() const; bool is_xrun() const; bool is_instrument_lib() const; - bool is_loaded() const; - void set_loaded(); + bool is_loaded() const NOT_JVMTI_RETURN_(false); + void set_loaded() NOT_JVMTI_RETURN; bool is_jplis() const; bool is_jplis(JvmtiEnv* env) const; void set_jplis(const void* jplis); diff --git a/src/hotspot/share/prims/jvmtiAgentList.cpp b/src/hotspot/share/prims/jvmtiAgentList.cpp index fb46ddea661..cb8e5beb11d 100644 --- a/src/hotspot/share/prims/jvmtiAgentList.cpp +++ b/src/hotspot/share/prims/jvmtiAgentList.cpp @@ -28,7 +28,6 @@ #include "prims/jvmtiExport.hpp" #include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" -#include "utilities/growableArray.hpp" JvmtiAgent* JvmtiAgentList::_list = nullptr; @@ -82,10 +81,6 @@ JvmtiAgentList::Iterator::Iterator(JvmtiAgent** list, Filter filter) : } } -JvmtiAgentList::Iterator::~Iterator() { - delete _stack; -} - bool JvmtiAgentList::Iterator::has_next() const { assert(_stack != nullptr, "invariant"); return _stack->is_nonempty(); diff --git a/src/hotspot/share/prims/jvmtiAgentList.hpp b/src/hotspot/share/prims/jvmtiAgentList.hpp index 5fc4e140887..cdb8b7722b0 100644 --- a/src/hotspot/share/prims/jvmtiAgentList.hpp +++ b/src/hotspot/share/prims/jvmtiAgentList.hpp @@ -27,9 +27,8 @@ #include "memory/allocation.hpp" #include "prims/jvmtiAgent.hpp" +#include "utilities/growableArray.hpp" -template -class GrowableArrayCHeap; class JvmtiEnv; // Maintains a single cas linked-list of JvmtiAgents. @@ -49,13 +48,14 @@ class JvmtiAgentList : AllStatic { }; GrowableArrayCHeap* _stack; const Filter _filter; + Iterator() : _stack(nullptr), _filter(ALL) {} Iterator(JvmtiAgent** list, Filter filter); JvmtiAgent* select(JvmtiAgent* agent) const; public: - bool has_next() const; - JvmtiAgent* next(); - const JvmtiAgent* next() const; - ~Iterator(); + bool has_next() const NOT_JVMTI_RETURN_(false); + JvmtiAgent* next() NOT_JVMTI_RETURN_(nullptr); + const JvmtiAgent* next() const NOT_JVMTI_RETURN_(nullptr); + ~Iterator() { delete _stack; } }; private: @@ -66,19 +66,19 @@ class JvmtiAgentList : AllStatic { static void convert_xrun_agents(); public: - static void add(JvmtiAgent* agent); - static void add(const char* name, char* options, bool absolute_path); - static void add_xrun(const char* name, char* options, bool absolute_path); + static void add(JvmtiAgent* agent) NOT_JVMTI_RETURN; + static void add(const char* name, char* options, bool absolute_path) NOT_JVMTI_RETURN; + static void add_xrun(const char* name, char* options, bool absolute_path) NOT_JVMTI_RETURN; - static void load_agents(); + static void load_agents() NOT_JVMTI_RETURN; static jint load_agent(const char* agent, const char* absParam, - const char* options, outputStream* st); - static void load_xrun_agents(); - static void unload_agents(); + const char* options, outputStream* st) NOT_JVMTI_RETURN_(0); + static void load_xrun_agents() NOT_JVMTI_RETURN; + static void unload_agents() NOT_JVMTI_RETURN; static JvmtiAgent* lookup(JvmtiEnv* env, void* f_ptr); - static Iterator agents(); + static Iterator agents() NOT_JVMTI({ Iterator it; return it; }); static Iterator java_agents(); static Iterator native_agents(); static Iterator xrun_agents(); From 1b5d35ad2c8f0f3a43caba9d7a6d8e74f66caf5f Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Tue, 18 Apr 2023 21:23:42 +0000 Subject: [PATCH 026/288] 8306059: improve the reliability of TestSerialGCWithCDS.java and ArchiveRelocationTest.java tests Reviewed-by: iklam --- .../jtreg/runtime/cds/appcds/ArchiveRelocationTest.java | 8 +------- .../jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ArchiveRelocationTest.java b/test/hotspot/jtreg/runtime/cds/appcds/ArchiveRelocationTest.java index e3e921a27f0..55d9b207da6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/ArchiveRelocationTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/ArchiveRelocationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -76,12 +76,6 @@ public class ArchiveRelocationTest { .assertNormalExit(output -> { if (run_reloc) { output.shouldContain("Try to map archive(s) at an alternative address"); - if (output.getOutput().contains("Trying to map heap") || output.getOutput().contains("Loaded heap")) { - // The native data in the RO/RW regions have been relocated. If the CDS heap is - // mapped/loaded, we must patch all the native pointers. (CDS heap is - // not supported on all platforms) - output.shouldContain("Patching native pointers in heap region"); - } } }); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java index 0e0fb41f160..8c8cb4d932a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestSerialGCWithCDS.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -136,12 +136,6 @@ public class TestSerialGCWithCDS { "-Xlog:cds,cds+heap", "-XX:ArchiveRelocationMode=1", // always relocate shared metadata "Hello"); - if (out.getOutput().contains("Trying to map heap") || out.getOutput().contains("Loaded heap")) { - // The native data in the RO/RW regions have been relocated. If the CDS heap is - // mapped/loaded, we must patch all the native pointers. (CDS heap is - // not supported on all platforms) - out.shouldContain("Patching native pointers in heap region"); - } checkExecOutput(dumpWithSerial, execWithSerial, out); int n = 2; From c06135b5a6b21f6165a2a6dc13fdea6e65ae75b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Wed, 8 Jun 2022 15:47:46 +0000 Subject: [PATCH 027/288] 8287404: Improve ping times Reviewed-by: alanb, dfuchs, rhalade --- src/java.base/unix/native/libnet/Inet4AddressImpl.c | 6 +++--- src/java.base/unix/native/libnet/Inet6AddressImpl.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/unix/native/libnet/Inet4AddressImpl.c b/src/java.base/unix/native/libnet/Inet4AddressImpl.c index 5d2dc5b5507..4b4d8812c8e 100644 --- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c @@ -346,8 +346,8 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, struct ip *ip; struct sockaddr_in sa_recv; jchar pid; - struct timeval tv; - size_t plen = ICMP_ADVLENMIN + sizeof(tv); + struct timeval tv = { 0, 0 }; + const size_t plen = ICMP_MINLEN + sizeof(tv); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); @@ -419,7 +419,7 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, ip = (struct ip *)recvbuf; hlen = ((jint)(unsigned int)(ip->ip_hl)) << 2; // check if we received enough data - if (n < (jint)(hlen + sizeof(struct icmp))) { + if (n < (jint)(hlen + plen)) { continue; } icmp = (struct icmp *)(recvbuf + hlen); diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c index fe511318072..41094dff321 100644 --- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c @@ -545,7 +545,7 @@ ping6(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, struct icmp6_hdr *icmp6; struct sockaddr_in6 sa_recv; jchar pid; - struct timeval tv; + struct timeval tv = { 0, 0 }; size_t plen = sizeof(struct icmp6_hdr) + sizeof(tv); #if defined(__linux__) From 3656939a6a5d2d308ea57dd4238cfd7296950893 Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Mon, 14 Nov 2022 18:16:35 +0000 Subject: [PATCH 028/288] 8295304: Runtime support improvements Reviewed-by: rhalade, rriggs, bchristi --- src/java.base/share/classes/java/lang/ProcessBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/ProcessBuilder.java b/src/java.base/share/classes/java/lang/ProcessBuilder.java index e870682a38e..e7d5d9debef 100644 --- a/src/java.base/share/classes/java/lang/ProcessBuilder.java +++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java @@ -1116,8 +1116,8 @@ public final class ProcessBuilder String dir = directory == null ? null : directory.toString(); - for (int i = 1; i < cmdarray.length; i++) { - if (cmdarray[i].indexOf('\u0000') >= 0) { + for (String s : cmdarray) { + if (s.indexOf('\u0000') >= 0) { throw new IOException("invalid null character in command"); } } From 5ec0120152f4aee594054118a74bb82087889363 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Tue, 13 Dec 2022 00:10:06 +0000 Subject: [PATCH 029/288] 8297371: Improve UTF8 representation redux Reviewed-by: rhalade, bchristi --- src/java.base/share/native/libjava/jni_util.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c index d6e3176c14d..c20d7484a92 100644 --- a/src/java.base/share/native/libjava/jni_util.c +++ b/src/java.base/share/native/libjava/jni_util.c @@ -35,8 +35,13 @@ * such as "z:" need to be appended with a "." so we * must allocate at least 4 bytes to allow room for * this expansion. See 4235353 for details. + * This macro returns NULL if the requested size is + * negative, or the size is INT_MAX as the macro adds 1 + * that overflows into negative value. */ -#define MALLOC_MIN4(len) ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1)) +#define MALLOC_MIN4(len) ((unsigned)(len) >= INT_MAX ? \ + NULL : \ + ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1))) /** * Throw a Java exception by name. Similar to SignalError. @@ -861,17 +866,10 @@ getStringUTF8(JNIEnv *env, jstring jstr) } } - // Check `jint` overflow - if (rlen < 0) { - (*env)->ReleasePrimitiveArrayCritical(env, value, str, 0); - JNU_ThrowOutOfMemoryError(env, "requested array size exceeds VM limit"); - return NULL; - } - result = MALLOC_MIN4(rlen); if (result == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, value, str, 0); - JNU_ThrowOutOfMemoryError(env, 0); + JNU_ThrowOutOfMemoryError(env, "requested array size exceeds VM limit"); return NULL; } From ec119716e542047f52aadefef142a9be64b35b7b Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 21 Dec 2022 10:04:07 +0000 Subject: [PATCH 030/288] 8296676: Improve String platform support Reviewed-by: aefimov, dfuchs --- .../share/classes/java/net/InetAddress.java | 8 +++++ .../www/protocol/http/HttpURLConnection.java | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index 0b05960647a..4ebe44ee422 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -1062,6 +1062,7 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In throws UnknownHostException { Objects.requireNonNull(host); Objects.requireNonNull(policy); + validate(host); InetAddress[] addrs; long comp = Blocker.begin(); try { @@ -1475,6 +1476,7 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In return ret; } + validate(host); boolean ipv6Expected = false; if (host.charAt(0) == '[') { // This is supposed to be an IPv6 literal @@ -1873,4 +1875,10 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In pf.put("family", holder().getFamily()); s.writeFields(); } + + private static void validate(String host) throws UnknownHostException { + if (host.indexOf(0) != -1) { + throw new UnknownHostException("NUL character not allowed in hostname"); + } + } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 4ed92b99308..b677278459a 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -2359,7 +2359,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * the connection. */ @SuppressWarnings({"removal","fallthrough"}) - private AuthenticationInfo getHttpProxyAuthentication(AuthenticationHeader authhdr) { + private AuthenticationInfo getHttpProxyAuthentication(AuthenticationHeader authhdr) + throws IOException { assert isLockHeldByCurrentThread(); @@ -2460,6 +2461,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { authenticator, host, null, port, url.getProtocol(), "", scheme, url, RequestorType.PROXY); + validateNTLMCredentials(a); } /* If we are not trying transparent authentication then * we need to have a PasswordAuthentication instance. For @@ -2529,7 +2531,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * preferred. */ @SuppressWarnings("fallthrough") - private AuthenticationInfo getServerAuthentication(AuthenticationHeader authhdr) { + private AuthenticationInfo getServerAuthentication(AuthenticationHeader authhdr) + throws IOException { // Only called from getInputStream0 assert isLockHeldByCurrentThread(); @@ -2641,6 +2644,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { authenticator, url.getHost(), addr, port, url.getProtocol(), "", scheme, url, RequestorType.SERVER); + validateNTLMCredentials(a); } /* If we are not trying transparent authentication then @@ -3997,6 +4001,27 @@ public class HttpURLConnection extends java.net.HttpURLConnection { private static URL newURL(URL context, String spec) throws MalformedURLException { return new URL(context, spec); } + + // ensure there are no null characters in username or password + private static void validateNTLMCredentials(PasswordAuthentication pw) + throws IOException { + + if (pw == null) { + return; + } + char[] password = pw.getPassword(); + if (password != null) { + for (int i=0; i Date: Thu, 5 Jan 2023 18:27:31 +0000 Subject: [PATCH 031/288] 8298667: Improved path handling Reviewed-by: rhalade, alanb --- src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java index 05ff0e04007..6a77df29c6c 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java @@ -75,6 +75,10 @@ class UnixUriUtils { int pos = 0; while (pos < len) { char c = p.charAt(pos++); + if ((c == '/') && (pos < len) && (p.charAt(pos) == '/')) { + // skip redundant slashes + continue; + } byte b; if (c == '%') { assert (pos+2) <= len; From 14aad787a81368ced426c2a9cb301f4ff0c37c3f Mon Sep 17 00:00:00 2001 From: Jamil Nimeh Date: Fri, 6 Jan 2023 23:17:41 +0000 Subject: [PATCH 032/288] 8294474: Better AES support Reviewed-by: ahgross, ascarpino --- .../share/classes/sun/security/ssl/KeyUpdate.java | 6 ++++-- .../classes/sun/security/ssl/SSLEngineImpl.java | 8 ++++---- .../classes/sun/security/ssl/SSLSocketImpl.java | 8 ++++---- .../classes/sun/security/ssl/TransportContext.java | 13 ++++++++++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/KeyUpdate.java b/src/java.base/share/classes/sun/security/ssl/KeyUpdate.java index ef42159b75d..49eb0420f47 100644 --- a/src/java.base/share/classes/sun/security/ssl/KeyUpdate.java +++ b/src/java.base/share/classes/sun/security/ssl/KeyUpdate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,7 +170,9 @@ final class KeyUpdate { public byte[] produce(ConnectionContext context) throws IOException { PostHandshakeContext hc = (PostHandshakeContext)context; return handshakeProducer.produce(context, - new KeyUpdateMessage(hc, KeyUpdateRequest.REQUESTED)); + new KeyUpdateMessage(hc, hc.conContext.isInboundClosed() ? + KeyUpdateRequest.NOTREQUESTED : + KeyUpdateRequest.REQUESTED)); } } diff --git a/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java index 316bec6b12c..115cfc68185 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -394,11 +394,11 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport { */ private HandshakeStatus tryKeyUpdate( HandshakeStatus currentHandshakeStatus) throws IOException { - // Don't bother to kickstart if handshaking is in progress, or if the - // connection is not duplex-open. + // Don't bother to kickstart if handshaking is in progress, or if + // the write side of the connection is not open. We allow a half- + // duplex write-only connection for key updates. if ((conContext.handshakeContext == null) && !conContext.isOutboundClosed() && - !conContext.isInboundClosed() && !conContext.isBroken) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.finest("trigger key update"); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java index 98d5ac1fa4e..b4129964662 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1537,11 +1537,11 @@ public final class SSLSocketImpl * wrapped. */ private void tryKeyUpdate() throws IOException { - // Don't bother to kickstart if handshaking is in progress, or if the - // connection is not duplex-open. + // Don't bother to kickstart if handshaking is in progress, or if + // the write side of the connection is not open. We allow a half- + // duplex write-only connection for key updates. if ((conContext.handshakeContext == null) && !conContext.isOutboundClosed() && - !conContext.isInboundClosed() && !conContext.isBroken) { if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { SSLLogger.finest("trigger key update"); diff --git a/src/java.base/share/classes/sun/security/ssl/TransportContext.java b/src/java.base/share/classes/sun/security/ssl/TransportContext.java index 361b0663a8b..c235da3068c 100644 --- a/src/java.base/share/classes/sun/security/ssl/TransportContext.java +++ b/src/java.base/share/classes/sun/security/ssl/TransportContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,7 +219,14 @@ final class TransportContext implements ConnectionContext { throw new IllegalStateException("Client/Server mode not yet set."); } - if (outputRecord.isClosed() || inputRecord.isClosed() || isBroken) { + // The threshold for allowing the method to continue processing + // depends on whether we are doing a key update or kickstarting + // a handshake. In the former case, we only require the write-side + // to be open where a handshake would require a full duplex connection. + boolean isNotUsable = outputRecord.writeCipher.atKeyLimit() ? + (outputRecord.isClosed() || isBroken) : + (outputRecord.isClosed() || inputRecord.isClosed() || isBroken); + if (isNotUsable) { if (closeReason != null) { throw new SSLException( "Cannot kickstart, the connection is broken or closed", @@ -247,7 +254,7 @@ final class TransportContext implements ConnectionContext { // // Need no kickstart message on server side unless the connection // has been established. - if(isNegotiated || sslConfig.isClientMode) { + if (isNegotiated || sslConfig.isClientMode) { handshakeContext.kickstart(); } } From b1c34c03d7a84a230b0799f30a420c03ebe89b14 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Wed, 18 Jan 2023 21:29:57 +0000 Subject: [PATCH 033/288] 8296684: Improve String platform support Reviewed-by: amenkov, michaelm, rhalade --- .../classes/sun/tools/attach/VirtualMachineImpl.java | 1 + .../classes/sun/tools/attach/VirtualMachineImpl.java | 1 + .../classes/sun/tools/attach/VirtualMachineImpl.java | 1 + .../sun/tools/attach/HotSpotVirtualMachine.java | 10 ++++++++++ .../classes/sun/tools/attach/VirtualMachineImpl.java | 1 + 5 files changed, 14 insertions(+) diff --git a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java index 9e00978f250..d0a6dac40c8 100644 --- a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java @@ -136,6 +136,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { */ InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException { assert args.length <= 3; // includes null + checkNulls(args); // did we detach? synchronized (this) { 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 324e52235cb..6a70d5d9f71 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -140,6 +140,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { */ InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException { assert args.length <= 3; // includes null + checkNulls(args); // did we detach? synchronized (this) { diff --git a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java index 7a3b79853e7..891a0561a8a 100644 --- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java @@ -136,6 +136,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { */ InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException { assert args.length <= 3; // includes null + checkNulls(args); // did we detach? synchronized (this) { 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 409aa055082..2c2e865a086 100644 --- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java +++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java @@ -487,4 +487,14 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { } return attachTimeout; } + + protected static void checkNulls(Object... args) { + for (Object arg : args) { + if (arg instanceof String s) { + if (s.indexOf(0) >= 0) { + throw new IllegalArgumentException("illegal null character in command"); + } + } + } + } } diff --git a/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java index f2241c209bb..184d07137e2 100644 --- a/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java @@ -73,6 +73,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { throws AgentLoadException, IOException { assert args.length <= 3; // includes null + checkNulls(args); // create a pipe using a random name Random rnd = new Random(); From 2e5700a92ce731af2da0c66a0a718b005ef6a6e2 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Thu, 19 Jan 2023 00:53:14 +0000 Subject: [PATCH 034/288] 8288436: Improve Xalan supports Reviewed-by: smarks, ahgross, rhalade, lancea, naoto --- .../xml/internal/utils/XMLReaderManager.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index a0bf61f5262..508ec4ad039 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -37,13 +37,15 @@ import org.xml.sax.XMLReader; * Creates XMLReader objects and caches them for re-use. * This class follows the singleton pattern. * - * @LastModified: Jan 2022 + * @LastModified: Jan 2023 */ public class XMLReaderManager { private static final XMLReaderManager m_singletonManager = new XMLReaderManager(); private static final String property = "org.xml.sax.driver"; + private final static String LEXICAL_HANDLER_PROPERTY = + "http://xml.org/sax/properties/lexical-handler"; /** * Cache of XMLReader objects @@ -186,12 +188,22 @@ public class XMLReaderManager { */ public synchronized void releaseXMLReader(XMLReader reader) { // If the reader that's being released is the cached reader - // for this thread, remove it from the m_isUse list. + // for this thread, remove it from the m_inUse list. ReaderWrapper rw = m_readers.get(); - if (rw.reader == reader && reader != null) { + if (rw != null && rw.reader == reader && reader != null) { + // reset the reader for reuse + reader.setContentHandler(null); + reader.setDTDHandler(null); + reader.setEntityResolver(null); + try { + reader.setProperty(LEXICAL_HANDLER_PROPERTY, null); + } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { + // shouldn't happen as the property is supported. + } m_inUse.remove(reader); } } + /** * Return the state of the services mechanism feature. */ From 9e56d100df23e8d781aa262ad59c7e1e0a3e6669 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 19 Jan 2023 04:26:22 +0000 Subject: [PATCH 035/288] 8296832: Improve Swing platform support Reviewed-by: skoivu, kizune, rhalade, prr --- .../javax/swing/plaf/basic/BasicHTML.java | 28 +++++++++++++++++-- .../javax/swing/text/html/HTMLEditorKit.java | 7 ++++- .../javax/swing/text/html/ObjectView.java | 10 +++++++ .../classes/sun/swing/SwingAccessor.java | 15 ++++++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicHTML.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicHTML.java index 4aaf7985156..4c40dc2d278 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicHTML.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicHTML.java @@ -33,6 +33,7 @@ import javax.swing.*; import javax.swing.text.*; import javax.swing.text.html.*; +import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; /** @@ -220,7 +221,7 @@ public class BasicHTML { View value = null; View oldValue = (View)c.getClientProperty(BasicHTML.propertyKey); Boolean htmlDisabled = (Boolean) c.getClientProperty(htmlDisable); - if (htmlDisabled != Boolean.TRUE && BasicHTML.isHTMLString(text)) { + if (!(Boolean.TRUE.equals(htmlDisabled)) && BasicHTML.isHTMLString(text)) { value = BasicHTML.createHTMLView(c, text); } if (value != oldValue && oldValue != null) { @@ -376,15 +377,36 @@ public class BasicHTML { */ static class BasicHTMLViewFactory extends HTMLEditorKit.HTMLFactory { public View create(Element elem) { - View view = super.create(elem); + View view = null; + try { + setAllowHTMLObject(); + view = super.create(elem); + } finally { + clearAllowHTMLObject(); + } if (view instanceof ImageView) { ((ImageView)view).setLoadsSynchronously(true); } return view; } - } + private static Boolean useOV = null; + + @SuppressWarnings("removal") + private static void setAllowHTMLObject() { + if (useOV == null) { + useOV = java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "swing.html.object")); + }; + SwingAccessor.setAllowHTMLObject(useOV); + } + + private static void clearAllowHTMLObject() { + SwingAccessor.setAllowHTMLObject(null); + } + } /** * The subclass of HTMLDocument that is used as the model. getForeground diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java index 24e8c255547..71a1096cfd5 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -93,6 +93,7 @@ import javax.swing.text.View; import javax.swing.text.ViewFactory; import javax.swing.text.html.parser.ParserDelegator; +import sun.swing.SwingAccessor; import sun.awt.AppContext; import static java.nio.charset.StandardCharsets.ISO_8859_1; @@ -1402,7 +1403,11 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { (kind == HTML.Tag.TEXTAREA)) { return new FormView(elem); } else if (kind == HTML.Tag.OBJECT) { - return new ObjectView(elem); + if (SwingAccessor.getAllowHTMLObject()) { + return new ObjectView(elem); + } else { + return new ObjectView(elem, false); + } } else if (kind == HTML.Tag.FRAMESET) { if (elem.getAttributes().isDefined(HTML.Attribute.ROWS)) { return new FrameSetView(elem, View.Y_AXIS); diff --git a/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java b/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java index 175ca18bfb6..050a79fe85e 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java @@ -71,6 +71,8 @@ import sun.reflect.misc.ReflectUtil; */ public class ObjectView extends ComponentView { + private boolean createComp = true; // default + /** * Creates a new ObjectView object. * @@ -80,6 +82,11 @@ public class ObjectView extends ComponentView { super(elem); } + ObjectView(Element elem, boolean createComp) { + super(elem); + this.createComp = createComp; + } + /** * Create the component. The classid is used * as a specification of the classname, which @@ -87,6 +94,9 @@ public class ObjectView extends ComponentView { */ @SuppressWarnings("deprecation") protected Component createComponent() { + if (!createComp) { + return getUnloadableRepresentation(); + } AttributeSet attr = getElement().getAttributes(); String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); try { diff --git a/src/java.desktop/share/classes/sun/swing/SwingAccessor.java b/src/java.desktop/share/classes/sun/swing/SwingAccessor.java index 0b823582e23..5c561de4a42 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingAccessor.java +++ b/src/java.desktop/share/classes/sun/swing/SwingAccessor.java @@ -321,4 +321,19 @@ public final class SwingAccessor { MethodHandles.lookup().ensureInitialized(c); } catch (IllegalAccessException e) {} } + + private static ThreadLocal tlObj = new ThreadLocal(); + + public static Boolean getAllowHTMLObject() { + Boolean b = tlObj.get(); + if (b == null) { + return Boolean.TRUE; + } else { + return b; + } + } + + public static void setAllowHTMLObject(Boolean val) { + tlObj.set(val); + } } From f098b490f13f9c7b25f970c60adc473bcf188a0f Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Thu, 19 Jan 2023 20:25:14 +0000 Subject: [PATCH 036/288] 8298310: Enhance TLS session negotiation Reviewed-by: rhalade, mschoene, weijun, ascarpino --- .../provider/certpath/AdjacencyList.java | 11 ++- .../security/provider/certpath/Builder.java | 15 ++-- .../provider/certpath/ForwardBuilder.java | 81 ++++++++++++------- .../provider/certpath/ForwardState.java | 32 ++------ .../sun/security/provider/certpath/State.java | 10 +-- .../provider/certpath/SunCertPathBuilder.java | 70 +++++++++------- 6 files changed, 114 insertions(+), 105 deletions(-) diff --git a/src/java.base/share/classes/sun/security/provider/certpath/AdjacencyList.java b/src/java.base/share/classes/sun/security/provider/certpath/AdjacencyList.java index 283fb649da6..b6d9bcddd34 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/AdjacencyList.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/AdjacencyList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -87,7 +87,7 @@ public class AdjacencyList { // the actual set of steps the AdjacencyList represents private final ArrayList mStepList; - // the original list, just for the toString method + // the original list private final List> mOrigList; /** @@ -114,6 +114,13 @@ public class AdjacencyList { return Collections.unmodifiableList(mStepList).iterator(); } + /** + * Returns the number of attempted paths (useful for debugging). + */ + public int numAttemptedPaths() { + return mOrigList.size(); + } + /** * Recursive, private method which actually builds the step list from * the given adjacency list. Follow is the parent BuildStep diff --git a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java index 23c12519ad7..50f0cfbd2ea 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -406,8 +406,7 @@ abstract class Builder { /** * Search the specified CertStores and add all certificates matching - * selector to resultCerts. Self-signed certs are not useful here - * and therefore ignored. + * selector to resultCerts. * * If the targetCert criterion of the selector is set, only that cert * is examined and the CertStores are not searched. @@ -426,8 +425,7 @@ abstract class Builder { X509Certificate targetCert = selector.getCertificate(); if (targetCert != null) { // no need to search CertStores - if (selector.match(targetCert) && !X509CertImpl.isSelfSigned - (targetCert, buildParams.sigProvider())) { + if (selector.match(targetCert)) { if (debug != null) { debug.println("Builder.addMatchingCerts: " + "adding target cert" + @@ -446,11 +444,8 @@ abstract class Builder { Collection certs = store.getCertificates(selector); for (Certificate cert : certs) { - if (!X509CertImpl.isSelfSigned - ((X509Certificate)cert, buildParams.sigProvider())) { - if (resultCerts.add((X509Certificate)cert)) { - add = true; - } + if (resultCerts.add((X509Certificate)cert)) { + add = true; } } if (!checkAll && add) { diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java index 17a11b4e7fe..26f97efc3d9 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -47,6 +47,7 @@ import sun.security.x509.AccessDescription; import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityKeyIdentifierExtension; import static sun.security.x509.PKIXExtensions.*; +import sun.security.x509.SubjectAlternativeNameExtension; import sun.security.x509.X500Name; import sun.security.x509.X509CertImpl; @@ -293,9 +294,7 @@ final class ForwardBuilder extends Builder { "\n Issuer: " + trustedCert.getIssuerX500Principal()); } - if (caCerts.add(trustedCert) && !searchAllCertStores) { - return; - } + caCerts.add(trustedCert); } } @@ -668,8 +667,7 @@ final class ForwardBuilder extends Builder { * only be executed in a reverse direction are deferred until the * complete path has been built. * - * Trust anchor certs are not validated, but are used to verify the - * signature and revocation status of the previous cert. + * Trust anchor certs are not validated. * * If the last certificate is being verified (the one whose subject * matches the target subject) then steps in 6.1.4 of the PKIX @@ -700,17 +698,15 @@ final class ForwardBuilder extends Builder { currState.untrustedChecker.check(cert, Collections.emptySet()); /* - * check for looping - abort a loop if we encounter the same - * certificate twice + * Abort if we encounter the same certificate or a certificate with + * the same public key, subject DN, and subjectAltNames as a cert + * that is already in path. */ - if (certPathList != null) { - for (X509Certificate cpListCert : certPathList) { - if (cert.equals(cpListCert)) { - if (debug != null) { - debug.println("loop detected!!"); - } - throw new CertPathValidatorException("loop detected"); - } + for (X509Certificate cpListCert : certPathList) { + if (repeated(cpListCert, cert)) { + throw new CertPathValidatorException( + "cert with repeated subject, public key, and " + + "subjectAltNames detected"); } } @@ -789,21 +785,48 @@ final class ForwardBuilder extends Builder { */ KeyChecker.verifyCAKeyUsage(cert); } + } - /* - * the following checks are performed even when the cert - * is a trusted cert, since we are only extracting the - * subjectDN, and publicKey from the cert - * in order to verify a previous cert - */ + /** + * Return true if two certificates are equal or have the same subject, + * public key, and subject alternative names. + */ + private static boolean repeated( + X509Certificate currCert, X509Certificate nextCert) { + if (currCert.equals(nextCert)) { + return true; + } + return (currCert.getSubjectX500Principal().equals( + nextCert.getSubjectX500Principal()) && + currCert.getPublicKey().equals(nextCert.getPublicKey()) && + altNamesEqual(currCert, nextCert)); + } - /* - * Check signature only if no key requiring key parameters has been - * encountered. - */ - if (!currState.keyParamsNeeded()) { - (currState.cert).verify(cert.getPublicKey(), - buildParams.sigProvider()); + /** + * Return true if two certificates have the same subject alternative names. + */ + private static boolean altNamesEqual( + X509Certificate currCert, X509Certificate nextCert) { + X509CertImpl curr, next; + try { + curr = X509CertImpl.toImpl(currCert); + next = X509CertImpl.toImpl(nextCert); + } catch (CertificateException ce) { + return false; + } + + SubjectAlternativeNameExtension currAltNameExt = + curr.getSubjectAlternativeNameExtension(); + SubjectAlternativeNameExtension nextAltNameExt = + next.getSubjectAlternativeNameExtension(); + if (currAltNameExt != null) { + if (nextAltNameExt == null) { + return false; + } + return Arrays.equals(currAltNameExt.getExtensionValue(), + nextAltNameExt.getExtensionValue()); + } else { + return (nextAltNameExt == null); } } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java index 24219a5a389..c93f0bcb3a0 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,10 +80,8 @@ class ForwardState implements State { /* The list of user-defined checkers that support forward checking */ ArrayList forwardCheckers; - /* Flag indicating if key needing to inherit key parameters has been - * encountered. - */ - boolean keyParamsNeededFlag = false; + /* Flag indicating if last cert in path is self-issued */ + boolean selfIssued; /** * Returns a boolean flag indicating if the state is initial @@ -96,18 +94,6 @@ class ForwardState implements State { return init; } - /** - * Return boolean flag indicating whether a public key that needs to inherit - * key parameters has been encountered. - * - * @return boolean true if key needing to inherit parameters has been - * encountered; false otherwise. - */ - @Override - public boolean keyParamsNeeded() { - return keyParamsNeededFlag; - } - /** * Display state for debugging purposes */ @@ -117,9 +103,9 @@ class ForwardState implements State { "\n issuerDN of last cert: " + issuerDN + "\n traversedCACerts: " + traversedCACerts + "\n init: " + init + - "\n keyParamsNeeded: " + keyParamsNeededFlag + "\n subjectNamesTraversed: \n" + subjectNamesTraversed + + "\n selfIssued: " + selfIssued + "\n" + "]\n"; } @@ -163,18 +149,14 @@ class ForwardState implements State { X509CertImpl icert = X509CertImpl.toImpl(cert); - /* see if certificate key has null parameters */ - if (PKIX.isDSAPublicKeyWithoutParams(icert.getPublicKey())) { - keyParamsNeededFlag = true; - } - /* update certificate */ this.cert = icert; /* update issuer DN */ issuerDN = cert.getIssuerX500Principal(); - if (!X509CertImpl.isSelfIssued(cert)) { + selfIssued = X509CertImpl.isSelfIssued(cert); + if (!selfIssued) { /* * update traversedCACerts only if this is a non-self-issued @@ -187,7 +169,7 @@ class ForwardState implements State { /* update subjectNamesTraversed only if this is the EE cert or if this cert is not self-issued */ - if (init || !X509CertImpl.isSelfIssued(cert)) { + if (init || !selfIssued) { X500Principal subjName = cert.getSubjectX500Principal(); subjectNamesTraversed.add(X500Name.asX500Name(subjName)); diff --git a/src/java.base/share/classes/sun/security/provider/certpath/State.java b/src/java.base/share/classes/sun/security/provider/certpath/State.java index a18ef2ad760..890689c9df5 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/State.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/State.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -62,12 +62,4 @@ interface State extends Cloneable { * @return boolean flag indicating if the state is initial (just starting) */ boolean isInitial(); - - /** - * Returns a boolean flag indicating if a key lacking necessary key - * algorithm parameters has been encountered. - * - * @return boolean flag indicating if key lacking parameters encountered. - */ - boolean keyParamsNeeded(); } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java index 6fed8f7df35..8c9081b3d9f 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -42,6 +42,7 @@ import javax.security.auth.x500.X500Principal; import sun.security.provider.certpath.PKIX.BuilderParams; import static sun.security.x509.PKIXExtensions.*; +import sun.security.x509.X509CertImpl; import sun.security.util.Debug; /** @@ -130,18 +131,21 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { List> adjList = new ArrayList<>(); PKIXCertPathBuilderResult result = buildCertPath(false, adjList); if (result == null) { - if (debug != null) { - debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " + + if (buildParams.certStores().size() > 1 || Builder.USE_AIA) { + if (debug != null) { + debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " + "try building again searching all certstores"); + } + // try again + adjList.clear(); + result = buildCertPath(true, adjList); + if (result != null) { + return result; + } } - // try again - adjList.clear(); - result = buildCertPath(true, adjList); - if (result == null) { - throw new SunCertPathBuilderException("unable to find valid " - + "certification path to requested target", - new AdjacencyList(adjList)); - } + throw new SunCertPathBuilderException("unable to find valid " + + "certification path to requested target", + new AdjacencyList(adjList)); } return result; } @@ -270,8 +274,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { /* * For each cert in the collection, verify anything * that hasn't been checked yet (signature, revocation, etc.) - * and check for loops. Call depthFirstSearchForward() - * recursively for each good cert. + * and check for certs with repeated public key and subject. + * Call depthFirstSearchForward() recursively for each good cert. */ vertices: @@ -346,26 +350,24 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { checkers.add(new AlgorithmChecker(builder.trustAnchor, buildParams.timestamp(), buildParams.variant())); - BasicChecker basicChecker = null; - if (nextState.keyParamsNeeded()) { - PublicKey rootKey = cert.getPublicKey(); - if (builder.trustAnchor.getTrustedCert() == null) { - rootKey = builder.trustAnchor.getCAPublicKey(); - if (debug != null) - debug.println( - "SunCertPathBuilder.depthFirstSearchForward " + - "using buildParams public key: " + - rootKey.toString()); - } - TrustAnchor anchor = new TrustAnchor - (cert.getSubjectX500Principal(), rootKey, null); + PublicKey rootKey = cert.getPublicKey(); + if (builder.trustAnchor.getTrustedCert() == null) { + rootKey = builder.trustAnchor.getCAPublicKey(); + if (debug != null) + debug.println( + "SunCertPathBuilder.depthFirstSearchForward " + + "using buildParams public key: " + + rootKey.toString()); + } + TrustAnchor anchor = new TrustAnchor + (cert.getSubjectX500Principal(), rootKey, null); - // add the basic checker - basicChecker = new BasicChecker(anchor, buildParams.date(), + // add the basic checker + BasicChecker basicChecker = new BasicChecker(anchor, + buildParams.date(), buildParams.sigProvider(), true); - checkers.add(basicChecker); - } + checkers.add(basicChecker); buildParams.setCertPath(cf.generateCertPath(appendedCerts)); @@ -511,6 +513,14 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { policyTreeResult = policyChecker.getPolicyTree(); return; } else { + // If successive certs are self-issued, don't continue search + // on this branch. + if (currentState.selfIssued && X509CertImpl.isSelfIssued(cert)) { + if (debug != null) { + debug.println("Successive certs are self-issued"); + } + return; + } builder.addCertToPath(cert, cpList); } From 77df3152c8ddc54ee678cce8334625a60a046bac Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 20 Jan 2023 09:12:24 +0000 Subject: [PATCH 037/288] 8296692: Improve String platform support Reviewed-by: rhalade, amenkov, michaelm --- .../unix/classes/jdk/internal/agent/FileSystemImpl.java | 8 ++++++-- .../classes/jdk/internal/agent/FileSystemImpl.java | 9 ++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java index 54158c1596c..9582a97cb8f 100644 --- a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java +++ b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -29,7 +29,7 @@ import java.io.File; import java.io.IOException; /* - * Solaris/Linux implementation of jdk.internal.agent.FileSystem + * Linux implementation of jdk.internal.agent.FileSystem */ @SuppressWarnings("removal") public class FileSystemImpl extends FileSystem { @@ -39,6 +39,10 @@ public class FileSystemImpl extends FileSystem { } public boolean isAccessUserOnly(File f) throws IOException { + String path = f.getPath(); + if (path.indexOf(0) >= 0) { + throw new IOException("illegal filename"); + } return isAccessUserOnly0(f.getPath()); } diff --git a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java index 9dad4b91943..f0fd31c0f9e 100644 --- a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java +++ b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -35,11 +35,18 @@ import java.io.IOException; public class FileSystemImpl extends FileSystem { public boolean supportsFileSecurity(File f) throws IOException { + String path = f.getAbsolutePath(); + if (path.indexOf(0) >= 0) { + throw new IOException("illegal filename"); + } return isSecuritySupported0(f.getAbsolutePath()); } public boolean isAccessUserOnly(File f) throws IOException { String path = f.getAbsolutePath(); + if (path.indexOf(0) >= 0) { + throw new IOException("illegal filename"); + } if (!isSecuritySupported0(path)) { throw new UnsupportedOperationException("File system does not support file security"); } From eb8d8cdddd10e4f586b37c00541e19c02f1e69a8 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Tue, 24 Jan 2023 14:40:58 +0000 Subject: [PATCH 038/288] 8299129: Enhance NameService lookups Reviewed-by: ahgross, michaelm, rhalade, dfuchs --- .../share/classes/java/net/InetAddress.java | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index 4ebe44ee422..8a4196644eb 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, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -1484,44 +1484,45 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In host = host.substring(1, host.length() -1); ipv6Expected = true; } else { - // This was supposed to be a IPv6 address, but it's not! - throw new UnknownHostException(host + ": invalid IPv6 address"); + // This was supposed to be a IPv6 literal, but it's not + throw invalidIPv6LiteralException(host, false); } } - // if host is an IP address, we won't do further lookup + // Check and try to parse host string as an IP address literal if (IPAddressUtil.digit(host.charAt(0), 16) != -1 || (host.charAt(0) == ':')) { - byte[] addr; + byte[] addr = null; int numericZone = -1; String ifname = null; - // see if it is IPv4 address - try { - addr = IPAddressUtil.validateNumericFormatV4(host); - } catch (IllegalArgumentException iae) { - var uhe = new UnknownHostException(host); - uhe.initCause(iae); - throw uhe; + + if (!ipv6Expected) { + // check if it is IPv4 address only if host is not wrapped in '[]' + try { + addr = IPAddressUtil.validateNumericFormatV4(host); + } catch (IllegalArgumentException iae) { + var uhe = new UnknownHostException(host); + uhe.initCause(iae); + throw uhe; + } } if (addr == null) { - // This is supposed to be an IPv6 literal - // Check if a numeric or string zone id is present + // Try to parse host string as an IPv6 literal + // Check if a numeric or string zone id is present first int pos; - if ((pos=host.indexOf ('%')) != -1) { - numericZone = checkNumericZone (host); + if ((pos = host.indexOf('%')) != -1) { + numericZone = checkNumericZone(host); if (numericZone == -1) { /* remainder of string must be an ifname */ - ifname = host.substring (pos+1); + ifname = host.substring(pos + 1); } } - if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && host.contains(":")) { - throw new UnknownHostException(host + ": invalid IPv6 address"); + if ((addr = IPAddressUtil.textToNumericFormatV6(host)) == null && + (host.contains(":") || ipv6Expected)) { + throw invalidIPv6LiteralException(host, ipv6Expected); } - } else if (ipv6Expected) { - // Means an IPv4 literal between brackets! - throw new UnknownHostException("["+host+"]"); } - InetAddress[] ret = new InetAddress[1]; if(addr != null) { + InetAddress[] ret = new InetAddress[1]; if (addr.length == Inet4Address.INADDRSZ) { if (numericZone != -1 || ifname != null) { // IPv4-mapped address must not contain zone-id @@ -1538,12 +1539,18 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In return ret; } } else if (ipv6Expected) { - // We were expecting an IPv6 Literal, but got something else - throw new UnknownHostException("["+host+"]"); + // We were expecting an IPv6 Literal since host string starts + // and ends with square brackets, but we got something else. + throw invalidIPv6LiteralException(host, true); } return getAllByName0(host, true, true); } + private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { + String hostString = wrapInBrackets ? "[" + host + "]" : host; + return new UnknownHostException(hostString + ": invalid IPv6 address literal"); + } + /** * Returns the loopback address. *

From c7faf60201a2401897e6159a5aaa03f22d4ae5d6 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Wed, 19 Apr 2023 02:53:02 +0000 Subject: [PATCH 039/288] 8305757: Call Method::compute_has_loops_flag() when creating CDS archive Reviewed-by: coleenp, ccheung --- src/hotspot/share/cds/metaspaceShared.cpp | 1 + src/hotspot/share/oops/instanceKlass.cpp | 10 ++++++++++ src/hotspot/share/oops/instanceKlass.hpp | 1 + 3 files changed, 12 insertions(+) diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 5d5ef2f4567..b62666a09f0 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -838,6 +838,7 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { SystemDictionaryShared::set_class_has_failed_verification(ik); _has_error_classes = true; } + ik->compute_has_loops_flag_for_methods(); BytecodeVerificationLocal = saved; return true; } else { diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 8bb3f10f868..a6f2245e3cd 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -2624,6 +2624,16 @@ void InstanceKlass::init_shared_package_entry() { #endif } +void InstanceKlass::compute_has_loops_flag_for_methods() { + Array* methods = this->methods(); + for (int index = 0; index < methods->length(); ++index) { + Method* m = methods->at(index); + if (!m->is_overpass()) { // work around JDK-8305771 + m->compute_has_loops_flag(); + } + } +} + void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS) { // InstanceKlass::add_to_hierarchy() sets the init_state to loaded diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 681fa7d648b..80fc684de25 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -1141,6 +1141,7 @@ public: void init_shared_package_entry(); bool can_be_verified_at_dumptime() const; bool methods_contain_jsr_bytecode() const; + void compute_has_loops_flag_for_methods(); #endif jint compute_modifier_flags() const; From 42b7260e8be02de78d82c6a4601519b9895826e9 Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Wed, 19 Apr 2023 07:18:26 +0000 Subject: [PATCH 040/288] 8306111: PPC64: RT call after thaw with exception requires larger ABI section Reviewed-by: mdoerr --- src/hotspot/cpu/ppc/globals_ppc.hpp | 4 ++-- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp index c33aee3c125..303f06eec55 100644 --- a/src/hotspot/cpu/ppc/globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2020 SAP SE. All rights reserved. + * Copyright (c) 2012, 2023 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 @@ -56,7 +56,7 @@ define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES); define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES); define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES); -define_pd_global(bool, VMContinuations, true BIG_ENDIAN_ONLY(&& false)); +define_pd_global(bool, VMContinuations, true); // Use large code-entry alignment. define_pd_global(uintx, CodeCacheSegmentSize, 128); diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index d194eb16875..a20baaee5c8 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -4576,8 +4576,11 @@ class StubGenerator: public StubCodeGenerator { Register ex_pc = R17_tos; // nonvolatile register __ ld(ex_pc, _abi0(lr), R1_SP); // LR __ mr(nvtmp, R3_RET); // save return value containing the exception oop + // The thawed top frame has got a frame::java_abi. This is not sufficient for the runtime call. + __ push_frame_reg_args(0, tmp1); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), R16_thread, ex_pc); __ mtlr(R3_RET); // the exception handler + __ pop_frame(); // See OptoRuntime::generate_exception_blob for register arguments __ mr(R3_ARG1, nvtmp); // exception oop __ mr(R4_ARG2, ex_pc); // exception pc From ebba42ac52109ca036f2e721402c06afa8f455bb Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 19 Apr 2023 07:22:56 +0000 Subject: [PATCH 041/288] 8305993: Add handleSocketErrorWithMessage to extend nio Net.c exception message Reviewed-by: alanb --- src/java.base/unix/native/libnio/ch/Net.c | 84 +++++++++++++---------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/java.base/unix/native/libnio/ch/Net.c b/src/java.base/unix/native/libnio/ch/Net.c index cc6bb984e16..5af38db378b 100644 --- a/src/java.base/unix/native/libnio/ch/Net.c +++ b/src/java.base/unix/native/libnio/ch/Net.c @@ -122,6 +122,51 @@ static jboolean isSourceFilterSupported(){ static jclass isa_class; /* java.net.InetSocketAddress */ static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */ +static jint handleSocketErrorWithMessage(JNIEnv *env, jint errorValue, + const char* message) +{ + char *xn; + switch (errorValue) { + case EINPROGRESS: /* Non-blocking connect */ + return 0; +#ifdef EPROTO + case EPROTO: + xn = JNU_JAVANETPKG "ProtocolException"; + break; +#endif + case ECONNREFUSED: + case ETIMEDOUT: + case ENOTCONN: + xn = JNU_JAVANETPKG "ConnectException"; + break; + + case EHOSTUNREACH: + xn = JNU_JAVANETPKG "NoRouteToHostException"; + break; + case EADDRINUSE: /* Fall through */ + case EADDRNOTAVAIL: + case EACCES: + xn = JNU_JAVANETPKG "BindException"; + break; + default: + xn = JNU_JAVANETPKG "SocketException"; + break; + } + errno = errorValue; + if (message == NULL) { + JNU_ThrowByNameWithLastError(env, xn, "NioSocketError"); + } else { + JNU_ThrowByNameWithMessageAndLastError(env, xn, message); + } + return IOS_THROWN; +} + +/* Declared in nio_util.h */ +jint handleSocketError(JNIEnv *env, jint errorValue) +{ + return handleSocketErrorWithMessage(env, errorValue, NULL); +} + JNIEXPORT void JNICALL Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz) { @@ -614,7 +659,7 @@ Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobjec if (n < 0) { if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) return IOS_UNAVAILABLE; - handleSocketError(env, errno); + handleSocketErrorWithMessage(env, errno, "setsockopt failed"); } return 0; } @@ -691,7 +736,7 @@ Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobjec if (n < 0) { if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) return IOS_UNAVAILABLE; - handleSocketError(env, errno); + handleSocketErrorWithMessage(env, errno, "setsockopt failed"); } return 0; } @@ -912,38 +957,3 @@ Java_sun_nio_ch_Net_sendOOB(JNIEnv* env, jclass this, jobject fdo, jbyte b) return convertReturnVal(env, n, JNI_FALSE); } -/* Declared in nio_util.h */ - -jint handleSocketError(JNIEnv *env, jint errorValue) -{ - char *xn; - switch (errorValue) { - case EINPROGRESS: /* Non-blocking connect */ - return 0; -#ifdef EPROTO - case EPROTO: - xn = JNU_JAVANETPKG "ProtocolException"; - break; -#endif - case ECONNREFUSED: - case ETIMEDOUT: - case ENOTCONN: - xn = JNU_JAVANETPKG "ConnectException"; - break; - - case EHOSTUNREACH: - xn = JNU_JAVANETPKG "NoRouteToHostException"; - break; - case EADDRINUSE: /* Fall through */ - case EADDRNOTAVAIL: - case EACCES: - xn = JNU_JAVANETPKG "BindException"; - break; - default: - xn = JNU_JAVANETPKG "SocketException"; - break; - } - errno = errorValue; - JNU_ThrowByNameWithLastError(env, xn, "NioSocketError"); - return IOS_THROWN; -} From 9fb53adfe00c5fdb8c8b5f7bc059634fc15b040d Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 19 Apr 2023 07:43:36 +0000 Subject: [PATCH 042/288] 8305716: Enhancements for printing age tables Reviewed-by: kdnilsen, ysr, tschatzl --- src/hotspot/share/gc/shared/ageTable.cpp | 50 +++++++++++++----------- src/hotspot/share/gc/shared/ageTable.hpp | 5 ++- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/gc/shared/ageTable.cpp b/src/hotspot/share/gc/shared/ageTable.cpp index b8586aa931c..879bf28797f 100644 --- a/src/hotspot/share/gc/shared/ageTable.cpp +++ b/src/hotspot/share/gc/shared/ageTable.cpp @@ -33,15 +33,16 @@ #include "oops/oop.inline.hpp" #include "runtime/perfData.hpp" #include "utilities/copy.hpp" +#include "logging/logStream.hpp" /* Copyright (c) 1992, 2021, Oracle and/or its affiliates, and Stanford University. See the LICENSE file for license information. */ -AgeTable::AgeTable(bool global) { +AgeTable::AgeTable(bool global) : _use_perf_data(UsePerfData && global) { clear(); - if (UsePerfData && global) { + if (_use_perf_data) { ResourceMark rm; EXCEPTION_MARK; @@ -70,7 +71,7 @@ void AgeTable::clear() { } } -void AgeTable::merge(AgeTable* subTable) { +void AgeTable::merge(const AgeTable* subTable) { for (int i = 0; i < table_size; i++) { sizes[i]+= subTable->sizes[i]; } @@ -105,25 +106,30 @@ uint AgeTable::compute_tenuring_threshold(size_t desired_survivor_size) { } void AgeTable::print_age_table(uint tenuring_threshold) { - if (log_is_enabled(Trace, gc, age) || UsePerfData || AgeTableTracer::is_tenuring_distribution_event_enabled()) { - log_trace(gc, age)("Age table with threshold %u (max threshold " UINTX_FORMAT ")", - tenuring_threshold, MaxTenuringThreshold); - - size_t total = 0; - uint age = 1; - while (age < table_size) { - size_t wordSize = sizes[age]; - total += wordSize; - if (wordSize > 0) { - log_trace(gc, age)("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", - age, wordSize * oopSize, total * oopSize); - } - AgeTableTracer::send_tenuring_distribution_event(age, wordSize * oopSize); - if (UsePerfData) { - _perf_sizes[age]->set_value(wordSize * oopSize); - } - age++; - } + LogTarget(Trace, gc, age) lt; + if (lt.is_enabled() || _use_perf_data || AgeTableTracer::is_tenuring_distribution_event_enabled()) { + LogStream st(lt); + print_on(&st, tenuring_threshold); } } +void AgeTable::print_on(outputStream* st, uint tenuring_threshold) { + st->print_cr("Age table with threshold %u (max threshold " UINTX_FORMAT ")", + tenuring_threshold, MaxTenuringThreshold); + + size_t total = 0; + uint age = 1; + while (age < table_size) { + size_t word_size = sizes[age]; + total += word_size; + if (word_size > 0) { + st->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", + age, word_size * oopSize, total * oopSize); + } + AgeTableTracer::send_tenuring_distribution_event(age, word_size * oopSize); + if (_use_perf_data) { + _perf_sizes[age]->set_value(word_size * oopSize); + } + age++; + } +} diff --git a/src/hotspot/share/gc/shared/ageTable.hpp b/src/hotspot/share/gc/shared/ageTable.hpp index b05e1a161f2..9f0c10ec312 100644 --- a/src/hotspot/share/gc/shared/ageTable.hpp +++ b/src/hotspot/share/gc/shared/ageTable.hpp @@ -63,14 +63,15 @@ class AgeTable { // Merge another age table with the current one. Used // for parallel young generation gc. - void merge(AgeTable* subTable); + void merge(const AgeTable* subTable); // Calculate new tenuring threshold based on age information. uint compute_tenuring_threshold(size_t desired_survivor_size); void print_age_table(uint tenuring_threshold); + void print_on(outputStream* st, uint tenuring_threshold); private: - + bool _use_perf_data; PerfVariable* _perf_sizes[table_size]; }; From c738c8ea3e9fda87abb03acb599a2433a344db09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Wed, 19 Apr 2023 10:59:10 +0000 Subject: [PATCH 043/288] 8306278: jvmtiAgentList.cpp:253 assert(offset >= 0) failed: invariant occurs on AIX after JDK-8257967 Reviewed-by: sspitsyn, dholmes, mbaesken --- src/hotspot/share/prims/jvmtiAgentList.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/prims/jvmtiAgentList.cpp b/src/hotspot/share/prims/jvmtiAgentList.cpp index cb8e5beb11d..22d74e930cf 100644 --- a/src/hotspot/share/prims/jvmtiAgentList.cpp +++ b/src/hotspot/share/prims/jvmtiAgentList.cpp @@ -245,7 +245,6 @@ JvmtiAgent* JvmtiAgentList::lookup(JvmtiEnv* env, void* f_ptr) { return nullptr; } assert(buffer[0] != '\0', "invariant"); - assert(offset >= 0, "invariant"); const void* const os_module_address = reinterpret_cast

(f_ptr) - offset; JvmtiAgentList::Iterator it = JvmtiAgentList::agents(); From 1a41e12c22168c6c50c6bc193ae249a4a390173c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 19 Apr 2023 14:04:19 +0000 Subject: [PATCH 044/288] 8306310: Move is_shared Klass flag Reviewed-by: iklam, fparain --- src/hotspot/share/oops/klass.hpp | 12 ++++++++++-- src/hotspot/share/utilities/accessFlags.hpp | 3 --- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index acb9a41730f..ce52452467f 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -176,6 +176,7 @@ private: // Various attributes for shared classes. Should be zero for a non-shared class. u2 _shared_class_flags; enum CDSSharedClassFlags { + _is_shared_class = 1 << 0, // shadows MetaspaceObj::is_shared _archived_lambda_proxy_is_available = 1 << 1, _has_value_based_class_annotation = 1 << 2, _verified_at_dump_time = 1 << 3, @@ -363,6 +364,15 @@ protected: NOT_CDS(return false;) } + bool is_shared() const { // shadows MetaspaceObj::is_shared)() + CDS_ONLY(return (_shared_class_flags & _is_shared_class) != 0;) + NOT_CDS(return false;) + } + + void set_is_shared() { + CDS_ONLY(_shared_class_flags |= _is_shared_class;) + } + // Obtain the module or package for this class virtual ModuleEntry* module() const = 0; virtual PackageEntry* package() const = 0; @@ -656,8 +666,6 @@ protected: void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); } bool has_miranda_methods () const { return access_flags().has_miranda_methods(); } void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); } - bool is_shared() const { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)() - void set_is_shared() { _access_flags.set_is_shared_class(); } bool is_hidden() const { return access_flags().is_hidden_class(); } void set_is_hidden() { _access_flags.set_is_hidden_class(); } bool is_value_based() { return _access_flags.is_value_based_class(); } diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 901be7964e4..921b29c854f 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -66,7 +66,6 @@ enum { JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method - JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined. @@ -126,7 +125,6 @@ class AccessFlags { bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } bool has_final_method () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD ) != 0; } bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } - bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; } bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; } @@ -196,7 +194,6 @@ class AccessFlags { void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); } void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); } void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); } - void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); } void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); } void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); } From ddb86469e024147ab41db7dd26344ba9e14ce17a Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 19 Apr 2023 14:06:02 +0000 Subject: [PATCH 045/288] 8306123: Move InstanceKlass writeable flags Reviewed-by: iklam, fparain --- src/hotspot/share/oops/instanceKlass.hpp | 31 +++------ src/hotspot/share/oops/instanceKlassFlags.cpp | 22 +++++++ src/hotspot/share/oops/instanceKlassFlags.hpp | 63 +++++++++++++++---- src/hotspot/share/runtime/vmStructs.cpp | 1 - src/hotspot/share/utilities/accessFlags.hpp | 9 --- .../sun/jvm/hotspot/oops/InstanceKlass.java | 4 -- 6 files changed, 80 insertions(+), 50 deletions(-) diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 80fc684de25..8927125351a 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -223,15 +223,11 @@ class InstanceKlass: public Klass { volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change - // _is_marked_dependent can be set concurrently, thus cannot be part of the - // _misc_flags right now. - bool _is_marked_dependent; // used for marking during flushing and deoptimization - volatile ClassState _init_state; // state of class u1 _reference_type; // reference type - // State is set while executing, eventually atomically to not disturb other state + // State is set either at parse time or while executing, atomically to not disturb other state InstanceKlassFlags _misc_flags; Monitor* _init_monitor; // mutual exclusion to _init_state and _init_thread. @@ -531,8 +527,8 @@ public: void set_should_verify_class(bool value) { _misc_flags.set_should_verify_class(value); } // marking - bool is_marked_dependent() const { return _is_marked_dependent; } - void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } + bool is_marked_dependent() const { return _misc_flags.is_marked_dependent(); } + void set_is_marked_dependent(bool value) { _misc_flags.set_is_marked_dependent(value); } // initialization (virtuals from Klass) bool should_be_initialized() const; // means that initialize should be called @@ -681,16 +677,8 @@ public: // Redefinition locking. Class can only be redefined by one thread at a time. // The flag is in access_flags so that it can be set and reset using atomic // operations, and not be reset by other misc_flag settings. - bool is_being_redefined() const { - return _access_flags.is_being_redefined(); - } - void set_is_being_redefined(bool value) { - if (value) { - _access_flags.set_is_being_redefined(); - } else { - _access_flags.clear_is_being_redefined(); - } - } + bool is_being_redefined() const { return _misc_flags.is_being_redefined(); } + void set_is_being_redefined(bool value) { _misc_flags.set_is_being_redefined(value); } // RedefineClasses() support for previous versions: void add_previous_version(InstanceKlass* ik, int emcp_method_count); @@ -716,13 +704,8 @@ public: bool is_scratch_class() const { return _misc_flags.is_scratch_class(); } void set_is_scratch_class() { _misc_flags.set_is_scratch_class(true); } - bool has_resolved_methods() const { - return _access_flags.has_resolved_methods(); - } - - void set_has_resolved_methods() { - _access_flags.set_has_resolved_methods(); - } + bool has_resolved_methods() const { return _misc_flags.has_resolved_methods(); } + void set_has_resolved_methods() { _misc_flags.set_has_resolved_methods(true); } public: #if INCLUDE_JVMTI diff --git a/src/hotspot/share/oops/instanceKlassFlags.cpp b/src/hotspot/share/oops/instanceKlassFlags.cpp index 8f845c482e0..d279d5b1b7d 100644 --- a/src/hotspot/share/oops/instanceKlassFlags.cpp +++ b/src/hotspot/share/oops/instanceKlassFlags.cpp @@ -26,9 +26,31 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "oops/instanceKlassFlags.hpp" +#include "runtime/atomic.hpp" #include "runtime/safepoint.hpp" #include "utilities/macros.hpp" +// This can be removed for the atomic bitset functions, when available. +void InstanceKlassFlags::atomic_set_bits(u1 bits) { + // Atomically update the status with the bits given + u1 old_status, new_status, f; + do { + old_status = _status; + new_status = old_status | bits; + f = Atomic::cmpxchg(&_status, old_status, new_status); + } while(f != old_status); +} + +void InstanceKlassFlags::atomic_clear_bits(u1 bits) { + // Atomically update the status with the bits given + u1 old_status, new_status, f; + do { + old_status = _status; + new_status = old_status & ~bits; + f = Atomic::cmpxchg(&_status, old_status, new_status); + } while(f != old_status); +} + #if INCLUDE_CDS void InstanceKlassFlags::set_shared_class_loader_type(s2 loader_type) { switch (loader_type) { diff --git a/src/hotspot/share/oops/instanceKlassFlags.hpp b/src/hotspot/share/oops/instanceKlassFlags.hpp index 6e147f6e33c..5423db111b2 100644 --- a/src/hotspot/share/oops/instanceKlassFlags.hpp +++ b/src/hotspot/share/oops/instanceKlassFlags.hpp @@ -27,6 +27,12 @@ class ClassLoaderData; +// The InstanceKlassFlags class contains the parse-time and writeable flags associated with +// an InstanceKlass, and their associated accessors. +// _flags are parse-time and constant in the InstanceKlass after that. _status are set at runtime and +// require atomic access. +// These flags are JVM internal and not part of the AccessFlags classfile specification. + class InstanceKlassFlags { friend class VMStructs; friend class JVMCIVMStructs; @@ -35,18 +41,15 @@ class InstanceKlassFlags { flag(rewritten , 1 << 0) /* methods rewritten. */ \ flag(has_nonstatic_fields , 1 << 1) /* for sizing with UseCompressedOops */ \ flag(should_verify_class , 1 << 2) /* allow caching of preverification */ \ - flag(unused , 1 << 3) /* not currently used */ \ - flag(is_contended , 1 << 4) /* marked with contended annotation */ \ - flag(has_nonstatic_concrete_methods , 1 << 5) /* class/superclass/implemented interfaces has non-static, concrete methods */ \ - flag(declares_nonstatic_concrete_methods, 1 << 6) /* directly declares non-static, concrete methods */ \ - flag(has_been_redefined , 1 << 7) /* class has been redefined */ \ - flag(shared_loading_failed , 1 << 8) /* class has been loaded from shared archive */ \ - flag(is_scratch_class , 1 << 9) /* class is the redefined scratch class */ \ - flag(is_shared_boot_class , 1 << 10) /* defining class loader is boot class loader */ \ - flag(is_shared_platform_class , 1 << 11) /* defining class loader is platform class loader */ \ - flag(is_shared_app_class , 1 << 12) /* defining class loader is app class loader */ \ - flag(has_contended_annotations , 1 << 13) /* has @Contended annotation */ \ - flag(has_localvariable_table , 1 << 14) /* has localvariable information */ + flag(is_contended , 1 << 3) /* marked with contended annotation */ \ + flag(has_nonstatic_concrete_methods , 1 << 4) /* class/superclass/implemented interfaces has non-static, concrete methods */ \ + flag(declares_nonstatic_concrete_methods, 1 << 5) /* directly declares non-static, concrete methods */ \ + flag(shared_loading_failed , 1 << 6) /* class has been loaded from shared archive */ \ + flag(is_shared_boot_class , 1 << 7) /* defining class loader is boot class loader */ \ + flag(is_shared_platform_class , 1 << 8) /* defining class loader is platform class loader */ \ + flag(is_shared_app_class , 1 << 9) /* defining class loader is app class loader */ \ + flag(has_contended_annotations , 1 << 10) /* has @Contended annotation */ \ + flag(has_localvariable_table , 1 << 11) /* has localvariable information */ #define IK_FLAGS_ENUM_NAME(name, value) _misc_##name = value, enum { @@ -54,6 +57,19 @@ class InstanceKlassFlags { }; #undef IK_FLAGS_ENUM_NAME +#define IK_STATUS_DO(status) \ + status(is_being_redefined , 1 << 0) /* True if the klass is being redefined */ \ + status(has_resolved_methods , 1 << 1) /* True if the klass has resolved MethodHandle methods */ \ + status(has_been_redefined , 1 << 2) /* class has been redefined */ \ + status(is_scratch_class , 1 << 3) /* class is the redefined scratch class */ \ + status(is_marked_dependent , 1 << 4) /* class is the redefined scratch class */ + +#define IK_STATUS_ENUM_NAME(name, value) _misc_##name = value, + enum { + IK_STATUS_DO(IK_STATUS_ENUM_NAME) + }; +#undef IK_STATUS_ENUM_NAME + u2 shared_loader_type_bits() const { return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class; } @@ -61,6 +77,9 @@ class InstanceKlassFlags { // These flags are write-once before the class is published and then read-only so don't require atomic updates. u2 _flags; + // These flags are written during execution so require atomic stores + u1 _status; + public: InstanceKlassFlags() : _flags(0) {} @@ -87,6 +106,26 @@ class InstanceKlassFlags { void assign_class_loader_type(const ClassLoaderData* cld); void assert_is_safe(bool set) NOT_DEBUG_RETURN; + + // Create getters and setters for the status values. +#define IK_STATUS_GET(name, ignore) \ + bool name() const { return (_status & _misc_##name) != 0; } + IK_STATUS_DO(IK_STATUS_GET) +#undef IK_STATUS_GET + +#define IK_STATUS_SET(name, ignore) \ + void set_##name(bool b) { \ + if (b) { \ + atomic_set_bits(_misc_##name); \ + } else { \ + atomic_clear_bits(_misc_##name); \ + } \ + } + IK_STATUS_DO(IK_STATUS_SET) +#undef IK_STATUS_SET + + void atomic_set_bits(u1 bits); + void atomic_clear_bits(u1 bits); }; #endif // SHARE_OOPS_INSTANCEKLASSFLAGS_HPP diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index b3d8584f82c..4f1b24a9aad 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -236,7 +236,6 @@ nonstatic_field(InstanceKlass, _static_field_size, int) \ nonstatic_field(InstanceKlass, _static_oop_field_count, u2) \ nonstatic_field(InstanceKlass, _nonstatic_oop_map_size, int) \ - nonstatic_field(InstanceKlass, _is_marked_dependent, bool) \ volatile_nonstatic_field(InstanceKlass, _init_state, InstanceKlass::ClassState) \ volatile_nonstatic_field(InstanceKlass, _init_thread, JavaThread*) \ nonstatic_field(InstanceKlass, _itable_len, int) \ diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 921b29c854f..d213b166e89 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -68,8 +68,6 @@ enum { JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class - JVM_ACC_IS_BEING_REDEFINED = 0x00100000, // True if the klass is being redefined. - JVM_ACC_HAS_RESOLVED_METHODS = 0x00200000, // True if the klass has resolved methods // Method* flags JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00400000, @@ -133,13 +131,6 @@ class AccessFlags { void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } void clear_has_localvariable_table() { atomic_clear_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } - bool is_being_redefined() const { return (_flags & JVM_ACC_IS_BEING_REDEFINED) != 0; } - void set_is_being_redefined() { atomic_set_bits(JVM_ACC_IS_BEING_REDEFINED); } - void clear_is_being_redefined() { atomic_clear_bits(JVM_ACC_IS_BEING_REDEFINED); } - - bool has_resolved_methods() const { return (_flags & JVM_ACC_HAS_RESOLVED_METHODS) != 0; } - void set_has_resolved_methods() { atomic_set_bits(JVM_ACC_HAS_RESOLVED_METHODS); } - bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; } // get .class file flags diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 1b7c6ac6a89..2c3f2d2a698 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -80,7 +80,6 @@ public class InstanceKlass extends Klass { staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0); staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0); nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0); - isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0); initState = new CIntField(type.getCIntegerField("_init_state"), 0); itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0); if (VM.getVM().isJvmtiSupported()) { @@ -145,7 +144,6 @@ public class InstanceKlass extends Klass { private static CIntField staticFieldSize; private static CIntField staticOopFieldCount; private static CIntField nonstaticOopMapSize; - private static CIntField isMarkedDependent; private static CIntField initState; private static CIntField itableLen; private static AddressField breakpoints; @@ -373,7 +371,6 @@ public class InstanceKlass extends Klass { public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } - public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } public long getItableLen() { return itableLen.getValue(this); } public long majorVersion() { return getConstants().majorVersion(); } public long minorVersion() { return getConstants().minorVersion(); } @@ -571,7 +568,6 @@ public class InstanceKlass extends Klass { visitor.doCInt(staticFieldSize, true); visitor.doCInt(staticOopFieldCount, true); visitor.doCInt(nonstaticOopMapSize, true); - visitor.doCInt(isMarkedDependent, true); visitor.doCInt(initState, true); visitor.doCInt(itableLen, true); } From a31a11f44a8477c2fbfde929b5c725f819470d25 Mon Sep 17 00:00:00 2001 From: Fredrik Bredberg Date: Wed, 19 Apr 2023 15:04:27 +0000 Subject: [PATCH 046/288] 8306006: strace001.java fails due to unknown methods on stack Reviewed-by: rehn, alanb, dholmes --- .../nsk/monitoring/stress/thread/strace001.java | 17 +++++++++++------ .../thread/strace001/TestDescription.java | 9 ++++----- .../thread/strace002/TestDescription.java | 9 ++++----- .../thread/strace003/TestDescription.java | 9 ++++----- .../thread/strace004/TestDescription.java | 9 ++++----- .../thread/strace005/TestDescription.java | 9 ++++----- .../thread/strace006/TestDescription.java | 9 ++++----- .../thread/strace007/TestDescription.java | 9 ++++----- .../thread/strace008/TestDescription.java | 9 ++++----- .../thread/strace009/TestDescription.java | 9 ++++----- 10 files changed, 47 insertions(+), 51 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001.java index 1794a2e9d31..40deb75b2fc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -141,10 +141,13 @@ public class strace001 { expectedSystemTrace = new String[]{ "java.lang.Thread.sleep", "java.lang.Thread.sleep0", + "java.lang.Thread.beforeSleep", + "java.lang.Thread.afterSleep", "java.lang.Thread.yield", "java.lang.Thread.yield0", "java.lang.Thread.currentCarrierThread", "java.lang.Thread.currentThread", + "java.util.concurrent.TimeUnit.toNanos", "jdk.internal.event.ThreadSleepEvent.", "jdk.internal.event.ThreadSleepEvent.isTurnedOn", "jdk.internal.event.ThreadSleepEvent.isEnabled" @@ -201,13 +204,15 @@ public class strace001 { // The method performs checks of the stack trace private static boolean checkTrace(StackTraceElement[] elements) { int length = elements.length; - int expectedLength = depth + 5; + // The length of the trace must not be greater than + // expectedLength. Number of recursionJava() or + // recursionNative() methods must not be greater than depth, + // also one run() and one waitForSign(), plus whatever can be + // reached from Thread.yield or Thread.sleep. + int expectedLength = depth + 6; boolean result = true; - // Check the length of the trace. It must not be greater than - // expectedLength. Number of recursionJava() or recursionNative() - // methods must not ne greater than depth, also one Object.wait() or - // Thread.yield() method, one run( ) and one waitForSign(). + // Check the length of the trace if (length > expectedLength) { log.complain("Length of the stack trace is " + length + ", but " + "expected to be not greater than " + expectedLength); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TestDescription.java index a9af73eed2b..53b73954af5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace001/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TestDescription.java index 044f0b7a78d..b41fb5f76f8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace002/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TestDescription.java index e973e4404b1..c39f4dde2af 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace003/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TestDescription.java index 60b0eb69867..8edd13c21d4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace004/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TestDescription.java index 93f63ad85c4..0309ee2936b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace005/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TestDescription.java index be2418921e3..e161cd18162 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace006/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TestDescription.java index 170d7cd737c..8d788dde42c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace007/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TestDescription.java index 4573ec83968..b918966976c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace008/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TestDescription.java index d7efb152ec0..dbfd033f9cc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/thread/strace009/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -42,10 +42,9 @@ * Main thread makes a snapshot of stack trace for all threads and checks it: * 1. If a thread is alive, ThreadMonitor.getThreadInfo(long, -1) must * return not null ThreadInfo. - * 2. The length of a trace must not be greater than (depth + 3). Number - * of recursionJava() or recursionNative() methods must not be greater - * than depth, also one Object.wait() or Thread.yield() method, one - * run(), and one waitForSign(). + * 2. Number of recursionJava() or recursionNative() methods must not be + * greater than depth + X, where X is implementation dependent. + * See strace001.java for more info. * 3. The latest method of the stack trace must be RunningThread.run(). * 4. getClassName() and getMethodName() methods must return expected * values for each element of the stack trace. From c57af319f668e10b2b357bb961903a6236d5521f Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Wed, 19 Apr 2023 15:56:34 +0000 Subject: [PATCH 047/288] 8306038: SystemModulesPlugin generates code that doesn't pop when return value not used Reviewed-by: alanb, mchung --- .../jlink/internal/plugins/SystemModulesPlugin.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java index a53ee4c397c..c01042bdc94 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java @@ -1085,7 +1085,8 @@ public final class SystemModulesPlugin extends AbstractPlugin { } cob.invokevirtual(CD_MODULE_BUILDER, "requires", - MTD_REQUIRES_ARRAY); + MTD_REQUIRES_ARRAY) + .pop(); } /* @@ -1129,7 +1130,8 @@ public final class SystemModulesPlugin extends AbstractPlugin { } cob.invokevirtual(CD_MODULE_BUILDER, "exports", - MTD_EXPORTS_ARRAY); + MTD_EXPORTS_ARRAY) + .pop(); } /* @@ -1185,7 +1187,8 @@ public final class SystemModulesPlugin extends AbstractPlugin { } cob.invokevirtual(CD_MODULE_BUILDER, "opens", - MTD_OPENS_ARRAY); + MTD_OPENS_ARRAY) + .pop(); } /* @@ -1254,7 +1257,8 @@ public final class SystemModulesPlugin extends AbstractPlugin { } cob.invokevirtual(CD_MODULE_BUILDER, "provides", - MTD_PROVIDES_ARRAY); + MTD_PROVIDES_ARRAY) + .pop(); } /* From 48fd4f2bd37562a159e4089b15aa108e0b1bebeb Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 19 Apr 2023 16:01:57 +0000 Subject: [PATCH 048/288] 8303431: [JVMCI] libgraal annotation API Reviewed-by: kvn, never, darcy --- src/hotspot/share/classfile/vmSymbols.hpp | 2 + src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 96 +++- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 1 + .../classes/jdk/internal/vm/VMSupport.java | 424 +++++++++++++++++- src/java.base/share/classes/module-info.java | 3 +- .../AnnotationInvocationHandler.java | 7 + .../reflect/annotation/AnnotationParser.java | 6 +- .../reflect/annotation/AnnotationSupport.java | 9 + .../vm/ci/hotspot/AnnotationDataDecoder.java | 73 +++ .../jdk/vm/ci/hotspot/CompilerToVM.java | 92 ++++ .../hotspot/HotSpotResolvedJavaFieldImpl.java | 28 +- .../HotSpotResolvedJavaMethodImpl.java | 38 +- .../HotSpotResolvedObjectTypeImpl.java | 63 +++ .../hotspot/HotSpotResolvedPrimitiveType.java | 14 + .../jdk/vm/ci/hotspot/HotSpotVMConfig.java | 1 + .../IndirectHotSpotObjectConstantImpl.java | 2 +- .../classes/jdk/vm/ci/meta/Annotated.java | 72 +++ .../jdk/vm/ci/meta/AnnotationData.java | 163 +++++++ .../classes/jdk/vm/ci/meta/EnumData.java | 78 ++++ .../classes/jdk/vm/ci/meta/ErrorData.java | 63 +++ .../jdk/vm/ci/meta/ResolvedJavaField.java | 2 +- .../jdk/vm/ci/meta/ResolvedJavaMethod.java | 2 +- .../jdk/vm/ci/meta/ResolvedJavaType.java | 6 +- .../runtime/test/TestResolvedJavaField.java | 19 + .../runtime/test/TestResolvedJavaMethod.java | 95 +++- .../ci/runtime/test/TestResolvedJavaType.java | 197 +++++++- .../jdk/vm/ci/runtime/test/TypeUniverse.java | 21 +- .../AnnotationTestInput.java | 375 ++++++++++++++++ .../MemberDeleted.java | 33 ++ .../MemberTypeChanged.java | 33 ++ .../TestAnnotationEncodingDecoding.java | 257 +++++++++++ .../alt/MemberDeleted.java | 32 ++ .../alt/MemberTypeChanged.java | 33 ++ .../internal/vm/TestTranslatedException.java | 9 - 34 files changed, 2298 insertions(+), 51 deletions(-) create mode 100644 src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/AnnotationDataDecoder.java create mode 100644 src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Annotated.java create mode 100644 src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java create mode 100644 src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EnumData.java create mode 100644 src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ErrorData.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/TestAnnotationEncodingDecoding.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java create mode 100644 test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index caf6788c028..16141c3ed47 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -756,6 +756,8 @@ template(encodeThrowable_name, "encodeThrowable") \ template(encodeThrowable_signature, "(Ljava/lang/Throwable;JI)I") \ template(decodeAndThrowThrowable_name, "decodeAndThrowThrowable") \ + template(encodeAnnotations_name, "encodeAnnotations") \ + template(encodeAnnotations_signature, "([BLjava/lang/Class;Ljdk/internal/reflect/ConstantPool;Z[Ljava/lang/Class;)[B")\ template(decodeAndThrowThrowable_signature, "(JZ)V") \ template(classRedefinedCount_name, "classRedefinedCount") \ template(classLoader_name, "classLoader") \ diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 74672c4ee30..503c77b2393 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2672,9 +2672,7 @@ C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMEN return JNIHandles::make_local(THREAD, executable); } -C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index)) - requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL); - Klass* klass = UNPACK_PAIR(Klass, klass); +static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) { if (!klass->is_instance_klass()) { JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Expected non-primitive type, got %s", klass->external_name())); @@ -2684,11 +2682,100 @@ C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAI JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Field index %d out of bounds for %s", index, klass->external_name())); } + return iklass; +} + +C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index)) + requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL); + Klass* klass = UNPACK_PAIR(Klass, klass); + InstanceKlass* iklass = check_field(klass, index, JVMCIENV); fieldDescriptor fd(iklass, index); oop reflected = Reflection::new_field(&fd, CHECK_NULL); return JNIHandles::make_local(THREAD, reflected); } +static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationArray* annotations_array, bool for_class, + jint filter_length, jlong filter_klass_pointers, + JavaThread* THREAD, JVMCIEnv* JVMCIENV) { + // Get a ConstantPool object for annotation parsing + Handle jcp = reflect_ConstantPool::create(CHECK_NULL); + reflect_ConstantPool::set_cp(jcp(), holder->constants()); + + // load VMSupport + Symbol* klass = vmSymbols::jdk_internal_vm_VMSupport(); + Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK_NULL); + + InstanceKlass* vm_support = InstanceKlass::cast(k); + if (vm_support->should_be_initialized()) { + vm_support->initialize(CHECK_NULL); + } + + typeArrayOop annotations_oop = Annotations::make_java_array(annotations_array, CHECK_NULL); + typeArrayHandle annotations = typeArrayHandle(THREAD, annotations_oop); + + InstanceKlass** filter = filter_length == 1 ? + (InstanceKlass**) &filter_klass_pointers: + (InstanceKlass**) filter_klass_pointers; + objArrayOop filter_oop = oopFactory::new_objectArray(filter_length, CHECK_NULL); + objArrayHandle filter_classes(THREAD, filter_oop); + for (int i = 0; i < filter_length; i++) { + filter_classes->obj_at_put(i, filter[i]->java_mirror()); + } + + // invoke VMSupport.encodeAnnotations + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(annotations); + args.push_oop(Handle(THREAD, holder->java_mirror())); + args.push_oop(jcp); + args.push_int(for_class); + args.push_oop(filter_classes); + Symbol* signature = vmSymbols::encodeAnnotations_signature(); + JavaCalls::call_static(&result, + vm_support, + vmSymbols::encodeAnnotations_name(), + signature, + &args, + CHECK_NULL); + + oop res = result.get_oop(); + if (JVMCIENV->is_hotspot()) { + return (jbyteArray) JNIHandles::make_local(THREAD, res); + } + + typeArrayOop ba = typeArrayOop(res); + int ba_len = ba->length(); + jbyte* ba_buf = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jbyte, ba_len); + if (ba_buf == nullptr) { + JVMCI_THROW_MSG_NULL(InternalError, + err_msg("could not allocate %d bytes", ba_len)); + + } + memcpy(ba_buf, ba->byte_at_addr(0), ba_len); + JVMCIPrimitiveArray ba_dest = JVMCIENV->new_byteArray(ba_len, JVMCI_CHECK_NULL); + JVMCIENV->copy_bytes_from(ba_buf, ba_dest, 0, ba_len); + return JVMCIENV->get_jbyteArray(ba_dest); +} + +C2V_VMENTRY_NULL(jbyteArray, getEncodedClassAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), + jobject filter, jint filter_length, jlong filter_klass_pointers)) + InstanceKlass* holder = InstanceKlass::cast(UNPACK_PAIR(Klass, klass)); + return get_encoded_annotation_data(holder, holder->class_annotations(), true, filter_length, filter_klass_pointers, THREAD, JVMCIENV); +C2V_END + +C2V_VMENTRY_NULL(jbyteArray, getEncodedExecutableAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(method), + jobject filter, jint filter_length, jlong filter_klass_pointers)) + methodHandle method(THREAD, UNPACK_PAIR(Method, method)); + return get_encoded_annotation_data(method->method_holder(), method->annotations(), false, filter_length, filter_klass_pointers, THREAD, JVMCIENV); +C2V_END + +C2V_VMENTRY_NULL(jbyteArray, getEncodedFieldAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index, + jobject filter, jint filter_length, jlong filter_klass_pointers)) + InstanceKlass* holder = check_field(InstanceKlass::cast(UNPACK_PAIR(Klass, klass)), index, JVMCIENV); + fieldDescriptor fd(holder, index); + return get_encoded_annotation_data(holder, fd.annotations(), false, filter_length, filter_klass_pointers, THREAD, JVMCIENV); +C2V_END + C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current)) FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address); int result_length = 0; @@ -2969,6 +3056,9 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "getCode", CC "(" HS_INSTALLED_CODE ")[B", FN_PTR(getCode)}, {CC "asReflectionExecutable", CC "(" HS_METHOD2 ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)}, {CC "asReflectionField", CC "(" HS_KLASS2 "I)" REFLECTION_FIELD, FN_PTR(asReflectionField)}, + {CC "getEncodedClassAnnotationData", CC "(" HS_KLASS2 OBJECT "IJ)[B", FN_PTR(getEncodedClassAnnotationData)}, + {CC "getEncodedExecutableAnnotationData", CC "(" HS_METHOD2 OBJECT "IJ)[B", FN_PTR(getEncodedExecutableAnnotationData)}, + {CC "getEncodedFieldAnnotationData", CC "(" HS_KLASS2 "I" OBJECT "IJ)[B", FN_PTR(getEncodedFieldAnnotationData)}, {CC "getFailedSpeculations", CC "(J[[B)[[B", FN_PTR(getFailedSpeculations)}, {CC "getFailedSpeculationsAddress", CC "(" HS_METHOD2 ")J", FN_PTR(getFailedSpeculationsAddress)}, {CC "releaseFailedSpeculations", CC "(J)V", FN_PTR(releaseFailedSpeculations)}, diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 15276d44d65..05631351de4 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -104,6 +104,7 @@ \ static_field(Abstract_VM_Version, _features, uint64_t) \ \ + nonstatic_field(Annotations, _class_annotations, AnnotationArray*) \ nonstatic_field(Annotations, _fields_annotations, Array*) \ \ nonstatic_field(Array, _length, int) \ diff --git a/src/java.base/share/classes/jdk/internal/vm/VMSupport.java b/src/java.base/share/classes/jdk/internal/vm/VMSupport.java index 86472e83830..659645a5006 100644 --- a/src/java.base/share/classes/jdk/internal/vm/VMSupport.java +++ b/src/java.base/share/classes/jdk/internal/vm/VMSupport.java @@ -24,16 +24,28 @@ */ package jdk.internal.vm; +import jdk.internal.misc.Unsafe; +import jdk.internal.misc.VM; +import jdk.internal.access.SharedSecrets; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.reflect.ConstantPool; +import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.AnnotationSupport; +import sun.reflect.annotation.AnnotationType; + +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.annotation.IncompleteAnnotationException; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.jar.Attributes; - -import jdk.internal.misc.VM; -import jdk.internal.misc.Unsafe; +import java.util.List; /* * Support class used by JVMCI, JVMTI and VM attach mechanism. @@ -167,4 +179,404 @@ public class VMSupport { U.copyMemory(encoding, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, buffer + 4, encoding.length); return requiredSize; } + + /** + * Parses {@code rawAnnotations} into a list of {@link Annotation}s and then + * serializes them to a byte array with {@link #encodeAnnotations(Collection)}. + */ + public static byte[] encodeAnnotations(byte[] rawAnnotations, + Class declaringClass, + ConstantPool cp, + boolean forClass, + Class[] selectAnnotationClasses) + { + for (Class c : selectAnnotationClasses) { + if (!c.isAnnotation()) { + throw new IllegalArgumentException(c + " is not an annotation interface"); + } + } + Map, Annotation> annotations = + AnnotationParser.parseSelectAnnotations(rawAnnotations, cp, declaringClass, selectAnnotationClasses); + if (forClass && annotations.size() != selectAnnotationClasses.length) { + Class superClass = declaringClass.getSuperclass(); + nextSuperClass: + while (superClass != null) { + JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); + Map, Annotation> superAnnotations = + AnnotationParser.parseSelectAnnotations( + jla.getRawClassAnnotations(superClass), + jla.getConstantPool(superClass), + superClass, + selectAnnotationClasses); + + for (Map.Entry, Annotation> e : superAnnotations.entrySet()) { + Class annotationClass = e.getKey(); + if (!annotations.containsKey(annotationClass) && AnnotationType.getInstance(annotationClass).isInherited()) { + if (annotations.isEmpty()) { + // An empty map might be unmodifiable (e.g. Collections.emptyMap()). + annotations = new LinkedHashMap, Annotation>(); + } + annotations.put(annotationClass, e.getValue()); + if (annotations.size() == selectAnnotationClasses.length) { + break nextSuperClass; + } + } + } + superClass = superClass.getSuperclass(); + } + } + return encodeAnnotations(annotations.values()); + } + + /** + * Encodes annotations to a byte array. The byte array can be decoded with {@link #decodeAnnotations(byte[], AnnotationDecoder)}. + */ + public static byte[] encodeAnnotations(Collection annotations) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(128); + try (DataOutputStream dos = new DataOutputStream(baos)) { + writeLength(dos, annotations.size()); + for (Annotation a : annotations) { + encodeAnnotation(dos, a); + } + } + return baos.toByteArray(); + } catch (Exception e) { + throw new InternalError(e); + } + } + + private static void encodeAnnotation(DataOutputStream dos, Annotation a) throws Exception { + Class type = a.annotationType(); + Map values = AnnotationSupport.memberValues(a); + dos.writeUTF(type.getName()); + writeLength(dos, values.size()); + for (Map.Entry e : values.entrySet()) { + Object value = e.getValue(); + if (value == null) { + // IncompleteAnnotationException + dos.writeByte('x'); + dos.writeUTF(new IncompleteAnnotationException(type, e.getKey()).toString()); + continue; + } + Class valueType = value.getClass(); + dos.writeUTF(e.getKey()); + if (valueType == Byte.class) { + dos.writeByte('B'); + dos.writeByte((byte) value); + } else if (valueType == Character.class) { + dos.writeByte('C'); + dos.writeChar((char) value); + } else if (valueType == Double.class) { + dos.writeByte('D'); + dos.writeDouble((double) value); + } else if (valueType == Float.class) { + dos.writeByte('F'); + dos.writeFloat((float) value); + } else if (valueType == Integer.class) { + dos.writeByte('I'); + dos.writeInt((int) value); + } else if (valueType == Long.class) { + dos.writeByte('J'); + dos.writeLong((long) value); + } else if (valueType == Short.class) { + dos.writeByte('S'); + dos.writeShort((short) value); + } else if (valueType == Boolean.class) { + dos.writeByte('Z'); + dos.writeBoolean((boolean) value); + } else if (valueType == String.class) { + dos.writeByte('s'); + dos.writeUTF((String) value); + } else if (valueType == Class.class) { + dos.writeByte('c'); + dos.writeUTF(((Class) value).getName()); + } else if (valueType.isEnum()) { + dos.writeByte('e'); + dos.writeUTF(valueType.getName()); + dos.writeUTF(((Enum) value).name()); + } else if (value instanceof Annotation) { + dos.writeByte('@'); + encodeAnnotation(dos, (Annotation) value); + } else if (valueType.isArray()) { + Class componentType = valueType.getComponentType(); + if (componentType == byte.class) { + byte[] array = (byte[]) value; + dos.writeByte('['); + dos.writeByte('B'); + writeLength(dos, array.length); + dos.write(array); + } else if (componentType == char.class) { + char[] array = (char[]) value; + dos.writeByte('['); + dos.writeByte('C'); + writeLength(dos, array.length); + for (char c : array) { + dos.writeChar(c); + } + } else if (componentType == double.class) { + double[] array = (double[]) value; + dos.writeByte('['); + dos.writeByte('D'); + writeLength(dos, array.length); + for (double v : array) { + dos.writeDouble(v); + } + } else if (componentType == float.class) { + float[] array = (float[]) value; + dos.writeByte('['); + dos.writeByte('F'); + writeLength(dos, array.length); + for (float v : array) { + dos.writeFloat(v); + } + } else if (componentType == int.class) { + int[] array = (int[]) value; + dos.writeByte('['); + dos.writeByte('I'); + writeLength(dos, array.length); + for (int j : array) { + dos.writeInt(j); + } + } else if (componentType == long.class) { + long[] array = (long[]) value; + dos.writeByte('['); + dos.writeByte('J'); + writeLength(dos, array.length); + for (long l : array) { + dos.writeLong(l); + } + } else if (componentType == short.class) { + short[] array = (short[]) value; + dos.writeByte('['); + dos.writeByte('S'); + writeLength(dos, array.length); + for (short item : array) { + dos.writeShort(item); + } + } else if (componentType == boolean.class) { + boolean[] array = (boolean[]) value; + dos.writeByte('['); + dos.writeByte('Z'); + writeLength(dos, array.length); + for (boolean b : array) { + dos.writeBoolean(b); + } + } else if (componentType == String.class) { + String[] array = (String[]) value; + dos.writeByte('['); + dos.writeByte('s'); + writeLength(dos, array.length); + for (String s : array) { + dos.writeUTF(s); + } + } else if (componentType == Class.class) { + Class[] array = (Class[]) value; + dos.writeByte('['); + dos.writeByte('c'); + writeLength(dos, array.length); + for (Class aClass : array) { + dos.writeUTF(aClass.getName()); + } + } else if (componentType.isEnum()) { + Enum[] array = (Enum[]) value; + dos.writeByte('['); + dos.writeByte('e'); + dos.writeUTF(componentType.getName()); + writeLength(dos, array.length); + for (Enum anEnum : array) { + dos.writeUTF(anEnum.name()); + } + } else if (componentType.isAnnotation()) { + Annotation[] array = (Annotation[]) value; + dos.writeByte('['); + dos.writeByte('@'); + writeLength(dos, array.length); + for (Annotation annotation : array) { + encodeAnnotation(dos, annotation); + } + } else { + dos.writeByte('x'); + dos.writeUTF(value.toString()); + } + + } else { + dos.writeByte('x'); + dos.writeUTF(value.toString()); + } + } + } + + /** + * Helper for {@link #decodeAnnotations(byte[], AnnotationDecoder)} to convert a byte + * array (ostensibly produced by {@link VMSupport#encodeAnnotations}) into objects. + * + * @param type to which a type name is {@linkplain #resolveType(String) resolved} + * @param type of the object representing a decoded annotation + * @param type of the object representing a decoded enum constant + * @param type of the object representing a decoded error + */ + public interface AnnotationDecoder { + /** + * Resolves a name in {@link Class#getName()} format to an object of type {@code T}. + */ + T resolveType(String name); + + /** + * Creates an object representing a decoded annotation. + * + * @param type the annotation interface of the annotation + * @param elements elements of the annotation + */ + A newAnnotation(T type, Map.Entry[] elements); + + /** + * Creates an object representing a decoded enum constant. + * + * @param enumType the enum type + * @param name the name of the enum constant + */ + E newEnumValue(T enumType, String name); + + /** + * Creates an object representing a decoded error value. + * + * @param description of the error + */ + X newErrorValue(String description); + } + + /** + * Decodes annotations serialized in {@code encoded} to objects. + * + * @param type to which a type name is resolved + * @param type of the object representing a decoded annotation + * @param type of the object representing a decoded enum constant + * @param type of the object representing a decoded error + * @return an immutable list of {@code A} objects + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static List decodeAnnotations(byte[] encoded, AnnotationDecoder decoder) { + try { + ByteArrayInputStream bais = new ByteArrayInputStream(encoded); + DataInputStream dis = new DataInputStream(bais); + return (List) readArray(dis, () -> decodeAnnotation(dis, decoder)); + } catch (Exception e) { + throw new InternalError(e); + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private static A decodeAnnotation(DataInputStream dis, AnnotationDecoder decoder) throws IOException { + String typeName = dis.readUTF(); + T type = decoder.resolveType(typeName); + int n = readLength(dis); + Map.Entry[] elements = new Map.Entry[n]; + for (int i = 0; i < n; i++) { + String name = dis.readUTF(); + byte tag = dis.readByte(); + elements[i] = Map.entry(name, switch (tag) { + case 'B' -> dis.readByte(); + case 'C' -> dis.readChar(); + case 'D' -> dis.readDouble(); + case 'F' -> dis.readFloat(); + case 'I' -> dis.readInt(); + case 'J' -> dis.readLong(); + case 'S' -> dis.readShort(); + case 'Z' -> dis.readBoolean(); + case 's' -> dis.readUTF(); + case 'c' -> decoder.resolveType(dis.readUTF()); + case 'e' -> decoder.newEnumValue(decoder.resolveType(dis.readUTF()), dis.readUTF()); + case '@' -> decodeAnnotation(dis, decoder); + case '[' -> decodeArray(dis, decoder); + case 'x' -> decoder.newErrorValue(dis.readUTF()); + default -> throw new InternalError("Unsupported tag: " + tag); + }); + } + return decoder.newAnnotation(type, (Map.Entry[]) elements); + } + @FunctionalInterface + interface IOReader { + Object read() throws IOException; + } + + private static Object decodeArray(DataInputStream dis, AnnotationDecoder decoder) throws IOException { + byte componentTag = dis.readByte(); + return switch (componentTag) { + case 'B' -> readArray(dis, dis::readByte); + case 'C' -> readArray(dis, dis::readChar); + case 'D' -> readArray(dis, dis::readDouble); + case 'F' -> readArray(dis, dis::readFloat); + case 'I' -> readArray(dis, dis::readInt); + case 'J' -> readArray(dis, dis::readLong); + case 'S' -> readArray(dis, dis::readShort); + case 'Z' -> readArray(dis, dis::readBoolean); + case 's' -> readArray(dis, dis::readUTF); + case 'c' -> readArray(dis, () -> readClass(dis, decoder)); + case 'e' -> { + T enumType = decoder.resolveType(dis.readUTF()); + yield readArray(dis, () -> readEnum(dis, decoder, enumType)); + } + case '@' -> readArray(dis, () -> decodeAnnotation(dis, decoder)); + default -> throw new InternalError("Unsupported component tag: " + componentTag); + }; + } + + /** + * Reads an enum encoded at the current read position of {@code dis} and + * returns it as an object of type {@code E}. + */ + private static E readEnum(DataInputStream dis, AnnotationDecoder decoder, T enumType) throws IOException { + return decoder.newEnumValue(enumType, dis.readUTF()); + } + + /** + * Reads a class encoded at the current read position of {@code dis} and + * returns it as an object of type {@code T}. + */ + private static T readClass(DataInputStream dis, AnnotationDecoder decoder) throws IOException { + return decoder.resolveType(dis.readUTF()); + } + + /** + * Reads an array encoded at the current read position of {@code dis} and + * returns it in an immutable list. + * + * @param reader reads array elements from {@code dis} + * @return an immutable list of {@code A} objects + */ + private static List readArray(DataInputStream dis, IOReader reader) throws IOException { + Object[] array = new Object[readLength(dis)]; + for (int i = 0; i < array.length; i++) { + array[i] = reader.read(); + } + return List.of(array); + } + + /** + * Encodes {@code length} in 1 byte if it is less than 128. + */ + private static void writeLength(DataOutputStream dos, int length) throws IOException { + if (length < 0) { + throw new NegativeArraySizeException(); + } else if (length <= 127) { + dos.writeByte((byte) (0x80 | length)); + } else { + dos.writeInt(length); + } + } + + private static int readLength(DataInputStream dis) throws IOException { + int ch1 = dis.readByte(); + int length; + if (ch1 < 0) { + length = ch1 & 0x7F; + } else { + int ch2 = dis.read(); + int ch3 = dis.read(); + int ch4 = dis.read(); + length = (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0); + } + return length; + } } diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 1576df9a236..64d621b602c 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -259,7 +259,8 @@ module java.base { jdk.incubator.concurrent, jdk.internal.jvmstat, jdk.management, - jdk.management.agent; + jdk.management.agent, + jdk.internal.vm.ci; exports jdk.internal.vm.annotation to java.instrument, jdk.internal.vm.ci, diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index c006c60e4eb..8ae1be2c54e 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -677,6 +677,13 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { UnsafeAccessor.setMemberValues(this, mv); } + /** + * Gets an unmodifiable view on the member values. + */ + Map memberValues() { + return Collections.unmodifiableMap(memberValues); + } + private static class UnsafeAccessor { private static final jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java index 16058df7aea..616fa075d57 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java @@ -83,14 +83,14 @@ public class AnnotationParser { * Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)} * with an additional parameter {@code selectAnnotationClasses} which selects the * annotation types to parse (other than selected are quickly skipped).

- * This method is only used to parse select meta annotations in the construction + * This method is used to parse select meta annotations in the construction * phase of {@link AnnotationType} instances to prevent infinite recursion. * * @param selectAnnotationClasses an array of annotation types to select when parsing */ @SafeVarargs @SuppressWarnings("varargs") // selectAnnotationClasses is used safely - static Map, Annotation> parseSelectAnnotations( + public static Map, Annotation> parseSelectAnnotations( byte[] rawAnnotations, ConstantPool constPool, Class container, @@ -336,6 +336,8 @@ public class AnnotationParser { ByteBuffer buf, ConstantPool constPool, Class container) { + // Note that VMSupport.encodeAnnotation (used by JVMCI) may need to + // be updated if new annotation member types are added. Object result = null; int tag = buf.get(); switch(tag) { diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java index 55b6edea730..a70ffafd363 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java @@ -281,4 +281,13 @@ public final class AnnotationSupport { } } } + + /** + * Gets an unmodifiable view of {@code a}'s elements. + * + * @return a map from element names to element values + */ + public static Map memberValues(Annotation a) { + return ((AnnotationInvocationHandler) Proxy.getInvocationHandler(a)).memberValues(); + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/AnnotationDataDecoder.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/AnnotationDataDecoder.java new file mode 100644 index 00000000000..9cc33a395fc --- /dev/null +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/AnnotationDataDecoder.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import java.util.Map; + +import jdk.internal.vm.VMSupport.AnnotationDecoder; +import jdk.vm.ci.meta.AnnotationData; +import jdk.vm.ci.meta.EnumData; +import jdk.vm.ci.meta.ErrorData; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.MetaUtil; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaType; + +/** + * Implementation of {@link AnnotationDecoder} that resolves type names to {@link JavaType} values + * and employs {@link AnnotationData} and {@link EnumData} to represent decoded annotations and enum + * constants respectively. + */ +final class AnnotationDataDecoder implements AnnotationDecoder { + + static final AnnotationDataDecoder INSTANCE = new AnnotationDataDecoder(); + + @Override + public JavaType resolveType(String name) { + String internalName = MetaUtil.toInternalName(name); + return UnresolvedJavaType.create(internalName); + } + + @Override + public AnnotationData newAnnotation(JavaType type, Map.Entry[] elements) { + return new AnnotationData(type, elements); + } + + @Override + public EnumData newEnumValue(JavaType enumType, String name) { + return new EnumData(enumType, name); + } + + @Override + public ErrorData newErrorValue(String description) { + return new ErrorData(description); + } + + static ResolvedJavaType[] asArray(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + ResolvedJavaType[] filter = new ResolvedJavaType[2 + types.length]; + filter[0] = type1; + filter[1] = type2; + System.arraycopy(types, 0, filter, 2, types.length); + return filter; + } +} 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 cbc542a7618..21aef3d9f7c 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 @@ -29,6 +29,7 @@ import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import java.lang.reflect.Executable; import java.lang.reflect.Field; +import jdk.internal.misc.Unsafe; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.InvalidInstalledCodeException; @@ -48,6 +49,12 @@ import jdk.vm.ci.meta.ResolvedJavaType; * Calls from Java into HotSpot. The behavior of all the methods in this class that take a native * pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not * denote a valid native object. + * + * Note also that some calls pass a raw VM value to avoid a JNI upcall. For example, + * {@link #getBytecode(HotSpotResolvedJavaMethodImpl, long)} needs the raw {@code Method*} value + * (stored in {@link HotSpotResolvedJavaMethodImpl#methodHandle}) in the C++ implementation. The + * {@link HotSpotResolvedJavaMethodImpl} wrapper is still passed as well as it may be the last + * reference keeping the raw value alive. */ final class CompilerToVM { /** @@ -1303,4 +1310,89 @@ final class CompilerToVM { native void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, long callerPointer, HotSpotResolvedJavaMethodImpl callee, long calleePointer, boolean succeeded, String message, int bci); + + /** + * Gets the serialized annotation info for {@code type} by calling + * {@code VMSupport.encodeAnnotations} in the HotSpot heap. + */ + byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, ResolvedJavaType[] filter) { + try (KlassPointers a = new KlassPointers(filter)) { + return getEncodedClassAnnotationData(type, type.getKlassPointer(), + a.types, a.types.length, a.buffer()); + } + } + + native byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, long klassPointer, + Object filter, int filterLength, long filterKlassPointers); + + /** + * Gets the serialized annotation info for {@code method} by calling + * {@code VMSupport.encodeAnnotations} in the HotSpot heap. + */ + byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, ResolvedJavaType[] filter) { + try (KlassPointers a = new KlassPointers(filter)) { + return getEncodedExecutableAnnotationData(method, method.getMethodPointer(), + a.types, a.types.length, a.buffer()); + } + } + + native byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, long methodPointer, + Object filter, int filterLength, long filterKlassPointers); + + /** + * Gets the serialized annotation info for the field denoted by {@code holder} and + * {@code fieldIndex} by calling {@code VMSupport.encodeAnnotations} in the HotSpot heap. + */ + byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, int fieldIndex, ResolvedJavaType[] filter) { + try (KlassPointers a = new KlassPointers(filter)) { + return getEncodedFieldAnnotationData(holder, holder.getKlassPointer(), fieldIndex, + a.types, a.types.length, a.buffer()); + } + } + + native byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, long klassPointer, int fieldIndex, + Object filterTypes, int filterLength, long filterKlassPointers); + + /** + * Helper for passing {@Klass*} values to native code. + */ + static final class KlassPointers implements AutoCloseable { + final ResolvedJavaType[] types; + long pointersArray; + final Unsafe unsafe = UnsafeAccess.UNSAFE; + + KlassPointers(ResolvedJavaType[] types) { + this.types = types; + } + + /** + * Gets the buffer in which to pass the {@Klass*} values to JNI. + * + * @return a {@Klass*} value if {@code types.length == 1} otherwise the address of a native + * buffer holding an array of {@Klass*} values + */ + long buffer() { + int length = types.length; + if (length == 1) { + return ((HotSpotResolvedObjectTypeImpl) types[0]).getKlassPointer(); + } else { + pointersArray = unsafe.allocateMemory(length * Long.BYTES); + long pos = pointersArray; + for (int i = 0; i < types.length; i++) { + HotSpotResolvedObjectTypeImpl hsType = (HotSpotResolvedObjectTypeImpl) types[i]; + unsafe.putLong(pos, hsType.getKlassPointer()); + pos += Long.BYTES; + } + } + return pointersArray; + } + + @Override + public void close() { + if (types.length != 1 && pointersArray != 0) { + unsafe.freeMemory(pointersArray); + pointersArray = 0; + } + } + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java index 1103f592b26..6eb4dfb9b02 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java @@ -23,14 +23,17 @@ package jdk.vm.ci.hotspot; import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; import java.lang.annotation.Annotation; +import java.util.Collections; +import java.util.List; -import jdk.internal.vm.annotation.Stable; - +import jdk.internal.vm.VMSupport; +import jdk.vm.ci.meta.AnnotationData; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaType; @@ -227,4 +230,25 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField { public JavaConstant getConstantValue() { return holder.getFieldInfo(index).getConstantValue(holder); } + + @Override + public AnnotationData getAnnotationData(ResolvedJavaType annotationType) { + if (!hasAnnotations()) { + return null; + } + return getAnnotationData0(annotationType).get(0); + } + + @Override + public List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + if (!hasAnnotations()) { + return Collections.emptyList(); + } + return getAnnotationData0(AnnotationDataDecoder.asArray(type1, type2, types)); + } + + private List getAnnotationData0(ResolvedJavaType... filter) { + byte[] encoded = compilerToVM().getEncodedFieldAnnotationData(holder, index, filter); + return VMSupport.decodeAnnotations(encoded, AnnotationDataDecoder.INSTANCE); + } } 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 0850d3625d6..3cbecb684d7 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 @@ -35,10 +35,14 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Executable; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.util.Collections; +import java.util.List; import java.util.Objects; +import jdk.internal.vm.VMSupport; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; +import jdk.vm.ci.meta.AnnotationData; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.DefaultProfilingInfo; @@ -523,7 +527,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp @Override public Annotation[] getAnnotations() { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + if (!hasAnnotations()) { return new Annotation[0]; } return runtime().reflection.getMethodAnnotations(this); @@ -531,7 +535,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp @Override public Annotation[] getDeclaredAnnotations() { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + if (!hasAnnotations()) { return new Annotation[0]; } return runtime().reflection.getMethodDeclaredAnnotations(this); @@ -539,12 +543,19 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp @Override public T getAnnotation(Class annotationClass) { - if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0 || isClassInitializer()) { + if (!hasAnnotations()) { return null; } return runtime().reflection.getMethodAnnotation(this, annotationClass); } + /** + * Returns whether this method has annotations. + */ + private boolean hasAnnotations() { + return (getConstMethodFlags() & config().constMethodHasMethodAnnotations) != 0 && !isClassInitializer(); + } + @Override public boolean isBridge() { return (BRIDGE & getModifiers()) != 0; @@ -752,4 +763,25 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp public int methodIdnum() { return UNSAFE.getChar(getConstMethod() + config().constMethodMethodIdnumOffset); } + + @Override + public AnnotationData getAnnotationData(ResolvedJavaType type) { + if (!hasAnnotations()) { + return null; + } + return getAnnotationData0(type).get(0); + } + + @Override + public List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + if (!hasAnnotations()) { + return Collections.emptyList(); + } + return getAnnotationData0(AnnotationDataDecoder.asArray(type1, type2, types)); + } + + private List getAnnotationData0(ResolvedJavaType... filter) { + byte[] encoded = compilerToVM().getEncodedExecutableAnnotationData(this, filter); + return VMSupport.decodeAnnotations(encoded, AnnotationDataDecoder.INSTANCE); + } } 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 11d08eb1c2b..ad61d11a4c4 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 @@ -35,10 +35,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.nio.ByteOrder; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.List; +import jdk.internal.vm.VMSupport; import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.AnnotationData; import jdk.vm.ci.meta.Assumptions.AssumptionResult; import jdk.vm.ci.meta.Assumptions.ConcreteMethod; import jdk.vm.ci.meta.Assumptions.ConcreteSubtype; @@ -871,18 +875,56 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem return getConstantPool().getSourceFileName(); } + /** + * Determines if this type may have annotations. A positive result does not mean this type has + * annotations but a negative result guarantees this type has no annotations. + * + * @param includingInherited if true, expand this query to include superclasses of this type + */ + private boolean mayHaveAnnotations(boolean includingInherited) { + if (isArray()) { + return false; + } + HotSpotVMConfig config = config(); + final long metaspaceAnnotations = UNSAFE.getAddress(getKlassPointer() + config.instanceKlassAnnotationsOffset); + if (metaspaceAnnotations != 0) { + long classAnnotations = UNSAFE.getAddress(metaspaceAnnotations + config.annotationsClassAnnotationsOffset); + if (classAnnotations != 0) { + return true; + } + } + if (includingInherited) { + HotSpotResolvedObjectTypeImpl superClass = getSuperclass(); + if (superClass != null) { + return superClass.mayHaveAnnotations(true); + } + } + return false; + } + + private static final Annotation[] NO_ANNOTATIONS = {}; + @Override public Annotation[] getAnnotations() { + if (!mayHaveAnnotations(true)) { + return NO_ANNOTATIONS; + } return runtime().reflection.getAnnotations(this); } @Override public Annotation[] getDeclaredAnnotations() { + if (!mayHaveAnnotations(false)) { + return NO_ANNOTATIONS; + } return runtime().reflection.getDeclaredAnnotations(this); } @Override public T getAnnotation(Class annotationClass) { + if (!mayHaveAnnotations(true)) { + return null; + } return runtime().reflection.getAnnotation(this, annotationClass); } @@ -1062,4 +1104,25 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem public boolean isCloneableWithAllocation() { return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0; } + + @Override + public AnnotationData getAnnotationData(ResolvedJavaType annotationType) { + if (!mayHaveAnnotations(true)) { + return null; + } + return getAnnotationData0(annotationType).get(0); + } + + @Override + public List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + if (!mayHaveAnnotations(true)) { + return Collections.emptyList(); + } + return getAnnotationData0(AnnotationDataDecoder.asArray(type1, type2, types)); + } + + private List getAnnotationData0(ResolvedJavaType... filter) { + byte[] encoded = compilerToVM().getEncodedClassAnnotationData(this, filter); + return VMSupport.decodeAnnotations(encoded, AnnotationDataDecoder.INSTANCE); + } } 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 84a1ab13fae..d95824998bc 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 @@ -27,9 +27,12 @@ import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.meta.AnnotationData; import jdk.vm.ci.meta.Assumptions.AssumptionResult; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; @@ -317,4 +320,15 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType JavaConstant getJavaMirror() { return mirror; } + + @Override + public AnnotationData getAnnotationData(ResolvedJavaType type) { + return null; + } + + @Override + public List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + return Collections.emptyList(); + } + } 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 223b210c555..b9ad5b77102 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 @@ -110,6 +110,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class); final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array*"); + final int annotationsClassAnnotationsOffset = getFieldOffset("Annotations::_class_annotations", Integer.class, "AnnotationArray*"); final int fieldsAnnotationsBaseOffset = getFieldValue("CompilerToVM::Data::_fields_annotations_base_offset", Integer.class, "int"); final int arrayU1LengthOffset = getFieldOffset("Array::_length", Integer.class, "int"); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java index b43859fe5d4..b89aae78aeb 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java @@ -40,7 +40,7 @@ import jdk.vm.ci.meta.JavaConstant; */ final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl { /** - * An object handle in {@code JVMCI::_object_handles}. + * An object handle in {@code JVMCIRuntime::_oop_handles}. */ private long objectHandle; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Annotated.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Annotated.java new file mode 100644 index 00000000000..666e1181cb1 --- /dev/null +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/Annotated.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.annotation.Inherited; +import java.util.List; + +/** + * Represents a program element such as a method, constructor, field or class for which annotations + * may be present. + */ +public interface Annotated { + + /** + * Constructs the annotations present on this element whose types are in the set composed of {@code type1}, + * {@code type2} and {@code types}. All enum types referenced by the returned annotation are + * initialized. Class initialization is not triggered for enum types referenced by other + * annotations of this element. + * + * If this element is a class, then {@link Inherited} annotations are included in the set of + * annotations considered. + * + * See {@link java.lang.reflect.AnnotatedElement} for the definition of present. + * + * @param type1 an annotation type + * @param type2 an annotation type + * @param types more annotation types + * @return an immutable list of the annotations present on this element that match one of the + * given types + * @throws IllegalArgumentException if any type in the set composed of {@code type1}, + * {@code type2} and {@code types} is not an annotation interface type + * @throws UnsupportedOperationException if this operation is not supported + */ + default List getAnnotationData(ResolvedJavaType type1, ResolvedJavaType type2, ResolvedJavaType... types) { + throw new UnsupportedOperationException(); + } + + /** + * Constructs the annotation present on this element of type {@code type}. + * + * See {@link java.lang.reflect.AnnotatedElement} for the definition of present. + * + * @param type the type object corresponding to the annotation interface type + * @return this element's annotation for the specified annotation type if present on this + * element, else null + * @throws IllegalArgumentException if {@code type} is not an annotation interface type + * @throws UnsupportedOperationException if this operation is not supported + */ + default AnnotationData getAnnotationData(ResolvedJavaType type) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java new file mode 100644 index 00000000000..17b6b714ba4 --- /dev/null +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +import java.lang.annotation.Annotation; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Represents an annotation where element values are represented with the types described + * {@linkplain #get here}. + * + * In contrast to the standard annotation API based on {@link Annotation}, use of + * {@link AnnotationData} allows annotations to be queried without the JVMCI runtime having to + * support dynamic loading of arbitrary {@link Annotation} classes. Such support is impossible in a + * closed world, ahead-of-time compiled environment such as libgraal. + */ +public final class AnnotationData { + + private final JavaType type; + private final Map elements; + + private static final Set> ELEMENT_TYPES = Set.of( + Boolean.class, + Byte.class, + Character.class, + Short.class, + Integer.class, + Float.class, + Long.class, + Double.class, + String.class, + EnumData.class, + AnnotationData.class); + + /** + * Creates an annotation. + * + * @param type the annotation interface of this annotation, represented as a {@link JavaType} + * @param elements the names and values of this annotation's element values. Each value's type + * must be one of the {@code AnnotationData} types described {@linkplain #get here} + * or it must be a {@link ErrorData} object whose {@code toString()} value describes + * the error raised while parsing the element. There is no distinction between a + * value explicitly present in the annotation and an element's default value. + * @throws IllegalArgumentException if the value of an entry in {@code elements} is not of an + * accepted type + * @throws NullPointerException if any of the above parameters is null or any entry in + * {@code elements} is null + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public AnnotationData(JavaType type, Map.Entry[] elements) { + this.type = Objects.requireNonNull(type); + for (Map.Entry e : elements) { + Object value = e.getValue(); + if (!(value instanceof ErrorData) && + !(value instanceof JavaType) && + !(value instanceof List) && + !ELEMENT_TYPES.contains(value.getClass())) { + throw new IllegalArgumentException("illegal type for element " + e.getKey() + ": " + value.getClass().getName()); + } + } + this.elements = Map.ofEntries(elements); + } + + /** + * @return the annotation interface of this annotation, represented as a {@link JavaType} + */ + public JavaType getAnnotationType() { + return type; + } + + // @formatter:off + /** + * Gets the annotation element denoted by {@code name}. The following table shows the + * correspondence between the type of an element as declared by a method in the annotation + * interface and the type of value returned by this method: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Annotation AnnotationData
boolean Boolean
byte Byte
char Character
short Short
int Integer
float Float
long Long
double Double
String String
Class JavaType
Enum EnumData
Annotation AnnotationData
[]immutable List<T> where T is one of the above types
+ * + * @param the type of the element as per the {@code AnnotationData} column in the above + * table or {@link Object} + * @param elementType the class for the type of the element + * @return the annotation element denoted by {@code name} + * @throws ClassCastException if the element is not of type {@code V} + * @throws IllegalArgumentException if this annotation has no element named {@code name} or if + * there was an error parsing or creating the element value + */ + // @formatter:on + @SuppressWarnings("unchecked") + public V get(String name, Class elementType) { + Object val = elements.get(name); + if (val == null) { + throw new IllegalArgumentException("no element named " + name); + } + Class valClass = val.getClass(); + if (valClass == ErrorData.class) { + throw new IllegalArgumentException(val.toString()); + } + return elementType.cast(val); + } + + @Override + public String toString() { + return "@" + type.getName() + "(" + elements + ")"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof AnnotationData) { + AnnotationData that = (AnnotationData) obj; + return this.type.equals(that.type) && this.elements.equals(that.elements); + + } + return false; + } + + @Override + public int hashCode() { + return type.hashCode() ^ elements.hashCode(); + } +} diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EnumData.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EnumData.java new file mode 100644 index 00000000000..4e8fc3a8ab7 --- /dev/null +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/EnumData.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents an enum constant within {@link AnnotationData}. + */ +public final class EnumData { + private final JavaType type; + private final String name; + + /** + * Creates an enum constant. + * + * @param type the {@linkplain Enum enum type} + * @param name the {@linkplain Enum#name() name} of the enum + */ + public EnumData(JavaType type, String name) { + this.type = type; + this.name = name; + } + + /** + * Gets the {@linkplain Enum enum type}. + */ + public JavaType getEnumType() { + return type; + } + + /** + * Gets the {@linkplain Enum#name() name} of the enum. + */ + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof EnumData) { + EnumData that = (EnumData) obj; + return this.type.equals(that.type) && this.name.equals(that.name); + } + return false; + } + + @Override + public int hashCode() { + return this.type.hashCode() ^ this.name.hashCode(); + } +} diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ErrorData.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ErrorData.java new file mode 100644 index 00000000000..72177ddcbbc --- /dev/null +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ErrorData.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.meta; + +/** + * Represents an error constant within {@link AnnotationData}. + * + * Similar to {@code sun.reflect.annotation.ExceptionProxy}. + */ +public final class ErrorData { + private final String description; + + /** + * Creates an error constant. + * + * @param description description of the error + */ + public ErrorData(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ErrorData) { + ErrorData that = (ErrorData) obj; + return this.description.equals(that.description); + } + return false; + } + + @Override + public int hashCode() { + return description.hashCode(); + } +} diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java index a6b5b7fb2d0..cb891ab2e1b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaField.java @@ -29,7 +29,7 @@ import java.lang.reflect.Modifier; * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * through {@link ConstantPool constant pools}. */ -public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement { +public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement, Annotated { /** * {@inheritDoc} 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 efb67ebf2f5..ce927e03ea1 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 @@ -33,7 +33,7 @@ import java.lang.reflect.Type; * Represents a resolved Java method. Methods, like fields and types, are resolved through * {@link ConstantPool constant pools}. */ -public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement { +public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement, Annotated { /** * Returns the method's bytecode. The returned bytecode does not contain breakpoints or non-Java 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 faff741c794..37762e759fc 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 @@ -31,7 +31,7 @@ import jdk.vm.ci.meta.Assumptions.AssumptionResult; * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools} * . */ -public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement { +public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement, Annotated { /** * Checks whether this type has a finalizer method. * @@ -137,8 +137,8 @@ public interface ResolvedJavaType extends JavaType, ModifiersProvider, Annotated boolean isAssignableFrom(ResolvedJavaType other); /** - * Returns {@code null} since support for VM anonymous class was removed by JDK-8243287. - * This method is preserved for JVMCI backwards compatibility. + * Returns {@code null} since support for VM anonymous class was removed by JDK-8243287. This + * method is preserved for JVMCI backwards compatibility. */ @Deprecated default ResolvedJavaType getHostClass() { diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java index a159dc64cc6..d3097629355 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java @@ -25,10 +25,20 @@ * @test * @requires vm.jvmci * @library ../../../../../ + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java + * TestResolvedJavaType.java + * @clean jdk.internal.vm.test.AnnotationTestInput$Missing + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common + * java.base/jdk.internal.reflect * java.base/jdk.internal.misc + * java.base/jdk.internal.vm + * java.base/sun.reflect.annotation * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaField */ @@ -57,6 +67,7 @@ import java.util.Set; import org.junit.Assert; import org.junit.Test; +import jdk.internal.vm.test.AnnotationTestInput; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaConstant; @@ -181,6 +192,14 @@ public class TestResolvedJavaField extends FieldUniverse { return null; } + @Test + public void getAnnotationDataTest() throws Exception { + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredField("annotatedField")); + for (Field f : fields.keySet()) { + TestResolvedJavaType.getAnnotationDataTest(f); + } + } + // @formatter:off private static final String[] untestedApiMethods = { }; 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 43116be77ba..12bad736adf 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,9 +25,20 @@ * @test * @requires vm.jvmci * @library ../../../../../ + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java + * TestResolvedJavaType.java + * @clean jdk.internal.vm.test.AnnotationTestInput$Missing + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime + * jdk.internal.vm.ci/jdk.vm.ci.common + * java.base/jdk.internal.reflect * java.base/jdk.internal.misc + * java.base/jdk.internal.vm + * java.base/sun.reflect.annotation * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaMethod */ @@ -61,11 +72,16 @@ import java.util.Set; import org.junit.Assert; import org.junit.Test; +import jdk.internal.vm.test.AnnotationTestInput; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ExceptionHandler; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.runtime.test.TestResolvedJavaMethod.AnnotationDataTest.Annotation1; +import jdk.vm.ci.runtime.test.TestResolvedJavaMethod.AnnotationDataTest.Annotation2; +import jdk.vm.ci.runtime.test.TestResolvedJavaMethod.AnnotationDataTest.Annotation3; +import jdk.vm.ci.runtime.test.TestResolvedJavaMethod.AnnotationDataTest.NumbersDE; /** * Tests for {@link ResolvedJavaMethod}. @@ -474,6 +490,83 @@ public class TestResolvedJavaMethod extends MethodUniverse { } } + /** + * Encapsulates input for {@link TestResolvedJavaMethod#getAnnotationDataTest}. + */ + static class AnnotationDataTest { + + public enum NumbersEN { + One, + Two; + } + + public enum NumbersDE { + Eins, + Zwei; + } + + public enum NumbersUA { + Odyn, + Dva; + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface Annotation1 { + NumbersEN value() default NumbersEN.One; + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface Annotation2 { + NumbersDE value() default NumbersDE.Eins; + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface Annotation3 { + NumbersUA value() default NumbersUA.Odyn; + } + + @Annotation1 + @Annotation2 + @Annotation3(NumbersUA.Dva) + static void methodWithThreeAnnotations() { + + } + } + + @Test + public void getAnnotationDataTest() throws Exception { + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("annotatedMethod")); + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("missingAnnotation")); + try { + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("missingNestedAnnotation")); + throw new AssertionError("expected " + NoClassDefFoundError.class.getName()); + } catch (NoClassDefFoundError e) { + Assert.assertEquals("jdk/internal/vm/test/AnnotationTestInput$Missing", e.getMessage()); + } + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("missingTypeOfClassMember")); + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("missingMember")); + TestResolvedJavaType.getAnnotationDataTest(AnnotationTestInput.class.getDeclaredMethod("changeTypeOfMember")); + + for (Method m : methods.keySet()) { + TestResolvedJavaType.getAnnotationDataTest(m); + } + + ResolvedJavaMethod m = metaAccess.lookupJavaMethod(AnnotationDataTest.class.getDeclaredMethod("methodWithThreeAnnotations")); + ResolvedJavaType a1 = metaAccess.lookupJavaType(Annotation1.class); + ResolvedJavaType a2 = metaAccess.lookupJavaType(Annotation2.class); + ResolvedJavaType a3 = metaAccess.lookupJavaType(Annotation3.class); + ResolvedJavaType a4 = metaAccess.lookupJavaType(AnnotationDataTest.class); + ResolvedJavaType numbersDEType = metaAccess.lookupJavaType(NumbersDE.class); + + // Ensure NumbersDE is not initialized before Annotation2 is requested + Assert.assertFalse(numbersDEType.isInitialized()); + Assert.assertEquals(2, m.getAnnotationData(a1, a3).size()); + + // Ensure NumbersDE is initialized after Annotation2 is requested + Assert.assertNotNull(m.getAnnotationData(a2)); + Assert.assertTrue(numbersDEType.isInitialized()); + } + private Method findTestMethod(Method apiMethod) { String testName = apiMethod.getName() + "Test"; for (Method m : getClass().getDeclaredMethods()) { 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 b8afd840e87..9540b965520 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,12 +25,20 @@ * @test * @requires vm.jvmci * @library ../../../../../ + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java + * @clean jdk.internal.vm.test.AnnotationTestInput$Missing + * @compile ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java + * ../../../../../../../../../../../jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java * @modules java.base/jdk.internal.org.objectweb.asm * java.base/jdk.internal.reflect * jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common * java.base/jdk.internal.misc + * java.base/jdk.internal.vm + * java.base/sun.reflect.annotation * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaType */ @@ -57,30 +65,43 @@ import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.AccessibleObject; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collections; +import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.Assert; import org.junit.Test; -import jdk.internal.org.objectweb.asm.*; import jdk.internal.reflect.ConstantPool; +import jdk.internal.vm.test.AnnotationTestInput; import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.Annotated; +import jdk.vm.ci.meta.AnnotationData; +import jdk.vm.ci.meta.EnumData; import jdk.vm.ci.meta.Assumptions.AssumptionResult; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.UnresolvedJavaType; +import sun.reflect.annotation.AnnotationSupport; /** * Tests for {@link ResolvedJavaType}. @@ -177,7 +198,8 @@ public class TestResolvedJavaType extends TypeUniverse { @Test public void lambdaInternalNameTest() { - // Verify that the last dot in lambda types is properly handled when transitioning from internal name to java + // Verify that the last dot in lambda types is properly handled when transitioning from + // internal name to java // name and vice versa. Supplier lambda = () -> () -> System.out.println("run"); ResolvedJavaType lambdaType = metaAccess.lookupJavaType(lambda.getClass()); @@ -903,11 +925,11 @@ public class TestResolvedJavaType extends TypeUniverse { return f.getName().equals("allowedModes") || f.getName().equals("lookupClass"); } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ClassLoader.class)) || - f.getDeclaringClass().equals(metaAccess.lookupJavaType(AccessibleObject.class)) || - f.getDeclaringClass().equals(metaAccess.lookupJavaType(Constructor.class)) || - f.getDeclaringClass().equals(metaAccess.lookupJavaType(Field.class)) || - f.getDeclaringClass().equals(metaAccess.lookupJavaType(Method.class)) || - f.getDeclaringClass().equals(metaAccess.lookupJavaType(Module.class))) { + f.getDeclaringClass().equals(metaAccess.lookupJavaType(AccessibleObject.class)) || + f.getDeclaringClass().equals(metaAccess.lookupJavaType(Constructor.class)) || + f.getDeclaringClass().equals(metaAccess.lookupJavaType(Field.class)) || + f.getDeclaringClass().equals(metaAccess.lookupJavaType(Method.class)) || + f.getDeclaringClass().equals(metaAccess.lookupJavaType(Module.class))) { return true; } return false; @@ -1131,6 +1153,40 @@ public class TestResolvedJavaType extends TypeUniverse { return null; } + @Test + public void getAnnotationDataTest() throws Exception { + getAnnotationDataTest(AnnotationTestInput.AnnotatedClass.class); + getAnnotationDataTest(int.class); + getAnnotationDataTest(void.class); + for (Class c : classes) { + getAnnotationDataTest(c); + } + + // Primitive classes have no annotations but we cannot directly + // test absence of annotations. Instead, just ensure empty answers + // are returned when looking up an arbitrary annotation type. + Class[] prims = {void.class, byte.class, int.class, double.class, float.class, short.class, char.class, long.class}; + ResolvedJavaType overrideType = metaAccess.lookupJavaType(Override.class); + for (Class c : prims) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + AnnotationData ad = type.getAnnotationData(overrideType); + Assert.assertNull(String.valueOf(ad), ad); + List adArray = type.getAnnotationData(overrideType, overrideType); + Assert.assertEquals(0, adArray.size()); + } + + // Test that inherited annotations are handled properly. + ResolvedJavaType namedType = metaAccess.lookupJavaType(AnnotationTestInput.Named.class); + AnnotationData ad = metaAccess.lookupJavaType(AnnotationTestInput.OwnName.class).getAnnotationData(namedType); + Assert.assertEquals("NonInheritedValue", ad.get("value", String.class)); + ad = metaAccess.lookupJavaType(AnnotationTestInput.InheritedName1.class).getAnnotationData(namedType); + Assert.assertEquals("Super1", ad.get("value", String.class)); + ad = metaAccess.lookupJavaType(AnnotationTestInput.InheritedName2.class).getAnnotationData(namedType); + Assert.assertEquals("Super2", ad.get("value", String.class)); + ad = metaAccess.lookupJavaType(AnnotationTestInput.InheritedName3.class).getAnnotationData(namedType); + Assert.assertEquals("Super1", ad.get("value", String.class)); + } + // @formatter:off private static final String[] untestedApiMethods = { "initialize", @@ -1174,4 +1230,129 @@ public class TestResolvedJavaType extends TypeUniverse { private static boolean isSignaturePolymorphic(ResolvedJavaMethod method) { return method.getAnnotation(SIGNATURE_POLYMORPHIC_CLASS) != null; } + + /** + * Tests that {@link AnnotationData} obtained from a {@link Class}, {@link Method} or + * {@link Field} matches {@link AnnotatedElement#getAnnotations()} for the corresponding JVMCI + * object. + * + * @param annotated a {@link Class}, {@link Method} or {@link Field} object + */ + public static void getAnnotationDataTest(AnnotatedElement annotated) throws Exception { + testGetAnnotationData(annotated, List.of(annotated.getAnnotations())); + } + + private static void testGetAnnotationData(AnnotatedElement annotated, List annotations) throws AssertionError { + for (Annotation a : annotations) { + AnnotationData ad = toAnnotated(annotated).getAnnotationData(metaAccess.lookupJavaType(a.annotationType())); + assertAnnotationsEquals(a, ad); + + // Check that encoding/decoding produces a stable result + AnnotationData ad2 = toAnnotated(annotated).getAnnotationData(metaAccess.lookupJavaType(a.annotationType())); + assertEquals(ad, ad2); + } + if (annotations.size() < 2) { + return; + } + ResolvedJavaType type1 = metaAccess.lookupJavaType(annotations.get(0).annotationType()); + ResolvedJavaType type2 = metaAccess.lookupJavaType(annotations.get(1).annotationType()); + for (int i = 2; i < annotations.size(); i++) { + + ResolvedJavaType[] types = annotations.// + subList(2, i + 1).// + stream().map(a -> metaAccess.lookupJavaType(a.annotationType())).// + toArray(ResolvedJavaType[]::new); + List annotationData = toAnnotated(annotated).getAnnotationData(type1, type2, types); + assertEquals(2 + types.length, annotationData.size()); + + for (int j = 0; j < annotationData.size(); j++) { + Annotation a = annotations.get(j); + AnnotationData ad = annotationData.get(j); + assertAnnotationsEquals(a, ad); + } + } + } + + private static Annotated toAnnotated(AnnotatedElement element) { + if (element instanceof Class t) { + return metaAccess.lookupJavaType(t); + } else if (element instanceof Method m) { + return metaAccess.lookupJavaMethod(m); + } else { + Field f = (Field) element; + return metaAccess.lookupJavaField(f); + } + } + + private static UnresolvedJavaType asType(Class valueType) { + return UnresolvedJavaType.create(MetaUtil.toInternalName(valueType.getName())); + } + + private static void assertAnnotationsEquals(Annotation a, AnnotationData ad) { + Map values = AnnotationSupport.memberValues(a); + for (Map.Entry e : values.entrySet()) { + String name = e.getKey(); + Object aValue = e.getValue(); + Object adValue; + try { + adValue = ad.get(name, Object.class); + } catch (IllegalArgumentException ex) { + assertEquals(aValue.toString(), ex.getMessage()); + continue; + } + try { + assertAnnotationElementsEqual(aValue, adValue); + } catch (ClassCastException ex) { + throw new AssertionError(a.getClass().getName() + "." + name + " has wrong type: " + adValue.getClass().getName(), ex); + } + } + } + + private static void assertAnnotationElementsEqual(Object aValue, Object adValue) { + Class valueType = aValue.getClass(); + if (valueType.isEnum()) { + assertEnumObjectsEquals(aValue, adValue); + } else if (aValue instanceof Class) { + assertClassObjectsEquals(aValue, adValue); + } else if (aValue instanceof Annotation) { + assertAnnotationObjectsEquals(aValue, adValue); + } else if (valueType.isArray()) { + List adList = (List) adValue; + int length = Array.getLength(aValue); + assertEquals(length, adList.size()); + for (int i = 0; i < length; i++) { + assertAnnotationElementsEqual(Array.get(aValue, i), adList.get(i)); + } + } else { + assertEquals(aValue.getClass(), adValue.getClass()); + assertEquals(aValue, adValue); + } + } + + private static void assertClassObjectsEquals(Object aValue, Object adValue) { + String aName = ((Class) aValue).getName(); + String adName = ((JavaType) adValue).toClassName(); + assertEquals(aName, adName); + } + + private static void assertEnumObjectsEquals(Object aValue, Object adValue) { + EnumData adEnum = (EnumData) adValue; + String adEnumName = adEnum.getName(); + String aEnumName = ((Enum) aValue).name(); + assertEquals(adEnumName, aEnumName); + } + + private static void assertAnnotationObjectsEquals(Object aValue, Object adValue) { + Annotation aAnnotation = (Annotation) aValue; + AnnotationData adAnnotation = (AnnotationData) adValue; + assertAnnotationsEquals(aAnnotation, adAnnotation); + } + + private static void assertArraysEqual(Object aValue, Object adValue, int length, BiConsumer assertEqualty) { + Object[] aArray = (Object[]) aValue; + Object[] adArray = (Object[]) adValue; + for (int i = 0; i < length; i++) { + assertEqualty.accept(aArray[i], adArray[i]); + } + } } diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java index 1416c317d3e..2420a133b63 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java @@ -22,14 +22,8 @@ */ package jdk.vm.ci.runtime.test; -import jdk.internal.misc.Unsafe; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.runtime.JVMCI; -import org.junit.Test; +import static java.lang.reflect.Modifier.isFinal; +import static java.lang.reflect.Modifier.isStatic; import java.io.Serializable; import java.lang.reflect.Array; @@ -54,8 +48,15 @@ import java.util.TreeMap; import java.util.function.Predicate; import java.util.stream.Collectors; -import static java.lang.reflect.Modifier.isFinal; -import static java.lang.reflect.Modifier.isStatic; +import org.junit.Test; + +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.runtime.JVMCI; /** * Context for type related tests. diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java new file mode 100644 index 00000000000..446fb891ac4 --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/AnnotationTestInput.java @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class AnnotationTestInput { + + enum Mood { + HAPPY, + SAD, + CONFUSED; + } + + private class PrivateClass {} + + @Single(string = "a", + stringArray = {"a", "b"}, + classValue = String.class, + classArray = {String.class, Exception.class}, + byteValue = 1, + byteArray = {1, 2, Byte.MIN_VALUE, Byte.MAX_VALUE}, + charValue = 'a', + charArray = {'a', 'b', + Character.MIN_VALUE, Character.MAX_VALUE, + '\b', '\f', '\n', '\r', '\t', '\\', '\'', '\"', '\u012A'}, + doubleValue = 3.3D, + doubleArray = {3.3D, 4.4D, + Double.MIN_VALUE, Double.MAX_VALUE, + Double.NaN, + Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}, + floatValue = 4.4F, + floatArray = {4.4F, 5.5F, + Float.MIN_VALUE, Float.MAX_VALUE, + Float.NaN, + Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}, + intValue = 5, + intArray = {5, 6, Integer.MIN_VALUE, Integer.MAX_VALUE}, + longValue = 6L, + longArray = {6L, 7L, Long.MIN_VALUE, Long.MAX_VALUE}, + shortValue = 7, + shortArray = {7, 8, Short.MIN_VALUE, Short.MAX_VALUE}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.SAD, + moodArray = {Mood.CONFUSED, Mood.HAPPY}, + nested = @NestedAnno("nested1"), + nestedArray = {@NestedAnno("nested2"), @NestedAnno("nested3")}) + @Single(string = "A", + stringArray = {"A", "B"}, + classValue = Thread.class, + classArray = {Thread.class, PrivateClass.class}, + byteValue = -1, + byteArray = {-1, -2}, + charValue = 'A', + charArray = {'a', 'b'}, + doubleValue = -3.3D, + doubleArray = {3.3D, 4.4D}, + floatValue = -4.4F, + floatArray = {4.4F, 5.5F}, + intValue = -5, + intArray = {5, 6}, + longValue = -6L, + longArray = {6L, 7L}, + shortValue = -7, + shortArray = {7, 8}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.CONFUSED, + moodArray = {Mood.SAD, Mood.CONFUSED}, + nested = @NestedAnno("nested4"), + nestedArray = {@NestedAnno("nested5"), @NestedAnno("nested6")}) + @SingleWithDefaults + @Deprecated + @SuppressWarnings("unchecked") + public void annotatedMethod() { + } + + @Named("Super1") + public static class Super1 {} + @Named("Super2") + public static class Super2 extends Super1 {} + public static class Super3 extends Super1 {} + + @Named("NonInheritedValue") + public static class OwnName extends Super1 {} + + public static class InheritedName1 extends Super1 {} + public static class InheritedName2 extends Super2 {} + public static class InheritedName3 extends Super3 {} + + @Named("AnnotatedClass") + @Single(string = "a", + stringArray = {"a", "b"}, + classValue = String.class, + classArray = {String.class, Exception.class}, + byteValue = 1, + byteArray = {1, 2, Byte.MIN_VALUE, Byte.MAX_VALUE}, + charValue = 'a', + charArray = {'a', 'b', + Character.MIN_VALUE, Character.MAX_VALUE, + '\b', '\f', '\n', '\r', '\t', '\\', '\'', '\"', '\u012A'}, + doubleValue = 3.3D, + doubleArray = {3.3D, 4.4D, + Double.MIN_VALUE, Double.MAX_VALUE, + Double.NaN, + Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}, + floatValue = 4.4F, + floatArray = {4.4F, 5.5F, + Float.MIN_VALUE, Float.MAX_VALUE, + Float.NaN, + Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}, + intValue = 5, + intArray = {5, 6, Integer.MIN_VALUE, Integer.MAX_VALUE}, + longValue = 6L, + longArray = {6L, 7L, Long.MIN_VALUE, Long.MAX_VALUE}, + shortValue = 7, + shortArray = {7, 8, Short.MIN_VALUE, Short.MAX_VALUE}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.SAD, + moodArray = {Mood.CONFUSED, Mood.HAPPY}, + nested = @NestedAnno("nested7"), + nestedArray = {@NestedAnno("nested8"), @NestedAnno("nested9")}) + @Single(string = "A", + stringArray = {"A", "B"}, + classValue = Thread.class, + classArray = {Thread.class, PrivateClass.class}, + byteValue = -1, + byteArray = {-1, -2}, + charValue = 'A', + charArray = {'a', 'b'}, + doubleValue = -3.3D, + doubleArray = {3.3D, 4.4D}, + floatValue = -4.4F, + floatArray = {4.4F, 5.5F}, + intValue = -5, + intArray = {5, 6}, + longValue = -6L, + longArray = {6L, 7L}, + shortValue = -7, + shortArray = {7, 8}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.CONFUSED, + moodArray = {Mood.SAD, Mood.CONFUSED}, + nested = @NestedAnno("nested10"), + nestedArray = {@NestedAnno("nested11"), @NestedAnno("nested12")}) + @Deprecated + @SuppressWarnings({"rawtypes", "all"}) + public static class AnnotatedClass {} + + @Single(string = "a", + stringArray = {"a", "b"}, + classValue = String.class, + classArray = {String.class, Exception.class}, + byteValue = 1, + byteArray = {1, 2, Byte.MIN_VALUE, Byte.MAX_VALUE}, + charValue = 'a', + charArray = {'a', 'b', + Character.MIN_VALUE, Character.MAX_VALUE, + '\b', '\f', '\n', '\r', '\t', '\\', '\'', '\"', '\u012A'}, + doubleValue = 3.3D, + doubleArray = {3.3D, 4.4D, + Double.MIN_VALUE, Double.MAX_VALUE, + Double.NaN, + Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}, + floatValue = 4.4F, + floatArray = {4.4F, 5.5F, + Float.MIN_VALUE, Float.MAX_VALUE, + Float.NaN, + Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}, + intValue = 5, + intArray = {5, 6, Integer.MIN_VALUE, Integer.MAX_VALUE}, + longValue = 6L, + longArray = {6L, 7L, Long.MIN_VALUE, Long.MAX_VALUE}, + shortValue = 7, + shortArray = {7, 8, Short.MIN_VALUE, Short.MAX_VALUE}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.SAD, + moodArray = {Mood.CONFUSED, Mood.HAPPY}, + nested = @NestedAnno("nested12"), + nestedArray = {@NestedAnno("nested13"), @NestedAnno("nested14")}) + @Single(string = "A", + stringArray = {"A", "B"}, + classValue = Thread.class, + classArray = {Thread.class, PrivateClass.class}, + byteValue = -1, + byteArray = {-1, -2}, + charValue = 'A', + charArray = {'a', 'b'}, + doubleValue = -3.3D, + doubleArray = {3.3D, 4.4D}, + floatValue = -4.4F, + floatArray = {4.4F, 5.5F}, + intValue = -5, + intArray = {5, 6}, + longValue = -6L, + longArray = {6L, 7L}, + shortValue = -7, + shortArray = {7, 8}, + booleanValue = true, + booleanArray = {true, false}, + mood = Mood.CONFUSED, + moodArray = {Mood.SAD, Mood.CONFUSED}, + nested = @NestedAnno("nested15"), + nestedArray = {@NestedAnno("nested16"), @NestedAnno("nested17")}) + private static final int annotatedField = 45; + + @Retention(RetentionPolicy.RUNTIME) + public @interface NestedAnno { + String value(); + } + + @Inherited + @Retention(RetentionPolicy.RUNTIME) + public @interface Named { + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Repeatable(SingleList.class) + public @interface Single { + Class classValue(); + Class[] classArray(); + + String string(); + String[] stringArray(); + + byte byteValue(); + byte[] byteArray(); + + char charValue(); + char[] charArray(); + + double doubleValue(); + double[] doubleArray(); + + float floatValue(); + float[] floatArray(); + + int intValue(); + int[] intArray(); + + long longValue(); + long[] longArray(); + + short shortValue(); + short[] shortArray(); + + boolean booleanValue(); + boolean[] booleanArray(); + + Mood mood(); + Mood[] moodArray(); + + NestedAnno nested(); + NestedAnno[] nestedArray(); + } + + @Retention(RetentionPolicy.RUNTIME) + @interface SingleWithDefaults { + Class classValue() default SingleWithDefaults.class; + Class[] classArray() default {}; + + String string() default "anonymous"; + String[] stringArray() default {}; + + byte byteValue() default 101; + byte[] byteArray() default {}; + + char charValue() default 'Z'; + char[] charArray() default {}; + + double doubleValue() default 102.102D; + double[] doubleArray() default {}; + + float floatValue() default 103.103F; + float[] floatArray() default {}; + + int intValue() default 104; + int[] intArray() default {}; + + long longValue() default 105L; + long[] longArray() default {}; + + short shortValue() default 105; + short[] shortArray() default {}; + + boolean booleanValue() default true; + boolean[] booleanArray() default {}; + + Mood mood() default Mood.HAPPY; + Mood[] moodArray() default {}; + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface SingleList { + Single[] value(); + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface Missing {} + + @Retention(RetentionPolicy.RUNTIME) + public @interface MissingWrapper { + Missing value(); + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface MissingContainer { + Class value(); + } + + /** + * Method with a directly missing annotation. + */ + @Missing + public void missingAnnotation() {} + + /** + * Method with an indirectly missing nested annotation. + */ + @MissingWrapper(@Missing) + public void missingNestedAnnotation() {} + + /** + * Method with an annotation that has a Class member + * that cannot be resolved. + */ + @MissingContainer(Missing.class) + public void missingTypeOfClassMember() {} + + /** + * Method with an annotation that has a member + * that is deleted in a newer version of the annotation. + */ + @MemberDeleted(value = "evolving", retained = -34, deleted = 56) + public void missingMember() {} + + /** + * Method with an annotation that has a member named "any" + * whose type is changed from int to String in a newer version + * of the annotation. + */ + @MemberTypeChanged(value = "evolving", retained = -34, any = 56) + public void changeTypeOfMember() {} + +} + diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java new file mode 100644 index 00000000000..2707886b4c7 --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberDeleted.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface MemberDeleted { + String value(); + int retained(); + int deleted(); +} diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java new file mode 100644 index 00000000000..99670e63b9a --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/MemberTypeChanged.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface MemberTypeChanged { + String value(); + int retained(); + int any(); +} diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/TestAnnotationEncodingDecoding.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/TestAnnotationEncodingDecoding.java new file mode 100644 index 00000000000..64e559a5713 --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/TestAnnotationEncodingDecoding.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @compile AnnotationTestInput.java MemberDeleted.java MemberTypeChanged.java + * @modules java.base/jdk.internal.vm + * java.base/sun.reflect.annotation + * @clean jdk.internal.vm.test.AnnotationTestInput$Missing + * @compile alt/MemberDeleted.java alt/MemberTypeChanged.java + * @run testng/othervm + * jdk.internal.vm.test.TestAnnotationEncodingDecoding + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.LinkedHashMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import sun.reflect.annotation.AnnotationSupport; +import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.ExceptionProxy; + +import jdk.internal.vm.VMSupport; +import jdk.internal.vm.VMSupport.AnnotationDecoder; + +public class TestAnnotationEncodingDecoding { + + @Test + public void encodeDecodeTest() throws Exception { + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredField("annotatedField")); + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("annotatedMethod")); + checkDecodedEqualsEncoded(AnnotationTestInput.AnnotatedClass.class); + + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("missingAnnotation")); + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("missingNestedAnnotation"), true); + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("missingTypeOfClassMember"), false); + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("missingMember")); + checkDecodedEqualsEncoded(AnnotationTestInput.class.getDeclaredMethod("changeTypeOfMember"), false); + } + + private void checkDecodedEqualsEncoded(AnnotatedElement annotated) { + checkDecodedEqualsEncoded(annotated, false); + } + + private void checkDecodedEqualsEncoded(AnnotatedElement annotated, boolean expectNCDFE) { + Annotation[] annotations = getAnnotations(annotated, expectNCDFE); + if (annotations == null) { + return; + } + + byte[] encoded = VMSupport.encodeAnnotations(List.of(annotations)); + MyDecoder decoder = new MyDecoder(); + List decoded = VMSupport.decodeAnnotations(encoded, decoder); + int i = 0; + for (AnnotationConst actual : decoded) { + AnnotationConst expect = new AnnotationConst(annotations[i]); + checkEquals(actual, expect); + checkEquals(actual.toString(), expect.toString()); + i++; + } + } + + private static Annotation[] getAnnotations(AnnotatedElement annotated, boolean expectNCDFE) throws AssertionError { + try { + Annotation[] annotations = annotated.getAnnotations(); + Assert.assertFalse(expectNCDFE, annotated.toString()); + return annotations; + } catch (NoClassDefFoundError e) { + if (!expectNCDFE) { + throw new AssertionError(annotated.toString(), e); + } + return null; + } + } + + private static void checkEquals(Object actual, Object expect) { + if (!actual.equals(expect)) { + throw new AssertionError(String.format("actual != expect%nactual: %s%n%nexpect: %s", actual, expect)); + } + } + + public static final class AnnotationConst { + final Class type; + final Map elements; + + AnnotationConst(Class type, Map.Entry[] elements) { + this.type = type; + this.elements = Map.ofEntries(elements); + } + + AnnotationConst(Annotation a) { + Map values = AnnotationSupport.memberValues(a); + this.type = a.annotationType(); + Map.Entry[] elements = new Map.Entry[values.size()]; + int i = 0; + for (Map.Entry e : values.entrySet()) { + elements[i++] = Map.entry(e.getKey(), decodeValue(e.getValue())); + } + this.elements = Map.ofEntries(elements); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AnnotationConst) { + AnnotationConst that = (AnnotationConst) obj; + return this.type.equals(that.type) && + this.elements.equals(that.elements); + } + return false; + } + + @Override + public String toString() { + return "@" + type.getName() + "(" + elements + ")"; + } + + private Object decodeValue(Object value) { + Class valueType = value.getClass(); + if (value instanceof Enum) { + return new EnumConst(valueType, ((Enum) value).name()); + } else if (value instanceof Annotation) { + return new AnnotationConst((Annotation) value); + } else if (valueType.isArray()) { + int len = Array.getLength(value); + Object[] arr = new Object[len]; + for (int i = 0; i < len; i++) { + arr[i] = decodeValue(Array.get(value, i)); + } + return List.of(arr); + } else if (value instanceof ExceptionProxy) { + return new ErrorConst(value.toString()); + } else { + return value; + } + } + + public Class getType() { + return type; + } + } + + public static final class ErrorConst { + final String desc; + public ErrorConst(String desc) { + this.desc = Objects.requireNonNull(desc); + } + + @Override + public String toString() { + return desc; + } + + @Override + public int hashCode() { + return desc.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ErrorConst) { + return ((ErrorConst) obj).desc.equals(desc); + } + return false; + } + } + + public static final class EnumConst { + final Class type; + final String name; + + public EnumConst(Class type, String name) { + this.type = type; + this.name = name; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof EnumConst) { + EnumConst that = (EnumConst) obj; + return this.type.equals(that.type) && + this.name.equals(that.name); + } + return false; + } + + @Override + public String toString() { + return type.getName() + "." + name; + } + + public Class getEnumType() { + return type; + } + + public String getName() { + return name; + } + } + + static class MyDecoder implements AnnotationDecoder, AnnotationConst, EnumConst, ErrorConst> { + @Override + public Class resolveType(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + @Override + public AnnotationConst newAnnotation(Class type, Map.Entry[] elements) { + return new AnnotationConst(type, elements); + } + + @Override + public EnumConst newEnumValue(Class enumType, String name) { + return new EnumConst(enumType, name); + } + + @Override + public ErrorConst newErrorValue(String description) { + return new ErrorConst(description); + } + } +} diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java new file mode 100644 index 00000000000..c27eca83229 --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberDeleted.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface MemberDeleted { + String value(); + int retained(); +} diff --git a/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java new file mode 100644 index 00000000000..b0518582166 --- /dev/null +++ b/test/jdk/jdk/internal/vm/AnnotationEncodingDecoding/alt/MemberTypeChanged.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm.test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface MemberTypeChanged { + String value(); + int retained(); + String any(); +} diff --git a/test/jdk/jdk/internal/vm/TestTranslatedException.java b/test/jdk/jdk/internal/vm/TestTranslatedException.java index 91dab187110..335f71ccf3a 100644 --- a/test/jdk/jdk/internal/vm/TestTranslatedException.java +++ b/test/jdk/jdk/internal/vm/TestTranslatedException.java @@ -58,15 +58,6 @@ public class TestTranslatedException { } encodeDecode(throwable); } - @SuppressWarnings("unchecked") - @Test - public void encodeDecodeTest2() throws Exception { - Throwable throwable = new ExceptionInInitializerError(new InvocationTargetException(new Untranslatable("test exception", new NullPointerException()), "invoke")); - for (int i = 0; i < 10; i++) { - throwable = new ExceptionInInitializerError(new InvocationTargetException(new RuntimeException(String.valueOf(i), throwable), "invoke")); - } - encodeDecode(throwable); - } private void encodeDecode(Throwable throwable) throws Exception { Unsafe unsafe = Unsafe.getUnsafe(); From 85de01e67638cf1356d5ad08ebd4a630df6bae03 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Wed, 19 Apr 2023 16:04:58 +0000 Subject: [PATCH 049/288] 8306323: Update license files in CLDR v43 Reviewed-by: lancea, srl, iris --- .../cldr/{unicode-license.txt => LICENSE.txt} | 0 src/java.base/share/legal/cldr.md | 94 ++++++++++--------- src/jdk.localedata/share/legal/cldr.md | 94 ++++++++++--------- 3 files changed, 98 insertions(+), 90 deletions(-) rename make/data/cldr/{unicode-license.txt => LICENSE.txt} (100%) diff --git a/make/data/cldr/unicode-license.txt b/make/data/cldr/LICENSE.txt similarity index 100% rename from make/data/cldr/unicode-license.txt rename to make/data/cldr/LICENSE.txt diff --git a/src/java.base/share/legal/cldr.md b/src/java.base/share/legal/cldr.md index 1660bd5d0cd..1c43d1af35f 100644 --- a/src/java.base/share/legal/cldr.md +++ b/src/java.base/share/legal/cldr.md @@ -6,8 +6,8 @@ UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE -See Terms of Use for definitions of Unicode Inc.'s -Data Files and Software. +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S @@ -52,54 +52,58 @@ use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. + ------------------------------------------------------------ Terms of Use --------------------------------------------------------------- -Unicode® Copyright and Terms of Use -For the general privacy policy governing access to this site, see the Unicode Privacy Policy. -Unicode Copyright -Copyright © 1991-2022 Unicode, Inc. All rights reserved. -Definitions -Unicode Data Files ("DATA FILES") include all data files under the directories: -https://www.unicode.org/Public/ -https://www.unicode.org/reports/ -https://www.unicode.org/ivd/data/ + Unicode® Copyright and Terms of Use -Unicode Data Files do not include PDF online code charts under the directory: -https://www.unicode.org/Public/ + For the general privacy policy governing access to this site, see the Unicode Privacy Policy. -Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard -or any source code or compiled code under the directories: -https://www.unicode.org/Public/PROGRAMS/ -https://www.unicode.org/Public/cldr/ -http://site.icu-project.org/download/ -Terms of Use -Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. -Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. -Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. -Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. -The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. -All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. -No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. -Modification is not permitted with respect to this document. All copies of this document must be verbatim. -Restricted Rights Legend -Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. -Warranties and Disclaimers -This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. -If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. -EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. -Waiver of Damages -In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. -Trademarks & Logos -The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. -The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. -All third party trademarks referenced herein are the property of their respective owners. -Miscellaneous -Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. -Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. -Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. -Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. -Entire Agreement. This Agreement constitutes the entire agreement between the parties. + Unicode Copyright + Copyright © 1991-2023 Unicode, Inc. All rights reserved. + Definitions + Unicode Data Files ("DATA FILES") include all data files under the directories: + https://www.unicode.org/Public/ + https://www.unicode.org/reports/ + https://www.unicode.org/ivd/data/ + + Unicode Data Files do not include PDF online code charts under the directory: + https://www.unicode.org/Public/ + + Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard + or any source code or compiled code under the directories: + https://www.unicode.org/Public/PROGRAMS/ + https://www.unicode.org/Public/cldr/ + http://site.icu-project.org/download/ + + Terms of Use + Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. + Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. + Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. + Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. + The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. + All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. + No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. + Modification is not permitted with respect to this document. All copies of this document must be verbatim. + Restricted Rights Legend + Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. + Warranties and Disclaimers + This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. + If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. + EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. + Waiver of Damages + In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. + Trademarks & Logos + The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. + The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. + All third party trademarks referenced herein are the property of their respective owners. + Miscellaneous + Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. + Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. + Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. + Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. + Entire Agreement. This Agreement constitutes the entire agreement between the parties. ``` diff --git a/src/jdk.localedata/share/legal/cldr.md b/src/jdk.localedata/share/legal/cldr.md index 1660bd5d0cd..1c43d1af35f 100644 --- a/src/jdk.localedata/share/legal/cldr.md +++ b/src/jdk.localedata/share/legal/cldr.md @@ -6,8 +6,8 @@ UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE -See Terms of Use for definitions of Unicode Inc.'s -Data Files and Software. +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S @@ -52,54 +52,58 @@ use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. + ------------------------------------------------------------ Terms of Use --------------------------------------------------------------- -Unicode® Copyright and Terms of Use -For the general privacy policy governing access to this site, see the Unicode Privacy Policy. -Unicode Copyright -Copyright © 1991-2022 Unicode, Inc. All rights reserved. -Definitions -Unicode Data Files ("DATA FILES") include all data files under the directories: -https://www.unicode.org/Public/ -https://www.unicode.org/reports/ -https://www.unicode.org/ivd/data/ + Unicode® Copyright and Terms of Use -Unicode Data Files do not include PDF online code charts under the directory: -https://www.unicode.org/Public/ + For the general privacy policy governing access to this site, see the Unicode Privacy Policy. -Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard -or any source code or compiled code under the directories: -https://www.unicode.org/Public/PROGRAMS/ -https://www.unicode.org/Public/cldr/ -http://site.icu-project.org/download/ -Terms of Use -Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. -Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. -Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. -Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. -The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. -All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. -No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. -Modification is not permitted with respect to this document. All copies of this document must be verbatim. -Restricted Rights Legend -Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. -Warranties and Disclaimers -This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. -If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. -EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. -Waiver of Damages -In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. -Trademarks & Logos -The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. -The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. -All third party trademarks referenced herein are the property of their respective owners. -Miscellaneous -Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. -Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. -Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. -Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. -Entire Agreement. This Agreement constitutes the entire agreement between the parties. + Unicode Copyright + Copyright © 1991-2023 Unicode, Inc. All rights reserved. + Definitions + Unicode Data Files ("DATA FILES") include all data files under the directories: + https://www.unicode.org/Public/ + https://www.unicode.org/reports/ + https://www.unicode.org/ivd/data/ + + Unicode Data Files do not include PDF online code charts under the directory: + https://www.unicode.org/Public/ + + Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard + or any source code or compiled code under the directories: + https://www.unicode.org/Public/PROGRAMS/ + https://www.unicode.org/Public/cldr/ + http://site.icu-project.org/download/ + + Terms of Use + Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. + Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. + Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. + Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. + The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. + All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. + No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. + Modification is not permitted with respect to this document. All copies of this document must be verbatim. + Restricted Rights Legend + Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. + Warranties and Disclaimers + This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. + If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. + EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. + Waiver of Damages + In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. + Trademarks & Logos + The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. + The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. + All third party trademarks referenced herein are the property of their respective owners. + Miscellaneous + Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. + Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. + Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. + Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. + Entire Agreement. This Agreement constitutes the entire agreement between the parties. ``` From 4ad3ac6317f6fc95fdf0340885d4099e785132ad Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Wed, 19 Apr 2023 16:56:00 +0000 Subject: [PATCH 050/288] 8306135: Clean up and open source some AWT tests Reviewed-by: azvegint --- .../awt/Cursor/SingleColorCursorTest.java | 78 ++++++++ .../java/awt/Dialog/ComponentShownEvent.java | 93 +++++++++ .../Dialog/DialogAsParentOfFileDialog.java | 189 ++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 test/jdk/java/awt/Cursor/SingleColorCursorTest.java create mode 100644 test/jdk/java/awt/Dialog/ComponentShownEvent.java create mode 100644 test/jdk/java/awt/Dialog/DialogAsParentOfFileDialog.java diff --git a/test/jdk/java/awt/Cursor/SingleColorCursorTest.java b/test/jdk/java/awt/Cursor/SingleColorCursorTest.java new file mode 100644 index 00000000000..a35b13606dd --- /dev/null +++ b/test/jdk/java/awt/Cursor/SingleColorCursorTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4653170 + @summary Make sure setCursor does not produce Arithmetic Exception. + @key headful + @run main SingleColorCursorTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Cursor; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; + +public class SingleColorCursorTest extends Panel { + public void init() { + setLayout (new BorderLayout()); + setSize (200,200); + add(new Button("JButton")); + } + + public void start () { + Cursor singleColorCursor = Toolkit.getDefaultToolkit() + .createCustomCursor(new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY), + new Point(0,0), "Single Color Cursor"); + try { + setCursor(singleColorCursor); + } catch (ArithmeticException ae) { + throw new RuntimeException("Setting a 1x1 custom cursor causes arithmetic exception"); + } + } + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(() -> { + Frame frame = new Frame("Test window"); + try { + SingleColorCursorTest test = new SingleColorCursorTest(); + test.init(); + frame.add(test); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + test.start(); + frame.setVisible(false); + } finally { + frame.dispose(); + } + }); + } +} diff --git a/test/jdk/java/awt/Dialog/ComponentShownEvent.java b/test/jdk/java/awt/Dialog/ComponentShownEvent.java new file mode 100644 index 00000000000..ab1763f719d --- /dev/null +++ b/test/jdk/java/awt/Dialog/ComponentShownEvent.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4274360 + @summary Ensures that Dialogs receive COMPONENT_SHOWN events + @key headful + @run main ComponentShownEvent +*/ + +import java.awt.AWTException; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.lang.reflect.InvocationTargetException; + +public class ComponentShownEvent { + + volatile boolean componentShown = false; + Frame f; + Dialog d; + + public void start() throws InterruptedException, + InvocationTargetException, AWTException { + Robot robot = new Robot(); + try { + EventQueue.invokeAndWait(() -> { + f = new Frame(); + d = new Dialog(f); + + d.addComponentListener(new ComponentAdapter() { + public void componentShown(ComponentEvent e) { + componentShown = true; + } + }); + + f.setSize(100, 100); + f.setLocationRelativeTo(null); + f.setVisible(true); + d.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + + if (!componentShown) { + throw new RuntimeException("test failed"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (d != null) { + d.setVisible(false); + d.dispose(); + } + if (f != null) { + f.setVisible(false); + f.dispose(); + } + }); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + ComponentShownEvent test = new ComponentShownEvent(); + test.start(); + System.out.println("test passed"); + } +} diff --git a/test/jdk/java/awt/Dialog/DialogAsParentOfFileDialog.java b/test/jdk/java/awt/Dialog/DialogAsParentOfFileDialog.java new file mode 100644 index 00000000000..c4ff95e8b59 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogAsParentOfFileDialog.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4221123 + @summary Why Dialog can't be an owner of FileDialog? + @key headful + @run main DialogAsParentOfFileDialog +*/ + +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class DialogAsParentOfFileDialog { + FileDialog fdialog; + + public void start () { + StringBuilder errors = new StringBuilder(); + String nl = System.lineSeparator(); + Dialog dlg; + String title; + int mode; + boolean passed; + + System.out.println("DialogAsParentOfFileDialog"); + + /* + * public FileDialog(Dialog parent), + * checks owner and default settings. + */ + System.out.print("\ttest 01: "); + dlg = new Dialog(new Frame()); + fdialog = new FileDialog(dlg); + passed = + fdialog.getOwner() == dlg + && fdialog.isModal() + && fdialog.getTitle().equals("") + && fdialog.getMode() == FileDialog.LOAD + && fdialog.getFile() == null + && fdialog.getDirectory() == null + && fdialog.getFilenameFilter() == null; + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + /* + * public FileDialog(Dialog parent, String title), + * checks owner, title and default settings. + */ + System.out.print("\ttest 02: "); + dlg = new Dialog(new Frame()); + title = "Title"; + fdialog = new FileDialog(dlg, title); + passed = + fdialog.getOwner() == dlg + && fdialog.isModal() + && fdialog.getTitle().equals(title) + && fdialog.getMode() == FileDialog.LOAD + && fdialog.getFile() == null + && fdialog.getDirectory() == null + && fdialog.getFilenameFilter() == null; + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + /* + * public FileDialog(Dialog parent, String title), + * title: null. + * expected results: FileDialog object with a null title + */ + System.out.print("\ttest 03: "); + dlg = new Dialog(new Frame()); + title = null; + fdialog = new FileDialog(dlg, title); + passed = + fdialog.getOwner() == dlg + && (fdialog.getTitle() == null + || fdialog.getTitle().equals("")); + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + /* + * public FileDialog(Dialog parent, String title, int mode), + * checks owner, title and mode. + */ + dlg = new Dialog(new Frame()); + title = "Title"; + + System.out.print("\ttest 04: "); + mode = FileDialog.SAVE; + fdialog = new FileDialog(dlg, title, mode); + passed = + fdialog.getOwner() == dlg + && fdialog.isModal() + && fdialog.getTitle().equals(title) + && fdialog.getMode() == mode + && fdialog.getFile() == null + && fdialog.getDirectory() == null + && fdialog.getFilenameFilter() == null; + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + System.out.print("\ttest 05: "); + mode = FileDialog.LOAD; + fdialog = new FileDialog(dlg, title, mode); + passed = + fdialog.getOwner() == dlg + && fdialog.isModal() + && fdialog.getTitle().equals(title) + && fdialog.getMode() == mode + && fdialog.getFile() == null + && fdialog.getDirectory() == null + && fdialog.getFilenameFilter() == null; + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + /* + * public FileDialog(Dialog parent, String title, int mode), + * mode: Integer.MIN_VALUE, Integer.MIN_VALUE+1, + * Integer.MAX_VALUE-1, Integer.MAX_VALUE + * expected results: IllegalArgumentException should be thrown + */ + System.out.print("\ttest 06: "); + dlg = new Dialog(new Frame()); + title = "Title"; + int[] modes = {Integer.MIN_VALUE, Integer.MIN_VALUE+1, + Integer.MAX_VALUE-1, Integer.MAX_VALUE}; + passed = true; + for (int i = 0; i < modes.length; i++) { + try { + fdialog = new FileDialog(dlg, title, modes[i]); + passed = false; + } catch (IllegalArgumentException e) {} + } + System.out.println(passed ? "passed" : "FAILED"); + if (!passed) { + errors.append(nl); + errors.append("DialogAsParentOfFileDialog FAILED"); + } + + if (!errors.isEmpty()) { + throw new RuntimeException("Following tests failed:" + errors); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + new DialogAsParentOfFileDialog().start(); + }); + } +} From fdb4bafa3142cedeb9eb3cb930890e97b35402de Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 19 Apr 2023 17:37:16 +0000 Subject: [PATCH 051/288] 8306134: Open source some AWT tests relating to Button and a few other classes Reviewed-by: azvegint --- .../ArrayStoreException.java | 51 +++ .../java/awt/AWTKeyStroke/ToStringTest.java | 323 ++++++++++++++++++ .../BorderLayout/NullConstraintsReturns.java | 42 +++ .../java/awt/Button/ButtonNullLabelTest.java | 94 +++++ .../java/awt/Button/DisabledButtonPress.java | 117 +++++++ .../awt/Button/DoubleActionEventTest.java | 112 ++++++ 6 files changed, 739 insertions(+) create mode 100644 test/jdk/java/awt/AWTEventMulticaster/ArrayStoreException.java create mode 100644 test/jdk/java/awt/AWTKeyStroke/ToStringTest.java create mode 100644 test/jdk/java/awt/BorderLayout/NullConstraintsReturns.java create mode 100644 test/jdk/java/awt/Button/ButtonNullLabelTest.java create mode 100644 test/jdk/java/awt/Button/DisabledButtonPress.java create mode 100644 test/jdk/java/awt/Button/DoubleActionEventTest.java diff --git a/test/jdk/java/awt/AWTEventMulticaster/ArrayStoreException.java b/test/jdk/java/awt/AWTEventMulticaster/ArrayStoreException.java new file mode 100644 index 00000000000..bb61fc13ad7 --- /dev/null +++ b/test/jdk/java/awt/AWTEventMulticaster/ArrayStoreException.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4513402 + @summary AWTEventMulticaster.getListeners throws unexpected ArrayStoreException +*/ + +import java.awt.AWTEventMulticaster; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentListener; +import java.awt.event.FocusListener; + +public class ArrayStoreException { + + public static void main(String[] args) throws Exception { + + ComponentListener mc = + AWTEventMulticaster.add( + new ComponentAdapter() {}, + new ComponentAdapter() {}); + + if (AWTEventMulticaster.getListeners(mc, FocusListener.class).length == 0) { + System.out.println("OKAY"); + } else { + System.out.println("empty array expected"); + throw new RuntimeException("Test failed"); + } + } +} diff --git a/test/jdk/java/awt/AWTKeyStroke/ToStringTest.java b/test/jdk/java/awt/AWTKeyStroke/ToStringTest.java new file mode 100644 index 00000000000..14d72f7e242 --- /dev/null +++ b/test/jdk/java/awt/AWTKeyStroke/ToStringTest.java @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4370733 + @summary AWTKeyStroke's getAWTKeyStroke(String) and toString() method aren't symmetric +*/ + +import java.awt.AWTKeyStroke; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.KeyStroke; + +public class ToStringTest { + + /* Note this test is deliberately testing the deprecated constants + * as well as their replacements. + */ + @SuppressWarnings("deprecation") + public static final int[] modifiers = { + 0, + InputEvent.SHIFT_MASK, + InputEvent.CTRL_MASK, + InputEvent.META_MASK, + InputEvent.ALT_MASK, + InputEvent.ALT_GRAPH_MASK, + InputEvent.BUTTON1_MASK, + InputEvent.BUTTON2_MASK, + InputEvent.BUTTON3_MASK, + InputEvent.SHIFT_DOWN_MASK, + InputEvent.CTRL_DOWN_MASK, + InputEvent.META_DOWN_MASK, + InputEvent.ALT_DOWN_MASK, + InputEvent.BUTTON1_DOWN_MASK, + InputEvent.BUTTON2_DOWN_MASK, + InputEvent.BUTTON3_DOWN_MASK, + InputEvent.ALT_GRAPH_DOWN_MASK + }; + + public static final int[] keys = { + KeyEvent.VK_A, + KeyEvent.VK_B, + KeyEvent.VK_C, + KeyEvent.VK_D, + KeyEvent.VK_E, + KeyEvent.VK_F, + KeyEvent.VK_G, + KeyEvent.VK_H, + KeyEvent.VK_I, + KeyEvent.VK_J, + KeyEvent.VK_K, + KeyEvent.VK_L, + KeyEvent.VK_M, + KeyEvent.VK_N, + KeyEvent.VK_O, + KeyEvent.VK_P, + KeyEvent.VK_Q, + KeyEvent.VK_R, + KeyEvent.VK_S, + KeyEvent.VK_T, + KeyEvent.VK_U, + KeyEvent.VK_V, + KeyEvent.VK_W, + KeyEvent.VK_X, + KeyEvent.VK_Y, + KeyEvent.VK_Z, + KeyEvent.VK_0, + KeyEvent.VK_1, + KeyEvent.VK_2, + KeyEvent.VK_3, + KeyEvent.VK_4, + KeyEvent.VK_5, + KeyEvent.VK_6, + KeyEvent.VK_7, + KeyEvent.VK_8, + KeyEvent.VK_9, + + KeyEvent.VK_COMMA, + KeyEvent.VK_PERIOD, + KeyEvent.VK_SLASH, + KeyEvent.VK_SEMICOLON, + KeyEvent.VK_EQUALS, + KeyEvent.VK_OPEN_BRACKET, + KeyEvent.VK_BACK_SLASH, + KeyEvent.VK_CLOSE_BRACKET, + + KeyEvent.VK_ENTER, + KeyEvent.VK_BACK_SPACE, + KeyEvent.VK_TAB, + KeyEvent.VK_CANCEL, + KeyEvent.VK_CLEAR, + KeyEvent.VK_SHIFT, + KeyEvent.VK_CONTROL, + KeyEvent.VK_ALT, + KeyEvent.VK_PAUSE, + KeyEvent.VK_CAPS_LOCK, + KeyEvent.VK_ESCAPE, + KeyEvent.VK_SPACE, + KeyEvent.VK_PAGE_UP, + KeyEvent.VK_PAGE_DOWN, + KeyEvent.VK_END, + KeyEvent.VK_HOME, + KeyEvent.VK_LEFT, + KeyEvent.VK_UP, + KeyEvent.VK_RIGHT, + KeyEvent.VK_DOWN, + KeyEvent.VK_ADD, + KeyEvent.VK_SEPARATOR, + KeyEvent.VK_SUBTRACT, + KeyEvent.VK_DECIMAL, + KeyEvent.VK_DIVIDE, + KeyEvent.VK_DELETE, + KeyEvent.VK_NUM_LOCK, + KeyEvent.VK_SCROLL_LOCK, + + KeyEvent.VK_WINDOWS, + KeyEvent.VK_CONTEXT_MENU, + + KeyEvent.VK_F1, + KeyEvent.VK_F2, + KeyEvent.VK_F3, + KeyEvent.VK_F4, + KeyEvent.VK_F5, + KeyEvent.VK_F6, + KeyEvent.VK_F7, + KeyEvent.VK_F8, + KeyEvent.VK_F9, + KeyEvent.VK_F10, + KeyEvent.VK_F11, + KeyEvent.VK_F12, + KeyEvent.VK_F13, + KeyEvent.VK_F14, + KeyEvent.VK_F15, + KeyEvent.VK_F16, + KeyEvent.VK_F17, + KeyEvent.VK_F18, + KeyEvent.VK_F19, + KeyEvent.VK_F20, + KeyEvent.VK_F21, + KeyEvent.VK_F22, + KeyEvent.VK_F23, + KeyEvent.VK_F24, + + KeyEvent.VK_PRINTSCREEN, + KeyEvent.VK_INSERT, + KeyEvent.VK_HELP, + KeyEvent.VK_META, + KeyEvent.VK_BACK_QUOTE, + KeyEvent.VK_QUOTE, + + KeyEvent.VK_KP_UP, + KeyEvent.VK_KP_DOWN, + KeyEvent.VK_KP_LEFT, + KeyEvent.VK_KP_RIGHT, + + KeyEvent.VK_DEAD_GRAVE, + KeyEvent.VK_DEAD_ACUTE, + KeyEvent.VK_DEAD_CIRCUMFLEX, + KeyEvent.VK_DEAD_TILDE, + KeyEvent.VK_DEAD_MACRON, + KeyEvent.VK_DEAD_BREVE, + KeyEvent.VK_DEAD_ABOVEDOT, + KeyEvent.VK_DEAD_DIAERESIS, + KeyEvent.VK_DEAD_ABOVERING, + KeyEvent.VK_DEAD_DOUBLEACUTE, + KeyEvent.VK_DEAD_CARON, + KeyEvent.VK_DEAD_CEDILLA, + KeyEvent.VK_DEAD_OGONEK, + KeyEvent.VK_DEAD_IOTA, + KeyEvent.VK_DEAD_VOICED_SOUND, + KeyEvent.VK_DEAD_SEMIVOICED_SOUND, + + KeyEvent.VK_AMPERSAND, + KeyEvent.VK_ASTERISK, + KeyEvent.VK_QUOTEDBL, + KeyEvent.VK_LESS, + KeyEvent.VK_GREATER, + KeyEvent.VK_BRACELEFT, + KeyEvent.VK_BRACERIGHT, + KeyEvent.VK_AT, + KeyEvent.VK_COLON, + KeyEvent.VK_CIRCUMFLEX, + KeyEvent.VK_DOLLAR, + KeyEvent.VK_EURO_SIGN, + KeyEvent.VK_EXCLAMATION_MARK, + KeyEvent.VK_INVERTED_EXCLAMATION_MARK, + KeyEvent.VK_LEFT_PARENTHESIS, + KeyEvent.VK_NUMBER_SIGN, + KeyEvent.VK_MINUS, + KeyEvent.VK_PLUS, + KeyEvent.VK_RIGHT_PARENTHESIS, + KeyEvent.VK_UNDERSCORE, + + KeyEvent.VK_FINAL, + KeyEvent.VK_CONVERT, + KeyEvent.VK_NONCONVERT, + KeyEvent.VK_ACCEPT, + KeyEvent.VK_MODECHANGE, + KeyEvent.VK_KANA, + KeyEvent.VK_KANJI, + KeyEvent.VK_ALPHANUMERIC, + KeyEvent.VK_KATAKANA, + KeyEvent.VK_HIRAGANA, + KeyEvent.VK_FULL_WIDTH, + KeyEvent.VK_HALF_WIDTH, + KeyEvent.VK_ROMAN_CHARACTERS, + KeyEvent.VK_ALL_CANDIDATES, + KeyEvent.VK_PREVIOUS_CANDIDATE, + KeyEvent.VK_CODE_INPUT, + KeyEvent.VK_JAPANESE_KATAKANA, + KeyEvent.VK_JAPANESE_HIRAGANA, + KeyEvent.VK_JAPANESE_ROMAN, + KeyEvent.VK_KANA_LOCK, + KeyEvent.VK_INPUT_METHOD_ON_OFF, + + KeyEvent.VK_AGAIN, + KeyEvent.VK_UNDO, + KeyEvent.VK_COPY, + KeyEvent.VK_PASTE, + KeyEvent.VK_CUT, + KeyEvent.VK_FIND, + KeyEvent.VK_PROPS, + KeyEvent.VK_STOP, + + KeyEvent.VK_COMPOSE, + KeyEvent.VK_ALT_GRAPH, + KeyEvent.VK_BEGIN, + + KeyEvent.VK_NUMPAD0, + KeyEvent.VK_NUMPAD1, + KeyEvent.VK_NUMPAD2, + KeyEvent.VK_NUMPAD3, + KeyEvent.VK_NUMPAD4, + KeyEvent.VK_NUMPAD5, + KeyEvent.VK_NUMPAD6, + KeyEvent.VK_NUMPAD7, + KeyEvent.VK_NUMPAD8, + KeyEvent.VK_NUMPAD9 + }; + + public static void main(String[] args) throws Exception { + + System.err.println("**** Testing AWTKeyStrokes"); + for (int n_key=0; n_key < keys.length; n_key++) { + for (int n_mod=0; n_mod < modifiers.length; n_mod++) { + checkStroke(AWTKeyStroke.getAWTKeyStroke(keys[n_key], + modifiers[n_mod], + true)); + checkStroke(AWTKeyStroke.getAWTKeyStroke(keys[n_key], + modifiers[n_mod], + false)); + } + } + + System.err.println("**** Testing Swing KeyStrokes"); + for (int n_key=0; n_key < keys.length; n_key++) { + for (int n_mod=0; n_mod < modifiers.length; n_mod++) { + checkStroke(KeyStroke.getKeyStroke(keys[n_key], + modifiers[n_mod], + true)); + checkStroke(KeyStroke.getKeyStroke(keys[n_key], + modifiers[n_mod], + false)); + } + } + + Character a = Character.valueOf('a'); + System.err.println("**** Testing KEY_TYPED AWTKeyStrokes"); + for (int n_mod = 0; n_mod < modifiers.length; n_mod++) { + checkStroke(AWTKeyStroke.getAWTKeyStroke(a, modifiers[n_mod])); + } + System.err.println("**** Testing KEY_TYPED Swing KeyStrokes"); + for (int n_mod = 0; n_mod < modifiers.length; n_mod++) { + checkStroke(KeyStroke.getKeyStroke(a, modifiers[n_mod])); + } + + System.out.println("Test passed."); + } + + public static void checkStroke(AWTKeyStroke original) { + System.err.println("AWT Original >> " + original); + AWTKeyStroke copy = AWTKeyStroke.getAWTKeyStroke(original.toString()); + // System.err.println("AWT Copy >> " + copy); + if (!original.equals(copy)) { + System.out.println("AWT bad copy for VK= 0x" + + Integer.toString(original.getKeyCode(), 16)); + throw new RuntimeException("Test Failed: for " + original); + } + } + + public static void checkStroke(KeyStroke original) { + System.err.println("Swing Original >> " + original); + KeyStroke copy = KeyStroke.getKeyStroke(original.toString()); + // System.err.println("Swing Copy >> " + copy); + if (!original.equals(copy)) { + System.out.println("Swing bad copy for VK= 0x" + + Integer.toString(original.getKeyCode(), 16)); + throw new RuntimeException("Test Failed: for " + original); + } + } + +} diff --git a/test/jdk/java/awt/BorderLayout/NullConstraintsReturns.java b/test/jdk/java/awt/BorderLayout/NullConstraintsReturns.java new file mode 100644 index 00000000000..5559636470c --- /dev/null +++ b/test/jdk/java/awt/BorderLayout/NullConstraintsReturns.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6242148 + @summary API method java.awt.BorderLayout.getConstraints(null) should return null +*/ + +import java.awt.BorderLayout; + +public class NullConstraintsReturns { + + public static void main(String[] args) { + BorderLayout bl = new BorderLayout(); + Object constraints = bl.getConstraints(null); + if (constraints != null) { + throw new RuntimeException("Test failed. Constraints is not null: " + constraints); + } + System.out.println("Test Passed."); + } +} diff --git a/test/jdk/java/awt/Button/ButtonNullLabelTest.java b/test/jdk/java/awt/Button/ButtonNullLabelTest.java new file mode 100644 index 00000000000..511512bc5de --- /dev/null +++ b/test/jdk/java/awt/Button/ButtonNullLabelTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4245382 + @summary Tests that Button.setLabel(null) does not cause NPE in Java code or VM crash + @key headful +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; + +public class ButtonNullLabelTest { + + public static void main(String args[]) throws Exception { + EventQueue.invokeAndWait(() -> runTest()); + } + + static void runTest() { + // Native code test + Frame frame = new Frame("Test null in native"); + Button button = new Button(); + try { + button.setLabel(null); + System.out.println("Set to null - test native"); + frame.add(button); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + System.out.println("Test null in native **successful**"); + } catch (NullPointerException npe) { + System.out.println("Test failed - test native"); + throw new RuntimeException("Test failed - test native"); + } finally { + frame.dispose(); + } + + // Peer code test + frame = new Frame("Test null in peer before show"); + button = new Button(); + try { + System.out.println("Set to null - test native before show"); + frame.add(button); + frame.pack(); + button.setLabel(null); + frame.setVisible(true); + System.out.println("Set null in peer before show **successful**"); + } catch (NullPointerException npe) { + System.out.println("Test failed - test peer before show"); + throw new RuntimeException("Test failed - test peer before show"); + } finally { + frame.dispose(); + } + + // Peer code test + frame = new Frame("Test null in peer after show"); + button = new Button(); + try { + System.out.println("Set to null - test peer after show"); + frame.add(button); + frame.pack(); + frame.setVisible(true); + button.setLabel(null); + System.out.println("Test null in peer after show **successful**"); + } catch (NullPointerException npe) { + System.out.println("Test failed - peer after show"); + throw new RuntimeException("Test failed - peer after show"); + } finally { + frame.dispose(); + } + } +} diff --git a/test/jdk/java/awt/Button/DisabledButtonPress.java b/test/jdk/java/awt/Button/DisabledButtonPress.java new file mode 100644 index 00000000000..aab1573bed8 --- /dev/null +++ b/test/jdk/java/awt/Button/DisabledButtonPress.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5044469 + @summary REG: Disabled component gains focus and receives keyevents on win32 + @key headful +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; + +public class DisabledButtonPress implements ActionListener, FocusListener { + + public static void main(String[] args) throws Exception { + try { + DisabledButtonPress test = new DisabledButtonPress(); + EventQueue.invokeAndWait(() -> test.createUI()); + runTest(); + } finally { + if (f != null) { + f.dispose(); + } + } + if (!testPassed) { + throw new RuntimeException("Test Failed."); + } + } + + final static Object FOCUS_LOCK = new Object(); + final static Object ACTION_LOCK = new Object(); + static volatile Frame f; + static volatile Button b2; + static volatile boolean testPassed = true; + + public void createUI() { + f = new Frame("DisabledButtonPress"); + b2 = new Button("Click Me"); + b2.addActionListener(this); + b2.addFocusListener(this); + f.add(b2); + f.pack(); + f.setVisible(true); + } + + static void runTest() throws Exception { + + Robot robot = new Robot(); + robot.delay(500); + System.out.println("Requesting focus"); + System.out.println(" b2.requestFocusInWindow()="+ b2.requestFocusInWindow()); + b2.setEnabled(false); + synchronized(FOCUS_LOCK) { + FOCUS_LOCK.wait(3000); + } + if (!b2.isFocusOwner()) { + throw new RuntimeException("Test failed. Button doesn't have a focus."); + } + System.out.println("Button disabling"); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_SPACE); + robot.delay(10); + robot.keyRelease(KeyEvent.VK_SPACE); + synchronized(ACTION_LOCK) { + ACTION_LOCK.wait(2000); //give time to handle + // ACTION_PERFORMED event from the Button if it was generated + } + } + + public void focusGained(FocusEvent ae) { + System.out.println("Button got focus"); + synchronized(FOCUS_LOCK) { + FOCUS_LOCK.notify(); + } + } + + public void focusLost(FocusEvent ae) {} + + public void actionPerformed(ActionEvent evt) { + System.out.println("Button: " + evt.getActionCommand() + " Clicked. Event is " +evt); + if (evt.getSource() == b2) { + testPassed = false; + synchronized(ACTION_LOCK) { + ACTION_LOCK.notify(); + } + } + } +} diff --git a/test/jdk/java/awt/Button/DoubleActionEventTest.java b/test/jdk/java/awt/Button/DoubleActionEventTest.java new file mode 100644 index 00000000000..97a5638d2f4 --- /dev/null +++ b/test/jdk/java/awt/Button/DoubleActionEventTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4531849 + @summary Test that double action event no longer sent + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +public class DoubleActionEventTest implements ActionListener, WindowListener { + + static class Lock { + boolean go = false; + public synchronized boolean getGo() {return go;} + public synchronized void setGo(boolean newGo) {go = newGo;} + } + + static volatile Frame f; + static volatile int numActionEvents = 0; + static volatile Lock lock = new Lock(); + + public static void main(String[] args) throws Exception { + try { + DoubleActionEventTest test = new DoubleActionEventTest(); + EventQueue.invokeAndWait(() -> test.createUI()); + runTest(); + } finally { + if (f != null) { + f.dispose(); + } + } + } + + public void createUI() { + f = new Frame("DoubleActionEventTest"); + f.setLayout (new BorderLayout()); + f.addWindowListener(this); + Button b = new Button("Action Listening Button"); + b.addActionListener(this); + f.add(b); + f.setBounds(100, 100, 200, 200); + f.setVisible(true); + } + + static void runTest() throws Exception { + + Robot robot = new Robot(); + robot.setAutoDelay(250); + robot.setAutoWaitForIdle(true); + robot.mouseMove(200, 200); + + while (!lock.getGo()) {} + + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + + if (numActionEvents != 1) { + System.out.println("Wrong number of ActionEvents. Test FAILS."); + throw new RuntimeException("TEST FAILS"); + } + } + + public void actionPerformed(ActionEvent e) { + numActionEvents++; + System.out.println("Number of ActionEvents: " + numActionEvents); + } + + public void windowActivated(WindowEvent e) { + lock.setGo(true); + } + public void windowClosed(WindowEvent e) {} + public void windowClosing(WindowEvent e) {} + public void windowDeactivated(WindowEvent e) {} + public void windowDeiconified(WindowEvent e) {} + public void windowIconified(WindowEvent e) {} + public void windowOpened(WindowEvent e) {} + +} From ed34e7f5aeb1d38d3a26d6bbd4c69624b0662cfb Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 19 Apr 2023 18:32:48 +0000 Subject: [PATCH 052/288] 8306321: Add an accessor for the top of a PLAB Reviewed-by: shade, ysr --- src/hotspot/share/gc/shared/plab.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/share/gc/shared/plab.hpp b/src/hotspot/share/gc/shared/plab.hpp index 1be6e2e10f7..cb1a44ec167 100644 --- a/src/hotspot/share/gc/shared/plab.hpp +++ b/src/hotspot/share/gc/shared/plab.hpp @@ -138,6 +138,10 @@ public: // Fills in the unallocated portion of the buffer with a garbage object and updates // statistics. To be called during GC. void retire(); + + HeapWord* top() const { + return _top; + } }; // PLAB book-keeping. From e764e9b740509ae1262ed0a41ab0dee9c313074d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 19 Apr 2023 18:36:07 +0000 Subject: [PATCH 053/288] 8306452: Fix Amazon copyright in JDK-8305425 test Reviewed-by: simonis --- test/jdk/java/lang/Thread/IsAlive.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/lang/Thread/IsAlive.java b/test/jdk/java/lang/Thread/IsAlive.java index ffb7ca6fea5..d6594bf15b6 100644 --- a/test/jdk/java/lang/Thread/IsAlive.java +++ b/test/jdk/java/lang/Thread/IsAlive.java @@ -1,5 +1,5 @@ /* - * Copyright 2023, Amazon.com Inc. or its affiliates. All Rights Reserved. + * 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 From d03128d0e5158ea967e714341c019b9af00ac4a1 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Wed, 19 Apr 2023 18:55:13 +0000 Subject: [PATCH 054/288] 8306280: Open source several choice AWT tests Reviewed-by: jdv, prr, serb --- test/jdk/java/awt/Choice/EmptyChoiceTest.java | 85 ++++++++++ .../jdk/java/awt/Choice/InsertRemoveTest.java | 92 +++++++++++ .../java/awt/Choice/OpenedChoiceHangs.java | 145 ++++++++++++++++++ .../awt/Choice/PressOutsideOpenedChoice.java | 113 ++++++++++++++ 4 files changed, 435 insertions(+) create mode 100644 test/jdk/java/awt/Choice/EmptyChoiceTest.java create mode 100644 test/jdk/java/awt/Choice/InsertRemoveTest.java create mode 100644 test/jdk/java/awt/Choice/OpenedChoiceHangs.java create mode 100644 test/jdk/java/awt/Choice/PressOutsideOpenedChoice.java diff --git a/test/jdk/java/awt/Choice/EmptyChoiceTest.java b/test/jdk/java/awt/Choice/EmptyChoiceTest.java new file mode 100644 index 00000000000..cf799979acf --- /dev/null +++ b/test/jdk/java/awt/Choice/EmptyChoiceTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4908468 + @summary Linux Empty Choice throws NPE + @key headful + @run main EmptyChoiceTest +*/ +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.lang.reflect.InvocationTargetException; + +public class EmptyChoiceTest +{ + Frame frame; + Choice choice = null; + + public static void main(String[] args) throws + InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + EmptyChoiceTest emptyChoiceTest = new EmptyChoiceTest(); + emptyChoiceTest.init(); + emptyChoiceTest.test(); + }); + } + + public void init() { + frame = new Frame(); + frame.setLayout(new BorderLayout()); + choice = new Choice(); + frame.add(choice, BorderLayout.NORTH); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void test () { + try { + int iWidth = choice.getWidth(); + int iHeight = choice.getHeight(); + Image componentImage = + choice.createImage(iWidth, iHeight); + Graphics graphics = + componentImage.getGraphics(); + graphics.setClip(0, 0, iWidth, iHeight); + choice.printAll(graphics); + System.out.println("PrintAll successful!"); + } catch (NullPointerException exp) { + throw new RuntimeException("Test failed. " + + "Empty Choice printAll throws NullPointerException"); + } catch (Exception exc){ + throw new RuntimeException("Test failed.", exc); + } finally { + frame.dispose(); + } + } +} diff --git a/test/jdk/java/awt/Choice/InsertRemoveTest.java b/test/jdk/java/awt/Choice/InsertRemoveTest.java new file mode 100644 index 00000000000..37c2f15f65a --- /dev/null +++ b/test/jdk/java/awt/Choice/InsertRemoveTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4115130 + @summary Tests Inserting/Removing items doesn't cause crash. + @key headful + @run main InsertRemoveTest + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class InsertRemoveTest { + Choice choice1; + Choice choice2; + Choice choice3; + Frame f; + int itemCount = 0; + int iterCount = 0; + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(() -> new InsertRemoveTest().start()); + } + + public void start() { + f = new Frame("Check Choice"); + f.setLayout(new BorderLayout()); + + choice1 = new Choice(); + choice2 = new Choice(); + choice3 = new Choice(); + + f.add(choice1, BorderLayout.NORTH); + f.add(choice3, BorderLayout.CENTER); + f.add(choice2, BorderLayout.SOUTH); + + f.pack(); + f.setLocationRelativeTo(null); + f.setVisible(true); + + try { + for (int i = 0; i < 50; i++) { + if (choice1 != null && itemCount < 40) { + choice1.insert("I am Choice, yes I am : " + iterCount, + 0); + choice2.add("I am the same, yes I am : " + iterCount); + choice3.insert("I am the same, yes I am : " + iterCount, + 10); + itemCount++; + iterCount++; + } + if (itemCount >= 20 && choice1 != null + && choice1.getItemCount() > 0) { + choice1.remove(0); + choice2.remove(10); + choice3.remove(19); + itemCount--; + } + f.validate(); + } + } finally { + f.dispose(); + } + } + +} diff --git a/test/jdk/java/awt/Choice/OpenedChoiceHangs.java b/test/jdk/java/awt/Choice/OpenedChoiceHangs.java new file mode 100644 index 00000000000..cd053918362 --- /dev/null +++ b/test/jdk/java/awt/Choice/OpenedChoiceHangs.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6246503 + @summary Disabling a choice after selection locks keyboard, \ + mouse and makes the system unusable + @key headful + @run main OpenedChoiceHangs +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class OpenedChoiceHangs implements ItemListener { + static final Object FOCUS_LOCK = new Object(); + + Frame frame; + Choice ch = new Choice(); + Button b = new Button("A button"); + Robot robot; + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + OpenedChoiceHangs openedChoiceHangs = new OpenedChoiceHangs(); + EventQueue.invokeAndWait(openedChoiceHangs::init); + openedChoiceHangs.test(); + } + + public void init() { + frame = new Frame(); + + frame.setLayout(new FlowLayout()); + for (int i = 1; i < 10; i++) { + ch.add("item " + i); + } + frame.add(ch); + frame.add(b); + ch.setBackground(new Color(255, 0, 0)); + ch.setForeground(new Color(255, 0, 0)); + ch.addItemListener(this); + + frame.setSize(200, 200); + frame.setVisible(true); + frame.setLocationRelativeTo(null); + frame.validate(); + } + + public void test() { + try { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + robot.mouseMove(ch.getLocationOnScreen().x + ch.getWidth() / 2, + ch.getLocationOnScreen().y + ch.getHeight() / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + if (!ch.isFocusOwner()) { + synchronized (FOCUS_LOCK) { + FOCUS_LOCK.wait(3000); + } + } + if (!ch.isFocusOwner()){ + throw new RuntimeException( + "Test failed. Choice has no focus after mouse press."); + } + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + robot.delay(1000); + + robot.keyPress(KeyEvent.VK_UP); + robot.keyRelease(KeyEvent.VK_UP); + robot.delay(1000); + + Color color = robot.getPixelColor( + ch.getLocationOnScreen().x + ch.getWidth() / 2, + ch.getLocationOnScreen().y + ch.getHeight() * 4); + System.out.println("Color is " + color); + if (color.equals(new Color(255, 0,0))){ + throw new RuntimeException( + "Test failed. Choice is disabled and still opened. "); + } + } catch (AWTException e) { + throw new RuntimeException( + "Test interrupted due to AWTException. Robot=" + robot, e); + } catch (InterruptedException e) { + throw new RuntimeException("Test interrupted. Robot=" + robot, e); + } finally { + EventQueue.invokeLater(frame::dispose); + } + + System.out.println("Test passed: Choice became closed after disabling."); + } + + public void itemStateChanged (ItemEvent ie) { + System.out.println("Choice Item has changed: "+ie); + ch.setEnabled(false); + } + public void focusGained(FocusEvent fEvent){ + System.out.println("focusGained"+fEvent); + synchronized(FOCUS_LOCK){ + FOCUS_LOCK.notify(); + } + } + + public void focusLost(FocusEvent fEvent){ + System.out.println("focusLost"+fEvent); + } +} diff --git a/test/jdk/java/awt/Choice/PressOutsideOpenedChoice.java b/test/jdk/java/awt/Choice/PressOutsideOpenedChoice.java new file mode 100644 index 00000000000..60803e775ad --- /dev/null +++ b/test/jdk/java/awt/Choice/PressOutsideOpenedChoice.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6259328 + @summary Choice scrolls when dragging the parent frame while drop-down \ + is active + @key headful + @run main PressOutsideOpenedChoice +*/ + + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + +public class PressOutsideOpenedChoice extends Frame { + Robot robot; + Choice choice1 = new Choice(); + Point pt; + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + PressOutsideOpenedChoice pressOutsideOpenedChoice = + new PressOutsideOpenedChoice(); + EventQueue.invokeAndWait(pressOutsideOpenedChoice::init); + pressOutsideOpenedChoice.start(); + } + + public void init() { + for (int i = 1; i < 50; i++) { + choice1.add("item-" + i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + add(choice1); + setLayout(new FlowLayout()); + setSize (200,200); + setLocationRelativeTo(null); + setVisible(true); + validate(); + } + + public void start() { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(1000); + testPressOutsideOpenedChoice(InputEvent.BUTTON1_DOWN_MASK); + } catch (Throwable e) { + throw new RuntimeException("Test failed. Exception thrown: " + e); + } finally { + EventQueue.invokeLater(this::dispose); + } + } + + public void testPressOutsideOpenedChoice(int button) { + pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth() - choice1.getHeight() / 4, + pt.y + choice1.getHeight() / 2); + robot.delay(100); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + //move mouse outside of the choice + robot.mouseMove(pt.x - choice1.getWidth() / 2, + pt.y + choice1.getHeight() / 2); + robot.delay(400); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + Color color = robot.getPixelColor(pt.x + choice1.getWidth() / 2, + pt.y + 3 * choice1.getHeight()); + System.out.println("color got " + + robot.getPixelColor(pt.x + choice1.getWidth() / 2, + pt.y + 3 * choice1.getHeight())); + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice didn't close " + + "after mouse press outside of Choice " + button); + } else { + System.out.println("Test passed. " + + "Choice closed with MousePress outside"); + } + } +} From 781d6d793ad4cecb774bcbcb362c726779408ffd Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 19 Apr 2023 20:53:51 +0000 Subject: [PATCH 055/288] 8306372: Open source AWT CardLayout and Checkbox tests Reviewed-by: serb, honkar --- .../java/awt/CardLayout/CardsOrderTest.java | 69 +++++++++++++++++++ .../java/awt/CardLayout/ObedienceTest.java | 59 ++++++++++++++++ .../java/awt/Checkbox/CheckboxCrashTest.java | 56 +++++++++++++++ .../MultiCheckedCheckboxGroupTest.java | 59 ++++++++++++++++ .../awt/Checkbox/NullCheckboxGroupTest.java | 55 +++++++++++++++ .../awt/Checkbox/SetCheckboxGroupNull.java | 66 ++++++++++++++++++ 6 files changed, 364 insertions(+) create mode 100644 test/jdk/java/awt/CardLayout/CardsOrderTest.java create mode 100644 test/jdk/java/awt/CardLayout/ObedienceTest.java create mode 100644 test/jdk/java/awt/Checkbox/CheckboxCrashTest.java create mode 100644 test/jdk/java/awt/Checkbox/MultiCheckedCheckboxGroupTest.java create mode 100644 test/jdk/java/awt/Checkbox/NullCheckboxGroupTest.java create mode 100644 test/jdk/java/awt/Checkbox/SetCheckboxGroupNull.java diff --git a/test/jdk/java/awt/CardLayout/CardsOrderTest.java b/test/jdk/java/awt/CardLayout/CardsOrderTest.java new file mode 100644 index 00000000000..5ca2cff1ae1 --- /dev/null +++ b/test/jdk/java/awt/CardLayout/CardsOrderTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4689398 + @summary Inserting items in a Container with CardLayout does not work since Merlin +*/ + +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Container; + +public class CardsOrderTest { + + public static void main(String[] args) throws Exception { + + CardLayout layout = new CardLayout(); + Container cont = new Container(); + Component comp1 = new Component() {}; + Component comp2 = new Component() {}; + Component comp3 = new Component() {}; + cont.setLayout(layout); + cont.add(comp1, "1", 0); + cont.add(comp2, "2", 0); + cont.add(comp3, "3", 0); + + // Testing visibility "state" - not actually if its visible on screen + // since this test does not require a UI. + System.out.println("comp1.isVisible() = " + comp1.isVisible()); + System.out.println("comp2.isVisible() = " + comp2.isVisible()); + System.out.println("comp3.isVisible() = " + comp3.isVisible()); + + if (!comp1.isVisible() || comp2.isVisible() || comp3.isVisible()) { + throw new RuntimeException("first added component must be visible"); + } + + System.out.println("CardLayout.next()"); + layout.next(cont); + + System.out.println("comp1.isVisible() = " + comp1.isVisible()); + System.out.println("comp2.isVisible() = " + comp2.isVisible()); + System.out.println("comp3.isVisible() = " + comp3.isVisible()); + + if (!comp3.isVisible() ||comp1.isVisible() || comp2.isVisible()) { + throw new RuntimeException("the wrong component is visible after CardLayout.next() (must be comp3)"); + } + } +} diff --git a/test/jdk/java/awt/CardLayout/ObedienceTest.java b/test/jdk/java/awt/CardLayout/ObedienceTest.java new file mode 100644 index 00000000000..0a3590dd425 --- /dev/null +++ b/test/jdk/java/awt/CardLayout/ObedienceTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4690266 + @summary REGRESSION: Wizard Page does not move to the next page +*/ + +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Container; + +public class ObedienceTest { + + public static void main(String[] args) { + Container cont = new Container(); + Component comp1 = new Component() {}; + Component comp2 = new Component() {}; + CardLayout layout = new CardLayout(); + cont.setLayout(layout); + cont.add(comp1, "first"); + cont.add(comp2, "second"); + + if (!comp1.isVisible()) { + throw new RuntimeException("first component must be visible"); + } + + comp1.setVisible(false); + comp2.setVisible(true); + layout.layoutContainer(cont); + + if (!comp2.isVisible() || comp1.isVisible()) { + System.out.println("comp1.isVisible() = " + comp1.isVisible()); + System.out.println("comp2.isVisible() = " + comp2.isVisible()); + throw new RuntimeException("manually shown component must be visible after layoutContainer()"); + } + } +} diff --git a/test/jdk/java/awt/Checkbox/CheckboxCrashTest.java b/test/jdk/java/awt/Checkbox/CheckboxCrashTest.java new file mode 100644 index 00000000000..3584233723a --- /dev/null +++ b/test/jdk/java/awt/Checkbox/CheckboxCrashTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4378378 + @summary Tests that checkbox.setLabel(null) doesn't crash the VM. + @key headful +*/ + +import java.awt.Checkbox; +import java.awt.EventQueue; +import java.awt.Frame; + +public class CheckboxCrashTest { + + static Frame f; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> runTest()); + Thread.sleep(1000); + } finally { + f.dispose(); + } + } + + static void runTest() { + f = new Frame("CheckboxCrashTest"); + Checkbox cb = new Checkbox(); + f.add(cb); + f.pack(); + cb.setLabel(null); + f.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Checkbox/MultiCheckedCheckboxGroupTest.java b/test/jdk/java/awt/Checkbox/MultiCheckedCheckboxGroupTest.java new file mode 100644 index 00000000000..4e52b8cd269 --- /dev/null +++ b/test/jdk/java/awt/Checkbox/MultiCheckedCheckboxGroupTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4136496 + @key headful + @summary Checkbox.setCheckboxGroup(CheckboxGroup) works wrong on some Checkbox states +*/ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; + +public class MultiCheckedCheckboxGroupTest { + + public static void main(String[] args) throws Exception { + + CheckboxGroup gr = new CheckboxGroup(); + Checkbox chb1 = new Checkbox("Box 1", true, gr); + Checkbox chb2 = new Checkbox("Box 2", true, null); + + chb2.setCheckboxGroup(gr); + + System.out.println("chb1="+chb1); + System.out.println("chb2="+chb2); + System.out.println("gr.getSelectedCheckbox="+gr.getSelectedCheckbox()); + + if(chb1.getState() + && !chb2.getState() + && chb1.getCheckboxGroup() == gr + && chb2.getCheckboxGroup() == gr + && gr.getSelectedCheckbox() == chb1) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + throw new RuntimeException("Test FAILED"); + } + } +} diff --git a/test/jdk/java/awt/Checkbox/NullCheckboxGroupTest.java b/test/jdk/java/awt/Checkbox/NullCheckboxGroupTest.java new file mode 100644 index 00000000000..be2d139d944 --- /dev/null +++ b/test/jdk/java/awt/Checkbox/NullCheckboxGroupTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4114268 + @key headful + @summary Checkbox.setCheckboxGroup(null) alters selection for CB's previous CBGroup +*/ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; + +public class NullCheckboxGroupTest { + + + public static void main(String[] args) { + CheckboxGroup cbg = new CheckboxGroup(); + Checkbox chbox1 = new Checkbox("First", cbg, true); + Checkbox chbox2 = new Checkbox("Second", cbg, false); + + chbox2.setCheckboxGroup(null); + + System.out.println("chbox1="+chbox1); + System.out.println("chbox2="+chbox2); + System.out.println("cbg="+cbg); + + if (cbg.getSelectedCheckbox() != chbox1) { + System.out.println("FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("PASSED"); + } + } + } diff --git a/test/jdk/java/awt/Checkbox/SetCheckboxGroupNull.java b/test/jdk/java/awt/Checkbox/SetCheckboxGroupNull.java new file mode 100644 index 00000000000..1ba339ecde7 --- /dev/null +++ b/test/jdk/java/awt/Checkbox/SetCheckboxGroupNull.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4726853 + @key headful + @summary Checkbox is changing it's state after removing from CheckboxGroup +*/ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; + +public class SetCheckboxGroupNull { + + public static void main(String[] args) { + boolean passed = true; + + // 1 step + { + CheckboxGroup g = new CheckboxGroup(); + Checkbox cb1 = new Checkbox("Label", true, g); + System.out.println("1. (should be true) "+cb1.getState()); + passed = passed && (cb1.getState() == true); + cb1.setCheckboxGroup(null); + System.out.println("2. (should be true) "+cb1.getState()); + passed = passed && (cb1.getState() == true); + } + + // 2 step + { + CheckboxGroup g = new CheckboxGroup(); + Checkbox cb1 = new Checkbox("CB1", true, g); + System.out.println("3. (should be true) " + cb1.getState()); + passed = passed && (cb1.getState() == true); + g.setSelectedCheckbox(null); + System.out.println("4. (should be false) " + cb1.getState()); + passed = passed && (cb1.getState() == false); + } + + if (!passed) { + throw new RuntimeException("SetCheckboxGroupNull FAILED"); + } + System.out.println("SetCheckboxGroupNull PASSED"); + } +} From b8f0a668dd69b831d9f0e617ac3cb65830f69909 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 20 Apr 2023 01:49:31 +0000 Subject: [PATCH 056/288] 8041676: remove the java.compiler system property Reviewed-by: dholmes, alanb, rriggs, iris --- src/hotspot/share/runtime/arguments.cpp | 31 +++++-------------- src/hotspot/share/runtime/arguments.hpp | 4 --- .../share/classes/java/lang/System.java | 2 -- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index c87c1cb03f9..67dfe8fb998 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -85,7 +85,6 @@ char* Arguments::_java_command = nullptr; SystemProperty* Arguments::_system_properties = nullptr; size_t Arguments::_conservative_max_heap_alignment = 0; Arguments::Mode Arguments::_mode = _mixed; -bool Arguments::_java_compiler = false; bool Arguments::_xdebug_mode = false; const char* Arguments::_java_vendor_url_bug = nullptr; const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER; @@ -1266,8 +1265,14 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop #endif if (strcmp(key, "java.compiler") == 0) { - process_java_compiler_argument(value); - // Record value in Arguments, but let it get passed to Java. + // we no longer support java.compiler system property, log a warning and let it get + // passed to Java, like any other system property + if (strlen(value) == 0 || strcasecmp(value, "NONE") == 0) { + // for applications using NONE or empty value, log a more informative message + warning("The java.compiler system property is obsolete and no longer supported, use -Xint"); + } else { + warning("The java.compiler system property is obsolete and no longer supported."); + } } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0) { // sun.java.launcher.is_altjvm property is // private and is processed in process_sun_java_launcher_properties(); @@ -1372,7 +1377,6 @@ void Arguments::set_mode_flags(Mode mode) { // Set up default values for all flags. // If you add a flag to any of the branches below, // add a default value for it here. - set_java_compiler(false); _mode = mode; // Ensure Agent_OnLoad has the correct initial values. @@ -1862,16 +1866,6 @@ jint Arguments::set_aggressive_opts_flags() { } //=========================================================================================================== -// Parsing of java.compiler property - -void Arguments::process_java_compiler_argument(const char* arg) { - // For backwards compatibility, Djava.compiler=NONE or "" - // causes us to switch to -Xint mode UNLESS -Xdebug - // is also specified. - if (strlen(arg) == 0 || strcasecmp(arg, "NONE") == 0) { - set_java_compiler(true); // "-Djava.compiler[=...]" most recently seen. - } -} void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) { if (_sun_java_launcher != _default_java_launcher) { @@ -3004,15 +2998,6 @@ jint Arguments::finalize_vm_init_args(bool patch_mod_javabase) { } } - // This must be done after all arguments have been processed. - // java_compiler() true means set to "NONE" or empty. - if (java_compiler() && !xdebug_mode()) { - // For backwards compatibility, we switch to interpreted mode if - // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was - // not specified. - set_mode_flags(_int); - } - // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode), // but like -Xint, leave compilation thresholds unaffected. // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well. diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 4f7eec12735..977422a2961 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -242,9 +242,6 @@ class Arguments : AllStatic { // Operation modi static Mode _mode; static void set_mode_flags(Mode mode); - static bool _java_compiler; - static void set_java_compiler(bool arg) { _java_compiler = arg; } - static bool java_compiler() { return _java_compiler; } // -Xdebug flag static bool _xdebug_mode; @@ -302,7 +299,6 @@ class Arguments : AllStatic { static bool parse_argument(const char* arg, JVMFlagOrigin origin); static bool process_argument(const char* arg, jboolean ignore_unrecognized, JVMFlagOrigin origin); static void process_java_launcher_argument(const char*, void*); - static void process_java_compiler_argument(const char* arg); static jint parse_options_environment_variable(const char* name, ScopedVMInitArgs* vm_args); static jint parse_java_tool_options_environment_variable(ScopedVMInitArgs* vm_args); static jint parse_java_options_environment_variable(ScopedVMInitArgs* vm_args); diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index f15b5861670..3fd13f89289 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -760,8 +760,6 @@ public final class System { * List of paths to search when loading libraries * {@systemProperty java.io.tmpdir} * Default temp file path - * {@systemProperty java.compiler} - * Name of JIT compiler to use * {@systemProperty os.name} * Operating system name * {@systemProperty os.arch} From 64ed816ad9f1a9773c9865a013e89b709a130e9c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 20 Apr 2023 02:35:05 +0000 Subject: [PATCH 057/288] 8305943: Open source few AWT Focus related tests Reviewed-by: prr, serb --- .../java/awt/Focus/NoFocusOwnerAWTTest.java | 133 +++++++++++++ .../java/awt/Focus/NoFocusOwnerSwingTest.java | 100 ++++++++++ .../Focus/RestoreFocusInfiniteLoopTest.java | 180 ++++++++++++++++++ .../SequencedLightweightRequestsTest.java | 173 +++++++++++++++++ test/jdk/java/awt/Focus/SetFocusableTest.java | 179 +++++++++++++++++ 5 files changed, 765 insertions(+) create mode 100644 test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java create mode 100644 test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java create mode 100644 test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java create mode 100644 test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java create mode 100644 test/jdk/java/awt/Focus/SetFocusableTest.java diff --git a/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java b/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java new file mode 100644 index 00000000000..953c392e79f --- /dev/null +++ b/test/jdk/java/awt/Focus/NoFocusOwnerAWTTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4390019 + @summary REGRESSION: Alt-F4 keybinding no longer shuts down java application on Windows + @key headful + @requires (os.family == "windows") + @run main NoFocusOwnerAWTTest +*/ +import java.awt.Frame; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.MenuBar; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; + +public class NoFocusOwnerAWTTest { + + static boolean actionFired = false; + static boolean closingWindowCalled = false; + static Frame frame; + + public static void main(String[] args) throws Exception { + try { + if (!System.getProperty("os.name").startsWith("Windows")) { + // this test is Win32 test only + return; + } + EventQueue.invokeAndWait(() -> { + + frame = new Frame("No Focus Owner AWT Test"); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.out.println("windowClosing() is called."); + closingWindowCalled = true; + } + }); + frame.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + System.out.println("focus gained on frame"); + } + public void focusLost(FocusEvent fe) { + System.out.println("focus lost on frame"); + } + }); + MenuBar mb = new MenuBar(); + Menu m = new Menu("This is Menu"); + MenuItem mi = new MenuItem("Menu Item"); + mi.setShortcut(new MenuShortcut(KeyEvent.VK_A)); + mi.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent ae) { + System.out.println("action"); + actionFired = true; + } + }); + m.add(mi); + mb.add(m); + frame.setMenuBar(mb); + Label lb; + frame.add(lb = new Label("press")); + lb.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent fe) { + System.out.println("focus gained on label"); + } + public void focusLost(FocusEvent fe) { + System.out.println("focus lost on label"); + } + }); + frame.pack(); + frame.toFront(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_A); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + robot.delay(1000); + + if (!actionFired || !closingWindowCalled) { + throw new RuntimeException("Test FAILED(actionFired="+actionFired+ + ";closingWindowCalled="+closingWindowCalled+")"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + }// class NoFocusOwnerAWTTest diff --git a/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java b/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java new file mode 100644 index 00000000000..23c898ae823 --- /dev/null +++ b/test/jdk/java/awt/Focus/NoFocusOwnerSwingTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4390019 + @summary REGRESSION: Alt-F4 keybinding no longer shuts down java application on Windows + @key headful + @requires (os.family == "windows") + @run main NoFocusOwnerSwingTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.MenuBar; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class NoFocusOwnerSwingTest { + static boolean closingWindowCalled = false; + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + if (!System.getProperty("os.name").startsWith("Windows")) { + // this test is Win32 test only + return; + } + + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("No Focus Owner Swing Test"); + JButton btn; + frame.getContentPane().add(btn = new JButton("press")); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.out.println("windowClosing is called"); + closingWindowCalled = true; + } + }); + frame.pack(); + frame.toFront(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.waitForIdle(); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + + if (!closingWindowCalled) { + throw new RuntimeException("Test FAILED(closingWindowCalled=" + + closingWindowCalled + ")"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +}// class NoFocusOwnerSwingTest diff --git a/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java b/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java new file mode 100644 index 00000000000..64b1ae9477c --- /dev/null +++ b/test/jdk/java/awt/Focus/RestoreFocusInfiniteLoopTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4504665 + @summary MerlinBeta2 - vetoing a focus change causes infinite loop + @key headful + @run main RestoreFocusInfiniteLoopTest +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +public class RestoreFocusInfiniteLoopTest { + static final int TEST_TIMEOUT = 1000; + static final int DELAY = 100; + static Button b1; + static Frame frame; + static Object b1Monitor; + static Point origin; + static Dimension dim; + static MonitoredFocusListener monitorer; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + + b1Monitor = new Object(); + frame = new Frame(); + b1 = new Button("1"); + Button b2 = new Button("2"); + b1.setName("b1"); + b2.setName("b2"); + + frame.setLayout(new FlowLayout()); + frame.add(b1); + frame.add(b2); + frame.pack(); + frame.setSize(100, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + FocusVetoableChangeListener vetoer = new FocusVetoableChangeListener(b2); + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener("focusOwner", vetoer); + + }); + Robot robot = new Robot(); + robot.setAutoDelay(DELAY); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + monitorer = new MonitoredFocusListener(b1Monitor); + b1.addFocusListener(monitorer); + origin = b1.getLocationOnScreen(); + dim = b1.getSize(); + }); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!b1.isFocusOwner()) { + synchronized (b1Monitor) { + b1Monitor.wait(TEST_TIMEOUT); + } + } + + monitorer.resetFocusLost(); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!monitorer.isFocusLostReceived() || !b1.isFocusOwner()) { + synchronized (b1Monitor) { + b1Monitor.wait(TEST_TIMEOUT); + } + } + if (!b1.isFocusOwner()) { + throw new RuntimeException("Test is FAILED"); + } else { + System.out.println("Test is PASSED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + }// class RestoreFocusInfiniteLoopTest + +class FocusVetoableChangeListener implements VetoableChangeListener { + Component vetoedComponent; + public FocusVetoableChangeListener(Component vetoedComponent) { + this.vetoedComponent = vetoedComponent; + } + public void vetoableChange(PropertyChangeEvent evt) + throws PropertyVetoException + { + Component oldComp = (Component)evt.getOldValue(); + Component newComp = (Component)evt.getNewValue(); + + boolean vetoFocusChange = (newComp == vetoedComponent); + process(evt.getPropertyName(), oldComp, newComp); + + if (vetoFocusChange) { + throw new PropertyVetoException("message", evt); + } + } + boolean process(String propName, Component o1, Component o2) { + System.out.println(propName + + " old=" + (o1 != null ? o1.getName() : "null") + + " new=" + (o2 != null ? o2.getName() : "null")); + return true; + } + } + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + boolean focuslost = false; + + public void resetFocusLost() { + focuslost = false; + } + public boolean isFocusLostReceived() { + return focuslost; + } + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusLost(FocusEvent fe) { + System.out.println(fe.toString()); + focuslost = true; + } + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java b/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java new file mode 100644 index 00000000000..9daa87a4263 --- /dev/null +++ b/test/jdk/java/awt/Focus/SequencedLightweightRequestsTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4648816 + @summary Sometimes focus requests on LW components are delayed + @key headful + @run main SequencedLightweightRequestsTest +*/ + +import java.awt.AWTException; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +public class SequencedLightweightRequestsTest implements FocusListener { + final int WAIT_TIME = 5000; + + JFrame testFrame; + JButton testButton1; + JButton testButton2; + JTextField testField; + + public void focusGained(FocusEvent fe) { + System.err.println("FocusGained on " + fe.getComponent().getName()); + } + + public void focusLost(FocusEvent fe) { + System.err.println("FocusLost on " + fe.getComponent().getName()); + } + + public static void main(String[] args) throws Exception { + SequencedLightweightRequestsTest test = + new SequencedLightweightRequestsTest(); + test.start(); + } + + public void start() throws Exception { + try { + + SwingUtilities.invokeAndWait(() -> { + testFrame = new JFrame("See my components!"); + testButton1 = new JButton("Click me!"); + testButton2 = new JButton("Do I have focus?"); + testField = new JTextField("Do I have focus?"); + testFrame.getContentPane().setLayout(new FlowLayout()); + testFrame.getContentPane().add(testButton1); + testFrame.getContentPane().add(testField); + testFrame.getContentPane().add(testButton2); + + testButton1.setName("Button1"); + testButton2.setName("Button2"); + testField.setName("textField"); + testButton1.addFocusListener(this); + testButton2.addFocusListener(this); + testField.addFocusListener(this); + testFrame.addFocusListener(this); + + testFrame.setSize(300, 100); + testFrame.setLocationRelativeTo(null); + testFrame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + + // wait to give to frame time for showing + robot.delay(1000); + + // make sure that first button has focus + Object monitor = new Object(); + MonitoredFocusListener monitorer = + new MonitoredFocusListener(monitor); + Point origin = testButton1.getLocationOnScreen(); + Dimension dim = testButton1.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + if (!testButton1.isFocusOwner()) { + synchronized (monitor) { + testButton1.addFocusListener(monitorer); + monitor.wait(WAIT_TIME); + testButton1.removeFocusListener(monitorer); + } + } + + // if first button still doesn't have focus, test fails + if (!testButton1.isFocusOwner()) { + throw new RuntimeException("First button doesn't receive focus"); + } + + // two lightweight requests + java.awt.EventQueue.invokeAndWait(new Runnable() { + public void run() { + testButton2.requestFocus(); + testField.requestFocus(); + } + }); + + // make sure third button receives focus + if (!testField.isFocusOwner()) { + synchronized (monitor) { + testField.addFocusListener(monitorer); + monitor.wait(WAIT_TIME); + testField.removeFocusListener(monitorer); + } + } + + // if the text field still doesn't have focus, test fails + if (!testField.isFocusOwner()) { + throw new RuntimeException("Text field doesn't receive focus"); + } + System.out.println("Test PASSED"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (testFrame != null) { + testFrame.dispose(); + } + }); + } + } +}// class SequencedLightweightRequestsTest + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusGained(FocusEvent fe) { + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/SetFocusableTest.java b/test/jdk/java/awt/Focus/SetFocusableTest.java new file mode 100644 index 00000000000..371b8ff49ba --- /dev/null +++ b/test/jdk/java/awt/Focus/SetFocusableTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4597455 + @summary setFocusable(false) is not moving the focus to next Focusable Component + @key headful + @run main SetFocusableTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextField; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +public class SetFocusableTest implements KeyListener { + static Object buttonMonitor; + Object tfMonitor; + static final int TEST_TIMEOUT = 5000; + Button button; + Frame frame; + TextField textfield; + + public static void main(String[] args) throws Exception { + SetFocusableTest test = new SetFocusableTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + buttonMonitor = new Object(); + tfMonitor = new Object(); + frame = new Frame(); + frame.setTitle("Test Frame"); + frame.setLocation(100, 100); + frame.setLayout(new FlowLayout()); + + button = new Button("BUTTON"); + textfield = new TextField("First"); + + button.addKeyListener(this); + textfield.addKeyListener(this); + + frame.add(button); + frame.add(textfield); + + frame.setBackground(Color.red); + frame.setSize(500,200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + button.addFocusListener(new MonitoredFocusListener(buttonMonitor)); + textfield.addFocusListener(new MonitoredFocusListener(tfMonitor)); + }); + + Robot robot; + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + robot.delay(1000); + + Point buttonOrigin = button.getLocationOnScreen(); + Dimension buttonSize = button.getSize(); + robot.mouseMove( + (int)buttonOrigin.getX() + (int)buttonSize.getWidth() / 2, + (int)buttonOrigin.getY() + (int)buttonSize.getHeight() / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!button.isFocusOwner()) { + synchronized (buttonMonitor) { + buttonMonitor.wait(TEST_TIMEOUT); + } + } + System.out.println("\n\nBefore calling the method button.setFocusable(false)"); + System.out.println("===================================================="); + System.out.println("Button is Focusable(button.isFocusable()) :"+button.isFocusable()); + System.out.println("Button is Focus owner(button.isFocusOwner()) :"+button.isFocusOwner()); + System.out.println("Button has Focus (button.hasFocus) :"+button.hasFocus()); + System.out.println("===================================================="); + + button.setFocusable(false); + + if (!textfield.isFocusOwner()) { + synchronized (tfMonitor) { + tfMonitor.wait(TEST_TIMEOUT); + } + } + + System.out.println("\nAfter Calling button.setFocusable(false)"); + System.out.println("===================================================="); + System.out.println("Button is Focusable(button.isFocusable()) :"+button.isFocusable()); + System.out.println("Button is Focus owner(button.isFocusOwner()) :"+button.isFocusOwner()); + System.out.println("Button has Focus (button.hasFocus()) :"+button.hasFocus()); + System.out.println("TextField is Focusable(textfield.isFocusable()) :"+textfield.isFocusable()); + System.out.println("TextField is Focus owner(textfield.isFocusOwner()) :"+textfield.isFocusOwner()); + System.out.println("TextField has Focus (textfield.hasFocus()) :"+textfield.hasFocus()); + System.out.println("====================================================n\n\n\n"); + + if (!button.hasFocus() && !button.isFocusOwner() && + textfield.hasFocus() && textfield.isFocusOwner()){ + System.out.println("\n\n\nASSERTION :PASSED"); + System.out.println("========================="); + System.out.println("Textfield is having the Focus.Transfer of Focus has happend."); + } else { + System.out.println("\n\n\nASSERTION :FAILED"); + System.out.println("=========================="); + System.out.println("Button is still having the Focus instead of TextField"); + throw new RuntimeException("Test FIALED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + }// start() + + public void keyPressed(KeyEvent e) { + System.out.println("Key Pressed "); + } + public void keyReleased(KeyEvent ke) { + System.out.println("keyReleased called "); + } + public void keyTyped(KeyEvent ke) { + System.out.println("keyTyped called "); + } +}// class SetFocusableTest + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} From 310aa9347861922af5f0311e9e93a5f49dee6adc Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 20 Apr 2023 07:07:00 +0000 Subject: [PATCH 058/288] 8304291: [AIX] Broken build after JDK-8301998 Reviewed-by: mdoerr, tsteele, prr --- src/java.desktop/share/native/libharfbuzz/hb-algs.hh | 3 ++- src/java.desktop/share/native/libharfbuzz/hb-subset.cc | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh index 28dc036a515..0080b380850 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh @@ -875,7 +875,8 @@ hb_in_ranges (T u, T lo1, T hi1, Ts... ds) static inline bool hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr) { -#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 8)) +/* avoid with xlc16 clang on AIX; it sets the gcc macros */ +#if (defined(__GNUC__) && !defined(AIX) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 8)) unsigned stack_result; if (!result) result = &stack_result; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc index a8161a32551..b2539de7432 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc @@ -43,7 +43,11 @@ #include "OT/Color/sbix/sbix.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" + +#if !defined(AIX) #include "hb-ot-post-table-v2subset.hh" +#endif + #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" From 6a7dff30edce7a24400b27bee4d7ddd45eed523d Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 20 Apr 2023 09:18:28 +0000 Subject: [PATCH 059/288] 8305880: Loom: Avoid putting stale object pointers in oops Reviewed-by: eosterlund, aboldtch --- src/hotspot/share/compiler/oopMap.cpp | 12 +++---- src/hotspot/share/compiler/oopMap.hpp | 9 +++--- src/hotspot/share/compiler/oopMap.inline.hpp | 6 ++-- src/hotspot/share/memory/iterator.hpp | 3 +- src/hotspot/share/oops/stackChunkOop.cpp | 31 ++++++++++++------- .../runtime/continuationWrapper.inline.hpp | 6 ++-- src/hotspot/share/runtime/frame.cpp | 8 ++--- .../runtime/stackChunkFrameStream.inline.hpp | 2 +- src/hotspot/share/utilities/devirtualizer.hpp | 2 +- .../share/utilities/devirtualizer.inline.hpp | 6 ++-- 10 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/compiler/oopMap.cpp b/src/hotspot/share/compiler/oopMap.cpp index a6b8a156450..58e9daa43a5 100644 --- a/src/hotspot/share/compiler/oopMap.cpp +++ b/src/hotspot/share/compiler/oopMap.cpp @@ -392,7 +392,7 @@ class AddDerivedOop : public DerivedOopClosure { SkipNull = true, NeedsLock = true }; - virtual void do_derived_oop(oop* base, derived_pointer* derived) { + virtual void do_derived_oop(derived_base* base, derived_pointer* derived) { #if COMPILER2_OR_JVMCI DerivedPointerTable::add(derived, base); #endif // COMPILER2_OR_JVMCI @@ -410,7 +410,7 @@ public: SkipNull = true, NeedsLock = true }; - virtual void do_derived_oop(oop* base, derived_pointer* derived) { + virtual void do_derived_oop(derived_base* base, derived_pointer* derived) { // All derived pointers must be processed before the base pointer of any derived pointer is processed. // Otherwise, if two derived pointers use the same base, the second derived pointer will get an obscured // offset, if the base pointer is processed in the first derived pointer. @@ -430,7 +430,7 @@ public: SkipNull = true, NeedsLock = true }; - virtual void do_derived_oop(oop* base, derived_pointer* derived) {} + virtual void do_derived_oop(derived_base* base, derived_pointer* derived) {} }; void OopMapSet::oops_do(const frame* fr, const RegisterMap* reg_map, OopClosure* f, DerivedPointerIterationMode mode) { @@ -915,8 +915,8 @@ void DerivedPointerTable::clear() { _active = true; } -void DerivedPointerTable::add(derived_pointer* derived_loc, oop *base_loc) { - assert(Universe::heap()->is_in_or_null(*base_loc), "not an oop"); +void DerivedPointerTable::add(derived_pointer* derived_loc, derived_base* base_loc) { + assert(Universe::heap()->is_in_or_null((void*)*base_loc), "not an oop"); assert(derived_loc != (void*)base_loc, "Base and derived in same location"); derived_pointer base_loc_as_derived_pointer = static_cast(reinterpret_cast(base_loc)); @@ -933,7 +933,7 @@ void DerivedPointerTable::add(derived_pointer* derived_loc, oop *base_loc) { "Add derived pointer@" INTPTR_FORMAT " - Derived: " INTPTR_FORMAT " Base: " INTPTR_FORMAT " (@" INTPTR_FORMAT ") (Offset: " INTX_FORMAT ")", - p2i(derived_loc), derived_pointer_value(*derived_loc), p2i(*base_loc), p2i(base_loc), offset + p2i(derived_loc), derived_pointer_value(*derived_loc), intptr_t(*base_loc), p2i(base_loc), offset ); } // Set derived oop location to point to base. diff --git a/src/hotspot/share/compiler/oopMap.hpp b/src/hotspot/share/compiler/oopMap.hpp index 3c23943e097..4b20464f69c 100644 --- a/src/hotspot/share/compiler/oopMap.hpp +++ b/src/hotspot/share/compiler/oopMap.hpp @@ -48,6 +48,7 @@ class OopClosure; class CodeBlob; class ImmutableOopMap; +enum class derived_base : intptr_t {}; enum class derived_pointer : intptr_t {}; class OopMapValue: public StackObj { @@ -481,12 +482,12 @@ class DerivedPointerTable : public AllStatic { friend class VMStructs; private: class Entry; - static bool _active; // do not record pointers for verify pass etc. + static bool _active; // do not record pointers for verify pass etc. public: - static void clear(); // Called before scavenge/GC - static void add(derived_pointer* derived, oop *base); // Called during scavenge/GC - static void update_pointers(); // Called after scavenge/GC + static void clear(); // Called before scavenge/GC + static void add(derived_pointer* derived, derived_base* base); // Called during scavenge/GC + static void update_pointers(); // Called after scavenge/GC static bool is_empty(); static bool is_active() { return _active; } static void set_active(bool value) { _active = value; } diff --git a/src/hotspot/share/compiler/oopMap.inline.hpp b/src/hotspot/share/compiler/oopMap.inline.hpp index 3f8a81d773b..c6531b1cd3a 100644 --- a/src/hotspot/share/compiler/oopMap.inline.hpp +++ b/src/hotspot/share/compiler/oopMap.inline.hpp @@ -84,15 +84,15 @@ void OopMapDo::iterate_oops_do(const frame } guarantee(loc != nullptr, "missing saved register"); derived_pointer* derived_loc = (derived_pointer*)loc; - void** base_loc = (void**) fr->oopmapreg_to_location(omv.content_reg(), reg_map); + derived_base* base_loc = (derived_base*) fr->oopmapreg_to_location(omv.content_reg(), reg_map); // Ignore nullptr oops and decoded null narrow oops which // equal to CompressedOops::base() when a narrow oop // implicit null check is used in compiled code. // The narrow_oop_base could be nullptr or be the address // of the page below heap depending on compressed oops mode. - if (base_loc != nullptr && !SkipNullValue::should_skip(*base_loc)) { - _derived_oop_fn->do_derived_oop((oop*)base_loc, derived_loc); + if (base_loc != nullptr && !SkipNullValue::should_skip((void*)*base_loc)) { + _derived_oop_fn->do_derived_oop(base_loc, derived_loc); } } } diff --git a/src/hotspot/share/memory/iterator.hpp b/src/hotspot/share/memory/iterator.hpp index eee59334757..5d5c494ef11 100644 --- a/src/hotspot/share/memory/iterator.hpp +++ b/src/hotspot/share/memory/iterator.hpp @@ -129,11 +129,12 @@ public: virtual void oops_do(OopClosure* cl) = 0; }; +enum class derived_base : intptr_t; enum class derived_pointer : intptr_t; class DerivedOopClosure : public Closure { public: enum { SkipNull = true }; - virtual void do_derived_oop(oop* base, derived_pointer* derived) = 0; + virtual void do_derived_oop(derived_base* base, derived_pointer* derived) = 0; }; class KlassClosure : public Closure { diff --git a/src/hotspot/share/oops/stackChunkOop.cpp b/src/hotspot/share/oops/stackChunkOop.cpp index 76e48cba53d..4e771939dc9 100644 --- a/src/hotspot/share/oops/stackChunkOop.cpp +++ b/src/hotspot/share/oops/stackChunkOop.cpp @@ -38,6 +38,11 @@ #include "runtime/smallRegisterMap.inline.hpp" #include "runtime/stackChunkFrameStream.inline.hpp" +// Note: Some functions in this file work with stale object pointers, e.g. +// DerivedPointerSupport. Be extra careful to not put those pointers into +// variables of the 'oop' type. There's extra GC verification around oops +// that may fail when stale oops are being used. + template class FrameOopIterator : public OopIterator { private: @@ -153,43 +158,45 @@ template void stackChunkOopDesc::do_barriers(base); + uintptr_t offset = derived_int_val - base; *(uintptr_t*)derived_loc = offset; } - static void derelativize(oop* base_loc, derived_pointer* derived_loc) { - oop base = *base_loc; - if (base == nullptr) { + static void derelativize(derived_base* base_loc, derived_pointer* derived_loc) { + uintptr_t base = *(uintptr_t*)base_loc; + if (base == 0) { return; } - assert(!UseCompressedOops || !CompressedOops::is_base(base), ""); + assert(!UseCompressedOops || !CompressedOops::is_base((void*)base), ""); // All derived pointers should have been relativized into offsets uintptr_t offset = *(uintptr_t*)derived_loc; // Restore the original derived pointer - *(uintptr_t*)derived_loc = cast_from_oop(base) + offset; + *(uintptr_t*)derived_loc = base + offset; } struct RelativizeClosure : public DerivedOopClosure { - virtual void do_derived_oop(oop* base_loc, derived_pointer* derived_loc) override { + virtual void do_derived_oop(derived_base* base_loc, derived_pointer* derived_loc) override { DerivedPointersSupport::relativize(base_loc, derived_loc); } }; struct DerelativizeClosure : public DerivedOopClosure { - virtual void do_derived_oop(oop* base_loc, derived_pointer* derived_loc) override { + virtual void do_derived_oop(derived_base* base_loc, derived_pointer* derived_loc) override { DerivedPointersSupport::derelativize(base_loc, derived_loc); } }; diff --git a/src/hotspot/share/runtime/continuationWrapper.inline.hpp b/src/hotspot/share/runtime/continuationWrapper.inline.hpp index fc89d98be64..03b2c726a0e 100644 --- a/src/hotspot/share/runtime/continuationWrapper.inline.hpp +++ b/src/hotspot/share/runtime/continuationWrapper.inline.hpp @@ -92,10 +92,8 @@ public: } inline ~SafepointOp() { // reload oops _cont._continuation = _conth(); - if (_cont._tail != nullptr) { - _cont._tail = jdk_internal_vm_Continuation::tail(_cont._continuation); - } - _cont.disallow_safepoint(); + _cont._tail = jdk_internal_vm_Continuation::tail(_cont._continuation); + _cont.disallow_safepoint(); } }; diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp index bb4a6cc2e54..d4e7c26f18b 100644 --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -1241,7 +1241,7 @@ class FrameValuesOopClosure: public OopClosure, public DerivedOopClosure { private: GrowableArray* _oops; GrowableArray* _narrow_oops; - GrowableArray* _base; + GrowableArray* _base; GrowableArray* _derived; NoSafepointVerifier nsv; @@ -1249,7 +1249,7 @@ public: FrameValuesOopClosure() { _oops = new (mtThread) GrowableArray(100, mtThread); _narrow_oops = new (mtThread) GrowableArray(100, mtThread); - _base = new (mtThread) GrowableArray(100, mtThread); + _base = new (mtThread) GrowableArray(100, mtThread); _derived = new (mtThread) GrowableArray(100, mtThread); } ~FrameValuesOopClosure() { @@ -1261,7 +1261,7 @@ public: virtual void do_oop(oop* p) override { _oops->push(p); } virtual void do_oop(narrowOop* p) override { _narrow_oops->push(p); } - virtual void do_derived_oop(oop* base_loc, derived_pointer* derived_loc) override { + virtual void do_derived_oop(derived_base* base_loc, derived_pointer* derived_loc) override { _base->push(base_loc); _derived->push(derived_loc); } @@ -1281,7 +1281,7 @@ public: } assert(_base->length() == _derived->length(), "should be the same"); for (int i = 0; i < _base->length(); i++) { - oop* base = _base->at(i); + derived_base* base = _base->at(i); derived_pointer* derived = _derived->at(i); values.describe(frame_no, (intptr_t*)derived, err_msg("derived pointer (base: " INTPTR_FORMAT ") for #%d", p2i(base), frame_no)); } diff --git a/src/hotspot/share/runtime/stackChunkFrameStream.inline.hpp b/src/hotspot/share/runtime/stackChunkFrameStream.inline.hpp index e5d300b0016..0a279c57385 100644 --- a/src/hotspot/share/runtime/stackChunkFrameStream.inline.hpp +++ b/src/hotspot/share/runtime/stackChunkFrameStream.inline.hpp @@ -410,7 +410,7 @@ inline void StackChunkFrameStream::iterate_derived_pointers(DerivedO assert(is_in_oops(base_loc, map), "not found: " INTPTR_FORMAT, p2i(base_loc)); assert(!is_in_oops(derived_loc, map), "found: " INTPTR_FORMAT, p2i(derived_loc)); - Devirtualizer::do_derived_oop(closure, (oop*)base_loc, (derived_pointer*)derived_loc); + Devirtualizer::do_derived_oop(closure, (derived_base*)base_loc, (derived_pointer*)derived_loc); } } diff --git a/src/hotspot/share/utilities/devirtualizer.hpp b/src/hotspot/share/utilities/devirtualizer.hpp index 813a56d3740..b4d444dc5a8 100644 --- a/src/hotspot/share/utilities/devirtualizer.hpp +++ b/src/hotspot/share/utilities/devirtualizer.hpp @@ -38,7 +38,7 @@ class Devirtualizer { template static void do_klass(OopClosureType* closure, Klass* k); template static void do_cld(OopClosureType* closure, ClassLoaderData* cld); template static bool do_metadata(OopClosureType* closure); - template static void do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived); + template static void do_derived_oop(DerivedOopClosureType* closure, derived_base* base, derived_pointer* derived); template static bool do_bit(BitMapClosureType* closure, BitMap::idx_t index); }; diff --git a/src/hotspot/share/utilities/devirtualizer.inline.hpp b/src/hotspot/share/utilities/devirtualizer.inline.hpp index 001596874cc..0cae27f87e9 100644 --- a/src/hotspot/share/utilities/devirtualizer.inline.hpp +++ b/src/hotspot/share/utilities/devirtualizer.inline.hpp @@ -154,18 +154,18 @@ void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) { template static typename EnableIf::value, void>::type -call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) { +call_do_derived_oop(void (Receiver::*)(derived_base*, derived_pointer*), void (Base::*)(derived_base*, derived_pointer*), DerivedOopClosureType* closure, derived_base* base, derived_pointer* derived) { closure->do_derived_oop(base, derived); } template static typename EnableIf::value, void>::type -call_do_derived_oop(void (Receiver::*)(oop*, derived_pointer*), void (Base::*)(oop*, derived_pointer*), DerivedOopClosureType* closure, oop* base, derived_pointer* derived) { +call_do_derived_oop(void (Receiver::*)(derived_base*, derived_pointer*), void (Base::*)(derived_base*, derived_pointer*), DerivedOopClosureType* closure, derived_base* base, derived_pointer* derived) { closure->DerivedOopClosureType::do_derived_oop(base, derived); } template -inline void Devirtualizer::do_derived_oop(DerivedOopClosureType* closure, oop* base, derived_pointer* derived) { +inline void Devirtualizer::do_derived_oop(DerivedOopClosureType* closure, derived_base* base, derived_pointer* derived) { call_do_derived_oop(&DerivedOopClosureType::do_derived_oop, &DerivedOopClosure::do_derived_oop, closure, base, derived); } From 9c2e5b387112606352b3150a5cc10ddec8d3afe9 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Thu, 20 Apr 2023 12:28:26 +0000 Subject: [PATCH 060/288] 8306459: s390x: Replace NULL to nullptr Reviewed-by: mdoerr --- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 2 +- src/hotspot/cpu/s390/templateTable_s390.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 26af54f75a3..d8a8560a0e6 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -3155,7 +3155,7 @@ class StubGenerator: public StubCodeGenerator { // nmethod entry barriers for concurrent class unloading BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); - if (bs_nm != NULL) { + if (bs_nm != nullptr) { StubRoutines::zarch::_nmethod_entry_barrier = generate_nmethod_entry_barrier(); } diff --git a/src/hotspot/cpu/s390/templateTable_s390.cpp b/src/hotspot/cpu/s390/templateTable_s390.cpp index c38a375849d..441600eea38 100644 --- a/src/hotspot/cpu/s390/templateTable_s390.cpp +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp @@ -2425,7 +2425,7 @@ void TemplateTable::load_invokedynamic_entry(Register method) { __ load_resolved_indy_entry(cache, index); __ z_lg(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset()))); - // The invokedynamic is unresolved iff method is NULL + // The invokedynamic is unresolved iff method is null __ z_clgij(method, (unsigned long)nullptr, Assembler::bcondNotEqual, resolved); // method != 0, jump to resolved Bytecodes::Code code = bytecode(); // Call to the interpreter runtime to resolve invokedynamic From 33a7978e85c0c2d610828f89fc1389696f55e1f2 Mon Sep 17 00:00:00 2001 From: Zixian Cai Date: Thu, 20 Apr 2023 12:41:50 +0000 Subject: [PATCH 061/288] 8306538: Zero variant build failure after JDK-8257967 Reviewed-by: shade, dholmes --- src/hotspot/share/prims/jvmtiAgent.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/prims/jvmtiAgent.hpp b/src/hotspot/share/prims/jvmtiAgent.hpp index 6eb646ee2d4..9baf6698868 100644 --- a/src/hotspot/share/prims/jvmtiAgent.hpp +++ b/src/hotspot/share/prims/jvmtiAgent.hpp @@ -62,7 +62,7 @@ class JvmtiAgent : public CHeapObj { const char* options() const; bool is_absolute_path() const NOT_JVMTI_RETURN_(false); void* os_lib() const NOT_JVMTI_RETURN_(nullptr); - void set_os_lib(void* os_lib); + void set_os_lib(void* os_lib) NOT_JVMTI_RETURN; const char* os_lib_path() const; void set_os_lib_path(const char* path) NOT_JVMTI_RETURN; bool is_static_lib() const NOT_JVMTI_RETURN_(false); From 73018b39cd25daf01d8928fb50b011160faaad8f Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Thu, 20 Apr 2023 13:02:36 +0000 Subject: [PATCH 062/288] 8306284: G1: Remove assertion in G1ScanHRForRegionClosure::do_claimed_block Reviewed-by: kbarrett, tschatzl --- src/hotspot/share/gc/g1/g1RemSet.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 62cf4a0194c..8208ca5d3a9 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -549,11 +549,6 @@ class G1ScanHRForRegionClosure : public HeapRegionClosure { _blocks_scanned++; HeapWord* const card_start = _ct->addr_for(dirty_l); -#ifdef ASSERT - HeapRegion* hr = _g1h->region_at_or_null(region_idx); - assert(hr == NULL || hr->is_in_reserved(card_start), - "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx)->hrm_index()); -#endif HeapWord* const top = _scan_state->scan_top(region_idx); if (card_start >= top) { return; From c6a288dcd63824230638f2d08a1372f1d6e16829 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Thu, 20 Apr 2023 14:09:25 +0000 Subject: [PATCH 063/288] 8305945: (zipfs) Opening a directory to get input stream produces incorrect exception message Reviewed-by: naoto, cstein --- .../classes/jdk/nio/zipfs/ZipFileSystem.java | 2 +- .../ZipFSDirectoryExceptionMessageTest.java | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 test/jdk/jdk/nio/zipfs/ZipFSDirectoryExceptionMessageTest.java 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 c8980307e39..705ca4fb596 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -860,7 +860,7 @@ class ZipFileSystem extends FileSystem { if (e == null) throw new NoSuchFileException(getString(path)); if (e.isDir()) - throw new FileSystemException(getString(path), "is a directory", null); + throw new FileSystemException(getString(path), null, "is a directory"); return getInputStream(e); } finally { endRead(); diff --git a/test/jdk/jdk/nio/zipfs/ZipFSDirectoryExceptionMessageTest.java b/test/jdk/jdk/nio/zipfs/ZipFSDirectoryExceptionMessageTest.java new file mode 100644 index 00000000000..afb56cda90e --- /dev/null +++ b/test/jdk/jdk/nio/zipfs/ZipFSDirectoryExceptionMessageTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @test + * @bug 8305945 + * @summary Validate that Zip FS provides the correct exception message when an + * attempt is made to obtain an InputStream from a directory entry + * @modules jdk.zipfs + * @run junit ZipFSDirectoryExceptionMessageTest + */ +public class ZipFSDirectoryExceptionMessageTest { + /** + * Name of Directory created within the Zip file + */ + public static final String DIRECTORY_NAME = "folder/"; + /** + * The expected error message + */ + public static final String DIR_EXCEPTION_MESSAGE = "/folder: is a directory"; + /** + * Zip file to create + */ + public static final Path ZIP_FILE = Path.of("directoryExceptionTest.zip"); + + /** + * Create a Zip file which contains a single directory entry + * @throws IOException if an error occurs + */ + @BeforeEach + public void setup() throws IOException { + var ze = new ZipEntry(DIRECTORY_NAME); + ze.setMethod(ZipEntry.STORED); + ze.setCompressedSize(0); + ze.setSize(0); + ze.setCrc(0); + try (ZipOutputStream zos = new ZipOutputStream( + Files.newOutputStream(ZIP_FILE))) { + zos.putNextEntry(ze); + } + } + + /** + * Delete the Zip file used by the test + * @throws IOException If an error occurs + */ + @AfterEach + public void cleanup() throws IOException { + Files.deleteIfExists(ZIP_FILE); + } + + /** + * Validate that Zip FS returns the correct Exception message when + * attempting to obtain an InputStream from a path representing a directory + * and the FileSystemException::getOtherfile returns null + * + * @throws IOException If an error occurs + */ + @Test + public void testException() throws IOException { + try (FileSystem zipfs = FileSystems.newFileSystem(ZIP_FILE)) { + var file = zipfs.getPath(DIRECTORY_NAME); + var x = assertThrows(FileSystemException.class, () -> Files.newInputStream(file)); + // validate that other file should be null + assertNull(x.getOtherFile()); + assertEquals(DIR_EXCEPTION_MESSAGE, x.getMessage()); + } + } +} From 955abcae55583367940e23ccec6c93328a169795 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 20 Apr 2023 15:38:11 +0000 Subject: [PATCH 064/288] 8306483: (ch) Channels.newReader(ReadableByteChannel,Charset) refers to csName Reviewed-by: alanb --- src/java.base/share/classes/java/nio/channels/Channels.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/nio/channels/Channels.java b/src/java.base/share/classes/java/nio/channels/Channels.java index 1d2ccaa7788..e5d0492b910 100644 --- a/src/java.base/share/classes/java/nio/channels/Channels.java +++ b/src/java.base/share/classes/java/nio/channels/Channels.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -490,7 +490,7 @@ public final class Channels { * behaves in exactly the same way as the expression * *

 {@code
-     *     Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
+     *     Channels.newReader(ch, charset.newDecoder(), -1)
      * } 
* *

The reader's default action for malformed-input and unmappable-character @@ -590,7 +590,7 @@ public final class Channels { * behaves in exactly the same way as the expression * *

 {@code
-     *     Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
+     *     Channels.newWriter(ch, charset.newEncoder(), -1)
      * } 
* *

The writer's default action for malformed-input and unmappable-character From 20b1d19d26a039b963590ca6f806f78a4a94c25f Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Thu, 20 Apr 2023 16:11:29 +0000 Subject: [PATCH 065/288] 8305746: InitializeEncoding should cache Charset object instead of charset name Reviewed-by: naoto --- src/java.base/share/native/libjava/jni_util.c | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c index c20d7484a92..43a2ac5440a 100644 --- a/src/java.base/share/native/libjava/jni_util.c +++ b/src/java.base/share/native/libjava/jni_util.c @@ -630,11 +630,11 @@ getStringCp1252Chars(JNIEnv *env, jstring jstr) } static int fastEncoding = NO_ENCODING_YET; -static jstring jnuEncoding = NULL; +static jobject jnuCharset = NULL; /* Cached method IDs */ -static jmethodID String_init_ID; /* String(byte[], enc) */ -static jmethodID String_getBytes_ID; /* String.getBytes(enc) */ +static jmethodID String_init_ID; /* String(byte[], Charset) */ +static jmethodID String_getBytes_ID; /* String.getBytes(Charset) */ /* Cached field IDs */ static jfieldID String_coder_ID; /* String.coder */ @@ -658,7 +658,7 @@ newSizedStringJava(JNIEnv *env, const char *str, const int len) CHECK_NULL_RETURN(strClazz, 0); (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *)str); result = (*env)->NewObject(env, strClazz, - String_init_ID, bytes, jnuEncoding); + String_init_ID, bytes, jnuCharset); (*env)->DeleteLocalRef(env, bytes); return result; } @@ -717,18 +717,15 @@ InitializeEncoding(JNIEnv *env, const char *encname) * "en_GB" locale -> "ISO8859-1" (on Sol 7/8) * "en_UK" locale -> "ISO8859-1" (on 2.6) */ + const char *charsetname = NULL; if ((strcmp(encname, "8859_1") == 0) || (strcmp(encname, "ISO8859-1") == 0) || (strcmp(encname, "ISO8859_1") == 0) || (strcmp(encname, "ISO-8859-1") == 0)) { fastEncoding = FAST_8859_1; } else if (strcmp(encname, "UTF-8") == 0) { - jstring enc = (*env)->NewStringUTF(env, encname); - if (enc == NULL) - return; + charsetname = encname; fastEncoding = FAST_UTF_8; - jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); - (*env)->DeleteLocalRef(env, enc); } else if (strcmp(encname, "ISO646-US") == 0) { fastEncoding = FAST_646_US; } else if (strcmp(encname, "Cp1252") == 0 || @@ -738,31 +735,38 @@ InitializeEncoding(JNIEnv *env, const char *encname) strcmp(encname, "utf-16le") == 0) { fastEncoding = FAST_CP1252; } else { - jboolean exe; - jstring enc = (*env)->NewStringUTF(env, encname); - if (enc == NULL) + charsetname = encname; + fastEncoding = NO_FAST_ENCODING; + } + while (charsetname != NULL) { + jstring enc = (*env)->NewStringUTF(env, charsetname); + if (enc == NULL) { + fastEncoding = NO_ENCODING_YET; return; - - if ((jboolean) JNU_CallStaticMethodByName ( - env, &exe, - "java/nio/charset/Charset", - "isSupported", - "(Ljava/lang/String;)Z", - enc).z == JNI_TRUE) { - fastEncoding = NO_FAST_ENCODING; - jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); - } else { - // jnuEncoding falls back to UTF-8 - jstring utf8 = (*env)->NewStringUTF(env, "UTF-8"); - if (utf8 == NULL) { - (*env)->DeleteLocalRef(env, enc); - return; - } - fastEncoding = FAST_UTF_8; - jnuEncoding = (jstring)(*env)->NewGlobalRef(env, utf8); - (*env)->DeleteLocalRef(env, utf8); + } + jboolean exc; + jvalue charset = JNU_CallStaticMethodByName( + env, &exc, + "java/nio/charset/Charset", + "forName", + "(Ljava/lang/String;)Ljava/nio/charset/Charset;", + enc); + if (exc) { + (*env)->ExceptionClear(env); } (*env)->DeleteLocalRef(env, enc); + + if (!exc && charset.l != NULL) { + jnuCharset = (*env)->NewGlobalRef(env, charset.l); + (*env)->DeleteLocalRef(env, charset.l); + break; // success, continue below + } else if (strcmp(charsetname, "UTF-8") != 0) { // fall back + charsetname = "UTF-8"; + fastEncoding = FAST_UTF_8; + } else { // give up + fastEncoding = NO_ENCODING_YET; + return; + } } } else { JNU_ThrowInternalError(env, "platform encoding undefined"); @@ -771,10 +775,10 @@ InitializeEncoding(JNIEnv *env, const char *encname) /* Initialize method-id cache */ String_getBytes_ID = (*env)->GetMethodID(env, strClazz, - "getBytes", "(Ljava/lang/String;)[B"); + "getBytes", "(Ljava/nio/charset/Charset;)[B"); CHECK_NULL(String_getBytes_ID); String_init_ID = (*env)->GetMethodID(env, strClazz, - "", "([BLjava/lang/String;)V"); + "", "([BLjava/nio/charset/Charset;)V"); CHECK_NULL(String_init_ID); String_coder_ID = (*env)->GetFieldID(env, strClazz, "coder", "B"); CHECK_NULL(String_coder_ID); @@ -813,7 +817,7 @@ static const char* getStringBytes(JNIEnv *env, jstring jstr) { if ((*env)->EnsureLocalCapacity(env, 2) < 0) return 0; - hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding); + hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuCharset); if (hab != 0) { if (!(*env)->ExceptionCheck(env)) { jint len = (*env)->GetArrayLength(env, hab); From 9412c0a2caf7d1c279f933e1f767eb3689a2a1ca Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Thu, 20 Apr 2023 17:02:53 +0000 Subject: [PATCH 066/288] 8297302: gtest/AsyncLogGtest.java fails AsyncLogTest.stdoutOutput_vm Reviewed-by: dholmes, shade --- test/hotspot/gtest/logging/test_asynclog.cpp | 38 +++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/test/hotspot/gtest/logging/test_asynclog.cpp b/test/hotspot/gtest/logging/test_asynclog.cpp index 6d159d2ef81..216cc320d38 100644 --- a/test/hotspot/gtest/logging/test_asynclog.cpp +++ b/test/hotspot/gtest/logging/test_asynclog.cpp @@ -93,10 +93,8 @@ LOG_LEVEL_LIST if (f != NULL) { size_t sz = output.size(); size_t written = fwrite(output.c_str(), sizeof(char), output.size(), f); - - if (written == sz * sizeof(char)) { - return fclose(f) == 0; - } + // at least see "header" + return fclose(f) == 0 && sz == written && sz >= 6; } return false; @@ -257,38 +255,46 @@ TEST_VM_F(AsyncLogTest, droppingMessage) { TEST_VM_F(AsyncLogTest, stdoutOutput) { testing::internal::CaptureStdout(); + fprintf(stdout, "header"); set_log_config("stdout", "logging=debug"); test_asynclog_ls(); test_asynclog_drop_messages(); AsyncLogWriter::flush(); - EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStdout())); + fflush(nullptr); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); + if (write_to_file(testing::internal::GetCapturedStdout())) { + EXPECT_TRUE(file_contains_substring(TestLogFileName, "header")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); - if (AsyncLogWriter::instance() != nullptr) { - EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + if (AsyncLogWriter::instance() != nullptr) { + EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + } } } TEST_VM_F(AsyncLogTest, stderrOutput) { testing::internal::CaptureStderr(); + fprintf(stderr, "header"); set_log_config("stderr", "logging=debug"); test_asynclog_ls(); test_asynclog_drop_messages(); AsyncLogWriter::flush(); - EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStderr())); + fflush(nullptr); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); - EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); + if (write_to_file(testing::internal::GetCapturedStderr())) { + EXPECT_TRUE(file_contains_substring(TestLogFileName, "header")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3")); + EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline")); - if (AsyncLogWriter::instance() != nullptr) { - EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + if (AsyncLogWriter::instance() != nullptr) { + EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging")); + } } } From d6cf4aa1551df591c7bc75cb8c5e90d57630ca2a Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Thu, 20 Apr 2023 18:34:19 +0000 Subject: [PATCH 067/288] 8305874: Open source AWT Key, Text Event related tests Reviewed-by: azvegint --- .../KeyEvent/KeyTyped/DeleteKeyTyped.java | 143 ++++++++++++++++++ .../KeyEvent/KeyTyped/EscapeKeyTyped.java | 136 +++++++++++++++++ .../java/awt/event/KeyEvent/ShiftF10Test.java | 68 +++++++++ .../OtherEvents/ContainerEventChildTest.java | 87 +++++++++++ .../event/TextEvent/InitialTextEventTest.java | 113 ++++++++++++++ 5 files changed, 547 insertions(+) create mode 100644 test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java create mode 100644 test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java create mode 100644 test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java create mode 100644 test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java create mode 100644 test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java diff --git a/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java b/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java new file mode 100644 index 00000000000..cde75cf7c3a --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/* + * @test + * @bug 4724007 + * @key headful + * @summary Tests that KeyTyped events are fired for the Delete key + * and that no extraneous characters are entered as a result. + */ + +public class DeleteKeyTyped { + private static Frame frame; + private static TextField tf; + + private static boolean deleteKeyTypedReceived = false; + private static final String ORIGINAL = "0123456789"; + private static final String SUCCESS = "123456789"; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + EventQueue.invokeAndWait(DeleteKeyTyped::createTestUI); + robot.waitForIdle(); + robot.delay(1000); + + // Move cursor to start of TextField + robot.keyPress(KeyEvent.VK_HOME); + robot.keyRelease(KeyEvent.VK_HOME); + robot.waitForIdle(); + robot.delay(50); + + // Press and release Delete + robot.keyPress(KeyEvent.VK_DELETE); + robot.keyRelease(KeyEvent.VK_DELETE); + robot.waitForIdle(); + robot.delay(50); + + EventQueue.invokeAndWait(DeleteKeyTyped::testDeleteKeyEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createTestUI() { + frame = new Frame(); + tf = new TextField(ORIGINAL, 20); + frame.add(tf); + frame.setSize(300, 100); + frame.setVisible(true); + tf.requestFocusInWindow(); + + tf.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent evt) { + printKey(evt); + } + + @Override + public void keyTyped(KeyEvent evt) { + printKey(evt); + int keychar = evt.getKeyChar(); + if (keychar == 127) { // Delete character is 127 or \u007F + deleteKeyTypedReceived = true; + } + } + + @Override + public void keyReleased(KeyEvent evt) { + printKey(evt); + } + + private void printKey(KeyEvent evt) { + switch(evt.getID()) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + break; + default: + System.out.println("Other Event"); + return; + } + + System.out.println("params= " + evt.paramString() + " \n" + + "KeyChar: " + evt.getKeyChar() + " = " + (int) evt.getKeyChar() + + " KeyCode: " + evt.getKeyCode() + + " Modifiers: " + evt.getModifiersEx()); + + if (evt.isActionKey()) { + System.out.println("Action Key"); + } + + System.out.println("keyText= " + KeyEvent.getKeyText(evt.getKeyCode()) + "\n"); + } + }); + } + + private static void testDeleteKeyEvent() { + if (deleteKeyTypedReceived) { + if (tf.getText().equals(SUCCESS)) { + System.out.println("Test PASSED"); + } else { + System.out.println("Test FAILED: wrong string"); + throw new RuntimeException("The test failed: wrong string: " + + tf.getText()); + } + } + } +} diff --git a/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java new file mode 100644 index 00000000000..6410fc4bad8 --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/* + * @test + * @key headful + * @bug 4734408 + * @summary Tests that KeyTyped events are fired for the Escape key + * and that no extraneous characters are entered as a result. + */ + +public class EscapeKeyTyped { + private static Frame frame; + private static TextField tf; + + private static final String ORIGINAL = "0123456789"; + private static boolean escapeKeyTypedReceived = false; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(30); + + EventQueue.invokeAndWait(EscapeKeyTyped::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + + // Press and release Escape + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + robot.delay(20); + + EventQueue.invokeAndWait(EscapeKeyTyped::testEscKeyEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + frame = new Frame(); + tf = new TextField(ORIGINAL, 20); + frame.add(tf); + frame.setSize(300, 100); + frame.setVisible(true); + tf.requestFocusInWindow(); + + tf.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + printKey(e); + } + + @Override + public void keyPressed(KeyEvent e) { + printKey(e); + int keychar = e.getKeyChar(); + if (keychar == 27) { // Escape character is 27 or \u0021 + escapeKeyTypedReceived = true; + } + } + + @Override + public void keyReleased(KeyEvent e) { + printKey(e); + } + + private void printKey(KeyEvent evt) { + switch (evt.getID()) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + break; + default: + System.out.println("Other Event"); + return; + } + + System.out.println("params= " + evt.paramString() + " \n" + + "KeyChar: " + evt.getKeyChar() + " = " + (int) evt.getKeyChar() + + " KeyCode: " + evt.getKeyCode() + + " Modifiers: " + evt.getModifiersEx()); + + if (evt.isActionKey()) { + System.out.println("Action Key"); + } + + System.out.println("keyText= " + KeyEvent.getKeyText(evt.getKeyCode()) + "\n"); + } + }); + } + + private static void testEscKeyEvent() { + if (escapeKeyTypedReceived) { + if (tf.getText().equals(ORIGINAL)) { + System.out.println("Test PASSED"); + } else { + System.out.println("Test FAILED: wrong string"); + throw new RuntimeException("The test failed: wrong string: " + + tf.getText()); + } + } + } +} diff --git a/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java b/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java new file mode 100644 index 00000000000..df002164ef8 --- /dev/null +++ b/test/jdk/java/awt/event/KeyEvent/ShiftF10Test.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +/* + * @test + * @key headful + * @bug 4965227 + * @requires (os.family == "linux") + * @summary tests that Shift+F10 during Window show doesn't cause deadlock- Linux only + */ + +public class ShiftF10Test { + private static Frame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + EventQueue.invokeLater(() -> { + frame = new Frame("Deadlocking one"); + frame.setSize(100, 100); + frame.setVisible(true); + }); + + for (int i = 0; i < 250; i++) { + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_F10); + robot.keyRelease(KeyEvent.VK_F10); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.delay(10); + } + } catch (Exception e) { + throw new RuntimeException("Test Failed due to following error: ", e); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java b/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java new file mode 100644 index 00000000000..5e0d6a4d32a --- /dev/null +++ b/test/jdk/java/awt/event/OtherEvents/ContainerEventChildTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ContainerAdapter; +import java.awt.event.ContainerEvent; + +/* + * @test + * @key headful + * @bug 4028904 + * @summary Tests whether System.out.println(ContainerEvent e) + * yields incorrect display or not. + */ + +public class ContainerEventChildTest { + private static Frame frame; + private static String com1, com2; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + Panel outerPanel = new Panel(); + Panel innerPanel = new Panel(); + Button b = new Button("Panel Button"); + + innerPanel.addContainerListener(new ContainerAdapter() { + public void componentAdded(ContainerEvent e) { + String str1 = e.toString(); + String str2 = (e.getChild()).toString(); + + // extracting child values from ContainerEvent i.e., "e" and "e.getChild()" + com1 = str1.substring(str1.indexOf("child") + 6, str1.indexOf("]")); + com2 = str2.substring(str2.indexOf("[") + 1, str2.indexOf(",")); + + System.out.println("e : " + com1); + System.out.println("e.getChild() : " + com2); + + // comparing the child values between "e" and "e.getChild()" + // if child value of "e" equals null and child values between + // "e" and "e.getChild()" are not equal then throws exception + if (com1.equals("null") && !(com1.equals(com2))) { + System.out.println("unequal"); + throw new RuntimeException("Test Failed e.toString returns false value"); + } else { + System.out.println("Test Passed - e and e.getChild() are same"); + } + } + }); + innerPanel.add(b); + outerPanel.add(innerPanel); + frame.add(outerPanel); + frame.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java b/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java new file mode 100644 index 00000000000..00d3e16a618 --- /dev/null +++ b/test/jdk/java/awt/event/TextEvent/InitialTextEventTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.IllegalComponentStateException; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; + +/* + * @test + * @bug 4503516 + * @key headful + * @summary TextEvent behaves differently across platforms, especially Solaris. + * Following testcase is used to test whether an initial TextEvent + * is triggered when a TextArea or TextField is initially added to UI. + */ + +public class InitialTextEventTest implements TextListener { + private static Frame frame; + private static TextField textField; + private static TextArea textArea; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + + InitialTextEventTest textEventObj = new InitialTextEventTest(); + EventQueue.invokeAndWait(textEventObj::createUI); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(textEventObj::testInitialTextEvent); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private void createUI() { + frame = new Frame(); + frame.setTitle("Text Event Test"); + frame.setLayout(new FlowLayout()); + + textField = new TextField("TextField"); + textArea = new TextArea("TextArea", 5, 10); + + textField.addTextListener(this); + textArea.addTextListener(this); + + frame.add(textField); + frame.add(textArea); + + frame.setBackground(Color.red); + frame.setSize(500,200); + frame.setVisible(true); + } + + private void testInitialTextEvent() { + Point pt; + boolean drawn = false; + while (!drawn) { + try { + pt = textArea.getLocationOnScreen(); + System.out.println("On-Screen Location on Text Area: " + pt); + pt = textField.getLocationOnScreen(); + System.out.println("On-Screen Location on Text Field: " + pt); + } catch (IllegalComponentStateException icse) { + try { + Thread.sleep(50); + } catch (InterruptedException ignored) {} + continue; + } + drawn = true; + } + } + + @Override + public void textValueChanged(TextEvent e) { + System.out.println("text event paramString: " + e.paramString()); + System.out.println("text event changed on: " + e.getSource().getClass().getName()); + throw new RuntimeException("InitialTextEventTest FAILED"); + } +} From afd2501fcc9f8ccb4993a6565d68b882e5130688 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 20 Apr 2023 19:13:14 +0000 Subject: [PATCH 068/288] 8306482: Remove unused Method AccessFlags Reviewed-by: dholmes, matsaave --- src/hotspot/share/runtime/vmStructs.cpp | 3 --- src/hotspot/share/utilities/accessFlags.hpp | 14 -------------- .../classes/sun/jvm/hotspot/oops/AccessFlags.java | 5 ----- .../sun/jvm/hotspot/runtime/ClassConstants.java | 5 ----- 4 files changed, 27 deletions(-) diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 4f1b24a9aad..551f83af902 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -2089,8 +2089,6 @@ declare_constant(JVM_ACC_LOOPS_FLAG_INIT) \ declare_constant(JVM_ACC_QUEUED) \ declare_constant(JVM_ACC_NOT_C2_OSR_COMPILABLE) \ - declare_constant(JVM_ACC_HAS_LINE_NUMBER_TABLE) \ - declare_constant(JVM_ACC_HAS_CHECKED_EXCEPTIONS) \ declare_constant(JVM_ACC_HAS_JSRS) \ declare_constant(JVM_ACC_IS_OLD) \ declare_constant(JVM_ACC_IS_OBSOLETE) \ @@ -2099,7 +2097,6 @@ declare_constant(JVM_ACC_HAS_VANILLA_CONSTRUCTOR) \ declare_constant(JVM_ACC_HAS_FINALIZER) \ declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ - declare_constant(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) \ \ declare_constant(JVM_CONSTANT_Utf8) \ declare_constant(JVM_CONSTANT_Unicode) \ diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index d213b166e89..36acf437e56 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -51,8 +51,6 @@ enum { JVM_ACC_NOT_C2_COMPILABLE = 0x02000000, JVM_ACC_NOT_C1_COMPILABLE = 0x04000000, JVM_ACC_NOT_C2_OSR_COMPILABLE = 0x08000000, - JVM_ACC_HAS_LINE_NUMBER_TABLE = 0x00100000, - JVM_ACC_HAS_CHECKED_EXCEPTIONS = 0x00400000, JVM_ACC_HAS_JSRS = 0x00800000, JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete @@ -68,9 +66,6 @@ enum { JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class - - // Method* flags - JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00400000, }; @@ -109,8 +104,6 @@ class AccessFlags { bool is_not_c1_compilable () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE ) != 0; } bool is_not_c2_compilable () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE ) != 0; } bool is_not_c2_osr_compilable() const { return (_flags & JVM_ACC_NOT_C2_OSR_COMPILABLE ) != 0; } - bool has_linenumber_table () const { return (_flags & JVM_ACC_HAS_LINE_NUMBER_TABLE ) != 0; } - bool has_checked_exceptions () const { return (_flags & JVM_ACC_HAS_CHECKED_EXCEPTIONS ) != 0; } bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; } bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; } @@ -126,11 +119,6 @@ class AccessFlags { bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; } - // Method* flags - bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; } - void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } - void clear_has_localvariable_table() { atomic_clear_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); } - bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; } // get .class file flags @@ -168,8 +156,6 @@ class AccessFlags { void set_not_c1_compilable() { atomic_set_bits(JVM_ACC_NOT_C1_COMPILABLE); } void set_not_c2_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_COMPILABLE); } void set_not_c2_osr_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); } - void set_has_linenumber_table() { atomic_set_bits(JVM_ACC_HAS_LINE_NUMBER_TABLE); } - void set_has_checked_exceptions() { atomic_set_bits(JVM_ACC_HAS_CHECKED_EXCEPTIONS); } void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); } void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index 917515c2a0d..10bf119532a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -64,8 +64,6 @@ public class AccessFlags implements /* imports */ ClassConstants { public boolean loopsFlagInit () { return (flags & JVM_ACC_LOOPS_FLAG_INIT ) != 0; } public boolean queuedForCompilation() { return (flags & JVM_ACC_QUEUED ) != 0; } public boolean isNotOsrCompilable () { return (flags & JVM_ACC_NOT_OSR_COMPILABLE ) != 0; } - public boolean hasLineNumberTable () { return (flags & JVM_ACC_HAS_LINE_NUMBER_TABLE ) != 0; } - public boolean hasCheckedExceptions() { return (flags & JVM_ACC_HAS_CHECKED_EXCEPTIONS ) != 0; } public boolean hasJsrs () { return (flags & JVM_ACC_HAS_JSRS ) != 0; } public boolean isObsolete () { return (flags & JVM_ACC_IS_OBSOLETE ) != 0; } @@ -75,9 +73,6 @@ public class AccessFlags implements /* imports */ ClassConstants { public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; } public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; } - // Klass* and Method* flags - public boolean hasLocalVariableTable() { return (flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE ) != 0; } - public void printOn(PrintStream tty) { // prints only .class flags and not the hotspot internal flags if (isPublic ()) tty.print("public " ); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 8492e222403..0032152a66a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -118,8 +118,6 @@ public interface ClassConstants // invocation counter machinery. Until it is, we will keep track of methods which // cannot be on stack replaced in the access flags. public static final long JVM_ACC_NOT_OSR_COMPILABLE = 0x08000000; - public static final long JVM_ACC_HAS_LINE_NUMBER_TABLE = 0x00100000; - public static final long JVM_ACC_HAS_CHECKED_EXCEPTIONS = 0x00400000; public static final long JVM_ACC_HAS_JSRS = 0x00800000; // RedefineClasses() has made method obsolete public static final long JVM_ACC_IS_OBSOLETE = 0x00010000; @@ -134,9 +132,6 @@ public interface ClassConstants // True if klass supports the Clonable interface public static final long JVM_ACC_IS_CLONEABLE = 0x80000000; - // Method* flags - public static final long JVM_ACC_HAS_LOCAL_VARIABLE_TABLE = 0x00200000; - // flags accepted by set_field_flags public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS; From f63362310e17ba5c3e415ef3c5bd5f9bd65fd67c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 20 Apr 2023 19:20:03 +0000 Subject: [PATCH 069/288] 8306474: Move InstanceKlass read-only flags Reviewed-by: jrose, dholmes --- src/hotspot/share/classfile/classFileParser.cpp | 8 ++++---- src/hotspot/share/oops/instanceKlass.cpp | 2 +- src/hotspot/share/oops/instanceKlass.hpp | 7 +++++++ src/hotspot/share/oops/instanceKlassFlags.hpp | 8 ++++++-- src/hotspot/share/oops/klass.hpp | 6 ------ src/hotspot/share/runtime/vmStructs.cpp | 2 -- src/hotspot/share/utilities/accessFlags.hpp | 9 --------- .../share/classes/sun/jvm/hotspot/oops/AccessFlags.java | 2 -- .../share/classes/sun/jvm/hotspot/oops/Klass.java | 4 +--- .../classes/sun/jvm/hotspot/runtime/ClassConstants.java | 4 ---- 10 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 74625830093..547167974ac 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -4070,7 +4070,7 @@ void OopMapBlocksBuilder::print_value_on(outputStream* st) const { void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) { assert(ik != nullptr, "invariant"); - const Klass* const super = ik->super(); + const InstanceKlass* const super = ik->java_super(); // Check if this klass has an empty finalize method (i.e. one with return bytecode only), // in which case we don't have to register objects as finalizable @@ -4349,7 +4349,7 @@ static void check_final_method_override(const InstanceKlass* this_klass, TRAPS) const Symbol* const name = m->name(); const Symbol* const signature = m->signature(); - const Klass* k = this_klass->super(); + const InstanceKlass* k = this_klass->java_super(); const Method* super_m = nullptr; while (k != nullptr) { // skip supers that don't have final methods. @@ -4381,11 +4381,11 @@ static void check_final_method_override(const InstanceKlass* this_klass, TRAPS) } // continue to look from super_m's holder's super. - k = super_m->method_holder()->super(); + k = super_m->method_holder()->java_super(); continue; } - k = k->super(); + k = k->java_super(); } } } diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index a6f2245e3cd..803b9ac6afa 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -2133,9 +2133,9 @@ void PrintClassClosure::do_klass(Klass* k) { char buf[10]; int i = 0; if (k->has_finalizer()) buf[i++] = 'F'; - if (k->has_final_method()) buf[i++] = 'f'; if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k); + if (ik->has_final_method()) buf[i++] = 'f'; if (ik->is_rewritten()) buf[i++] = 'W'; if (ik->is_contended()) buf[i++] = 'C'; if (ik->has_been_redefined()) buf[i++] = 'R'; diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 8927125351a..32d6cc881df 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -759,6 +759,13 @@ public: bool declares_nonstatic_concrete_methods() const { return _misc_flags.declares_nonstatic_concrete_methods(); } void set_declares_nonstatic_concrete_methods(bool b) { _misc_flags.set_declares_nonstatic_concrete_methods(b); } + bool has_vanilla_constructor() const { return _misc_flags.has_vanilla_constructor(); } + void set_has_vanilla_constructor() { _misc_flags.set_has_vanilla_constructor(true); } + bool has_miranda_methods () const { return _misc_flags.has_miranda_methods(); } + void set_has_miranda_methods() { _misc_flags.set_has_miranda_methods(true); } + bool has_final_method() const { return _misc_flags.has_final_method(); } + void set_has_final_method() { _misc_flags.set_has_final_method(true); } + // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } diff --git a/src/hotspot/share/oops/instanceKlassFlags.hpp b/src/hotspot/share/oops/instanceKlassFlags.hpp index 5423db111b2..8655e7ad5c8 100644 --- a/src/hotspot/share/oops/instanceKlassFlags.hpp +++ b/src/hotspot/share/oops/instanceKlassFlags.hpp @@ -49,7 +49,11 @@ class InstanceKlassFlags { flag(is_shared_platform_class , 1 << 8) /* defining class loader is platform class loader */ \ flag(is_shared_app_class , 1 << 9) /* defining class loader is app class loader */ \ flag(has_contended_annotations , 1 << 10) /* has @Contended annotation */ \ - flag(has_localvariable_table , 1 << 11) /* has localvariable information */ + flag(has_localvariable_table , 1 << 11) /* has localvariable information */ \ + flag(has_miranda_methods , 1 << 12) /* True if this class has miranda methods in it's vtable */ \ + flag(has_vanilla_constructor , 1 << 13) /* True if klass has a vanilla default constructor */ \ + flag(has_final_method , 1 << 14) /* True if klass has final method */ \ + /* end of list */ #define IK_FLAGS_ENUM_NAME(name, value) _misc_##name = value, enum { @@ -82,7 +86,7 @@ class InstanceKlassFlags { public: - InstanceKlassFlags() : _flags(0) {} + InstanceKlassFlags() : _flags(0), _status(0) {} // Create getters and setters for the flag values. #define IK_FLAGS_GET(name, ignore) \ diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index ce52452467f..abe8951fddd 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -659,13 +659,7 @@ protected: bool is_synthetic() const { return _access_flags.is_synthetic(); } void set_is_synthetic() { _access_flags.set_is_synthetic(); } bool has_finalizer() const { return _access_flags.has_finalizer(); } - bool has_final_method() const { return _access_flags.has_final_method(); } void set_has_finalizer() { _access_flags.set_has_finalizer(); } - void set_has_final_method() { _access_flags.set_has_final_method(); } - bool has_vanilla_constructor() const { return _access_flags.has_vanilla_constructor(); } - void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); } - bool has_miranda_methods () const { return access_flags().has_miranda_methods(); } - void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); } bool is_hidden() const { return access_flags().is_hidden_class(); } void set_is_hidden() { _access_flags.set_is_hidden_class(); } bool is_value_based() { return _access_flags.is_value_based_class(); } diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 551f83af902..0aea64ba14a 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -2093,8 +2093,6 @@ declare_constant(JVM_ACC_IS_OLD) \ declare_constant(JVM_ACC_IS_OBSOLETE) \ declare_constant(JVM_ACC_IS_PREFIXED_NATIVE) \ - declare_constant(JVM_ACC_HAS_MIRANDA_METHODS) \ - declare_constant(JVM_ACC_HAS_VANILLA_CONSTRUCTOR) \ declare_constant(JVM_ACC_HAS_FINALIZER) \ declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ \ diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index 36acf437e56..80b504f838f 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -59,11 +59,8 @@ enum { JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method // Klass* flags - JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000, // True if this class has miranda methods in it's vtable - JVM_ACC_HAS_VANILLA_CONSTRUCTOR = 0x20000000, // True if klass has a vanilla default constructor JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code - JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class }; @@ -111,10 +108,7 @@ class AccessFlags { bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; } // Klass* flags - bool has_miranda_methods () const { return (_flags & JVM_ACC_HAS_MIRANDA_METHODS ) != 0; } - bool has_vanilla_constructor () const { return (_flags & JVM_ACC_HAS_VANILLA_CONSTRUCTOR) != 0; } bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } - bool has_final_method () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD ) != 0; } bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; } @@ -166,11 +160,8 @@ class AccessFlags { void clear_not_c2_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_COMPILABLE); } void clear_not_c2_osr_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); } // Klass* flags - void set_has_vanilla_constructor() { atomic_set_bits(JVM_ACC_HAS_VANILLA_CONSTRUCTOR); } void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); } - void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); } void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); } - void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); } void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); } void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java index 10bf119532a..15b0941332b 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/AccessFlags.java @@ -68,8 +68,6 @@ public class AccessFlags implements /* imports */ ClassConstants { public boolean isObsolete () { return (flags & JVM_ACC_IS_OBSOLETE ) != 0; } // Klass* flags - public boolean hasMirandaMethods () { return (flags & JVM_ACC_HAS_MIRANDA_METHODS ) != 0; } - public boolean hasVanillaConstructor() { return (flags & JVM_ACC_HAS_VANILLA_CONSTRUCTOR) != 0; } public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; } public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java index 2f61619052d..ce869afad8a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -232,6 +232,4 @@ public class Klass extends Metadata implements ClassConstants { public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); } public boolean hasFinalizer() { return getAccessFlagsObj().hasFinalizer(); } public boolean isCloneable() { return getAccessFlagsObj().isCloneable(); } - public boolean hasVanillaConstructor() { return getAccessFlagsObj().hasVanillaConstructor(); } - public boolean hasMirandaMethods () { return getAccessFlagsObj().hasMirandaMethods(); } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java index 0032152a66a..aee4d1bcdc9 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java @@ -123,10 +123,6 @@ public interface ClassConstants public static final long JVM_ACC_IS_OBSOLETE = 0x00010000; // Klass* flags - // True if this class has miranda methods in it's vtable - public static final long JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000; - // True if klass has a vanilla default constructor - public static final long JVM_ACC_HAS_VANILLA_CONSTRUCTOR = 0x20000000; // True if klass has a non-empty finalize() method public static final long JVM_ACC_HAS_FINALIZER = 0x40000000; // True if klass supports the Clonable interface From 174c1a6d53d3ea95649a511f4088c7807d80b59b Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Thu, 20 Apr 2023 21:11:00 +0000 Subject: [PATCH 070/288] 4737887: (cal) API: Calendar methods taking field should document exceptions Reviewed-by: naoto --- .../share/classes/java/util/Calendar.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java index c9b9dc41ec9..0414eebda8e 100644 --- a/src/java.base/share/classes/java/util/Calendar.java +++ b/src/java.base/share/classes/java/util/Calendar.java @@ -105,6 +105,10 @@ import sun.util.spi.CalendarProvider; * the Epoch) or values of the calendar fields. Calling the * {@code get}, {@code getTimeInMillis}, {@code getTime}, * {@code add} and {@code roll} involves such calculation. + * Unless otherwise specified, any {@code Calendar} method containing the + * parameter {@code int field} will throw an {@code ArrayIndexOutOfBoundsException} + * if the specified field is out of range ({@code field} < 0 || + * {@code field} >= {@link #FIELD_COUNT}). * *

Leniency

* @@ -1844,8 +1848,8 @@ public abstract class Calendar implements Serializable, Cloneable, Comparablefield < 0 || field >= FIELD_COUNT). + * @throws IllegalArgumentException if this {@code Calendar} is non-lenient and any + * of the calendar fields have invalid values. * @see #set(int,int) * @see #complete() */ @@ -1873,8 +1877,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparablefield < 0 || field >= FIELD_COUNT). * @see #areFieldsSet * @see #isTimeSet * @see #areAllFieldsSet @@ -1891,9 +1893,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparablefield < 0 || field >= FIELD_COUNT). - * in non-lenient mode. * @see #set(int,int,int) * @see #set(int,int,int,int,int) * @see #set(int,int,int,int,int,int) @@ -2816,6 +2815,9 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable Date: Thu, 20 Apr 2023 21:20:08 +0000 Subject: [PATCH 071/288] 8305207: Calendar.aggregateStamp(int, int) return value can be simplified Reviewed-by: naoto, rriggs, iris --- src/java.base/share/classes/java/util/Calendar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java index 0414eebda8e..6e3fa4a561d 100644 --- a/src/java.base/share/classes/java/util/Calendar.java +++ b/src/java.base/share/classes/java/util/Calendar.java @@ -2630,7 +2630,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable stamp_b) ? stamp_a : stamp_b; + return Math.max(stamp_a, stamp_b); } /** From 2c70828e7dc78783c174e3f93c94b6e2439d2dfb Mon Sep 17 00:00:00 2001 From: sunguoyun Date: Fri, 21 Apr 2023 00:47:24 +0000 Subject: [PATCH 072/288] 8305236: Some LoadLoad barriers in the interpreter are unnecessary after JDK-8220051 Reviewed-by: dholmes, fyang, aph --- src/hotspot/cpu/aarch64/templateTable_aarch64.cpp | 12 ------------ src/hotspot/cpu/riscv/templateTable_riscv.cpp | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp index 20177d8d49e..3a93d89da62 100644 --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp @@ -1747,12 +1747,6 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) void TemplateTable::branch(bool is_jsr, bool is_wide) { - // We might be moving to a safepoint. The thread which calls - // Interpreter::notice_safepoints() will effectively flush its cache - // when it makes a system call, but we need to do something to - // ensure that we see the changed dispatch table. - __ membar(MacroAssembler::LoadLoad); - __ profile_taken_branch(r0, r1); const ByteSize be_offset = MethodCounters::backedge_counter_offset() + InvocationCounter::counter_offset(); @@ -1968,12 +1962,6 @@ void TemplateTable::if_acmp(Condition cc) void TemplateTable::ret() { transition(vtos, vtos); - // We might be moving to a safepoint. The thread which calls - // Interpreter::notice_safepoints() will effectively flush its cache - // when it makes a system call, but we need to do something to - // ensure that we see the changed dispatch table. - __ membar(MacroAssembler::LoadLoad); - locals_index(r1); __ ldr(r1, aaddress(r1)); // get return bci, compute return bcp __ profile_ret(r1, r2); diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index 82858f0c7dc..deff3080a81 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1600,12 +1600,6 @@ void TemplateTable::float_cmp(bool is_float, int unordered_result) { } void TemplateTable::branch(bool is_jsr, bool is_wide) { - // We might be moving to a safepoint. The thread which calls - // Interpreter::notice_safepoints() will effectively flush its cache - // when it makes a system call, but we need to do something to - // ensure that we see the changed dispatch table. - __ membar(MacroAssembler::LoadLoad); - __ profile_taken_branch(x10, x11); const ByteSize be_offset = MethodCounters::backedge_counter_offset() + InvocationCounter::counter_offset(); @@ -1854,12 +1848,6 @@ void TemplateTable::if_acmp(Condition cc) { void TemplateTable::ret() { transition(vtos, vtos); - // We might be moving to a safepoint. The thread which calls - // Interpreter::notice_safepoints() will effectively flush its cache - // when it makes a system call, but we need to do something to - // ensure that we see the changed dispatch table. - __ membar(MacroAssembler::LoadLoad); - locals_index(x11); __ ld(x11, aaddress(x11, t1, _masm)); // get return bci, compute return bcp __ profile_ret(x11, x12); From 9a68d1d952c308c03c29747794d409831008c144 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 21 Apr 2023 02:42:55 +0000 Subject: [PATCH 073/288] 8306060: Open source few AWT Insets related tests Reviewed-by: serb, prr --- .../Insets/ClobberSharedInsetsObjectTest.java | 88 +++++++++++++++++++ .../java/awt/Insets/RemoveMenuBarTest.java | 68 ++++++++++++++ test/jdk/java/awt/Insets/SetInsetsTest.java | 45 ++++++++++ .../jdk/java/awt/Insets/WindowInsetsTest.java | 69 +++++++++++++++ 4 files changed, 270 insertions(+) create mode 100644 test/jdk/java/awt/Insets/ClobberSharedInsetsObjectTest.java create mode 100644 test/jdk/java/awt/Insets/RemoveMenuBarTest.java create mode 100644 test/jdk/java/awt/Insets/SetInsetsTest.java create mode 100644 test/jdk/java/awt/Insets/WindowInsetsTest.java diff --git a/test/jdk/java/awt/Insets/ClobberSharedInsetsObjectTest.java b/test/jdk/java/awt/Insets/ClobberSharedInsetsObjectTest.java new file mode 100644 index 00000000000..8b18d8aa17f --- /dev/null +++ b/test/jdk/java/awt/Insets/ClobberSharedInsetsObjectTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4198994 + @summary getInsets should return Insets object that is safe to modify + @key headful + @run main ClobberSharedInsetsObjectTest +*/ + +/** + * ClobberSharedInsetsObjectTest.java + * + * summary: The bug is that getInsets directly returns Insets object + * obtained from peer getInsets. The latter always return the + * reference to the same object, so modifying this object will affect + * other code that calls getInsets. The test checks that it's safe to + * modify the Insets object returned by getInsets. If the change to + * this object is not visible on the next invocation, the bug is + * considered to be fixed. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Panel; + +public class ClobberSharedInsetsObjectTest { + static Panel p; + + // Impossible inset value to use for the test + final static int SENTINEL_INSET_VALUE = -10; + static Frame f; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + // Need a peer anyway, so let the bug manifest visuially, even + // though we can detect it automatically. + f = new Frame(); + p = new Panel(); + p.setBackground(Color.red); + f.setLayout (new BorderLayout ()); + f.add(p, "Center"); + + Insets insetsBefore = p.getInsets(); + insetsBefore.top = SENTINEL_INSET_VALUE; + + Insets insetsAfter = p.getInsets(); + if (insetsAfter.top == SENTINEL_INSET_VALUE) { // OOPS! + throw new Error("4198994: getInsets returns the same object on subsequent invocations"); + } + + f.setSize (200,200); + f.setLocationRelativeTo(null); + f.setVisible(true); + + System.out.println("getInsets is ok. The object it returns is safe to modify."); + } finally { + if (f != null) { + f.dispose(); + } + } + }); + } +} diff --git a/test/jdk/java/awt/Insets/RemoveMenuBarTest.java b/test/jdk/java/awt/Insets/RemoveMenuBarTest.java new file mode 100644 index 00000000000..d6285ee3176 --- /dev/null +++ b/test/jdk/java/awt/Insets/RemoveMenuBarTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6353381 + @summary REG: Container.getInsets() returns an incorrect value after removal of menubar, Win32 + @key headful + @run main RemoveMenuBarTest +*/ +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Menu; +import java.awt.MenuBar; + +public class RemoveMenuBarTest { + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + // old insets: top>0 | left>0 + // new insets: top=0 & left=0 + // the bug is that updating doesn't happen + frame = new Frame(); + MenuBar menubar = new MenuBar(); + frame.setBounds(100,100,100,100); + frame.setUndecorated(true); + frame.pack(); + menubar.add(new Menu()); + frame.setMenuBar(menubar); + System.out.println(frame.getInsets()); + + frame.setMenuBar(null); + Insets insets = frame.getInsets(); + System.out.println(insets); + if (insets.top != 0 || insets.left != 0 || + insets.bottom !=0 || insets.right != 0) { + throw new RuntimeException("Test failed: the incorrect insets"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } +} diff --git a/test/jdk/java/awt/Insets/SetInsetsTest.java b/test/jdk/java/awt/Insets/SetInsetsTest.java new file mode 100644 index 00000000000..c1177160958 --- /dev/null +++ b/test/jdk/java/awt/Insets/SetInsetsTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4704042 + @summary Unit tests for Insets.set() + @run main SetInsetsTest +*/ +import java.awt.Insets; +import java.awt.EventQueue; + +public class SetInsetsTest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + Insets insets = new Insets(0,0,0,0); + insets.set(100,100,100,100); + if (insets.top != 100 || + insets.bottom != 100 || + insets.left != 100 || + insets.right != 100) { + throw new RuntimeException("Test Failed! Insets=" + insets); + } + }); + } +}// class SetInsetsTest diff --git a/test/jdk/java/awt/Insets/WindowInsetsTest.java b/test/jdk/java/awt/Insets/WindowInsetsTest.java new file mode 100644 index 00000000000..56abfecdc43 --- /dev/null +++ b/test/jdk/java/awt/Insets/WindowInsetsTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 5089312 + @summary Bottom inset must not change after a second pack call. + @key headful + @run main WindowInsetsTest +*/ +import java.awt.EventQueue; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JWindow; + +public class WindowInsetsTest { + static JFrame frame; + static JWindow window; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + frame = new JFrame("Window Test"); + frame.setBounds(100, 100, 400, 300); + frame.setVisible(true); + + JButton button = new JButton("A Button"); + window = new JWindow(frame); + window.getContentPane().add(button); + window.pack(); + window.setLocation(200, 200); + window.show(); + double h0 = window.getSize().getHeight(); + window.pack(); + double h1 = window.getSize().getHeight(); + if( Math.abs(h1 - h0) > 0.5 ) { + throw new RuntimeException("Test failed: Bad insets."); + } + System.out.println("Test Passed."); + } finally { + if (window != null) { + window.dispose(); + } + if (frame != null) { + frame.dispose(); + } + } + }); + } +} From 8346ae2bc1152f13bc77c643252d84e2043ffe0b Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 21 Apr 2023 02:51:12 +0000 Subject: [PATCH 074/288] 8305942: Open source several AWT Focus related tests Reviewed-by: prr --- test/jdk/java/awt/Focus/QuickTypeTest.java | 215 +++++++++++++++++ .../Focus/RowToleranceTransitivityTest.java | 220 ++++++++++++++++++ .../Focus/TemporaryLostComponentDeadlock.java | 74 ++++++ .../Focus/TraversalKeysPropertyNamesTest.java | 112 +++++++++ test/jdk/java/awt/Focus/UpFocusCycleTest.java | 95 ++++++++ .../Focus/VetoableChangeListenerLoopTest.java | 115 +++++++++ 6 files changed, 831 insertions(+) create mode 100644 test/jdk/java/awt/Focus/QuickTypeTest.java create mode 100644 test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java create mode 100644 test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java create mode 100644 test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java create mode 100644 test/jdk/java/awt/Focus/UpFocusCycleTest.java create mode 100644 test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java diff --git a/test/jdk/java/awt/Focus/QuickTypeTest.java b/test/jdk/java/awt/Focus/QuickTypeTest.java new file mode 100644 index 00000000000..0cfd0ef5f1d --- /dev/null +++ b/test/jdk/java/awt/Focus/QuickTypeTest.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + @test + @bug 4423838 + @summary KEY_TYPED and KEY_PRESSED generated by the same key are notified to + different TextFields + @key headful + @run main QuickTypeTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import java.util.Properties; + +import javax.swing.JFrame; +import javax.swing.JTextField; + +public class QuickTypeTest { + static final int TEST_TIMEOUT=10000; + static JFrame frame1; + static JFrame frame2; + static JTextField tf1; + static JTextField tf2; + static SmartKeyAdapter ska; + static Object keyMonitor; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame1 = new JFrame("First Frame"); + frame2 = new JFrame("Second Frame"); + tf1 = new JTextField("", 10); + tf2 = new JTextField("", 10); + frame1.getContentPane().add(tf1); + frame2.getContentPane().add(tf2); + frame1.setLocation(200,220); + frame2.setLocation(220,300); + frame1.pack(); + frame2.pack(); + keyMonitor = new Object(); + ska = new SmartKeyAdapter(frame2, keyMonitor); + tf1.addKeyListener(ska); + frame1.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); + Object tf1Monitor = new Object(); + MonitoredFocusListener monitorer = new MonitoredFocusListener(tf1Monitor); + tf1.addFocusListener(monitorer); + Point origin = tf1.getLocationOnScreen(); + Dimension dim = tf1.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!tf1.isFocusOwner()) { + synchronized (tf1Monitor) { + tf1Monitor.wait(TEST_TIMEOUT); + } + } + if (!tf1.isFocusOwner()) { + throw new RuntimeException("TEST FAILED. tf1 doesn't receive focus."); + } + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_B); + robot.keyRelease(KeyEvent.VK_B); + if (!ska.isFrameShown) { + synchronized (keyMonitor) { + keyMonitor.wait(TEST_TIMEOUT); + } + } + if (!ska.isFrameShown) { + throw new RuntimeException("TEST FAILED. Second frame is not shown."); + } + + Object waitMonitor = new Object(); + ReleaseWaiter waiter = new ReleaseWaiter(waitMonitor, KeyEvent.VK_C); + tf1.addKeyListener(waiter); + tf2.addKeyListener(waiter); + robot.keyPress(KeyEvent.VK_C); + robot.keyRelease(KeyEvent.VK_C); + + synchronized (waitMonitor) { + waitMonitor.wait(2000); + } + + if ((tf1.getText().length() > 2) || (tf2.getText().length() < 1)) { + System.out.println("tf1's text = \"" + tf1.getText() + "\""); + System.out.println("tf2's text = \"" + tf2.getText() + "\""); + System.out.println("l1 = " + tf1.getText().length()); + System.out.println("l2 = " + tf2.getText().length()); + throw new RuntimeException("TEST FAILED."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame1 != null) { + frame1.dispose(); + } + if (frame2 != null) { + frame2.dispose(); + } + }); + } + } + + }// class QuickTypeTest + +class ReleaseWaiter extends KeyAdapter { + Object monitor; + int keycode; + public ReleaseWaiter(Object monitor, int keycode) { + this.monitor = monitor; + this.keycode = keycode; + } + + public void keyReleased(KeyEvent ke) { + System.out.println("keyReleased " + ke.getKeyCode()); + if (ke.getKeyCode() == keycode) { + synchronized (monitor) { + monitor.notify(); + } + } + } +} + +class SmartKeyAdapter implements KeyListener { + JFrame frame; + int charCounter = 0; + boolean isFrameShown = false; + Object monitor; + + public SmartKeyAdapter(JFrame frame, Object monitor) { + this.frame = frame; + this.monitor = monitor; + } + + public void keyReleased(KeyEvent ke) { + System.out.println(ke.toString()); + } + public void keyPressed(KeyEvent ke) { + System.out.println(ke.toString()); + charCounter++; + if (charCounter == 2) { + frame.setVisible(true); + isFrameShown = true; + synchronized (monitor) { + monitor.notify(); + } + } + } + public void keyTyped(KeyEvent ke) { + System.out.println(ke.toString()); + } +} + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusLost(FocusEvent fe) { + System.out.println(fe.toString()); + } + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java new file mode 100644 index 00000000000..099e81a1ab0 --- /dev/null +++ b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5070991 + @key headful + @summary Tests for a transitivity problem with ROW_TOLERANCE in SortingFTP. + @run main RowToleranceTransitivityTest +*/ +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class RowToleranceTransitivityTest { + static JFrame frame; + static JPanel panel; + static JFormattedTextField ft; + static JCheckBox cb; + static GridBagConstraints gc; + static Robot robot; + + static AtomicBoolean focusGained = new AtomicBoolean(false); + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + try { + EventQueue.invokeAndWait(() -> { + gc = new GridBagConstraints(); + frame = new JFrame("JFrame"); + JPanel panel = new JPanel(new GridBagLayout()); + ft = new JFormattedTextField(); + cb = new JCheckBox("JCheckBox"); + Dimension dim = new Dimension(100, ft.getPreferredSize().height); + ft.setPreferredSize(dim); + ft.setMinimumSize(dim); + gc.gridx = 5; + gc.gridy = 1; + gc.gridwidth = 10; + panel.add(ft, gc); + + gc.gridy = 3; + panel.add(cb, gc); + + cb.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + gc.weightx = 1.0; + gc.gridwidth = 1; + gc.gridy = 0; + gc.gridx = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridy++; + } + + gc.gridx = 0; + gc.gridy = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridx++; + } + + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.setAlwaysOnTop(true); + + }); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() throws Exception { + robot.delay(500); + + // Set focus on the first component to start traversal + if (!setFocusOn(ft, new Runnable() { + public void run() { + clickOn(ft); + } + })) { + System.out.println("Couldn't set focus on " + ft); + throw new RuntimeException("Test couldn't be performed."); + } + + robot.delay(500); + + // Try to traverse + if (!setFocusOn(cb, new Runnable() { + public void run() { + robot.keyPress(KeyEvent.VK_TAB); + } + })) { + System.out.println("Focus got stuck while traversing."); + throw new RuntimeException("Test failed!"); + } + + System.out.println("Test passed."); + } + + static boolean setFocusOn(Component comp, Runnable action) { + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == comp) { + System.out.println("Already focus owner: " + comp); + return true; + } + + focusGained.set(false); + + System.out.println("Setting focus on " + comp); + + comp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + action.run(); + + synchronized (focusGained) { + if (!focusGained.get()) { + try { + focusGained.wait(3000); + } catch (InterruptedException e) { + System.out.println("Unexpected exception caught!"); + throw new RuntimeException(e); + } + } + } + + return focusGained.get(); + } + + static JLabel getlabel(){ + Dimension dim = new Dimension(5, 9); // LayoutComparator.ROW_TOLERANCE = 10; + JLabel l = new JLabel("*"); + l.setMinimumSize(dim); + l.setMaximumSize(dim); + l.setPreferredSize(dim); + return l; + } + + static void clickOn(Component c) { + Point p = c.getLocationOnScreen(); + Dimension d = c.getSize(); + + System.out.println("Clicking " + c); + + if (c instanceof Frame) { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + ((Frame)c).getInsets().top/2); + } else { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); + } + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + } + +} diff --git a/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java new file mode 100644 index 00000000000..e14492ecf16 --- /dev/null +++ b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4794413 + * @summary Tests that access to temporaryLostComponent from two different threads doesn't cause a deadlock + * @key headful + * @run main TemporaryLostComponentDeadlock +*/ +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; + +public class TemporaryLostComponentDeadlock { + static Dialog frame1; + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("frame"); + frame1 = new Dialog(frame, "Frame 1", false); + frame1.add(new Button("focus owner")); + frame1.pack(); + frame1.setLocationRelativeTo(null); + frame1.setVisible(true); + }); + + Thread t1 = new Thread() { + public void run() { + synchronized(frame1) { + frame1.dispose(); + synchronized(frame1) { + frame1.notify(); + } + } + } + }; + try { + synchronized(frame1) { + t1.start(); + frame1.wait(); + } + } catch( InterruptedException ie) { + } finally { + if (frame != null) { + frame.dispose(); + } + } + System.out.println("Test PASSED"); + } + +}// class TemporaryLostComponentDeadlock diff --git a/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java new file mode 100644 index 00000000000..aec724e457d --- /dev/null +++ b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4457455 + @summary Component and KeyboardFocusManager use wrong names of the properties + @run main TraversalKeysPropertyNamesTest +*/ + +import java.awt.AWTKeyStroke; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashSet; + +public class TraversalKeysPropertyNamesTest implements PropertyChangeListener { + final String[] properties = { + "forwardDefaultFocusTraversalKeys", + "backwardDefaultFocusTraversalKeys", + "upCycleDefaultFocusTraversalKeys", + "downCycleDefaultFocusTraversalKeys", + "forwardFocusTraversalKeys", + "backwardFocusTraversalKeys", + "upCycleFocusTraversalKeys", + "downCycleFocusTraversalKeys" + }; + final int PROPERTIES_COUNT = properties.length; + boolean[] flags = new boolean[PROPERTIES_COUNT]; + + public static void main(String[] args) throws Exception { + TraversalKeysPropertyNamesTest test = new TraversalKeysPropertyNamesTest(); + test.start(); + } + + public void start() throws Exception { + EventQueue.invokeAndWait(() -> { + Container cont = new Container() {}; + HashSet forwardKeys = new HashSet(); + forwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl A")); + HashSet backwardKeys = new HashSet(); + backwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl B")); + HashSet upKeys = new HashSet(); + upKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl C")); + HashSet downKeys = new HashSet(); + downKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl D")); + + KeyboardFocusManager manager = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + manager.addPropertyChangeListener(this); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + cont.addPropertyChangeListener(this); + cont.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + for (int i = 0; i < PROPERTIES_COUNT; i++) { + if (!flags[i]) { + throw new RuntimeException( + "Notification on "+properties[i]+" change was not received"); + } + } + }); + }// start() + + public void propertyChange(PropertyChangeEvent pce) { + String property = pce.getPropertyName(); + System.err.println(property); + int index; + for (index = 0; index < PROPERTIES_COUNT; index++) { + if (property.equals(properties[index])) { + break; + } + } + + if (index < PROPERTIES_COUNT) { + flags[index] = true; + } + } + }// class TraversalKeysPropertyNamesTest diff --git a/test/jdk/java/awt/Focus/UpFocusCycleTest.java b/test/jdk/java/awt/Focus/UpFocusCycleTest.java new file mode 100644 index 00000000000..2c421ffe822 --- /dev/null +++ b/test/jdk/java/awt/Focus/UpFocusCycleTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4394789 + @summary KeyboardFocusManager.upFocusCycle is not working for Swing properly + @key headful + @run main UpFocusCycleTest +*/ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Color; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.Robot; +import javax.swing.DefaultFocusManager; +import javax.swing.JButton; +import javax.swing.JFrame; + +public class UpFocusCycleTest { + static boolean isFailed = true; + static Object sema = new Object(); + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + + frame = new JFrame("Test frame"); + + Container container1 = frame.getContentPane(); + container1.setBackground(Color.yellow); + + JButton button = new JButton("Button"); + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + DefaultKeyboardFocusManager manager = new DefaultFocusManager(); + manager.upFocusCycle(button); + System.out.println("Button receive focus"); + frame.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Frame receive focus"); + synchronized (sema) { + isFailed = false; + sema.notifyAll(); + } + } + }); + } + }); + container1.add(button,BorderLayout.WEST); + button.requestFocus(); + frame.setSize(300,300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + if (isFailed) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("Test PASSED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + }// class UpFocusCycleTest diff --git a/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java new file mode 100644 index 00000000000..b6449b16dbc --- /dev/null +++ b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5074189 + @summary Tests that VetoableChangeListener doesn't initiate infinite loop. + @key headful + @run main VetoableChangeListenerLoopTest +*/ +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +public class VetoableChangeListenerLoopTest { + static Button b1; + static Button b2; + static Frame frame; + static Robot robot; + + static int counter = 0; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener(new VetoableChangeListener () { + public void vetoableChange(PropertyChangeEvent evt) + throws PropertyVetoException { + if (b1.equals(evt.getNewValue())) { + System.out.println("VETOING: " + (counter++)); + if (counter > 2) { + throw new RuntimeException("Test failed!"); + } + throw new PropertyVetoException("Change in property", evt); + } + } + }); + + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + System.out.println(e.toString()); + } + }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK); + + b1 = new Button("Button 1"); + b2 = new Button("Button 2"); + Frame frame = new Frame(); + frame.add(b1); + frame.add(b2); + frame.setSize(200, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() { + b2.requestFocusInWindow(); + waitTillFocus(b2); + b2.setVisible(false); + } + + + static void waitTillFocus(Component comp) { + while (!checkFocusOwner(comp)) { + robot.delay(100); + } + } + + static boolean checkFocusOwner(Component comp) { + return (comp == KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()); + } +} From 36ec05d52a79185d8c6669713fd17933128c032a Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Fri, 21 Apr 2023 05:38:17 +0000 Subject: [PATCH 075/288] 8306430: Open source some AWT tests related to TextComponent and Toolkit Reviewed-by: serb --- .../PeerlessSetCaret/PeerlessSetCaret.java | 46 +++++ .../SelectionBounds/SelectionBounds.java | 107 +++++++++++ .../TextAreaCRLFTest/TextAreaCRLFTest.java | 150 +++++++++++++++ .../AWTEventListenerProxyTest.java | 172 ++++++++++++++++++ .../ListenerDeadlockTest.java | 87 +++++++++ 5 files changed, 562 insertions(+) create mode 100644 test/jdk/java/awt/TextComponent/PeerlessSetCaret/PeerlessSetCaret.java create mode 100644 test/jdk/java/awt/TextComponent/SelectionBounds/SelectionBounds.java create mode 100644 test/jdk/java/awt/TextComponent/TextAreaCRLFTest/TextAreaCRLFTest.java create mode 100644 test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java create mode 100644 test/jdk/java/awt/Toolkit/ListenersDeadlockTest/ListenerDeadlockTest.java diff --git a/test/jdk/java/awt/TextComponent/PeerlessSetCaret/PeerlessSetCaret.java b/test/jdk/java/awt/TextComponent/PeerlessSetCaret/PeerlessSetCaret.java new file mode 100644 index 00000000000..2182cb338e2 --- /dev/null +++ b/test/jdk/java/awt/TextComponent/PeerlessSetCaret/PeerlessSetCaret.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4257143 + @summary RFE: Cannot set some AWT properties until peer has been created + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.TextArea; +import java.awt.TextField; + +public class PeerlessSetCaret { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + TextField tf = new TextField("Hello, World!"); + TextArea ta = new TextArea("Hello, World!"); + + // without the fix these will throw IllegalComponentStateException + tf.setCaretPosition(1); + ta.setCaretPosition(1); + }); + } +} diff --git a/test/jdk/java/awt/TextComponent/SelectionBounds/SelectionBounds.java b/test/jdk/java/awt/TextComponent/SelectionBounds/SelectionBounds.java new file mode 100644 index 00000000000..51a075e7016 --- /dev/null +++ b/test/jdk/java/awt/TextComponent/SelectionBounds/SelectionBounds.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4118247 + @summary Make sure bounds are enforced correctly on + TextComponent.Select(int, int) + @key headful +*/ + +import java.awt.EventQueue; +import java.awt.TextArea; +import java.awt.TextComponent; + +public class SelectionBounds { + public static TextComponent tc; + + public static int[][] index = { + {0, 0}, // 0 = selectionStart = selectionEnd + {5, 5}, // selectionStart = selectionEnd + {5, 7}, // 0 < selectionStart < selectionEnd < textLength + {-50, 7}, // selectionStart < 0 < selectionEnd < textLength + {-50, 50}, // selectionStart < 0 < textLength < selectionEnd + {5, 50}, // 0 < selectionStart < textLength < selectionEnd + {40, 50}, // 0 < textLength < selectionStart < selectionEnd + {-50, -40}, // selectionStart < selectionEnd < 0 < textLength + {7, 5}, // 0 < selectionEnd < selectionStart < textLength + {7, -50}, // selectionEnd < 0 < selectionStart < textLength + {50, -50}, // selectionEnd < 0 < textLength < selectionStart + {50, 5}, // 0 < selectionEnd < textLength < selectionStart + {50, 40}, // 0 < textLength < selectionEnd < selectionStart + {-40, -50} // selectionEnd < selectionStart < 0 < textLength + }; + + public static String[] selections = { + "", + "", + "56", + "0123456", + "0123456789", + "56789", + "", + "", + "", + "", + "", + "", + "", + "" + }; + + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + tc = new TextArea("0123456789"); + runTheTest(); + }); + } + + private static void runTheTest() { + int i; + String str1; + + for (i=0; i { + aDialog = new Dialog(new Frame()); + aDialog.setTitle("ADialog"); + aDialog.setBackground(Color.lightGray); + aDialog.setLayout(new BorderLayout()); + Panel mainPanel = new Panel(); + mainPanel.setLayout(new BorderLayout(6, 6)); + area = new TextArea(atextCRLF, 25, 68, + TextArea.SCROLLBARS_VERTICAL_ONLY); + area.setFont(new Font("Monospaced", Font.PLAIN, 11)); + mainPanel.add(area, "Center"); + aDialog.add(mainPanel, "Center"); + aDialog.pack(); + System.out.println("before: "+hexEncode(atextCRLF)); + System.out.println(" after: "+hexEncode(area.getText())); + res = area.getText().equals(atextCRLF); + System.out.println("01: " + res + "\n"); + passed = passed && res; + area.setText(atextCRLF); + System.out.println("before: "+hexEncode(atextCRLF)); + System.out.println(" after: "+hexEncode(area.getText())); + res = area.getText().equals(atextCRLF); + System.out.println("02: " + res + "\n"); + passed = passed && res; + + area.setText(""); + atext = "row1"; + area.append(atext+"\r"); + area.append(atext+"\r"); + System.out.println("before: " + +hexEncode(atext+"\r" + atext+"\r")); + System.out.println(" after: "+hexEncode(area.getText())); + res = area.getText().equals(atext + atext); + System.out.println("03: " + res + "\n"); + passed = passed && res; + + area.setText(""); + String atext1 = "fine."; + String atext2 = "messed up."; + atext = atext1 +"\r\n"+ atext2; + for (int i = 0; i < atext.length(); i++) { + area.append(atext.substring(i, i+1)); + } + System.out.println("before: " + +hexEncode(atext1 +"\r\n"+ atext2)); + System.out.println(" after: "+hexEncode(area.getText())); + String s = area.getText(); + String t = s.substring(s.length()-atext2.length()); + res = t.equals(atext2); + System.out.println("04: " + res); + passed = passed && res; + + area.setText(""); + atext = "\r"; + area.append(atext); + System.out.println("before: "+hexEncode(atext)); + System.out.println(" after: "+hexEncode(area.getText())); + res = area.getText().equals(""); + System.out.println("05: " + res + "\n"); + passed = passed && res; + + if (System.getProperty("os.name").toUpperCase(). + startsWith("WIN")) { + if (!passed) { + throw new RuntimeException("TextAreaCRLFTest FAILED."); + } else { + System.out.println("TextAreaCRLFTest PASSED"); + } + } else { + System.out.println("This is a Windows oriented testcase."); + } + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (aDialog != null) { + aDialog.dispose(); + } + }); + } + } + + private static String hexEncode(String str) { + return hexEncode(str.getBytes()); + } + + private static String hexEncode(byte[] bytes) { + StringBuffer buffer = new StringBuffer(bytes.length * 2); + for (int i = 0; i < bytes.length; i++) { + byte b = bytes[i]; + buffer.append(DIGITS[(b & 0xF0) >> 4]); + buffer.append(DIGITS[b & 0x0F]); + } + return buffer.toString(); + } +} diff --git a/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java b/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java new file mode 100644 index 00000000000..a2c8613efc9 --- /dev/null +++ b/test/jdk/java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4290704 + @summary Test use of AWTEventListenerProxyTest class +*/ + +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.AWTEventListenerProxy; +import java.util.EventListener; + +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"); + } + System.out.println("[Empty array test passed]"); + + // simple add/get test + DumbListener dl1 = new DumbListener(); + final long dl1MASK = AWTEvent.ACTION_EVENT_MASK; + tk.addAWTEventListener(dl1, dl1MASK); + + 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"); + } + AWTEventListenerProxy dp1 = (AWTEventListenerProxy) array1[0]; + EventListener getdl1 = dp1.getListener(); + if (getdl1 != dl1) { + System.out.println("[Simple add/get test failed - " + + "wrong listener!!]"); + throw new RuntimeException("Test failed - wrong " + + "listener in proxy"); + } + + long getmask = dp1.getEventMask(); + if (getmask != dl1MASK) { + System.out.println("[Simple add/get test failed - " + + "wrong mask!!]"); + throw new RuntimeException("Test failed - wrong mask in proxy"); + } + System.out.println("[Simple add/get test passed]"); + + // add the same listener inside a proxy, with a different mask + // should get back one listener, with the ORed mask + final long dl2MASK = AWTEvent.CONTAINER_EVENT_MASK; + AWTEventListenerProxy newp = new AWTEventListenerProxy(dl2MASK, + dl1); + tk.addAWTEventListener(newp, dl2MASK); + array1 = tk.getAWTEventListeners(); + if (array1.length != 1) { + System.out.println("[Proxy add/get test failed!!]"); + throw new RuntimeException("Test failed - added proxy, " + + "but didn't return array of 1"); + } + dp1 = (AWTEventListenerProxy) array1[0]; + getdl1 = dp1.getListener(); + if (getdl1 != dl1) { + System.out.println("[Proxy add/get test " + + "failed - wrong listener!!]"); + throw new RuntimeException("Test failed - added proxy, " + + "wrong listener in proxy"); + } + getmask = dp1.getEventMask(); + if (getmask != (dl1MASK | dl2MASK)) { + System.out.println("[Proxy add/get test failed - " + + "wrong mask!!]"); + throw new RuntimeException("Test failed - added proxy, " + + "wrong mask in proxy"); + } + System.out.println("[Proxy add/get test passed]"); + + // add some other listener + DumbListener dl3 = new DumbListener(); + final long dl3MASK = AWTEvent.FOCUS_EVENT_MASK; + tk.addAWTEventListener(dl3, dl3MASK); + + // test getting with a mask for a listener already added + array1 = tk.getAWTEventListeners(dl1MASK); + if (array1.length != 1) { + System.out.println("[Get w/ mask test failed!! - " + + "not 1 listener!]"); + throw new RuntimeException("Test failed - tried to " + + "get w/ mask"); + } + dp1 = (AWTEventListenerProxy) array1[0]; + getdl1 = dp1.getListener(); + if (getdl1 != dl1) { + System.out.println("[Get w/ mask test failed!! - " + + "wrong listener]"); + throw new RuntimeException("Test failed - tried to get " + + "w/ mask, wrong listener in proxy"); + } + System.out.println("[Get w/ mask test passed]"); + + // test getting with a mask for a listener not added + array1 = tk.getAWTEventListeners(AWTEvent.MOUSE_EVENT_MASK); + if (array1.length != 0) { + System.out.println("[Get w/ mask test 2 failed!! - " + + "not 0 listeners!]"); + throw new RuntimeException("Test failed - tried to get " + + "w/ mask 2"); + } + System.out.println("[Get w/ mask test 2 passed]"); + + + // test getting with a compound mask for a listener already added + array1 = tk.getAWTEventListeners(dl1MASK | dl2MASK); + if (array1.length != 1) { + System.out.println("[Get w/ compound mask test failed!! - " + + "not 1 listeners!]"); + throw new RuntimeException("Test failed - tried to get w/ 2 " + + "ORed masks"); + } + dp1 = (AWTEventListenerProxy) array1[0]; + getdl1 = dp1.getListener(); + if (getdl1 != dl1) { + System.out.println("[Get w/ compound mask test failed!! - " + + "wrong listener]"); + throw new RuntimeException("Test failed - tried to get w/ " + + "compound mask, wrong listener in proxy"); + } + System.out.println("[Get w/ compound mask test passed]"); + }); + } + + public static class DumbListener implements AWTEventListener { + public DumbListener() {} + public void eventDispatched(AWTEvent e) {} + } +} diff --git a/test/jdk/java/awt/Toolkit/ListenersDeadlockTest/ListenerDeadlockTest.java b/test/jdk/java/awt/Toolkit/ListenersDeadlockTest/ListenerDeadlockTest.java new file mode 100644 index 00000000000..11a3f34c1e4 --- /dev/null +++ b/test/jdk/java/awt/Toolkit/ListenersDeadlockTest/ListenerDeadlockTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4338463 + @summary excessive synchronization in notifyAWTEventListeners leads to + deadlock +*/ + +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.Panel; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.ActionEvent; + +public class ListenerDeadlockTest { + public static final Object lock = new Object(); + + public static final Toolkit toolkit = Toolkit.getDefaultToolkit(); + + public static Panel panel = new Panel(); + + public static final AWTEventListener listener = new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e.getSource() == panel) { + System.out.println(e); + System.out.println("No deadlock"); + synchronized(lock) { + lock.notifyAll(); + } + } + } + }; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + toolkit.addAWTEventListener(listener, -1); + + Thread thread = new Thread(new Runnable() { + public void run() { + synchronized (toolkit) { + synchronized (lock) { + try { + lock.notifyAll(); + lock.wait(); + } catch (InterruptedException ex) { + } + } + } + } + }); + + synchronized (lock) { + thread.start(); + try { + lock.wait(); + } catch (InterruptedException ex) { + } + } + + panel.dispatchEvent(new ActionEvent(panel, + ActionEvent.ACTION_PERFORMED, "Try")); + }); + } +} From fdaabd6eecd86d1a8b1d1a4ed11cd03996d1db65 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Fri, 21 Apr 2023 07:13:50 +0000 Subject: [PATCH 076/288] 8306581: JVMCI tests failed when run with -XX:TypeProfileLevel=222 after JDK-8303431 Reviewed-by: never, kvn --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 503c77b2393..00e7a7c9dad 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2716,7 +2716,7 @@ static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationA InstanceKlass** filter = filter_length == 1 ? (InstanceKlass**) &filter_klass_pointers: (InstanceKlass**) filter_klass_pointers; - objArrayOop filter_oop = oopFactory::new_objectArray(filter_length, CHECK_NULL); + objArrayOop filter_oop = oopFactory::new_objArray(vmClasses::Class_klass(), filter_length, CHECK_NULL); objArrayHandle filter_classes(THREAD, filter_oop); for (int i = 0; i < filter_length; i++) { filter_classes->obj_at_put(i, filter[i]->java_mirror()); From 3da987adacc3acc120a2781ee9a2111e26356723 Mon Sep 17 00:00:00 2001 From: Oli Gillespie Date: Fri, 21 Apr 2023 09:51:36 +0000 Subject: [PATCH 077/288] 8306075: Micro-optimize Enum.hashCode Co-authored-by: Aleksey Shipilev Reviewed-by: redestad, shade, rriggs, liach, apangin, jvernee --- .../share/classes/java/lang/Enum.java | 19 ++++++- .../openjdk/bench/java/lang/EnumHashCode.java | 55 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/micro/org/openjdk/bench/java/lang/EnumHashCode.java diff --git a/src/java.base/share/classes/java/lang/Enum.java b/src/java.base/share/classes/java/lang/Enum.java index 355d18d621b..56016779243 100644 --- a/src/java.base/share/classes/java/lang/Enum.java +++ b/src/java.base/share/classes/java/lang/Enum.java @@ -37,6 +37,8 @@ import java.lang.constant.DynamicConstantDesc; import java.lang.invoke.MethodHandles; import java.util.Optional; +import jdk.internal.vm.annotation.Stable; + import static java.util.Objects.requireNonNull; /** @@ -166,13 +168,28 @@ public abstract class Enum> return this==other; } + /** + * The hash code of this enumeration constant. + */ + @Stable + private int hash; + /** * Returns a hash code for this enum constant. * * @return a hash code for this enum constant. */ public final int hashCode() { - return super.hashCode(); + // Once initialized, the hash field value does not change. + // HotSpot's identity hash code generation also never returns zero + // as the identity hash code. This makes zero a convenient marker + // for the un-initialized value for both @Stable and the lazy + // initialization code below. + int hc = hash; + if (hc == 0) { + hc = hash = System.identityHashCode(this); + } + return hc; } /** diff --git a/test/micro/org/openjdk/bench/java/lang/EnumHashCode.java b/test/micro/org/openjdk/bench/java/lang/EnumHashCode.java new file mode 100644 index 00000000000..eb941bd86e3 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/EnumHashCode.java @@ -0,0 +1,55 @@ +/* + * 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. + */ +package org.openjdk.bench.java.lang; + +import org.openjdk.jmh.annotations.*; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(3) +public class EnumHashCode { + + enum E { + A, B, C; + } + + Enum e = E.A; + + @Benchmark + public int constant() { + // Tests that hash code is constant-foldable + return E.A.hashCode(); + } + + @Benchmark + public int field() { + // Tests that hash code is efficient + return e.hashCode(); + } + +} From 5a00617b1be998327825c3abe82ddc213336758d Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Fri, 21 Apr 2023 11:34:36 +0000 Subject: [PATCH 078/288] 8306543: GHA: MSVC installation is failing Reviewed-by: shade, mdoerr --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 95ef72b31eb..cc5abb20319 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -102,7 +102,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 (x86)\Microsoft Visual Studio\2019\Enterprise' \ --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} - name: 'Configure' From be6031b87d6e0f088a79fdd1697982bb15a7145d Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Fri, 21 Apr 2023 13:31:45 +0000 Subject: [PATCH 079/288] 8303703: Add support of execution tests using virtual thread factory jtreg plugin Reviewed-by: erikj, jpai --- doc/testing.html | 8 +++ doc/testing.md | 9 +++ make/Main.gmk | 22 ++++++- make/RunTests.gmk | 14 +++- make/autoconf/configure.ac | 1 + make/autoconf/lib-tests.m4 | 19 ++++++ make/autoconf/spec.gmk.in | 4 +- make/test/BuildJtregTestThreadFactory.gmk | 65 +++++++++++++++++++ .../src/share/classes/Virtual.java | 43 ++++++++++++ 9 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 make/test/BuildJtregTestThreadFactory.gmk create mode 100644 test/jtreg_test_thread_factory/src/share/classes/Virtual.java diff --git a/doc/testing.html b/doc/testing.html index 37d4df604f5..0f81647ecae 100644 --- a/doc/testing.html +++ b/doc/testing.html @@ -426,6 +426,14 @@ GB/2.

Sets the argument -timeoutHandlerTimeout for JTReg. The default value is 0. This is only valid if the failure handler is built.

+

JTREG_TEST_THREAD_FACTORY

+

Sets the -testThreadFactory for JTReg. It should be the +fully qualified classname of a class which implements +java.util.concurrent.ThreadFactory. One such implementation +class, named Virtual, is currently part of the JDK build in the +test/jtreg_test_thread_factory/ directory. This class gets +compiled during the test image build. The implementation of the Virtual +class creates a new virtual thread for executing each test class.

TEST_MODE

The test mode (agentvm or othervm).

Defaults to agentvm.

diff --git a/doc/testing.md b/doc/testing.md index 3de0c26c391..764fec15c8d 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -378,6 +378,15 @@ Defaults to 4. Sets the argument `-timeoutHandlerTimeout` for JTReg. The default value is 0. This is only valid if the failure handler is built. +#### JTREG_TEST_THREAD_FACTORY + +Sets the `-testThreadFactory` for JTReg. It should be the fully qualified classname +of a class which implements `java.util.concurrent.ThreadFactory`. +One such implementation class, named Virtual, is currently part of the JDK build +in the `test/jtreg_test_thread_factory/` directory. This class gets compiled during +the test image build. The implementation of the Virtual class creates a new virtual +thread for executing each test class. + #### TEST_MODE The test mode (`agentvm` or `othervm`). diff --git a/make/Main.gmk b/make/Main.gmk index 3c7c30caba7..5f647c963b0 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -747,6 +747,22 @@ ifeq ($(BUILD_FAILURE_HANDLER), true) )) endif +ifeq ($(BUILD_JTREG_TEST_THREAD_FACTORY), true) + # Builds the test thread factory jtreg extension + $(eval $(call SetupTarget, build-test-test-thread-factory, \ + MAKEFILE := test/BuildJtregTestThreadFactory, \ + TARGET := build, \ + DEPS := interim-langtools exploded-image, \ + )) + + # Copies the jtreg test thread factory into the test image + $(eval $(call SetupTarget, test-image-test-thread-factory, \ + MAKEFILE := test/BuildJtregTestThreadFactory, \ + TARGET := images, \ + DEPS := build-test-test-thread-factory, \ + )) +endif + $(eval $(call SetupTarget, build-microbenchmark, \ MAKEFILE := test/BuildMicrobenchmark, \ DEPS := interim-langtools exploded-image, \ @@ -1227,6 +1243,10 @@ ifeq ($(BUILD_FAILURE_HANDLER), true) test-image: test-image-failure-handler endif +ifeq ($(BUILD_JTREG_TEST_THREAD_FACTORY), true) + test-image: test-image-test-thread-factory +endif + ifneq ($(JMH_CORE_JAR), ) test-image: build-microbenchmark endif diff --git a/make/RunTests.gmk b/make/RunTests.gmk index 50342077645..aba7b3a78f6 100644 --- a/make/RunTests.gmk +++ b/make/RunTests.gmk @@ -93,6 +93,9 @@ endif JTREG_FAILURE_HANDLER_DIR := $(TEST_IMAGE_DIR)/failure_handler JTREG_FAILURE_HANDLER := $(JTREG_FAILURE_HANDLER_DIR)/jtregFailureHandler.jar +JTREG_TEST_THREAD_FACTORY_DIR := $(TEST_IMAGE_DIR)/jtreg_test_thread_factory +JTREG_TEST_THREAD_FACTORY_JAR := $(JTREG_TEST_THREAD_FACTORY_DIR)/jtregTestThreadFactory.jar + JTREG_FAILURE_HANDLER_TIMEOUT ?= 0 ifneq ($(wildcard $(JTREG_FAILURE_HANDLER)), ) @@ -200,7 +203,7 @@ $(eval $(call SetTestOpt,REPORT,JTREG)) $(eval $(call ParseKeywordVariable, JTREG, \ SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR FAILURE_HANDLER_TIMEOUT \ - TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM RUN_PROBLEM_LISTS \ + TEST_MODE ASSERT VERBOSE RETAIN TEST_THREAD_FACTORY MAX_MEM RUN_PROBLEM_LISTS \ RETRY_COUNT REPEAT_COUNT MAX_OUTPUT REPORT $(CUSTOM_JTREG_SINGLE_KEYWORDS), \ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS KEYWORDS \ EXTRA_PROBLEM_LISTS LAUNCHER_OPTIONS \ @@ -752,6 +755,7 @@ define SetupRunJtregTestBody JTREG_VERBOSE ?= fail,error,summary JTREG_RETAIN ?= fail,error + JTREG_TEST_THREAD_FACTORY ?= JTREG_RUN_PROBLEM_LISTS ?= false JTREG_RETRY_COUNT ?= 0 JTREG_REPEAT_COUNT ?= 0 @@ -765,6 +769,14 @@ define SetupRunJtregTestBody endif endif + ifneq ($$(JTREG_TEST_THREAD_FACTORY), ) + $1_JTREG_BASIC_OPTIONS += -testThreadFactoryPath:$$(JTREG_TEST_THREAD_FACTORY_JAR) + $1_JTREG_BASIC_OPTIONS += -testThreadFactory:$$(JTREG_TEST_THREAD_FACTORY) + $1_JTREG_BASIC_OPTIONS += $$(addprefix $$(JTREG_PROBLEM_LIST_PREFIX), $$(wildcard \ + $$(addprefix $$($1_TEST_ROOT)/, ProblemList-$$(JTREG_TEST_THREAD_FACTORY).txt) \ + )) + endif + ifneq ($$(JTREG_LAUNCHER_OPTIONS), ) $1_JTREG_LAUNCHER_OPTIONS += $$(JTREG_LAUNCHER_OPTIONS) endif diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index 5d48bd9aadd..2d6cb000d43 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -249,6 +249,7 @@ HOTSPOT_SETUP_MISC ############################################################################### LIB_TESTS_ENABLE_DISABLE_FAILURE_HANDLER +LIB_TESTS_ENABLE_DISABLE_JTREG_TEST_THREAD_FACTORY JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST JDKOPT_EXCLUDE_TRANSLATIONS diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4 index 4d771f7e5f2..6af9045a136 100644 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -301,3 +301,22 @@ AC_DEFUN_ONCE([LIB_TESTS_ENABLE_DISABLE_FAILURE_HANDLER], ]) AC_SUBST(BUILD_FAILURE_HANDLER) ]) + +AC_DEFUN_ONCE([LIB_TESTS_ENABLE_DISABLE_JTREG_TEST_THREAD_FACTORY], +[ + UTIL_ARG_ENABLE(NAME: jtreg-test-thread-factory, DEFAULT: auto, + RESULT: BUILD_JTREG_TEST_THREAD_FACTORY, + DESC: [enable building of the jtreg test thread factory], + DEFAULT_DESC: [enabled if jtreg is present], + CHECKING_MSG: [if the jtreg test thread factory should be built], + CHECK_AVAILABLE: [ + AC_MSG_CHECKING([if the jtreg test thread factory is available]) + if test "x$JT_HOME" != "x"; then + AC_MSG_RESULT([yes]) + else + AVAILABLE=false + AC_MSG_RESULT([no (jtreg not present)]) + fi + ]) + AC_SUBST(BUILD_JTREG_TEST_THREAD_FACTORY) +]) diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index ff073c78c92..550c196ed89 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -358,6 +358,8 @@ BUILDJDK_OUTPUTDIR=$(OUTPUTDIR)/buildjdk BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@ +BUILD_JTREG_TEST_THREAD_FACTORY := @BUILD_JTREG_TEST_THREAD_FACTORY@ + ENABLE_GENERATE_CLASSLIST := @ENABLE_GENERATE_CLASSLIST@ EXCLUDE_TRANSLATIONS := @EXCLUDE_TRANSLATIONS@ diff --git a/make/test/BuildJtregTestThreadFactory.gmk b/make/test/BuildJtregTestThreadFactory.gmk new file mode 100644 index 00000000000..b096ae303ea --- /dev/null +++ b/make/test/BuildJtregTestThreadFactory.gmk @@ -0,0 +1,65 @@ +# +# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# 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. +# + +default: build + +include $(SPEC) +include MakeBase.gmk +include JavaCompilation.gmk + +TARGETS := + +################################################################################ + +TTF_BASEDIR := $(TOPDIR)/test/jtreg_test_thread_factory +TTF_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/jtreg_test_thread_factory +TTF_JAR := $(TTF_SUPPORT)/jtregTestThreadFactory.jar + +$(eval $(call SetupJavaCompilation, BUILD_JTREG_TEST_THREAD_FACTORY, \ + TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ + SRC := $(TTF_BASEDIR)/src/share/classes, \ + BIN := $(TTF_SUPPORT)/classes, \ + JAR := $(TTF_JAR), \ +)) + +TARGETS += $(BUILD_JTREG_TEST_THREAD_FACTORY) + +################################################################################ +# Targets for building test-image. +################################################################################ + +# Copy to hotspot jtreg test image +$(eval $(call SetupCopyFiles, COPY_TTF, \ + SRC := $(TTF_SUPPORT), \ + DEST := $(TEST_IMAGE_DIR)/jtreg_test_thread_factory, \ + FILES := $(TTF_JAR), \ +)) + +IMAGES_TARGETS += $(COPY_TTF) + +build: $(TARGETS) +images: $(IMAGES_TARGETS) + +.PHONY: all images diff --git a/test/jtreg_test_thread_factory/src/share/classes/Virtual.java b/test/jtreg_test_thread_factory/src/share/classes/Virtual.java new file mode 100644 index 00000000000..80b0b59fa1a --- /dev/null +++ b/test/jtreg_test_thread_factory/src/share/classes/Virtual.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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.concurrent.ThreadFactory; + +public class Virtual implements ThreadFactory { + + static { + // This property is used by ProcessTools and some tests + try { + System.setProperty("main.wrapper", "Virtual"); + } catch (Throwable t) { + // might be thrown by security manager + } + } + + static final ThreadFactory VIRTUAL_TF = Thread.ofVirtual().factory(); + + @Override + public Thread newThread(Runnable task) { + return VIRTUAL_TF.newThread(task); + } +} From 6e77e14fdbf4ab083020467cf2ecb8225f3dcbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Fri, 21 Apr 2023 13:36:36 +0000 Subject: [PATCH 080/288] 8306456: Don't leak _worklist's memory in PhaseLive::compute Reviewed-by: kvn, dlong --- src/hotspot/share/opto/live.cpp | 21 +++++++++++---------- src/hotspot/share/opto/live.hpp | 10 ++++------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/opto/live.cpp b/src/hotspot/share/opto/live.cpp index ea1722702ce..6932fd6a697 100644 --- a/src/hotspot/share/opto/live.cpp +++ b/src/hotspot/share/opto/live.cpp @@ -54,7 +54,6 @@ PhaseLive::PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, b void PhaseLive::compute(uint maxlrg) { _maxlrg = maxlrg; - _worklist = new (_arena) Block_List(); // Init the sparse live arrays. This data is live on exit from here! // The _live info is the live-out info. @@ -88,6 +87,8 @@ void PhaseLive::compute(uint maxlrg) { _free_IndexSet = nullptr; + Block_List worklist; + // Blocks having done pass-1 VectorSet first_pass; @@ -135,13 +136,13 @@ void PhaseLive::compute(uint maxlrg) { // Push these live-in things to predecessors for (uint l = 1; l < block->num_preds(); l++) { Block* p = _cfg.get_block_for_node(block->pred(l)); - add_liveout(p, use, first_pass); + add_liveout(worklist, p, use, first_pass); // PhiNode uses go in the live-out set of prior blocks. for (uint k = i; k > 0; k--) { Node *phi = block->get_node(k - 1); if (l < phi->req()) { - add_liveout(p, _names.at(phi->in(l)->_idx), first_pass); + add_liveout(worklist, p, _names.at(phi->in(l)->_idx), first_pass); } } } @@ -149,15 +150,15 @@ void PhaseLive::compute(uint maxlrg) { first_pass.set(block->_pre_order); // Inner loop: blocks that picked up new live-out values to be propagated - while (_worklist->size()) { - Block* block = _worklist->pop(); + while (worklist.size() != 0) { + Block* block = worklist.pop(); IndexSet *delta = getset(block); assert(delta->count(), "missing delta set"); // Add new-live-in to predecessors live-out sets for (uint l = 1; l < block->num_preds(); l++) { Block* predecessor = _cfg.get_block_for_node(block->pred(l)); - add_liveout(predecessor, delta, first_pass); + add_liveout(worklist, predecessor, delta, first_pass); } freeset(block); @@ -228,7 +229,7 @@ void PhaseLive::freeset(Block *p) { // Add a live-out value to a given blocks live-out set. If it is new, then // also add it to the delta set and stick the block on the worklist. -void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) { +void PhaseLive::add_liveout(Block_List& worklist, Block* p, uint r, VectorSet& first_pass) { IndexSet *live = &_live[p->_pre_order-1]; if (live->insert(r)) { // If actually inserted... // We extended the live-out set. See if the value is generated locally. @@ -236,7 +237,7 @@ void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) { if (!_defs[p->_pre_order-1].member(r)) { if (!_deltas[p->_pre_order-1] && // Not on worklist? first_pass.test(p->_pre_order)) { - _worklist->push(p); // Actually go on worklist if already 1st pass + worklist.push(p); // Actually go on worklist if already 1st pass } getset(p)->insert(r); } @@ -244,7 +245,7 @@ void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) { } // Add a vector of live-out values to a given blocks live-out set. -void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) { +void PhaseLive::add_liveout(Block_List& worklist, Block* p, IndexSet* lo, VectorSet& first_pass) { IndexSet *live = &_live[p->_pre_order-1]; IndexSet *defs = &_defs[p->_pre_order-1]; IndexSet *on_worklist = _deltas[p->_pre_order-1]; @@ -265,7 +266,7 @@ void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) { _deltas[p->_pre_order-1] = delta; // Flag as on worklist now if (!on_worklist && // Not on worklist? first_pass.test(p->_pre_order)) { - _worklist->push(p); // Actually go on worklist if already 1st pass + worklist.push(p); // Actually go on worklist if already 1st pass } } else { // Nothing there; just free it delta->set_next(_free_IndexSet); diff --git a/src/hotspot/share/opto/live.hpp b/src/hotspot/share/opto/live.hpp index d5ff1570fd1..1ff93bc5767 100644 --- a/src/hotspot/share/opto/live.hpp +++ b/src/hotspot/share/opto/live.hpp @@ -57,20 +57,18 @@ class PhaseLive : public Phase { IndexSet **_deltas; IndexSet *_free_IndexSet; // Free list of same - Block_List *_worklist; // Worklist for iterative solution - const PhaseCFG &_cfg; // Basic blocks const LRG_List &_names; // Mapping from Nodes to live ranges uint _maxlrg; // Largest live-range number Arena *_arena; bool _keep_deltas; // Retain live in information - IndexSet *getset( Block *p ); + IndexSet *getset(Block* p); IndexSet *getfreeset( ); void freeset( Block *p ); - void add_liveout( Block *p, uint r, VectorSet &first_pass ); - void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ); - void add_livein( Block *p, IndexSet *lo ); + void add_liveout(Block_List& worklist, Block* p, uint r, VectorSet& first_pass); + void add_liveout(Block_List& worklist, Block* p, IndexSet* lo, VectorSet& first_pass); + void add_livein(Block* p, IndexSet* lo); public: PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, bool keep_deltas); From 9cd5741c14358d6e9ffc97d63ba2d2adebf73ca2 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Fri, 21 Apr 2023 14:05:16 +0000 Subject: [PATCH 081/288] 8306436: Rename PSS*:_n_workers to PSS*:_num_workers Reviewed-by: ayang, iwalulya --- .../share/gc/g1/g1ParScanThreadState.cpp | 30 ++++++++++--------- .../share/gc/g1/g1ParScanThreadState.hpp | 6 ++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index 4b650004630..f81e7ebec49 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -58,7 +58,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, G1RedirtyCardsQueueSet* rdcqs, PreservedMarks* preserved_marks, uint worker_id, - uint n_workers, + uint num_workers, size_t young_cset_length, size_t optional_cset_length, G1EvacFailureRegions* evac_failure_regions) @@ -81,7 +81,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _surviving_words_length(young_cset_length + 1), _old_gen_is_full(false), _partial_objarray_chunk_size(ParGCArrayScanChunk), - _partial_array_stepper(n_workers), + _partial_array_stepper(num_workers), _string_dedup_requests(), _num_optional_regions(optional_cset_length), _numa(g1h->numa()), @@ -562,13 +562,15 @@ oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr region_attr, } G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) { - assert(worker_id < _n_workers, "out of bounds access"); + assert(worker_id < _num_workers, "out of bounds access"); if (_states[worker_id] == NULL) { _states[worker_id] = new G1ParScanThreadState(_g1h, rdcqs(), _preserved_marks_set.get(worker_id), - worker_id, _n_workers, - _young_cset_length, _optional_cset_length, + worker_id, + _num_workers, + _young_cset_length, + _optional_cset_length, _evac_failure_regions); } return _states[worker_id]; @@ -582,7 +584,7 @@ const size_t* G1ParScanThreadStateSet::surviving_young_words() const { void G1ParScanThreadStateSet::flush_stats() { assert(!_flushed, "thread local state from the per thread states should be flushed once"); - for (uint worker_id = 0; worker_id < _n_workers; ++worker_id) { + for (uint worker_id = 0; worker_id < _num_workers; ++worker_id) { G1ParScanThreadState* pss = _states[worker_id]; assert(pss != nullptr, "must be initialized"); @@ -592,20 +594,20 @@ void G1ParScanThreadStateSet::flush_stats() { // because it resets the PLAB allocator where we get this info from. size_t lab_waste_bytes = pss->lab_waste_words() * HeapWordSize; size_t lab_undo_waste_bytes = pss->lab_undo_waste_words() * HeapWordSize; - size_t copied_bytes = pss->flush_stats(_surviving_young_words_total, _n_workers) * HeapWordSize; + size_t copied_bytes = pss->flush_stats(_surviving_young_words_total, _num_workers) * HeapWordSize; p->record_or_add_thread_work_item(G1GCPhaseTimes::MergePSS, worker_id, copied_bytes, G1GCPhaseTimes::MergePSSCopiedBytes); p->record_or_add_thread_work_item(G1GCPhaseTimes::MergePSS, worker_id, lab_waste_bytes, G1GCPhaseTimes::MergePSSLABWasteBytes); p->record_or_add_thread_work_item(G1GCPhaseTimes::MergePSS, worker_id, lab_undo_waste_bytes, G1GCPhaseTimes::MergePSSLABUndoWasteBytes); delete pss; - _states[worker_id] = NULL; + _states[worker_id] = nullptr; } _flushed = true; } void G1ParScanThreadStateSet::record_unused_optional_region(HeapRegion* hr) { - for (uint worker_index = 0; worker_index < _n_workers; ++worker_index) { + for (uint worker_index = 0; worker_index < _num_workers; ++worker_index) { G1ParScanThreadState* pss = _states[worker_index]; assert(pss != nullptr, "must be initialized"); @@ -687,22 +689,22 @@ void G1ParScanThreadState::update_numa_stats(uint node_index) { } G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, - uint n_workers, + uint num_workers, size_t young_cset_length, size_t optional_cset_length, G1EvacFailureRegions* evac_failure_regions) : _g1h(g1h), _rdcqs(G1BarrierSet::dirty_card_queue_set().allocator()), _preserved_marks_set(true /* in_c_heap */), - _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)), + _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, num_workers, mtGC)), _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length + 1, mtGC)), _young_cset_length(young_cset_length), _optional_cset_length(optional_cset_length), - _n_workers(n_workers), + _num_workers(num_workers), _flushed(false), _evac_failure_regions(evac_failure_regions) { - _preserved_marks_set.init(n_workers); - for (uint i = 0; i < n_workers; ++i) { + _preserved_marks_set.init(num_workers); + for (uint i = 0; i < num_workers; ++i) { _states[i] = NULL; } memset(_surviving_young_words_total, 0, (young_cset_length + 1) * sizeof(size_t)); diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index bd8da47fefc..6fb95ea6e93 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -115,7 +115,7 @@ public: G1RedirtyCardsQueueSet* rdcqs, PreservedMarks* preserved_marks, uint worker_id, - uint n_workers, + uint num_workers, size_t young_cset_length, size_t optional_cset_length, G1EvacFailureRegions* evac_failure_regions); @@ -236,13 +236,13 @@ class G1ParScanThreadStateSet : public StackObj { size_t* _surviving_young_words_total; size_t _young_cset_length; size_t _optional_cset_length; - uint _n_workers; + uint _num_workers; bool _flushed; G1EvacFailureRegions* _evac_failure_regions; public: G1ParScanThreadStateSet(G1CollectedHeap* g1h, - uint n_workers, + uint num_workers, size_t young_cset_length, size_t optional_cset_length, G1EvacFailureRegions* evac_failure_regions); From d518dbf726ca41f4566df74deed6adeb39ce2ed7 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Fri, 21 Apr 2023 14:16:34 +0000 Subject: [PATCH 082/288] 8306440: Rename PSS:_num_optional_regions to _max_num_optional_regions Reviewed-by: ayang, iwalulya --- src/hotspot/share/gc/g1/g1ParScanThreadState.cpp | 4 ++-- src/hotspot/share/gc/g1/g1ParScanThreadState.hpp | 3 ++- .../share/gc/g1/g1ParScanThreadState.inline.hpp | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index f81e7ebec49..a3740982c45 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -83,7 +83,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _partial_objarray_chunk_size(ParGCArrayScanChunk), _partial_array_stepper(num_workers), _string_dedup_requests(), - _num_optional_regions(optional_cset_length), + _max_num_optional_regions(optional_cset_length), _numa(g1h->numa()), _obj_alloc_stat(NULL), EVAC_FAILURE_INJECTOR_ONLY(_evac_failure_inject_counter(0) COMMA) @@ -106,7 +106,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _closures = G1EvacuationRootClosures::create_root_closures(this, _g1h); - _oops_into_optional_regions = new G1OopStarChunkedList[_num_optional_regions]; + _oops_into_optional_regions = new G1OopStarChunkedList[_max_num_optional_regions]; initialize_numa_stats(); } diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index 6fb95ea6e93..cef6fe8c253 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -92,7 +92,8 @@ class G1ParScanThreadState : public CHeapObj { G1CardTable* ct() { return _ct; } - size_t _num_optional_regions; + // Maximum number of optional regions at start of gc. + size_t _max_num_optional_regions; G1OopStarChunkedList* _oops_into_optional_regions; G1NUMA* _numa; diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp index c37f0f38e51..41553e6bf19 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp @@ -74,8 +74,8 @@ template inline void G1ParScanThreadState::remember_root_into_optional_region(T* p) { oop o = RawAccess::oop_load(p); uint index = _g1h->heap_region_containing(o)->index_in_opt_cset(); - assert(index < _num_optional_regions, - "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _num_optional_regions); + assert(index < _max_num_optional_regions, + "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _max_num_optional_regions); _oops_into_optional_regions[index].push_root(p); } @@ -83,16 +83,16 @@ template inline void G1ParScanThreadState::remember_reference_into_optional_region(T* p) { oop o = RawAccess::oop_load(p); uint index = _g1h->heap_region_containing(o)->index_in_opt_cset(); - assert(index < _num_optional_regions, - "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _num_optional_regions); + assert(index < _max_num_optional_regions, + "Trying to access optional region idx %u beyond " SIZE_FORMAT, index, _max_num_optional_regions); _oops_into_optional_regions[index].push_oop(p); verify_task(p); } G1OopStarChunkedList* G1ParScanThreadState::oops_into_optional_region(const HeapRegion* hr) { - assert(hr->index_in_opt_cset() < _num_optional_regions, + assert(hr->index_in_opt_cset() < _max_num_optional_regions, "Trying to access optional region idx %u beyond " SIZE_FORMAT " " HR_FORMAT, - hr->index_in_opt_cset(), _num_optional_regions, HR_FORMAT_PARAMS(hr)); + hr->index_in_opt_cset(), _max_num_optional_regions, HR_FORMAT_PARAMS(hr)); return &_oops_into_optional_regions[hr->index_in_opt_cset()]; } From 723037a79d2a43b9a1a247d8f81a47907faadab1 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 21 Apr 2023 15:29:45 +0000 Subject: [PATCH 083/288] 8298048: Combine CDS archive heap into a single block Co-authored-by: Thomas Schatzl Reviewed-by: matsaave, tschatzl --- src/hotspot/share/cds/archiveBuilder.cpp | 129 ++--- src/hotspot/share/cds/archiveBuilder.hpp | 18 +- src/hotspot/share/cds/archiveHeapLoader.cpp | 245 +++----- src/hotspot/share/cds/archiveHeapLoader.hpp | 62 +- .../share/cds/archiveHeapLoader.inline.hpp | 16 +- src/hotspot/share/cds/archiveHeapWriter.cpp | 331 ++++------- src/hotspot/share/cds/archiveHeapWriter.hpp | 83 ++- src/hotspot/share/cds/archiveUtils.cpp | 2 +- src/hotspot/share/cds/dumpAllocStats.cpp | 2 +- src/hotspot/share/cds/dynamicArchive.cpp | 4 +- src/hotspot/share/cds/filemap.cpp | 530 ++++++------------ src/hotspot/share/cds/filemap.hpp | 54 +- src/hotspot/share/cds/heapShared.cpp | 149 ++--- src/hotspot/share/cds/heapShared.hpp | 45 +- src/hotspot/share/cds/metaspaceShared.cpp | 43 +- src/hotspot/share/cds/metaspaceShared.hpp | 24 +- src/hotspot/share/classfile/javaClasses.cpp | 3 - src/hotspot/share/classfile/vmClasses.cpp | 2 +- src/hotspot/share/gc/g1/g1Allocator.cpp | 2 - src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 358 ++++-------- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 48 +- .../share/gc/g1/g1CollectedHeap.inline.hpp | 8 +- .../share/gc/g1/g1CollectionSetCandidates.cpp | 7 +- .../share/gc/g1/g1CollectionSetChooser.cpp | 4 +- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 14 +- .../share/gc/g1/g1ConcurrentMark.inline.hpp | 9 +- src/hotspot/share/gc/g1/g1FullCollector.cpp | 2 - src/hotspot/share/gc/g1/g1FullCollector.hpp | 1 - .../share/gc/g1/g1FullCollector.inline.hpp | 4 - .../share/gc/g1/g1FullGCAdjustTask.cpp | 8 +- .../share/gc/g1/g1FullGCHeapRegionAttr.hpp | 14 +- .../share/gc/g1/g1FullGCMarker.inline.hpp | 9 +- .../gc/g1/g1FullGCOopClosures.inline.hpp | 2 +- .../share/gc/g1/g1FullGCPrepareTask.cpp | 2 - .../gc/g1/g1FullGCPrepareTask.inline.hpp | 7 - .../share/gc/g1/g1FullGCResetMetadataTask.cpp | 8 +- .../share/gc/g1/g1HeapRegionTraceType.hpp | 4 - src/hotspot/share/gc/g1/g1HeapTransition.cpp | 19 +- src/hotspot/share/gc/g1/g1HeapTransition.hpp | 3 +- src/hotspot/share/gc/g1/g1HeapVerifier.cpp | 126 +---- src/hotspot/share/gc/g1/g1HeapVerifier.hpp | 2 - src/hotspot/share/gc/g1/g1RemSet.cpp | 21 +- src/hotspot/share/gc/g1/g1RemSetSummary.cpp | 9 +- .../share/gc/g1/g1RemSetTrackingPolicy.cpp | 24 +- .../gc/g1/g1YoungGCPostEvacuateTasks.cpp | 2 +- src/hotspot/share/gc/g1/heapRegion.cpp | 12 +- src/hotspot/share/gc/g1/heapRegion.hpp | 23 +- src/hotspot/share/gc/g1/heapRegion.inline.hpp | 14 +- src/hotspot/share/gc/g1/heapRegionSet.cpp | 5 +- src/hotspot/share/gc/g1/heapRegionType.cpp | 10 +- src/hotspot/share/gc/g1/heapRegionType.hpp | 32 +- src/hotspot/share/gc/g1/vmStructs_g1.hpp | 4 +- src/hotspot/share/gc/shared/collectedHeap.cpp | 4 - src/hotspot/share/gc/shared/collectedHeap.hpp | 3 - src/hotspot/share/include/cds.h | 6 +- .../share/oops/instanceMirrorKlass.inline.hpp | 3 - src/hotspot/share/oops/oop.cpp | 7 - src/hotspot/share/oops/oop.hpp | 2 - src/hotspot/share/oops/oop.inline.hpp | 2 - src/hotspot/share/prims/whitebox.cpp | 23 +- .../jvm/hotspot/gc/g1/G1CollectedHeap.java | 10 +- .../sun/jvm/hotspot/gc/g1/HeapRegionType.java | 11 +- .../sun/jvm/hotspot/tools/HeapSummary.java | 5 +- .../runtime/cds/SpaceUtilizationCheck.java | 20 +- .../cds/appcds/SharedArchiveConsistency.java | 7 +- .../cacheObject/ArchivedIntegerCacheTest.java | 48 +- .../cacheObject/ArchivedModuleComboTest.java | 189 ------- .../ArchivedModuleWithCustomImageTest.java | 31 +- .../cacheObject/CheckArchivedModuleApp.java | 152 ----- .../cacheObject/CheckCachedMirrorApp.java | 92 --- .../cacheObject/CheckCachedMirrorTest.java | 66 --- .../CheckCachedResolvedReferences.java | 65 --- .../CheckCachedResolvedReferencesApp.java | 77 --- .../cacheObject/CheckIntegerCacheApp.java | 49 +- .../cds/appcds/cacheObject/GCStressApp.java | 94 ---- .../cds/appcds/cacheObject/GCStressTest.java | 58 -- .../MirrorWithReferenceFieldsApp.java | 14 +- .../appcds/cacheObject/OpenArchiveRegion.java | 8 +- .../appcds/cacheObject/PrimitiveTypesApp.java | 205 ------- .../cacheObject/PrimitiveTypesTest.java | 60 -- .../appcds/cacheObject/RedefineClassApp.java | 14 +- .../lib/jdk/test/lib/cds/CDSArchiveUtils.java | 7 +- test/lib/jdk/test/whitebox/WhiteBox.java | 2 - 83 files changed, 803 insertions(+), 3090 deletions(-) delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleComboTest.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorApp.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorTest.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferences.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferencesApp.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressApp.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressTest.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesApp.java delete mode 100644 test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesTest.java diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 1a73c4ab2ac..1ab95f889da 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -161,8 +161,7 @@ ArchiveBuilder::ArchiveBuilder() : _ro_src_objs(), _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), - _total_closed_heap_region_size(0), - _total_open_heap_region_size(0), + _total_heap_region_size(0), _estimated_metaspaceobj_bytes(0), _estimated_hashtable_bytes(0) { @@ -1051,42 +1050,40 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { } #if INCLUDE_CDS_JAVA_HEAP - // open and closed archive regions - static void log_heap_regions(const char* which, GrowableArray *regions) { - for (int i = 0; i < regions->length(); i++) { - address start = address(regions->at(i).start()); - address end = address(regions->at(i).end()); - log_region(which, start, end, to_requested(start)); + static void log_heap_region(ArchiveHeapInfo* heap_info) { + MemRegion r = heap_info->memregion(); + address start = address(r.start()); + address end = address(r.end()); + log_region("heap", start, end, to_requested(start)); - while (start < end) { - size_t byte_size; - oop original_oop = ArchiveHeapWriter::buffered_addr_to_source_obj(start); - if (original_oop != nullptr) { - ResourceMark rm; - log_info(cds, map)(PTR_FORMAT ": @@ Object %s", - p2i(to_requested(start)), original_oop->klass()->external_name()); - byte_size = original_oop->size() * BytesPerWord; - } else if (start == ArchiveHeapWriter::buffered_heap_roots_addr()) { - // HeapShared::roots() is copied specially so it doesn't exist in - // HeapShared::OriginalObjectTable. See HeapShared::copy_roots(). - log_info(cds, map)(PTR_FORMAT ": @@ Object HeapShared::roots (ObjArray)", - p2i(to_requested(start))); - byte_size = ArchiveHeapWriter::heap_roots_word_size() * BytesPerWord; - } else { - // We have reached the end of the region - break; - } - address oop_end = start + byte_size; - log_data(start, oop_end, to_requested(start), /*is_heap=*/true); - start = oop_end; - } - if (start < end) { + while (start < end) { + size_t byte_size; + oop original_oop = ArchiveHeapWriter::buffered_addr_to_source_obj(start); + if (original_oop != nullptr) { + ResourceMark rm; + log_info(cds, map)(PTR_FORMAT ": @@ Object %s", + p2i(to_requested(start)), original_oop->klass()->external_name()); + byte_size = original_oop->size() * BytesPerWord; + } else if (start == ArchiveHeapWriter::buffered_heap_roots_addr()) { + // HeapShared::roots() is copied specially so it doesn't exist in + // HeapShared::OriginalObjectTable. See HeapShared::copy_roots(). + log_info(cds, map)(PTR_FORMAT ": @@ Object HeapShared::roots (ObjArray)", + p2i(to_requested(start))); + byte_size = ArchiveHeapWriter::heap_roots_word_size() * BytesPerWord; + } else { + // We have reached the end of the region, but have some unused space + // at the end. log_info(cds, map)(PTR_FORMAT ": @@ Unused heap space " SIZE_FORMAT " bytes", p2i(to_requested(start)), size_t(end - start)); log_data(start, end, to_requested(start), /*is_heap=*/true); + break; } + address oop_end = start + byte_size; + log_data(start, oop_end, to_requested(start), /*is_heap=*/true); + start = oop_end; } } + static address to_requested(address p) { return ArchiveHeapWriter::buffered_addr_to_requested_addr(p); } @@ -1118,8 +1115,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { public: static void log(ArchiveBuilder* builder, FileMapInfo* mapinfo, - GrowableArray *closed_heap_regions, - GrowableArray *open_heap_regions, + ArchiveHeapInfo* heap_info, char* bitmap, size_t bitmap_size_in_bytes) { log_info(cds, map)("%s CDS archive map for %s", DumpSharedSpaces ? "Static" : "Dynamic", mapinfo->full_path()); @@ -1140,11 +1136,8 @@ public: log_data((address)bitmap, bitmap_end, 0); #if INCLUDE_CDS_JAVA_HEAP - if (closed_heap_regions != nullptr) { - log_heap_regions("closed heap region", closed_heap_regions); - } - if (open_heap_regions != nullptr) { - log_heap_regions("open heap region", open_heap_regions); + if (heap_info->is_used()) { + log_heap_region(heap_info); } #endif @@ -1161,11 +1154,7 @@ void ArchiveBuilder::clean_up_src_obj_table() { _src_obj_table.iterate(&cleaner); } -void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, - GrowableArray* closed_heap_regions, - GrowableArray* open_heap_regions, - GrowableArray* closed_heap_bitmaps, - GrowableArray* open_heap_bitmaps) { +void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) { // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with // MetaspaceShared::n_regions (internal to hotspot). assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity"); @@ -1174,23 +1163,14 @@ void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false); size_t bitmap_size_in_bytes; - char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), closed_heap_bitmaps, open_heap_bitmaps, + char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), heap_info, bitmap_size_in_bytes); - if (closed_heap_regions != nullptr) { - _total_closed_heap_region_size = mapinfo->write_heap_regions( - closed_heap_regions, - closed_heap_bitmaps, - MetaspaceShared::first_closed_heap_region, - MetaspaceShared::max_num_closed_heap_regions); - _total_open_heap_region_size = mapinfo->write_heap_regions( - open_heap_regions, - open_heap_bitmaps, - MetaspaceShared::first_open_heap_region, - MetaspaceShared::max_num_open_heap_regions); + if (heap_info->is_used()) { + _total_heap_region_size = mapinfo->write_heap_region(heap_info); } - print_region_stats(mapinfo, closed_heap_regions, open_heap_regions); + print_region_stats(mapinfo, heap_info); mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address()); mapinfo->set_header_crc(mapinfo->compute_header_crc()); @@ -1204,7 +1184,7 @@ void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, } if (log_is_enabled(Info, cds, map)) { - CDSMapLogger::log(this, mapinfo, closed_heap_regions, open_heap_regions, + CDSMapLogger::log(this, mapinfo, heap_info, bitmap, bitmap_size_in_bytes); } CDS_JAVA_HEAP_ONLY(HeapShared::destroy_archived_object_cache()); @@ -1215,20 +1195,16 @@ void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegi mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec); } -void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, - GrowableArray* closed_heap_regions, - GrowableArray* open_heap_regions) { +void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* heap_info) { // Print statistics of all the regions const size_t bitmap_used = mapinfo->region_at(MetaspaceShared::bm)->used(); const size_t bitmap_reserved = mapinfo->region_at(MetaspaceShared::bm)->used_aligned(); const size_t total_reserved = _ro_region.reserved() + _rw_region.reserved() + bitmap_reserved + - _total_closed_heap_region_size + - _total_open_heap_region_size; + _total_heap_region_size; const size_t total_bytes = _ro_region.used() + _rw_region.used() + bitmap_used + - _total_closed_heap_region_size + - _total_open_heap_region_size; + _total_heap_region_size; const double total_u_perc = percent_of(total_bytes, total_reserved); _rw_region.print(total_reserved); @@ -1236,30 +1212,25 @@ void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, print_bitmap_region_stats(bitmap_used, total_reserved); - if (closed_heap_regions != nullptr) { - print_heap_region_stats(closed_heap_regions, "ca", total_reserved); - print_heap_region_stats(open_heap_regions, "oa", total_reserved); + if (heap_info->is_used()) { + print_heap_region_stats(heap_info, total_reserved); } - log_debug(cds)("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", + log_debug(cds)("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", total_bytes, total_reserved, total_u_perc); } void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) { - log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]", + log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]", size, size/double(total_size)*100.0, size); } -void ArchiveBuilder::print_heap_region_stats(GrowableArray* regions, - const char *name, size_t total_size) { - int arr_len = regions == nullptr ? 0 : regions->length(); - for (int i = 0; i < arr_len; i++) { - char* start = (char*)regions->at(i).start(); - size_t size = regions->at(i).byte_size(); - char* top = start + size; - log_debug(cds)("%s%d space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT, - name, i, size, size/double(total_size)*100.0, size, p2i(start)); - } +void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total_size) { + char* start = info->start(); + size_t size = info->byte_size(); + char* top = start + size; + log_debug(cds)("hp space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT, + size, size/double(total_size)*100.0, size, p2i(start)); } void ArchiveBuilder::report_out_of_space(const char* name, size_t needed_bytes) { diff --git a/src/hotspot/share/cds/archiveBuilder.hpp b/src/hotspot/share/cds/archiveBuilder.hpp index 9d39892fdc4..222a13e660a 100644 --- a/src/hotspot/share/cds/archiveBuilder.hpp +++ b/src/hotspot/share/cds/archiveBuilder.hpp @@ -36,7 +36,7 @@ #include "utilities/resizeableResourceHash.hpp" #include "utilities/resourceHash.hpp" -struct ArchiveHeapBitmapInfo; +class ArchiveHeapInfo; class CHeapBitMap; class FileMapInfo; class Klass; @@ -234,15 +234,11 @@ private: // statistics DumpAllocStats _alloc_stats; - size_t _total_closed_heap_region_size; - size_t _total_open_heap_region_size; + size_t _total_heap_region_size; - void print_region_stats(FileMapInfo *map_info, - GrowableArray* closed_heap_regions, - GrowableArray* open_heap_regions); + void print_region_stats(FileMapInfo *map_info, ArchiveHeapInfo* heap_info); void print_bitmap_region_stats(size_t size, size_t total_size); - void print_heap_region_stats(GrowableArray* regions, - const char *name, size_t total_size); + void print_heap_region_stats(ArchiveHeapInfo* heap_info, size_t total_size); // For global access. static ArchiveBuilder* _current; @@ -403,11 +399,7 @@ public: void relocate_vm_classes(); void make_klasses_shareable(); void relocate_to_requested(); - void write_archive(FileMapInfo* mapinfo, - GrowableArray* closed_heap_regions, - GrowableArray* open_heap_regions, - GrowableArray* closed_heap_oopmaps, - GrowableArray* open_heap_oopmaps); + void write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info); void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only, bool allow_exec); diff --git a/src/hotspot/share/cds/archiveHeapLoader.cpp b/src/hotspot/share/cds/archiveHeapLoader.cpp index d674ab5e3c1..28d2718b75a 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.cpp +++ b/src/hotspot/share/cds/archiveHeapLoader.cpp @@ -38,8 +38,7 @@ #if INCLUDE_CDS_JAVA_HEAP -bool ArchiveHeapLoader::_closed_regions_mapped = false; -bool ArchiveHeapLoader::_open_regions_mapped = false; +bool ArchiveHeapLoader::_is_mapped = false; bool ArchiveHeapLoader::_is_loaded = false; bool ArchiveHeapLoader::_narrow_oop_base_initialized = false; @@ -49,15 +48,9 @@ int ArchiveHeapLoader::_narrow_oop_shift; // Support for loaded heap. uintptr_t ArchiveHeapLoader::_loaded_heap_bottom = 0; uintptr_t ArchiveHeapLoader::_loaded_heap_top = 0; -uintptr_t ArchiveHeapLoader::_dumptime_base_0 = UINTPTR_MAX; -uintptr_t ArchiveHeapLoader::_dumptime_base_1 = UINTPTR_MAX; -uintptr_t ArchiveHeapLoader::_dumptime_base_2 = UINTPTR_MAX; -uintptr_t ArchiveHeapLoader::_dumptime_base_3 = UINTPTR_MAX; -uintptr_t ArchiveHeapLoader::_dumptime_top = 0; -intx ArchiveHeapLoader::_runtime_offset_0 = 0; -intx ArchiveHeapLoader::_runtime_offset_1 = 0; -intx ArchiveHeapLoader::_runtime_offset_2 = 0; -intx ArchiveHeapLoader::_runtime_offset_3 = 0; +uintptr_t ArchiveHeapLoader::_dumptime_base = UINTPTR_MAX; +uintptr_t ArchiveHeapLoader::_dumptime_top = 0; +intx ArchiveHeapLoader::_runtime_offset = 0; bool ArchiveHeapLoader::_loading_failed = false; // Support for mapped heap. @@ -84,10 +77,10 @@ void ArchiveHeapLoader::init_narrow_oop_decoding(address base, int shift) { _narrow_oop_shift = shift; } -void ArchiveHeapLoader::fixup_regions() { +void ArchiveHeapLoader::fixup_region() { FileMapInfo* mapinfo = FileMapInfo::current_info(); if (is_mapped()) { - mapinfo->fixup_mapped_heap_regions(); + mapinfo->fixup_mapped_heap_region(); } else if (_loading_failed) { fill_failed_loaded_heap(); } @@ -160,9 +153,8 @@ class PatchUncompressedEmbeddedPointers: public BitMapClosure { void ArchiveHeapLoader::patch_compressed_embedded_pointers(BitMapView bm, FileMapInfo* info, - FileMapRegion* map_region, MemRegion region) { - narrowOop dt_encoded_bottom = info->encoded_heap_region_dumptime_address(map_region); + narrowOop dt_encoded_bottom = info->encoded_heap_region_dumptime_address(); narrowOop rt_encoded_bottom = CompressedOops::encode_not_null(cast_to_oop(region.start())); log_info(cds)("patching heap embedded pointers: narrowOop 0x%8x -> 0x%8x", (uint)dt_encoded_bottom, (uint)rt_encoded_bottom); @@ -188,7 +180,6 @@ void ArchiveHeapLoader::patch_compressed_embedded_pointers(BitMapView bm, // Patch all the non-null pointers that are embedded in the archived heap objects // in this (mapped) region void ArchiveHeapLoader::patch_embedded_pointers(FileMapInfo* info, - FileMapRegion* map_region, MemRegion region, address oopmap, size_t oopmap_size_in_bits) { BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits); @@ -200,7 +191,7 @@ void ArchiveHeapLoader::patch_embedded_pointers(FileMapInfo* info, #endif if (UseCompressedOops) { - patch_compressed_embedded_pointers(bm, info, map_region, region); + patch_compressed_embedded_pointers(bm, info, region); } else { PatchUncompressedEmbeddedPointers patcher((oop*)region.start()); bm.iterate(&patcher); @@ -219,44 +210,15 @@ struct LoadedArchiveHeapRegion { uintptr_t _dumptime_base; // The dump-time (decoded) address of the first object in this region intx _runtime_offset; // If an object's dump time address P is within in this region, its // runtime address is P + _runtime_offset - - static int comparator(const void* a, const void* b) { - LoadedArchiveHeapRegion* reg_a = (LoadedArchiveHeapRegion*)a; - LoadedArchiveHeapRegion* reg_b = (LoadedArchiveHeapRegion*)b; - if (reg_a->_dumptime_base < reg_b->_dumptime_base) { - return -1; - } else if (reg_a->_dumptime_base == reg_b->_dumptime_base) { - return 0; - } else { - return 1; - } - } - uintptr_t top() { return _dumptime_base + _region_size; } }; -void ArchiveHeapLoader::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_regions, - int num_loaded_regions) { - _dumptime_base_0 = loaded_regions[0]._dumptime_base; - _dumptime_base_1 = loaded_regions[1]._dumptime_base; - _dumptime_base_2 = loaded_regions[2]._dumptime_base; - _dumptime_base_3 = loaded_regions[3]._dumptime_base; - _dumptime_top = loaded_regions[num_loaded_regions-1].top(); - - _runtime_offset_0 = loaded_regions[0]._runtime_offset; - _runtime_offset_1 = loaded_regions[1]._runtime_offset; - _runtime_offset_2 = loaded_regions[2]._runtime_offset; - _runtime_offset_3 = loaded_regions[3]._runtime_offset; - - assert(2 <= num_loaded_regions && num_loaded_regions <= 4, "must be"); - if (num_loaded_regions < 4) { - _dumptime_base_3 = UINTPTR_MAX; - } - if (num_loaded_regions < 3) { - _dumptime_base_2 = UINTPTR_MAX; - } +void ArchiveHeapLoader::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_region) { + _dumptime_base = loaded_region->_dumptime_base; + _dumptime_top = loaded_region->top(); + _runtime_offset = loaded_region->_runtime_offset; } bool ArchiveHeapLoader::can_load() { @@ -267,36 +229,18 @@ bool ArchiveHeapLoader::can_load() { return Universe::heap()->can_load_archived_objects(); } -template -class PatchLoadedRegionPointers: public BitMapClosure { +class ArchiveHeapLoader::PatchLoadedRegionPointers: public BitMapClosure { narrowOop* _start; - intx _offset_0; - intx _offset_1; - intx _offset_2; - intx _offset_3; - uintptr_t _base_0; - uintptr_t _base_1; - uintptr_t _base_2; - uintptr_t _base_3; + intx _offset; + uintptr_t _base; uintptr_t _top; - static_assert(MetaspaceShared::max_num_heap_regions == 4, "can't handle more than 4 regions"); - static_assert(NUM_LOADED_REGIONS >= 2, "we have at least 2 loaded regions"); - static_assert(NUM_LOADED_REGIONS <= 4, "we have at most 4 loaded regions"); - public: - PatchLoadedRegionPointers(narrowOop* start, LoadedArchiveHeapRegion* loaded_regions) + PatchLoadedRegionPointers(narrowOop* start, LoadedArchiveHeapRegion* loaded_region) : _start(start), - _offset_0(loaded_regions[0]._runtime_offset), - _offset_1(loaded_regions[1]._runtime_offset), - _offset_2(loaded_regions[2]._runtime_offset), - _offset_3(loaded_regions[3]._runtime_offset), - _base_0(loaded_regions[0]._dumptime_base), - _base_1(loaded_regions[1]._dumptime_base), - _base_2(loaded_regions[2]._dumptime_base), - _base_3(loaded_regions[3]._dumptime_base) { - _top = loaded_regions[NUM_LOADED_REGIONS-1].top(); - } + _offset(loaded_region->_runtime_offset), + _base(loaded_region->_dumptime_base), + _top(loaded_region->top()) {} bool do_bit(size_t offset) { assert(UseCompressedOops, "PatchLoadedRegionPointers for uncompressed oops is unimplemented"); @@ -304,138 +248,94 @@ class PatchLoadedRegionPointers: public BitMapClosure { narrowOop v = *p; assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); uintptr_t o = cast_from_oop(ArchiveHeapLoader::decode_from_archive(v)); - assert(_base_0 <= o && o < _top, "must be"); + assert(_base <= o && o < _top, "must be"); - // We usually have only 2 regions for the default archive. Use template to avoid unnecessary comparisons. - if (NUM_LOADED_REGIONS > 3 && o >= _base_3) { - o += _offset_3; - } else if (NUM_LOADED_REGIONS > 2 && o >= _base_2) { - o += _offset_2; - } else if (o >= _base_1) { - o += _offset_1; - } else { - o += _offset_0; - } + o += _offset; ArchiveHeapLoader::assert_in_loaded_heap(o); RawAccess::oop_store(p, cast_to_oop(o)); return true; } }; -int ArchiveHeapLoader::init_loaded_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, +bool ArchiveHeapLoader::init_loaded_region(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region, MemRegion& archive_space) { size_t total_bytes = 0; - int num_loaded_regions = 0; - for (int i = MetaspaceShared::first_archive_heap_region; - i <= MetaspaceShared::last_archive_heap_region; i++) { - FileMapRegion* r = mapinfo->region_at(i); - r->assert_is_heap_region(); - if (r->used() > 0) { - assert(is_aligned(r->used(), HeapWordSize), "must be"); - total_bytes += r->used(); - LoadedArchiveHeapRegion* ri = &loaded_regions[num_loaded_regions++]; - ri->_region_index = i; - ri->_region_size = r->used(); - ri->_dumptime_base = (uintptr_t)mapinfo->heap_region_dumptime_address(r); - } + FileMapRegion* r = mapinfo->region_at(MetaspaceShared::hp); + r->assert_is_heap_region(); + if (r->used() == 0) { + return false; } + assert(is_aligned(r->used(), HeapWordSize), "must be"); + total_bytes += r->used(); + loaded_region->_region_index = MetaspaceShared::hp; + loaded_region->_region_size = r->used(); + loaded_region->_dumptime_base = (uintptr_t)mapinfo->heap_region_dumptime_address(); + assert(is_aligned(total_bytes, HeapWordSize), "must be"); size_t word_size = total_bytes / HeapWordSize; HeapWord* buffer = Universe::heap()->allocate_loaded_archive_space(word_size); if (buffer == nullptr) { - return 0; + return false; } archive_space = MemRegion(buffer, word_size); _loaded_heap_bottom = (uintptr_t)archive_space.start(); _loaded_heap_top = _loaded_heap_bottom + total_bytes; - return num_loaded_regions; + loaded_region->_runtime_offset = _loaded_heap_bottom - loaded_region->_dumptime_base; + + return true; } -void ArchiveHeapLoader::sort_loaded_regions(LoadedArchiveHeapRegion* loaded_regions, int num_loaded_regions, - uintptr_t buffer) { - // Find the relocation offset of the pointers in each region - qsort(loaded_regions, num_loaded_regions, sizeof(LoadedArchiveHeapRegion), - LoadedArchiveHeapRegion::comparator); - - uintptr_t p = buffer; - for (int i = 0; i < num_loaded_regions; i++) { - // This region will be loaded at p, so all objects inside this - // region will be shifted by ri->offset - LoadedArchiveHeapRegion* ri = &loaded_regions[i]; - ri->_runtime_offset = p - ri->_dumptime_base; - p += ri->_region_size; - } - assert(p == _loaded_heap_top, "must be"); -} - -bool ArchiveHeapLoader::load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, - int num_loaded_regions, uintptr_t buffer) { +bool ArchiveHeapLoader::load_heap_region_impl(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region, + uintptr_t load_address) { uintptr_t bitmap_base = (uintptr_t)mapinfo->map_bitmap_region(); if (bitmap_base == 0) { _loading_failed = true; return false; // OOM or CRC error } - uintptr_t load_address = buffer; - for (int i = 0; i < num_loaded_regions; i++) { - LoadedArchiveHeapRegion* ri = &loaded_regions[i]; - FileMapRegion* r = mapinfo->region_at(ri->_region_index); - if (!mapinfo->read_region(ri->_region_index, (char*)load_address, r->used(), /* do_commit = */ false)) { - // There's no easy way to free the buffer, so we will fill it with zero later - // in fill_failed_loaded_heap(), and it will eventually be GC'ed. - log_warning(cds)("Loading of heap region %d has failed. Archived objects are disabled", i); - _loading_failed = true; - return false; - } - log_info(cds)("Loaded heap region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT - " size " SIZE_FORMAT_W(6) " delta " INTX_FORMAT, - ri->_region_index, load_address, load_address + ri->_region_size, - ri->_region_size, ri->_runtime_offset); - - uintptr_t oopmap = bitmap_base + r->oopmap_offset(); - BitMapView bm((BitMap::bm_word_t*)oopmap, r->oopmap_size_in_bits()); - - if (num_loaded_regions == 4) { - PatchLoadedRegionPointers<4> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } else if (num_loaded_regions == 3) { - PatchLoadedRegionPointers<3> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } else { - assert(num_loaded_regions == 2, "must be"); - PatchLoadedRegionPointers<2> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } - - assert(r->mapped_base() == (char*)load_address, "sanity"); - load_address += r->used(); + FileMapRegion* r = mapinfo->region_at(loaded_region->_region_index); + if (!mapinfo->read_region(loaded_region->_region_index, (char*)load_address, r->used(), /* do_commit = */ false)) { + // There's no easy way to free the buffer, so we will fill it with zero later + // in fill_failed_loaded_heap(), and it will eventually be GC'ed. + log_warning(cds)("Loading of heap region %d has failed. Archived objects are disabled", loaded_region->_region_index); + _loading_failed = true; + return false; } + assert(r->mapped_base() == (char*)load_address, "sanity"); + log_info(cds)("Loaded heap region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT + " size " SIZE_FORMAT_W(6) " delta " INTX_FORMAT, + loaded_region->_region_index, load_address, load_address + loaded_region->_region_size, + loaded_region->_region_size, loaded_region->_runtime_offset); + uintptr_t oopmap = bitmap_base + r->oopmap_offset(); + BitMapView bm((BitMap::bm_word_t*)oopmap, r->oopmap_size_in_bits()); + + PatchLoadedRegionPointers patcher((narrowOop*)load_address, loaded_region); + bm.iterate(&patcher); return true; } -bool ArchiveHeapLoader::load_heap_regions(FileMapInfo* mapinfo) { +bool ArchiveHeapLoader::load_heap_region(FileMapInfo* mapinfo) { assert(UseCompressedOops, "loaded heap for !UseCompressedOops is unimplemented"); init_narrow_oop_decoding(mapinfo->narrow_oop_base(), mapinfo->narrow_oop_shift()); - LoadedArchiveHeapRegion loaded_regions[MetaspaceShared::max_num_heap_regions]; - memset(loaded_regions, 0, sizeof(loaded_regions)); + LoadedArchiveHeapRegion loaded_region; + memset(&loaded_region, 0, sizeof(loaded_region)); MemRegion archive_space; - int num_loaded_regions = init_loaded_regions(mapinfo, loaded_regions, archive_space); - if (num_loaded_regions <= 0) { + if (!init_loaded_region(mapinfo, &loaded_region, archive_space)) { return false; } - sort_loaded_regions(loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start()); - if (!load_regions(mapinfo, loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start())) { + + if (!load_heap_region_impl(mapinfo, &loaded_region, (uintptr_t)archive_space.start())) { assert(_loading_failed, "must be"); return false; } - init_loaded_heap_relocation(loaded_regions, num_loaded_regions); + init_loaded_heap_relocation(&loaded_region); _is_loaded = true; return true; @@ -448,14 +348,14 @@ class VerifyLoadedHeapEmbeddedPointers: public BasicOopIterateClosure { VerifyLoadedHeapEmbeddedPointers(ResourceHashtable* table) : _table(table) {} virtual void do_oop(narrowOop* p) { - // This should be called before the loaded regions are modified, so all the embedded pointers - // must be null, or must point to a valid object in the loaded regions. + // This should be called before the loaded region is modified, so all the embedded pointers + // must be null, or must point to a valid object in the loaded region. narrowOop v = *p; if (!CompressedOops::is_null(v)) { oop o = CompressedOops::decode_not_null(v); uintptr_t u = cast_from_oop(o); ArchiveHeapLoader::assert_in_loaded_heap(u); - guarantee(_table->contains(u), "must point to beginning of object in loaded archived regions"); + guarantee(_table->contains(u), "must point to beginning of object in loaded archived region"); } } virtual void do_oop(oop* p) { @@ -539,15 +439,12 @@ void ArchiveHeapLoader::patch_native_pointers() { return; } - for (int i = MetaspaceShared::first_archive_heap_region; - i <= MetaspaceShared::last_archive_heap_region; i++) { - FileMapRegion* r = FileMapInfo::current_info()->region_at(i); - if (r->mapped_base() != nullptr && r->has_ptrmap()) { - log_info(cds, heap)("Patching native pointers in heap region %d", i); - BitMapView bm = r->ptrmap_view(); - PatchNativePointers patcher((Metadata**)r->mapped_base()); - bm.iterate(&patcher); - } + FileMapRegion* r = FileMapInfo::current_info()->region_at(MetaspaceShared::hp); + if (r->mapped_base() != nullptr && r->has_ptrmap()) { + log_info(cds, heap)("Patching native pointers in heap region"); + BitMapView bm = r->ptrmap_view(); + PatchNativePointers patcher((Metadata**)r->mapped_base()); + bm.iterate(&patcher); } } #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/archiveHeapLoader.hpp b/src/hotspot/share/cds/archiveHeapLoader.hpp index 530e4ff5bc2..ac87efdadb1 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.hpp +++ b/src/hotspot/share/cds/archiveHeapLoader.hpp @@ -40,24 +40,21 @@ struct LoadedArchiveHeapRegion; class ArchiveHeapLoader : AllStatic { public: - // At runtime, heap regions in the CDS archive can be used in two different ways, + // At runtime, the heap region in the CDS archive can be used in two different ways, // depending on the GC type: - // - Mapped: (G1 only) the regions are directly mapped into the Java heap - // - Loaded: At VM start-up, the objects in the heap regions are copied into the + // - Mapped: (G1 only) the region is directly mapped into the Java heap + // - Loaded: At VM start-up, the objects in the heap region are copied into the // Java heap. This is easier to implement than mapping but // slightly less efficient, as the embedded pointers need to be relocated. static bool can_use() { return can_map() || can_load(); } - // Can this VM map archived heap regions? Currently only G1+compressed{oops,cp} + // Can this VM map archived heap region? Currently only G1+compressed{oops,cp} static bool can_map() { CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedClassPointers);) NOT_CDS_JAVA_HEAP(return false;) } - static bool is_mapped() { - return closed_regions_mapped() && open_regions_mapped(); - } - // Can this VM load the objects from archived heap regions into the heap at start-up? + // Can this VM load the objects from archived heap region into the heap at start-up? static bool can_load() NOT_CDS_JAVA_HEAP_RETURN_(false); static void finish_initialization() NOT_CDS_JAVA_HEAP_RETURN; static bool is_loaded() { @@ -76,25 +73,17 @@ public: NOT_CDS_JAVA_HEAP_RETURN_(0L); } - static void set_closed_regions_mapped() { - CDS_JAVA_HEAP_ONLY(_closed_regions_mapped = true;) + static void set_mapped() { + CDS_JAVA_HEAP_ONLY(_is_mapped = true;) NOT_CDS_JAVA_HEAP_RETURN; } - static bool closed_regions_mapped() { - CDS_JAVA_HEAP_ONLY(return _closed_regions_mapped;) - NOT_CDS_JAVA_HEAP_RETURN_(false); - } - static void set_open_regions_mapped() { - CDS_JAVA_HEAP_ONLY(_open_regions_mapped = true;) - NOT_CDS_JAVA_HEAP_RETURN; - } - static bool open_regions_mapped() { - CDS_JAVA_HEAP_ONLY(return _open_regions_mapped;) + static bool is_mapped() { + CDS_JAVA_HEAP_ONLY(return _is_mapped;) NOT_CDS_JAVA_HEAP_RETURN_(false); } // NarrowOops stored in the CDS archive may use a different encoding scheme - // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_regions_impl. + // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_region_impl. // To decode them, do not use CompressedOops::decode_not_null. Use this // function instead. inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); @@ -104,34 +93,25 @@ public: static void patch_compressed_embedded_pointers(BitMapView bm, FileMapInfo* info, - FileMapRegion* map_region, MemRegion region) NOT_CDS_JAVA_HEAP_RETURN; static void patch_embedded_pointers(FileMapInfo* info, - FileMapRegion* map_region, MemRegion region, address oopmap, size_t oopmap_size_in_bits) NOT_CDS_JAVA_HEAP_RETURN; - static void fixup_regions() NOT_CDS_JAVA_HEAP_RETURN; + static void fixup_region() NOT_CDS_JAVA_HEAP_RETURN; #if INCLUDE_CDS_JAVA_HEAP static void init_mapped_heap_relocation(ptrdiff_t delta, int dumptime_oop_shift); private: - static bool _closed_regions_mapped; - static bool _open_regions_mapped; + static bool _is_mapped; static bool _is_loaded; // Support for loaded archived heap. These are cached values from // LoadedArchiveHeapRegion's. - static uintptr_t _dumptime_base_0; - static uintptr_t _dumptime_base_1; - static uintptr_t _dumptime_base_2; - static uintptr_t _dumptime_base_3; + static uintptr_t _dumptime_base; static uintptr_t _dumptime_top; - static intx _runtime_offset_0; - static intx _runtime_offset_1; - static intx _runtime_offset_2; - static intx _runtime_offset_3; + static intx _runtime_offset; static uintptr_t _loaded_heap_bottom; static uintptr_t _loaded_heap_top; @@ -148,14 +128,10 @@ private: static bool _mapped_heap_relocation_initialized; static void init_narrow_oop_decoding(address base, int shift); - static int init_loaded_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, + static bool init_loaded_region(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region, MemRegion& archive_space); - static void sort_loaded_regions(LoadedArchiveHeapRegion* loaded_regions, int num_loaded_regions, - uintptr_t buffer); - static bool load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, - int num_loaded_regions, uintptr_t buffer); - static void init_loaded_heap_relocation(LoadedArchiveHeapRegion* reloc_info, - int num_loaded_regions); + static bool load_heap_region_impl(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region, uintptr_t buffer); + static void init_loaded_heap_relocation(LoadedArchiveHeapRegion* reloc_info); static void patch_native_pointers(); static void finish_loaded_heap(); static void verify_loaded_heap(); @@ -168,9 +144,11 @@ private: template inline static oop decode_from_archive_impl(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + class PatchLoadedRegionPointers; + public: - static bool load_heap_regions(FileMapInfo* mapinfo); + static bool load_heap_region(FileMapInfo* mapinfo); static void assert_in_loaded_heap(uintptr_t o) { assert(is_in_loaded_heap(o), "must be"); } diff --git a/src/hotspot/share/cds/archiveHeapLoader.inline.hpp b/src/hotspot/share/cds/archiveHeapLoader.inline.hpp index 6f344ddf526..9efd39b8d26 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.inline.hpp +++ b/src/hotspot/share/cds/archiveHeapLoader.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,18 +38,10 @@ inline oop ArchiveHeapLoader::decode_from_archive_impl(narrowOop v) { assert(_narrow_oop_base_initialized, "relocation information must have been initialized"); uintptr_t p = ((uintptr_t)_narrow_oop_base) + ((uintptr_t)v << _narrow_oop_shift); if (IS_MAPPED) { - assert(_dumptime_base_0 == UINTPTR_MAX, "must be"); - } else if (p >= _dumptime_base_0) { + assert(_dumptime_base == UINTPTR_MAX, "must be"); + } else if (p >= _dumptime_base) { assert(p < _dumptime_top, "must be"); - if (p >= _dumptime_base_3) { - p += _runtime_offset_3; - } else if (p >= _dumptime_base_2) { - p += _runtime_offset_2; - } else if (p >= _dumptime_base_1) { - p += _runtime_offset_1; - } else { - p += _runtime_offset_0; - } + p += _runtime_offset; } oop result = cast_to_oop((uintptr_t)p); diff --git a/src/hotspot/share/cds/archiveHeapWriter.cpp b/src/hotspot/share/cds/archiveHeapWriter.cpp index 91cd15c762d..530754d2e03 100644 --- a/src/hotspot/share/cds/archiveHeapWriter.cpp +++ b/src/hotspot/share/cds/archiveHeapWriter.cpp @@ -47,26 +47,16 @@ #if INCLUDE_CDS_JAVA_HEAP - GrowableArrayCHeap* ArchiveHeapWriter::_buffer; // The following are offsets from buffer_bottom() -size_t ArchiveHeapWriter::_buffer_top; -size_t ArchiveHeapWriter::_open_bottom; -size_t ArchiveHeapWriter::_open_top; -size_t ArchiveHeapWriter::_closed_bottom; -size_t ArchiveHeapWriter::_closed_top; -size_t ArchiveHeapWriter::_heap_roots_bottom; +size_t ArchiveHeapWriter::_buffer_used; +size_t ArchiveHeapWriter::_heap_roots_bottom_offset; size_t ArchiveHeapWriter::_heap_roots_word_size; -address ArchiveHeapWriter::_requested_open_region_bottom; -address ArchiveHeapWriter::_requested_open_region_top; -address ArchiveHeapWriter::_requested_closed_region_bottom; -address ArchiveHeapWriter::_requested_closed_region_top; - -ResourceBitMap* ArchiveHeapWriter::_closed_oopmap; -ResourceBitMap* ArchiveHeapWriter::_open_oopmap; +address ArchiveHeapWriter::_requested_bottom; +address ArchiveHeapWriter::_requested_top; GrowableArrayCHeap* ArchiveHeapWriter::_native_pointers; GrowableArrayCHeap* ArchiveHeapWriter::_source_objs; @@ -80,10 +70,8 @@ void ArchiveHeapWriter::init() { _buffer_offset_to_source_obj_table = new BufferOffsetToSourceObjectTable(); - _requested_open_region_bottom = nullptr; - _requested_open_region_top = nullptr; - _requested_closed_region_bottom = nullptr; - _requested_closed_region_top = nullptr; + _requested_bottom = nullptr; + _requested_top = nullptr; _native_pointers = new GrowableArrayCHeap(2048); _source_objs = new GrowableArrayCHeap(10000); @@ -97,17 +85,13 @@ void ArchiveHeapWriter::add_source_obj(oop src_obj) { _source_objs->append(src_obj); } -// For the time being, always support two regions (to be strictly compatible with existing G1 -// mapping code. We might eventually use a single region (JDK-8298048). void ArchiveHeapWriter::write(GrowableArrayCHeap* roots, - GrowableArray* closed_regions, GrowableArray* open_regions, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps) { + ArchiveHeapInfo* heap_info) { assert(HeapShared::can_write(), "sanity"); allocate_buffer(); copy_source_objs_to_buffer(roots); - set_requested_address_for_regions(closed_regions, open_regions); - relocate_embedded_oops(roots, closed_bitmaps, open_bitmaps); + set_requested_address(heap_info); + relocate_embedded_oops(roots, heap_info); } bool ArchiveHeapWriter::is_too_large_to_archive(oop o) { @@ -133,18 +117,15 @@ bool ArchiveHeapWriter::is_too_large_to_archive(size_t size) { } // Various lookup functions between source_obj, buffered_obj and requested_obj -bool ArchiveHeapWriter::is_in_requested_regions(oop o) { - assert(_requested_open_region_bottom != nullptr, "do not call before this is initialized"); - assert(_requested_closed_region_bottom != nullptr, "do not call before this is initialized"); - +bool ArchiveHeapWriter::is_in_requested_range(oop o) { + assert(_requested_bottom != nullptr, "do not call before _requested_bottom is initialized"); address a = cast_from_oop
(o); - return (_requested_open_region_bottom <= a && a < _requested_open_region_top) || - (_requested_closed_region_bottom <= a && a < _requested_closed_region_top); + return (_requested_bottom <= a && a < _requested_top); } oop ArchiveHeapWriter::requested_obj_from_buffer_offset(size_t offset) { - oop req_obj = cast_to_oop(_requested_open_region_bottom + offset); - assert(is_in_requested_regions(req_obj), "must be"); + oop req_obj = cast_to_oop(_requested_bottom + offset); + assert(is_in_requested_range(req_obj), "must be"); return req_obj; } @@ -168,30 +149,22 @@ oop ArchiveHeapWriter::buffered_addr_to_source_obj(address buffered_addr) { } address ArchiveHeapWriter::buffered_addr_to_requested_addr(address buffered_addr) { - return _requested_open_region_bottom + buffered_address_to_offset(buffered_addr); + return _requested_bottom + buffered_address_to_offset(buffered_addr); } oop ArchiveHeapWriter::heap_roots_requested_address() { - return requested_obj_from_buffer_offset(_heap_roots_bottom); + return cast_to_oop(_requested_bottom + _heap_roots_bottom_offset); } -address ArchiveHeapWriter::heap_region_requested_bottom(int heap_region_idx) { +address ArchiveHeapWriter::requested_address() { assert(_buffer != nullptr, "must be initialized"); - switch (heap_region_idx) { - case MetaspaceShared::first_closed_heap_region: - return _requested_closed_region_bottom; - case MetaspaceShared::first_open_heap_region: - return _requested_open_region_bottom; - default: - ShouldNotReachHere(); - return nullptr; - } + return _requested_bottom; } void ArchiveHeapWriter::allocate_buffer() { int initial_buffer_size = 100000; _buffer = new GrowableArrayCHeap(initial_buffer_size); - _open_bottom = _buffer_top = 0; + _buffer_used = 0; ensure_buffer_space(1); // so that buffer_bottom() works } @@ -203,7 +176,7 @@ void ArchiveHeapWriter::ensure_buffer_space(size_t min_bytes) { void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeap* roots) { Klass* k = Universe::objectArrayKlassObj(); // already relocated to point to archived klass - int length = roots != nullptr ? roots->length() : 0; + int length = roots->length(); _heap_roots_word_size = objArrayOopDesc::object_size(length); size_t byte_size = _heap_roots_word_size * HeapWordSize; if (byte_size >= MIN_GC_REGION_ALIGNMENT) { @@ -213,10 +186,10 @@ void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeap(_buffer_top); + HeapWord* mem = offset_to_buffered_address(_buffer_used); memset(mem, 0, byte_size); { // This is copied from MemAllocator::finish @@ -238,40 +211,27 @@ void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeapobj_at_addr(i) = o; } } - log_info(cds)("archived obj roots[%d] = " SIZE_FORMAT " bytes, klass = %p, obj = %p", length, byte_size, k, mem); + log_info(cds, heap)("archived obj roots[%d] = " SIZE_FORMAT " bytes, klass = %p, obj = %p", length, byte_size, k, mem); - _heap_roots_bottom = _buffer_top; - _buffer_top = new_top; + _heap_roots_bottom_offset = _buffer_used; + _buffer_used = new_used; } void ArchiveHeapWriter::copy_source_objs_to_buffer(GrowableArrayCHeap* roots) { - copy_source_objs_to_buffer_by_region(/*copy_open_region=*/true); - copy_roots_to_buffer(roots); - _open_top = _buffer_top; - - // Align the closed region to the next G1 region - _buffer_top = _closed_bottom = align_up(_buffer_top, HeapRegion::GrainBytes); - copy_source_objs_to_buffer_by_region(/*copy_open_region=*/false); - _closed_top = _buffer_top; - - log_info(cds, heap)("Size of open region = " SIZE_FORMAT " bytes", _open_top - _open_bottom); - log_info(cds, heap)("Size of closed region = " SIZE_FORMAT " bytes", _closed_top - _closed_bottom); -} - -void ArchiveHeapWriter::copy_source_objs_to_buffer_by_region(bool copy_open_region) { for (int i = 0; i < _source_objs->length(); i++) { oop src_obj = _source_objs->at(i); HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(src_obj); assert(info != nullptr, "must be"); - if (info->in_open_region() == copy_open_region) { - // For region-based collectors such as G1, we need to make sure that we don't have - // an object that can possible span across two regions. - size_t buffer_offset = copy_one_source_obj_to_buffer(src_obj); - info->set_buffer_offset(buffer_offset); + size_t buffer_offset = copy_one_source_obj_to_buffer(src_obj); + info->set_buffer_offset(buffer_offset); - _buffer_offset_to_source_obj_table->put(buffer_offset, src_obj); - } + _buffer_offset_to_source_obj_table->put(buffer_offset, src_obj); } + + copy_roots_to_buffer(roots); + + log_info(cds)("Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots", + _buffer_used, _source_objs->length() + 1, roots->length()); } size_t ArchiveHeapWriter::filler_array_byte_size(int length) { @@ -298,7 +258,7 @@ int ArchiveHeapWriter::filler_array_length(size_t fill_bytes) { void ArchiveHeapWriter::init_filler_array_at_buffer_top(int array_length, size_t fill_bytes) { assert(UseCompressedClassPointers, "Archived heap only supported for compressed klasses"); Klass* oak = Universe::objectArrayKlassObj(); // already relocated to point to archived klass - HeapWord* mem = offset_to_buffered_address(_buffer_top); + HeapWord* mem = offset_to_buffered_address(_buffer_used); memset(mem, 0, fill_bytes); oopDesc::set_mark(mem, markWord::prototype()); narrowKlass nk = ArchiveBuilder::current()->get_requested_narrow_klass(oak); @@ -313,10 +273,10 @@ void ArchiveHeapWriter::maybe_fill_gc_region_gap(size_t required_byte_size) { // required_byte_size has been allocated. If not, fill the remainder of the current // region. size_t min_filler_byte_size = filler_array_byte_size(0); - size_t new_top = _buffer_top + required_byte_size + min_filler_byte_size; + size_t new_used = _buffer_used + required_byte_size + min_filler_byte_size; - const size_t cur_min_region_bottom = align_down(_buffer_top, MIN_GC_REGION_ALIGNMENT); - const size_t next_min_region_bottom = align_down(new_top, MIN_GC_REGION_ALIGNMENT); + const size_t cur_min_region_bottom = align_down(_buffer_used, MIN_GC_REGION_ALIGNMENT); + const size_t next_min_region_bottom = align_down(new_used, MIN_GC_REGION_ALIGNMENT); if (cur_min_region_bottom != next_min_region_bottom) { // Make sure that no objects span across MIN_GC_REGION_ALIGNMENT. This way @@ -326,16 +286,16 @@ void ArchiveHeapWriter::maybe_fill_gc_region_gap(size_t required_byte_size) { "no buffered object can be larger than %d bytes", MIN_GC_REGION_ALIGNMENT); const size_t filler_end = next_min_region_bottom; - const size_t fill_bytes = filler_end - _buffer_top; + const size_t fill_bytes = filler_end - _buffer_used; assert(fill_bytes > 0, "must be"); ensure_buffer_space(filler_end); int array_length = filler_array_length(fill_bytes); log_info(cds, heap)("Inserting filler obj array of %d elements (" SIZE_FORMAT " bytes total) @ buffer offset " SIZE_FORMAT, - array_length, fill_bytes, _buffer_top); + array_length, fill_bytes, _buffer_used); init_filler_array_at_buffer_top(array_length, fill_bytes); - _buffer_top = filler_end; + _buffer_used = filler_end; } } @@ -344,72 +304,58 @@ size_t ArchiveHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) { size_t byte_size = src_obj->size() * HeapWordSize; assert(byte_size > 0, "no zero-size objects"); + // For region-based collectors such as G1, the archive heap may be mapped into + // multiple regions. We need to make sure that we don't have an object that can possible + // span across two regions. maybe_fill_gc_region_gap(byte_size); - size_t new_top = _buffer_top + byte_size; - assert(new_top > _buffer_top, "no wrap around"); + size_t new_used = _buffer_used + byte_size; + assert(new_used > _buffer_used, "no wrap around"); - size_t cur_min_region_bottom = align_down(_buffer_top, MIN_GC_REGION_ALIGNMENT); - size_t next_min_region_bottom = align_down(new_top, MIN_GC_REGION_ALIGNMENT); + size_t cur_min_region_bottom = align_down(_buffer_used, MIN_GC_REGION_ALIGNMENT); + size_t next_min_region_bottom = align_down(new_used, MIN_GC_REGION_ALIGNMENT); assert(cur_min_region_bottom == next_min_region_bottom, "no object should cross minimal GC region boundaries"); - ensure_buffer_space(new_top); + ensure_buffer_space(new_used); address from = cast_from_oop
(src_obj); - address to = offset_to_buffered_address
(_buffer_top); - assert(is_object_aligned(_buffer_top), "sanity"); + address to = offset_to_buffered_address
(_buffer_used); + assert(is_object_aligned(_buffer_used), "sanity"); assert(is_object_aligned(byte_size), "sanity"); memcpy(to, from, byte_size); - size_t buffered_obj_offset = _buffer_top; - _buffer_top = new_top; + size_t buffered_obj_offset = _buffer_used; + _buffer_used = new_used; return buffered_obj_offset; } -void ArchiveHeapWriter::set_requested_address_for_regions(GrowableArray* closed_regions, - GrowableArray* open_regions) { - assert(closed_regions->length() == 0, "must be"); - assert(open_regions->length() == 0, "must be"); - +void ArchiveHeapWriter::set_requested_address(ArchiveHeapInfo* info) { + assert(!info->is_used(), "only set once"); assert(UseG1GC, "must be"); address heap_end = (address)G1CollectedHeap::heap()->reserved().end(); log_info(cds, heap)("Heap end = %p", heap_end); - size_t closed_region_byte_size = _closed_top - _closed_bottom; - size_t open_region_byte_size = _open_top - _open_bottom; - assert(closed_region_byte_size > 0, "must archived at least one object for closed region!"); - assert(open_region_byte_size > 0, "must archived at least one object for open region!"); + size_t heap_region_byte_size = _buffer_used; + assert(heap_region_byte_size > 0, "must archived at least one object!"); - // The following two asserts are ensured by copy_source_objs_to_buffer_by_region(). - assert(is_aligned(_closed_bottom, HeapRegion::GrainBytes), "sanity"); - assert(is_aligned(_open_bottom, HeapRegion::GrainBytes), "sanity"); + _requested_bottom = align_down(heap_end - heap_region_byte_size, HeapRegion::GrainBytes); + assert(is_aligned(_requested_bottom, HeapRegion::GrainBytes), "sanity"); - _requested_closed_region_bottom = align_down(heap_end - closed_region_byte_size, HeapRegion::GrainBytes); - _requested_open_region_bottom = _requested_closed_region_bottom - (_closed_bottom - _open_bottom); + _requested_top = _requested_bottom + _buffer_used; - assert(is_aligned(_requested_closed_region_bottom, HeapRegion::GrainBytes), "sanity"); - assert(is_aligned(_requested_open_region_bottom, HeapRegion::GrainBytes), "sanity"); - - _requested_open_region_top = _requested_open_region_bottom + (_open_top - _open_bottom); - _requested_closed_region_top = _requested_closed_region_bottom + (_closed_top - _closed_bottom); - - assert(_requested_open_region_top <= _requested_closed_region_bottom, "no overlap"); - - closed_regions->append(MemRegion(offset_to_buffered_address(_closed_bottom), - offset_to_buffered_address(_closed_top))); - open_regions->append( MemRegion(offset_to_buffered_address(_open_bottom), - offset_to_buffered_address(_open_top))); + info->set_memregion(MemRegion(offset_to_buffered_address(0), + offset_to_buffered_address(_buffer_used))); } // Oop relocation template T* ArchiveHeapWriter::requested_addr_to_buffered_addr(T* p) { - assert(is_in_requested_regions(cast_to_oop(p)), "must be"); + assert(is_in_requested_range(cast_to_oop(p)), "must be"); address addr = address(p); - assert(addr >= _requested_open_region_bottom, "must be"); - size_t offset = addr - _requested_open_region_bottom; + assert(addr >= _requested_bottom, "must be"); + size_t offset = addr - _requested_bottom; return offset_to_buffered_address(offset); } @@ -421,7 +367,7 @@ template oop ArchiveHeapWriter::load_source_oop_from_buffer(T* buff template void ArchiveHeapWriter::store_requested_oop_in_buffer(T* buffered_addr, oop request_oop) { - assert(is_in_requested_regions(request_oop), "must be"); + assert(is_in_requested_range(request_oop), "must be"); store_oop_in_buffer(buffered_addr, request_oop); } @@ -445,30 +391,22 @@ oop ArchiveHeapWriter::load_oop_from_buffer(narrowOop* buffered_addr) { return CompressedOops::decode(*buffered_addr); } -template void ArchiveHeapWriter::relocate_field_in_buffer(T* field_addr_in_buffer) { +template void ArchiveHeapWriter::relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap) { oop source_referent = load_source_oop_from_buffer(field_addr_in_buffer); if (!CompressedOops::is_null(source_referent)) { oop request_referent = source_obj_to_requested_obj(source_referent); store_requested_oop_in_buffer(field_addr_in_buffer, request_referent); - mark_oop_pointer(field_addr_in_buffer); + mark_oop_pointer(field_addr_in_buffer, oopmap); } } -template void ArchiveHeapWriter::mark_oop_pointer(T* buffered_addr) { +template void ArchiveHeapWriter::mark_oop_pointer(T* buffered_addr, CHeapBitMap* oopmap) { T* request_p = (T*)(buffered_addr_to_requested_addr((address)buffered_addr)); - ResourceBitMap* oopmap; address requested_region_bottom; - if (request_p >= (T*)_requested_closed_region_bottom) { - assert(request_p < (T*)_requested_closed_region_top, "sanity"); - oopmap = _closed_oopmap; - requested_region_bottom = _requested_closed_region_bottom; - } else { - assert(request_p >= (T*)_requested_open_region_bottom, "sanity"); - assert(request_p < (T*)_requested_open_region_top, "sanity"); - oopmap = _open_oopmap; - requested_region_bottom = _requested_open_region_bottom; - } + assert(request_p >= (T*)_requested_bottom, "sanity"); + assert(request_p < (T*)_requested_top, "sanity"); + requested_region_bottom = _requested_bottom; // Mark the pointer in the oopmap T* region_bottom = (T*)requested_region_bottom; @@ -501,18 +439,19 @@ void ArchiveHeapWriter::update_header_for_requested_obj(oop requested_obj, oop s } // Relocate an element in the buffered copy of HeapShared::roots() -template void ArchiveHeapWriter::relocate_root_at(oop requested_roots, int index) { +template void ArchiveHeapWriter::relocate_root_at(oop requested_roots, int index, CHeapBitMap* oopmap) { size_t offset = (size_t)((objArrayOop)requested_roots)->obj_at_offset(index); - relocate_field_in_buffer((T*)(buffered_heap_roots_addr() + offset)); + relocate_field_in_buffer((T*)(buffered_heap_roots_addr() + offset), oopmap); } class ArchiveHeapWriter::EmbeddedOopRelocator: public BasicOopIterateClosure { oop _src_obj; address _buffered_obj; + CHeapBitMap* _oopmap; public: - EmbeddedOopRelocator(oop src_obj, address buffered_obj) : - _src_obj(src_obj), _buffered_obj(buffered_obj) {} + EmbeddedOopRelocator(oop src_obj, address buffered_obj, CHeapBitMap* oopmap) : + _src_obj(src_obj), _buffered_obj(buffered_obj), _oopmap(oopmap) {} void do_oop(narrowOop *p) { EmbeddedOopRelocator::do_oop_work(p); } void do_oop( oop *p) { EmbeddedOopRelocator::do_oop_work(p); } @@ -520,82 +459,40 @@ public: private: template void do_oop_work(T *p) { size_t field_offset = pointer_delta(p, _src_obj, sizeof(char)); - ArchiveHeapWriter::relocate_field_in_buffer((T*)(_buffered_obj + field_offset)); + ArchiveHeapWriter::relocate_field_in_buffer((T*)(_buffered_obj + field_offset), _oopmap); } }; // Update all oop fields embedded in the buffered objects void ArchiveHeapWriter::relocate_embedded_oops(GrowableArrayCHeap* roots, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps) { + ArchiveHeapInfo* heap_info) { size_t oopmap_unit = (UseCompressedOops ? sizeof(narrowOop) : sizeof(oop)); - size_t closed_region_byte_size = _closed_top - _closed_bottom; - size_t open_region_byte_size = _open_top - _open_bottom; - ResourceBitMap closed_oopmap(closed_region_byte_size / oopmap_unit); - ResourceBitMap open_oopmap (open_region_byte_size / oopmap_unit); - - _closed_oopmap = &closed_oopmap; - _open_oopmap = &open_oopmap; + size_t heap_region_byte_size = _buffer_used; + heap_info->oopmap()->resize(heap_region_byte_size / oopmap_unit); auto iterator = [&] (oop src_obj, HeapShared::CachedOopInfo& info) { oop requested_obj = requested_obj_from_buffer_offset(info.buffer_offset()); update_header_for_requested_obj(requested_obj, src_obj, src_obj->klass()); - address buffered_obj = offset_to_buffered_address
(info.buffer_offset()); - EmbeddedOopRelocator relocator(src_obj, buffered_obj); - + EmbeddedOopRelocator relocator(src_obj, buffered_obj, heap_info->oopmap()); src_obj->oop_iterate(&relocator); }; HeapShared::archived_object_cache()->iterate_all(iterator); // Relocate HeapShared::roots(), which is created in copy_roots_to_buffer() and // doesn't have a corresponding src_obj, so we can't use EmbeddedOopRelocator on it. - oop requested_roots = requested_obj_from_buffer_offset(_heap_roots_bottom); + oop requested_roots = requested_obj_from_buffer_offset(_heap_roots_bottom_offset); update_header_for_requested_obj(requested_roots, nullptr, Universe::objectArrayKlassObj()); int length = roots != nullptr ? roots->length() : 0; for (int i = 0; i < length; i++) { if (UseCompressedOops) { - relocate_root_at(requested_roots, i); + relocate_root_at(requested_roots, i, heap_info->oopmap()); } else { - relocate_root_at(requested_roots, i); + relocate_root_at(requested_roots, i, heap_info->oopmap()); } } - closed_bitmaps->append(make_bitmap_info(&closed_oopmap, /*is_open=*/false, /*is_oopmap=*/true)); - open_bitmaps ->append(make_bitmap_info(&open_oopmap, /*is_open=*/false, /*is_oopmap=*/true)); - - closed_bitmaps->append(compute_ptrmap(/*is_open=*/false)); - open_bitmaps ->append(compute_ptrmap(/*is_open=*/true)); - - _closed_oopmap = nullptr; - _open_oopmap = nullptr; -} - -ArchiveHeapBitmapInfo ArchiveHeapWriter::make_bitmap_info(ResourceBitMap* bitmap, bool is_open, bool is_oopmap) { - size_t size_in_bits = bitmap->size(); - size_t size_in_bytes; - uintptr_t* buffer; - - if (size_in_bits > 0) { - size_in_bytes = bitmap->size_in_bytes(); - buffer = (uintptr_t*)NEW_C_HEAP_ARRAY(char, size_in_bytes, mtInternal); - bitmap->write_to(buffer, size_in_bytes); - } else { - size_in_bytes = 0; - buffer = nullptr; - } - - log_info(cds, heap)("%s @ " INTPTR_FORMAT " (" SIZE_FORMAT_W(6) " bytes) for %s heap region", - is_oopmap ? "Oopmap" : "Ptrmap", - p2i(buffer), size_in_bytes, - is_open? "open" : "closed"); - - ArchiveHeapBitmapInfo info; - info._map = (address)buffer; - info._size_in_bits = size_in_bits; - info._size_in_bytes = size_in_bytes; - - return info; + compute_ptrmap(heap_info); } void ArchiveHeapWriter::mark_native_pointer(oop src_obj, int field_offset) { @@ -608,50 +505,44 @@ void ArchiveHeapWriter::mark_native_pointer(oop src_obj, int field_offset) { } } -ArchiveHeapBitmapInfo ArchiveHeapWriter::compute_ptrmap(bool is_open) { +void ArchiveHeapWriter::compute_ptrmap(ArchiveHeapInfo* heap_info) { int num_non_null_ptrs = 0; - Metadata** bottom = (Metadata**) (is_open ? _requested_open_region_bottom: _requested_closed_region_bottom); - Metadata** top = (Metadata**) (is_open ? _requested_open_region_top: _requested_closed_region_top); // exclusive - ResourceBitMap ptrmap(top - bottom); + Metadata** bottom = (Metadata**) _requested_bottom; + Metadata** top = (Metadata**) _requested_top; // exclusive + heap_info->ptrmap()->resize(top - bottom); + BitMap::idx_t max_idx = 32; // paranoid - don't make it too small for (int i = 0; i < _native_pointers->length(); i++) { NativePointerInfo info = _native_pointers->at(i); oop src_obj = info._src_obj; int field_offset = info._field_offset; HeapShared::CachedOopInfo* p = HeapShared::archived_object_cache()->get(src_obj); - if (p->in_open_region() == is_open) { - // requested_field_addr = the address of this field in the requested space - oop requested_obj = requested_obj_from_buffer_offset(p->buffer_offset()); - Metadata** requested_field_addr = (Metadata**)(cast_from_oop
(requested_obj) + field_offset); - assert(bottom <= requested_field_addr && requested_field_addr < top, "range check"); + // requested_field_addr = the address of this field in the requested space + oop requested_obj = requested_obj_from_buffer_offset(p->buffer_offset()); + Metadata** requested_field_addr = (Metadata**)(cast_from_oop
(requested_obj) + field_offset); + assert(bottom <= requested_field_addr && requested_field_addr < top, "range check"); - // Mark this field in the bitmap - BitMap::idx_t idx = requested_field_addr - bottom; - ptrmap.set_bit(idx); - num_non_null_ptrs ++; + // Mark this field in the bitmap + BitMap::idx_t idx = requested_field_addr - bottom; + heap_info->ptrmap()->set_bit(idx); + num_non_null_ptrs ++; + max_idx = MAX2(max_idx, idx); - // Set the native pointer to the requested address of the metadata (at runtime, the metadata will have - // this address if the RO/RW regions are mapped at the default location). + // Set the native pointer to the requested address of the metadata (at runtime, the metadata will have + // this address if the RO/RW regions are mapped at the default location). - Metadata** buffered_field_addr = requested_addr_to_buffered_addr(requested_field_addr); - Metadata* native_ptr = *buffered_field_addr; - assert(native_ptr != nullptr, "sanity"); + Metadata** buffered_field_addr = requested_addr_to_buffered_addr(requested_field_addr); + Metadata* native_ptr = *buffered_field_addr; + assert(native_ptr != nullptr, "sanity"); - address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr); - address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr); - *buffered_field_addr = (Metadata*)requested_native_ptr; - } + address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr); + address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr); + *buffered_field_addr = (Metadata*)requested_native_ptr; } - log_info(cds, heap)("compute_ptrmap: marked %d non-null native pointers for %s heap region", - num_non_null_ptrs, is_open ? "open" : "closed"); - - if (num_non_null_ptrs == 0) { - ResourceBitMap empty; - return make_bitmap_info(&empty, is_open, /*is_oopmap=*/ false); - } else { - return make_bitmap_info(&ptrmap, is_open, /*is_oopmap=*/ false); - } + heap_info->ptrmap()->resize(max_idx + 1); + log_info(cds, heap)("calculate_ptrmap: marked %d non-null native pointers for heap region (" SIZE_FORMAT " bits)", + num_non_null_ptrs, size_t(heap_info->ptrmap()->size())); } #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/archiveHeapWriter.hpp b/src/hotspot/share/cds/archiveHeapWriter.hpp index 18eef9bcf46..6001012ba85 100644 --- a/src/hotspot/share/cds/archiveHeapWriter.hpp +++ b/src/hotspot/share/cds/archiveHeapWriter.hpp @@ -35,11 +35,28 @@ #include "utilities/macros.hpp" #include "utilities/resourceHash.hpp" -#if INCLUDE_CDS_JAVA_HEAP - -struct ArchiveHeapBitmapInfo; class MemRegion; +class ArchiveHeapInfo { + MemRegion _memregion; + CHeapBitMap _oopmap; + CHeapBitMap _ptrmap; + +public: + ArchiveHeapInfo() : _memregion(), _oopmap(128, mtClassShared), _ptrmap(128, mtClassShared) {} + bool is_used() { return !_memregion.is_empty(); } + + MemRegion memregion() { return _memregion; } + void set_memregion(MemRegion r) { _memregion = r; } + + char* start() { return (char*)_memregion.start(); } + size_t byte_size() { return _memregion.byte_size(); } + + CHeapBitMap* oopmap() { return &_oopmap; } + CHeapBitMap* ptrmap() { return &_ptrmap; } +}; + +#if INCLUDE_CDS_JAVA_HEAP class ArchiveHeapWriter : AllStatic { class EmbeddedOopRelocator; struct NativePointerInfo { @@ -72,31 +89,16 @@ class ArchiveHeapWriter : AllStatic { static GrowableArrayCHeap* _buffer; - // The exclusive top of the last object that has been copied into this->_buffer. - static size_t _buffer_top; - - // The bounds of the open region inside this->_buffer. - static size_t _open_bottom; // inclusive - static size_t _open_top; // exclusive - - // The bounds of the closed region inside this->_buffer. - static size_t _closed_bottom; // inclusive - static size_t _closed_top; // exclusive + // The number of bytes that have written into _buffer (may be smaller than _buffer->length()). + static size_t _buffer_used; // The bottom of the copy of Heap::roots() inside this->_buffer. - static size_t _heap_roots_bottom; + static size_t _heap_roots_bottom_offset; static size_t _heap_roots_word_size; - static address _requested_open_region_bottom; - static address _requested_open_region_top; - static address _requested_closed_region_bottom; - static address _requested_closed_region_top; - - static ResourceBitMap* _closed_oopmap; - static ResourceBitMap* _open_oopmap; - - static ArchiveHeapBitmapInfo _closed_oopmap_info; - static ArchiveHeapBitmapInfo _open_oopmap_info; + // The address range of the requested location of the archived heap objects. + static address _requested_bottom; + static address _requested_top; static GrowableArrayCHeap* _native_pointers; static GrowableArrayCHeap* _source_objs; @@ -127,8 +129,9 @@ class ArchiveHeapWriter : AllStatic { return offset_to_buffered_address
(0); } + // The exclusive end of the last object that was copied into the buffer. static address buffer_top() { - return buffer_bottom() + _buffer_top; + return buffer_bottom() + _buffer_used; } static bool in_buffer(address buffered_addr) { @@ -142,7 +145,6 @@ class ArchiveHeapWriter : AllStatic { static void copy_roots_to_buffer(GrowableArrayCHeap* roots); static void copy_source_objs_to_buffer(GrowableArrayCHeap* roots); - static void copy_source_objs_to_buffer_by_region(bool copy_open_region); static size_t copy_one_source_obj_to_buffer(oop src_obj); static void maybe_fill_gc_region_gap(size_t required_byte_size); @@ -150,14 +152,10 @@ class ArchiveHeapWriter : AllStatic { static int filler_array_length(size_t fill_bytes); static void init_filler_array_at_buffer_top(int array_length, size_t fill_bytes); - static void set_requested_address_for_regions(GrowableArray* closed_regions, - GrowableArray* open_regions); - static void relocate_embedded_oops(GrowableArrayCHeap* roots, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps); - static ArchiveHeapBitmapInfo compute_ptrmap(bool is_open); - static ArchiveHeapBitmapInfo make_bitmap_info(ResourceBitMap* bitmap, bool is_open, bool is_oopmap); - static bool is_in_requested_regions(oop o); + static void set_requested_address(ArchiveHeapInfo* info); + static void relocate_embedded_oops(GrowableArrayCHeap* roots, ArchiveHeapInfo* info); + static void compute_ptrmap(ArchiveHeapInfo *info); + static bool is_in_requested_range(oop o); static oop requested_obj_from_buffer_offset(size_t offset); static oop load_oop_from_buffer(oop* buffered_addr); @@ -169,9 +167,9 @@ class ArchiveHeapWriter : AllStatic { template static void store_requested_oop_in_buffer(T* buffered_addr, oop request_oop); template static T* requested_addr_to_buffered_addr(T* p); - template static void relocate_field_in_buffer(T* field_addr_in_buffer); - template static void mark_oop_pointer(T* buffered_addr); - template static void relocate_root_at(oop requested_roots, int index); + template static void relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap); + template static void mark_oop_pointer(T* buffered_addr, CHeapBitMap* oopmap); + template static void relocate_root_at(oop requested_roots, int index, CHeapBitMap* oopmap); static void update_header_for_requested_obj(oop requested_obj, oop src_obj, Klass* src_klass); public: @@ -180,14 +178,11 @@ public: static bool is_too_large_to_archive(size_t size); static bool is_too_large_to_archive(oop obj); static bool is_string_too_large_to_archive(oop string); - static void write(GrowableArrayCHeap*, - GrowableArray* closed_regions, GrowableArray* open_regions, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps); - static address heap_region_requested_bottom(int heap_region_idx); - static oop heap_roots_requested_address(); + static void write(GrowableArrayCHeap*, ArchiveHeapInfo* heap_info); + static address requested_address(); // requested address of the lowest achived heap object + static oop heap_roots_requested_address(); // requested address of HeapShared::roots() static address buffered_heap_roots_addr() { - return offset_to_buffered_address
(_heap_roots_bottom); + return offset_to_buffered_address
(_heap_roots_bottom_offset); } static size_t heap_roots_word_size() { return _heap_roots_word_size; diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 9f99d1d98fc..952f69749b3 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -226,7 +226,7 @@ void DumpRegion::append_intptr_t(intptr_t n, bool need_to_mark) { } void DumpRegion::print(size_t total_bytes) const { - log_debug(cds)("%-3s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT, + log_debug(cds)("%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT, _name, used(), percent_of(used(), total_bytes), reserved(), percent_of(used(), reserved()), p2i(ArchiveBuilder::current()->to_requested(_base))); } diff --git a/src/hotspot/share/cds/dumpAllocStats.cpp b/src/hotspot/share/cds/dumpAllocStats.cpp index 523fe858704..21a40ca8f28 100644 --- a/src/hotspot/share/cds/dumpAllocStats.cpp +++ b/src/hotspot/share/cds/dumpAllocStats.cpp @@ -54,7 +54,7 @@ void DumpAllocStats::print_stats(int ro_all, int rw_all) { LogMessage(cds) msg; - msg.debug("Detailed metadata info (excluding heap regions):"); + msg.debug("Detailed metadata info (excluding heap region):"); msg.debug("%s", hdr); msg.debug("%s", sep); for (int type = 0; type < int(_number_of_types); type ++) { diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index 36728e459c6..0aa11ef8d5b 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapWriter.hpp" #include "cds/archiveUtils.inline.hpp" #include "cds/cds_globals.hpp" #include "cds/classPrelinker.hpp" @@ -323,7 +324,8 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) { assert(dynamic_info != nullptr, "Sanity"); dynamic_info->open_for_write(); - ArchiveBuilder::write_archive(dynamic_info, nullptr, nullptr, nullptr, nullptr); + ArchiveHeapInfo no_heap_for_dynamic_dump; + ArchiveBuilder::write_archive(dynamic_info, &no_heap_for_dynamic_dump); address base = _requested_dynamic_archive_bottom; address top = _requested_dynamic_archive_top; diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index a0c82dcdcc2..369bae8c561 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1413,7 +1413,7 @@ bool FileMapInfo::init_from_file(int fd) { size_t len = os::lseek(fd, 0, SEEK_END); - for (int i = 0; i <= MetaspaceShared::last_valid_region; i++) { + for (int i = 0; i < MetaspaceShared::n_regions; i++) { FileMapRegion* r = region_at(i); if (r->file_offset() > len || len - r->file_offset() < r->used()) { log_warning(cds)("The shared archive file has been truncated."); @@ -1515,12 +1515,14 @@ void FileMapRegion::init(int region_index, size_t mapping_offset, size_t size, b _mapped_base = nullptr; } -void FileMapRegion::init_bitmaps(ArchiveHeapBitmapInfo oopmap, ArchiveHeapBitmapInfo ptrmap) { - _oopmap_offset = oopmap._bm_region_offset; - _oopmap_size_in_bits = oopmap._size_in_bits; +void FileMapRegion::init_oopmap(size_t offset, size_t size_in_bits) { + _oopmap_offset = offset; + _oopmap_size_in_bits = size_in_bits; +} - _ptrmap_offset = ptrmap._bm_region_offset; - _ptrmap_size_in_bits = ptrmap._size_in_bits; +void FileMapRegion::init_ptrmap(size_t offset, size_t size_in_bits) { + _ptrmap_offset = offset; + _ptrmap_size_in_bits = size_in_bits; } BitMapView FileMapRegion::bitmap_view(bool is_oopmap) { @@ -1559,7 +1561,7 @@ bool FileMapRegion::check_region_crc() const { static const char* region_name(int region_index) { static const char* names[] = { - "rw", "ro", "bm", "ca0", "ca1", "oa0", "oa1" + "rw", "ro", "bm", "hp" }; const int num_regions = sizeof(names)/sizeof(names[0]); assert(0 <= region_index && region_index < num_regions, "sanity"); @@ -1600,7 +1602,7 @@ void FileMapInfo::write_region(int region, char* base, size_t size, assert(HeapShared::can_write(), "sanity"); #if INCLUDE_CDS_JAVA_HEAP assert(!DynamicDumpSharedSpaces, "must be"); - requested_base = (char*)ArchiveHeapWriter::heap_region_requested_bottom(region); + requested_base = (char*)ArchiveHeapWriter::requested_address(); if (UseCompressedOops) { mapping_offset = (size_t)((address)requested_base - CompressedOops::base()); assert((mapping_offset >> CompressedOops::shift()) << CompressedOops::shift() == mapping_offset, "must be"); @@ -1620,7 +1622,7 @@ void FileMapInfo::write_region(int region, char* base, size_t size, r->set_file_offset(_file_offset); int crc = ClassLoader::crc32(0, base, (jint)size); if (size > 0) { - log_info(cds)("Shared file region (%-3s) %d: " SIZE_FORMAT_W(8) + log_info(cds)("Shared file region (%s) %d: " SIZE_FORMAT_W(8) " bytes, addr " INTPTR_FORMAT " file offset 0x%08" PRIxPTR " crc 0x%08x", region_name(region), region, size, p2i(requested_base), _file_offset, crc); @@ -1633,113 +1635,49 @@ void FileMapInfo::write_region(int region, char* base, size_t size, } } -size_t FileMapInfo::set_bitmaps_offset(GrowableArray* bitmaps, size_t curr_size) { - for (int i = 0; i < bitmaps->length(); i++) { - bitmaps->at(i)._bm_region_offset = curr_size; - curr_size += bitmaps->at(i)._size_in_bytes; - } - return curr_size; +static size_t write_bitmap(const CHeapBitMap* map, char* output, size_t offset) { + size_t size_in_bytes = map->size_in_bytes(); + map->write_to((BitMap::bm_word_t*)(output + offset), size_in_bytes); + return offset + size_in_bytes; } -size_t FileMapInfo::write_bitmaps(GrowableArray* bitmaps, size_t curr_offset, char* buffer) { - for (int i = 0; i < bitmaps->length(); i++) { - memcpy(buffer + curr_offset, bitmaps->at(i)._map, bitmaps->at(i)._size_in_bytes); - curr_offset += bitmaps->at(i)._size_in_bytes; - } - return curr_offset; -} - -char* FileMapInfo::write_bitmap_region(const CHeapBitMap* ptrmap, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps, +char* FileMapInfo::write_bitmap_region(const CHeapBitMap* ptrmap, ArchiveHeapInfo* heap_info, size_t &size_in_bytes) { - size_t size_in_bits = ptrmap->size(); size_in_bytes = ptrmap->size_in_bytes(); - if (closed_bitmaps != nullptr && open_bitmaps != nullptr) { - size_in_bytes = set_bitmaps_offset(closed_bitmaps, size_in_bytes); - size_in_bytes = set_bitmaps_offset(open_bitmaps, size_in_bytes); + if (heap_info->is_used()) { + size_in_bytes += heap_info->oopmap()->size_in_bytes(); + size_in_bytes += heap_info->ptrmap()->size_in_bytes(); } + // The bitmap region contains up to 3 parts: + // ptrmap: metaspace pointers inside the ro/rw regions + // heap_info->oopmap(): Java oop pointers in the heap region + // heap_info->ptrmap(): metaspace pointers in the heap region char* buffer = NEW_C_HEAP_ARRAY(char, size_in_bytes, mtClassShared); - ptrmap->write_to((BitMap::bm_word_t*)buffer, ptrmap->size_in_bytes()); - header()->set_ptrmap_size_in_bits(size_in_bits); + size_t written = 0; + written = write_bitmap(ptrmap, buffer, written); + header()->set_ptrmap_size_in_bits(ptrmap->size()); - if (closed_bitmaps != nullptr && open_bitmaps != nullptr) { - size_t curr_offset = write_bitmaps(closed_bitmaps, ptrmap->size_in_bytes(), buffer); - write_bitmaps(open_bitmaps, curr_offset, buffer); + if (heap_info->is_used()) { + FileMapRegion* r = region_at(MetaspaceShared::hp); + + r->init_oopmap(written, heap_info->oopmap()->size()); + written = write_bitmap(heap_info->oopmap(), buffer, written); + + r->init_ptrmap(written, heap_info->ptrmap()->size()); + written = write_bitmap(heap_info->ptrmap(), buffer, written); } write_region(MetaspaceShared::bm, (char*)buffer, size_in_bytes, /*read_only=*/true, /*allow_exec=*/false); return buffer; } -// Write out the given archive heap memory regions. GC code combines multiple -// consecutive archive GC regions into one MemRegion whenever possible and -// produces the 'regions' array. -// -// If the archive heap memory size is smaller than a single dump time GC region -// size, there is only one MemRegion in the array. -// -// If the archive heap memory size is bigger than one dump time GC region size, -// the 'regions' array may contain more than one consolidated MemRegions. When -// the first/bottom archive GC region is a partial GC region (with the empty -// portion at the higher address within the region), one MemRegion is used for -// the bottom partial archive GC region. The rest of the consecutive archive -// GC regions are combined into another MemRegion. -// -// Here's the mapping from (archive heap GC regions) -> (GrowableArray *regions). -// + We have 1 or more archive heap regions: ah0, ah1, ah2 ..... ahn -// + We have 1 or 2 consolidated heap memory regions: r0 and r1 -// -// If there's a single archive GC region (ah0), then r0 == ah0, and r1 is empty. -// Otherwise: -// -// "X" represented space that's occupied by heap objects. -// "_" represented unused spaced in the heap region. -// -// -// |ah0 | ah1 | ah2| ...... | ahn| -// |XXXXXX|__ |XXXXX|XXXX|XXXXXXXX|XXXX| -// |<-r0->| |<- r1 ----------------->| -// ^^^ -// | -// +-- gap -size_t FileMapInfo::write_heap_regions(GrowableArray* regions, - GrowableArray* bitmaps, - int first_region_id, int max_num_regions) { - assert(max_num_regions <= 2, "Only support maximum 2 memory regions"); - - int arr_len = regions == nullptr ? 0 : regions->length(); - if (arr_len > max_num_regions) { - log_error(cds)("Unable to write archive heap memory regions: " - "number of memory regions exceeds maximum due to fragmentation. " - "Please increase java heap size " - "(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").", - MaxHeapSize, InitialHeapSize); - MetaspaceShared::unrecoverable_writing_error(); - } - - size_t total_size = 0; - for (int i = 0; i < max_num_regions; i++) { - char* start = nullptr; - size_t size = 0; - if (i < arr_len) { - start = (char*)regions->at(i).start(); - size = regions->at(i).byte_size(); - total_size += size; - } - - int region_idx = i + first_region_id; - write_region(region_idx, start, size, false, false); - if (size > 0) { - int oopmap_idx = i * 2; - int ptrmap_idx = i * 2 + 1; - region_at(region_idx)->init_bitmaps(bitmaps->at(oopmap_idx), - bitmaps->at(ptrmap_idx)); - } - } - return total_size; +size_t FileMapInfo::write_heap_region(ArchiveHeapInfo* heap_info) { + char* start = heap_info->start(); + size_t size = heap_info->byte_size(); + write_region(MetaspaceShared::hp, start, size, false, false); + return size; } // Dump bytes to file -- at the current file position. @@ -1832,8 +1770,7 @@ bool FileMapInfo::remap_shared_readonly_as_readwrite() { } // Memory map a region in the address space. -static const char* shared_region_name[] = { "ReadWrite", "ReadOnly", "Bitmap", - "String1", "String2", "OpenArchive1", "OpenArchive2" }; +static const char* shared_region_name[] = { "ReadWrite", "ReadOnly", "Bitmap", "Heap" }; MapArchiveResult FileMapInfo::map_regions(int regions[], int num_regions, char* mapped_base_address, ReservedSpace rs) { DEBUG_ONLY(FileMapRegion* last_region = nullptr); @@ -2054,58 +1991,38 @@ size_t FileMapInfo::readonly_total() { return total; } -static MemRegion *closed_heap_regions = nullptr; -static MemRegion *open_heap_regions = nullptr; -static int num_closed_heap_regions = 0; -static int num_open_heap_regions = 0; - #if INCLUDE_CDS_JAVA_HEAP -bool FileMapInfo::has_heap_regions() { - return (region_at(MetaspaceShared::first_closed_heap_region)->used() > 0); +MemRegion FileMapInfo::_mapped_heap_memregion; + +bool FileMapInfo::has_heap_region() { + return (region_at(MetaspaceShared::hp)->used() > 0); } -// Returns the address range of the archived heap regions computed using the +// Returns the address range of the archived heap region computed using the // current oop encoding mode. This range may be different than the one seen at // dump time due to encoding mode differences. The result is used in determining // if/how these regions should be relocated at run time. -MemRegion FileMapInfo::get_heap_regions_requested_range() { - address start = (address) max_uintx; - address end = nullptr; +MemRegion FileMapInfo::get_heap_region_requested_range() { + FileMapRegion* r = region_at(MetaspaceShared::hp); + size_t size = r->used(); + assert(size > 0, "must have non-empty heap region"); - for (int i = MetaspaceShared::first_closed_heap_region; - i <= MetaspaceShared::last_valid_region; - i++) { - FileMapRegion* r = region_at(i); - size_t size = r->used(); - if (size > 0) { - address s = heap_region_requested_address(r); - address e = s + size; - log_info(cds)("Heap region %s = " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes", - region_name(i), p2i(s), p2i(e), size); - if (start > s) { - start = s; - } - if (end < e) { - end = e; - } - } - } - assert(end != nullptr, "must have at least one used heap region"); - - start = align_down(start, HeapRegion::GrainBytes); - end = align_up(end, HeapRegion::GrainBytes); + address start = heap_region_requested_address(); + address end = start + size; + log_info(cds)("Requested heap region [" INTPTR_FORMAT " - " INTPTR_FORMAT "] = " SIZE_FORMAT_W(8) " bytes", + p2i(start), p2i(end), size); return MemRegion((HeapWord*)start, (HeapWord*)end); } -void FileMapInfo::map_or_load_heap_regions() { +void FileMapInfo::map_or_load_heap_region() { bool success = false; - if (can_use_heap_regions()) { + if (can_use_heap_region()) { if (ArchiveHeapLoader::can_map()) { - success = map_heap_regions(); + success = map_heap_region(); } else if (ArchiveHeapLoader::can_load()) { - success = ArchiveHeapLoader::load_heap_regions(this); + success = ArchiveHeapLoader::load_heap_region(this); } else { if (!UseCompressedOops && !ArchiveHeapLoader::can_map()) { // TODO - remove implicit knowledge of G1 @@ -2121,8 +2038,8 @@ void FileMapInfo::map_or_load_heap_regions() { } } -bool FileMapInfo::can_use_heap_regions() { - if (!has_heap_regions()) { +bool FileMapInfo::can_use_heap_region() { + if (!has_heap_region()) { return false; } if (JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()) { @@ -2168,22 +2085,22 @@ bool FileMapInfo::can_use_heap_regions() { } // The actual address of this region during dump time. -address FileMapInfo::heap_region_dumptime_address(FileMapRegion* r) { +address FileMapInfo::heap_region_dumptime_address() { + FileMapRegion* r = region_at(MetaspaceShared::hp); assert(UseSharedSpaces, "runtime only"); - r->assert_is_heap_region(); assert(is_aligned(r->mapping_offset(), sizeof(HeapWord)), "must be"); if (UseCompressedOops) { return /*dumptime*/ narrow_oop_base() + r->mapping_offset(); } else { - return heap_region_requested_address(r); + return heap_region_requested_address(); } } // The address where this region can be mapped into the runtime heap without // patching any of the pointers that are embedded in this region. -address FileMapInfo::heap_region_requested_address(FileMapRegion* r) { +address FileMapInfo::heap_region_requested_address() { assert(UseSharedSpaces, "runtime only"); - r->assert_is_heap_region(); + FileMapRegion* r = region_at(MetaspaceShared::hp); assert(is_aligned(r->mapping_offset(), sizeof(HeapWord)), "must be"); assert(ArchiveHeapLoader::can_map(), "cannot be used by ArchiveHeapLoader::can_load() mode"); if (UseCompressedOops) { @@ -2209,284 +2126,171 @@ address FileMapInfo::heap_region_requested_address(FileMapRegion* r) { // The address where this shared heap region is actually mapped at runtime. This function // can be called only after we have determined the value for ArchiveHeapLoader::mapped_heap_delta(). -address FileMapInfo::heap_region_mapped_address(FileMapRegion* r) { +address FileMapInfo::heap_region_mapped_address() { assert(UseSharedSpaces, "runtime only"); - r->assert_is_heap_region(); assert(ArchiveHeapLoader::can_map(), "cannot be used by ArchiveHeapLoader::can_load() mode"); - return heap_region_requested_address(r) + ArchiveHeapLoader::mapped_heap_delta(); + return heap_region_requested_address() + ArchiveHeapLoader::mapped_heap_delta(); } -// -// Map the closed and open archive heap objects to the runtime java heap. -// -// The shared objects are mapped at (or close to ) the java heap top in -// closed archive regions. The mapped objects contain no out-going -// references to any other java heap regions. GC does not write into the -// mapped closed archive heap region. -// -// The open archive heap objects are mapped below the shared objects in -// the runtime java heap. The mapped open archive heap data only contains -// references to the shared objects and open archive objects initially. -// During runtime execution, out-going references to any other java heap -// regions may be added. GC may mark and update references in the mapped -// open archive objects. -void FileMapInfo::map_heap_regions_impl() { - // G1 -- always map at the very top of the heap to avoid fragmentation. - assert(UseG1GC, "the following code assumes G1"); - _heap_pointers_need_patching = false; - - MemRegion heap_range = G1CollectedHeap::heap()->reserved(); - MemRegion archive_range = get_heap_regions_requested_range(); - - address heap_end = (address)heap_range.end(); - address archive_end = (address)archive_range.end(); - - assert(is_aligned(heap_end, HeapRegion::GrainBytes), "must be"); - assert(is_aligned(archive_end, HeapRegion::GrainBytes), "must be"); - - if (UseCompressedOops && - (narrow_oop_mode() != CompressedOops::mode() || - narrow_oop_shift() != CompressedOops::shift())) { - log_info(cds)("CDS heap data needs to be relocated because the archive was created with an incompatible oop encoding mode."); - _heap_pointers_need_patching = true; - } else if (!heap_range.contains(archive_range)) { - log_info(cds)("CDS heap data needs to be relocated because"); - log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(archive_range.start()), p2i(archive_range.end())); - log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(heap_range.start()), p2i(heap_range.end())); - _heap_pointers_need_patching = true; - } else { - assert(heap_end >= archive_end, "must be"); - if (heap_end != archive_end) { - log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); - _heap_pointers_need_patching = true; - } - } - - ptrdiff_t delta = 0; - if (_heap_pointers_need_patching) { - delta = heap_end - archive_end; - } - - log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta); - - FileMapRegion* r = region_at(MetaspaceShared::first_closed_heap_region); - address relocated_closed_heap_region_bottom = heap_region_requested_address(r) + delta; - - if (!is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes)) { - // Align the bottom of the closed archive heap regions at G1 region boundary. - // This will avoid the situation where the highest open region and the lowest - // closed region sharing the same G1 region. Otherwise we will fail to map the - // open regions. - size_t align = size_t(relocated_closed_heap_region_bottom) % HeapRegion::GrainBytes; - delta -= align; - log_info(cds)("CDS heap data needs to be relocated lower by a further " SIZE_FORMAT - " bytes to " INTX_FORMAT " to be aligned with HeapRegion::GrainBytes", - align, delta); - _heap_pointers_need_patching = true; - } - - ArchiveHeapLoader::init_mapped_heap_relocation(delta, narrow_oop_shift()); - relocated_closed_heap_region_bottom = heap_region_mapped_address(r); - - assert(is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes), - "must be"); +bool FileMapInfo::map_heap_region() { + init_heap_region_relocation(); if (_heap_pointers_need_patching) { char* bitmap_base = map_bitmap_region(); if (bitmap_base == nullptr) { log_info(cds)("CDS heap cannot be used because bitmap region cannot be mapped"); _heap_pointers_need_patching = false; - return; + return false; } } - // Map the closed heap regions: GC does not write into these regions. - if (map_heap_regions(MetaspaceShared::first_closed_heap_region, - MetaspaceShared::max_num_closed_heap_regions, - /*is_open_archive=*/ false, - &closed_heap_regions, &num_closed_heap_regions)) { - ArchiveHeapLoader::set_closed_regions_mapped(); + if (map_heap_region_impl()) { +#ifdef ASSERT + // The "old" regions must be parsable -- we cannot have any unused space + // at the start of the lowest G1 region that contains archived objects. + assert(is_aligned(_mapped_heap_memregion.start(), HeapRegion::GrainBytes), "must be"); - // Now, map the open heap regions: GC can write into these regions. - if (map_heap_regions(MetaspaceShared::first_open_heap_region, - MetaspaceShared::max_num_open_heap_regions, - /*is_open_archive=*/ true, - &open_heap_regions, &num_open_heap_regions)) { - ArchiveHeapLoader::set_open_regions_mapped(); - } - } -} + // Make sure we map at the very top of the heap - see comments in + // init_heap_region_relocation(). + MemRegion heap_range = G1CollectedHeap::heap()->reserved(); + assert(heap_range.contains(_mapped_heap_memregion), "must be"); -bool FileMapInfo::map_heap_regions() { - map_heap_regions_impl(); + address heap_end = (address)heap_range.end(); + address mapped_heap_region_end = (address)_mapped_heap_memregion.end(); + assert(heap_end >= mapped_heap_region_end, "must be"); + assert(heap_end - mapped_heap_region_end < (intx)(HeapRegion::GrainBytes), + "must be at the top of the heap to avoid fragmentation"); +#endif - if (!ArchiveHeapLoader::closed_regions_mapped()) { - assert(closed_heap_regions == nullptr && - num_closed_heap_regions == 0, "sanity"); - } - - if (!ArchiveHeapLoader::open_regions_mapped()) { - assert(open_heap_regions == nullptr && num_open_heap_regions == 0, "sanity"); - return false; - } else { + ArchiveHeapLoader::set_mapped(); return true; + } else { + return false; } } -bool FileMapInfo::map_heap_regions(int first, int max, bool is_open_archive, - MemRegion** regions_ret, int* num_regions_ret) { - MemRegion* regions = MemRegion::create_array(max, mtInternal); +void FileMapInfo::init_heap_region_relocation() { + assert(UseG1GC, "the following code assumes G1"); + _heap_pointers_need_patching = false; - struct Cleanup { - MemRegion* _regions; - uint _length; - bool _aborted; - Cleanup(MemRegion* regions, uint length) : _regions(regions), _length(length), _aborted(true) { } - ~Cleanup() { if (_aborted) { MemRegion::destroy_array(_regions, _length); } } - } cleanup(regions, max); + MemRegion heap_range = G1CollectedHeap::heap()->reserved(); + MemRegion archive_range = get_heap_region_requested_range(); - FileMapRegion* r; - int num_regions = 0; + address requested_bottom = (address)archive_range.start(); + address heap_end = (address)heap_range.end(); + assert(is_aligned(heap_end, HeapRegion::GrainBytes), "must be"); - for (int i = first; - i < first + max; i++) { - r = region_at(i); - size_t size = r->used(); - if (size > 0) { - HeapWord* start = (HeapWord*)heap_region_mapped_address(r); - regions[num_regions] = MemRegion(start, size / HeapWordSize); - num_regions ++; - log_info(cds)("Trying to map heap data: region[%d] at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes", - i, p2i(start), size); - } + // We map the archive heap region at the very top of the heap to avoid fragmentation. + // To do that, we make sure that the bottom of the archived region is at the same + // address as the bottom of the highest possible G1 region. + address mapped_bottom = heap_end - align_up(archive_range.byte_size(), HeapRegion::GrainBytes); + + if (UseCompressedOops && + (narrow_oop_mode() != CompressedOops::mode() || + narrow_oop_shift() != CompressedOops::shift())) { + log_info(cds)("CDS heap data needs to be relocated because the archive was created with an incompatible oop encoding mode."); + _heap_pointers_need_patching = true; + } else if (requested_bottom != mapped_bottom) { + log_info(cds)("CDS heap data needs to be relocated because it is mapped at a different address @ " INTPTR_FORMAT, + p2i(mapped_bottom)); + _heap_pointers_need_patching = true; } - if (num_regions == 0) { + ptrdiff_t delta = 0; + if (_heap_pointers_need_patching) { + delta = mapped_bottom - requested_bottom; + } + + log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta); + ArchiveHeapLoader::init_mapped_heap_relocation(delta, narrow_oop_shift()); +} + +bool FileMapInfo::map_heap_region_impl() { + FileMapRegion* r = region_at(MetaspaceShared::hp); + size_t size = r->used(); + + if (size > 0) { + HeapWord* start = (HeapWord*)heap_region_mapped_address(); + _mapped_heap_memregion = MemRegion(start, size / HeapWordSize); + log_info(cds)("Trying to map heap data at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes", + p2i(start), size); + } else { return false; // no archived java heap data } - // Check that regions are within the java heap - if (!G1CollectedHeap::heap()->check_archive_addresses(regions, num_regions)) { + // Check that the region is within the java heap + if (!G1CollectedHeap::heap()->check_archive_addresses(_mapped_heap_memregion)) { log_info(cds)("Unable to allocate region, range is not within java heap."); return false; } // allocate from java heap - if (!G1CollectedHeap::heap()->alloc_archive_regions( - regions, num_regions, is_open_archive)) { + if (!G1CollectedHeap::heap()->alloc_archive_regions(_mapped_heap_memregion)) { log_info(cds)("Unable to allocate region, java heap range is already in use."); return false; } // Map the archived heap data. No need to call MemTracker::record_virtual_memory_type() - // for mapped regions as they are part of the reserved java heap, which is - // already recorded. - for (int i = 0; i < num_regions; i++) { - r = region_at(first + i); - char* addr = (char*)regions[i].start(); - char* base = os::map_memory(_fd, _full_path, r->file_offset(), - addr, regions[i].byte_size(), r->read_only(), - r->allow_exec()); - if (base == nullptr || base != addr) { - // dealloc the regions from java heap - dealloc_heap_regions(regions, num_regions); - log_info(cds)("Unable to map at required address in java heap. " - INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes", - p2i(addr), regions[i].byte_size()); - return false; - } - - r->set_mapped_base(base); - if (VerifySharedSpaces && !r->check_region_crc()) { - // dealloc the regions from java heap - dealloc_heap_regions(regions, num_regions); - log_info(cds)("mapped heap regions are corrupt"); - return false; - } + // for mapped region as it is part of the reserved java heap, which is already recorded. + char* addr = (char*)_mapped_heap_memregion.start(); + char* base = os::map_memory(_fd, _full_path, r->file_offset(), + addr, _mapped_heap_memregion.byte_size(), r->read_only(), + r->allow_exec()); + if (base == nullptr || base != addr) { + dealloc_heap_region(); + log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. " + INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes", + p2i(addr), _mapped_heap_memregion.byte_size()); + return false; + } + + r->set_mapped_base(base); + if (VerifySharedSpaces && !r->check_region_crc()) { + dealloc_heap_region(); + log_info(cds)("mapped heap region is corrupt"); + return false; } - cleanup._aborted = false; - // the shared heap data is mapped successfully - *regions_ret = regions; - *num_regions_ret = num_regions; return true; } -void FileMapInfo::patch_heap_embedded_pointers() { - if (!_heap_pointers_need_patching) { - return; - } - - patch_heap_embedded_pointers(closed_heap_regions, - num_closed_heap_regions, - MetaspaceShared::first_closed_heap_region); - - patch_heap_embedded_pointers(open_heap_regions, - num_open_heap_regions, - MetaspaceShared::first_open_heap_region); -} - -narrowOop FileMapInfo::encoded_heap_region_dumptime_address(FileMapRegion* r) { +narrowOop FileMapInfo::encoded_heap_region_dumptime_address() { assert(UseSharedSpaces, "runtime only"); assert(UseCompressedOops, "sanity"); - r->assert_is_heap_region(); + FileMapRegion* r = region_at(MetaspaceShared::hp); return CompressedOops::narrow_oop_cast(r->mapping_offset() >> narrow_oop_shift()); } -void FileMapInfo::patch_heap_embedded_pointers(MemRegion* regions, int num_regions, - int first_region_idx) { +void FileMapInfo::patch_heap_embedded_pointers() { + if (!ArchiveHeapLoader::is_mapped() || !_heap_pointers_need_patching) { + return; + } + char* bitmap_base = map_bitmap_region(); assert(bitmap_base != nullptr, "must have already been mapped"); - for (int i=0; imapped_base()) + r->oopmap_offset(), r->oopmap_size_in_bits()); - } } -// This internally allocates objects using vmClasses::Object_klass(), so it -// must be called after the Object_klass is loaded -void FileMapInfo::fixup_mapped_heap_regions() { - assert(vmClasses::Object_klass_loaded(), "must be"); - // If any closed regions were found, call the fill routine to make them parseable. - // Note that closed_heap_regions may be non-null even if no regions were found. - if (num_closed_heap_regions != 0) { - assert(closed_heap_regions != nullptr, - "Null closed_heap_regions array with non-zero count"); - G1CollectedHeap::heap()->fill_archive_regions(closed_heap_regions, - num_closed_heap_regions); - // G1 marking uses the BOT for object chunking during marking in - // G1CMObjArrayProcessor::process_slice(); for this reason we need to - // initialize the BOT for closed archive regions too. - G1CollectedHeap::heap()->populate_archive_regions_bot_part(closed_heap_regions, - num_closed_heap_regions); - } +void FileMapInfo::fixup_mapped_heap_region() { + if (ArchiveHeapLoader::is_mapped()) { + assert(!_mapped_heap_memregion.is_empty(), "sanity"); - // do the same for mapped open archive heap regions - if (num_open_heap_regions != 0) { - assert(open_heap_regions != nullptr, "Null open_heap_regions array with non-zero count"); - G1CollectedHeap::heap()->fill_archive_regions(open_heap_regions, - num_open_heap_regions); - - // Populate the open archive regions' G1BlockOffsetTableParts. That ensures + // Populate the archive regions' G1BlockOffsetTableParts. That ensures // fast G1BlockOffsetTablePart::block_start operations for any given address - // within the open archive regions when trying to find start of an object + // within the archive regions when trying to find start of an object // (e.g. during card table scanning). - G1CollectedHeap::heap()->populate_archive_regions_bot_part(open_heap_regions, - num_open_heap_regions); + G1CollectedHeap::heap()->populate_archive_regions_bot_part(_mapped_heap_memregion); } } // dealloc the archive regions from java heap -void FileMapInfo::dealloc_heap_regions(MemRegion* regions, int num) { - if (num > 0) { - assert(regions != nullptr, "Null archive regions array with non-zero count"); - G1CollectedHeap::heap()->dealloc_archive_regions(regions, num); - } +void FileMapInfo::dealloc_heap_region() { + G1CollectedHeap::heap()->dealloc_archive_regions(_mapped_heap_memregion); } #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index b415ec6c0d3..dce1ad94b62 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -40,6 +40,7 @@ static const int JVM_IDENT_MAX = 256; +class ArchiveHeapInfo; class BitMapView; class CHeapBitMap; class ClassFileStream; @@ -104,13 +105,6 @@ public: } }; -struct ArchiveHeapBitmapInfo { - address _map; // bitmap for relocating embedded oops - size_t _bm_region_offset; // this bitmap is stored at this offset from the bottom of the BM region - size_t _size_in_bits; - size_t _size_in_bytes; -}; - class SharedPathTable { Array* _table; int _size; @@ -173,7 +167,8 @@ public: void set_mapped_from_file(bool v) { _mapped_from_file = v; } void init(int region_index, size_t mapping_offset, size_t size, bool read_only, bool allow_exec, int crc); - void init_bitmaps(ArchiveHeapBitmapInfo oopmap, ArchiveHeapBitmapInfo ptrmap); + void init_oopmap(size_t offset, size_t size_in_bits); + void init_ptrmap(size_t offset, size_t size_in_bits); BitMapView oopmap_view(); BitMapView ptrmap_view(); bool has_ptrmap() { return _ptrmap_size_in_bits != 0; } @@ -451,26 +446,20 @@ public: void write_header(); void write_region(int region, char* base, size_t size, bool read_only, bool allow_exec); - char* write_bitmap_region(const CHeapBitMap* ptrmap, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps, + char* write_bitmap_region(const CHeapBitMap* ptrmap, ArchiveHeapInfo* heap_info, size_t &size_in_bytes); - size_t write_heap_regions(GrowableArray* regions, - GrowableArray* bitmaps, - int first_region_id, int max_num_regions); + size_t write_heap_region(ArchiveHeapInfo* heap_info); void write_bytes(const void* buffer, size_t count); void write_bytes_aligned(const void* buffer, size_t count); size_t read_bytes(void* buffer, size_t count); static size_t readonly_total(); MapArchiveResult map_regions(int regions[], int num_regions, char* mapped_base_address, ReservedSpace rs); void unmap_regions(int regions[], int num_regions); - void map_or_load_heap_regions() NOT_CDS_JAVA_HEAP_RETURN; - void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN; + void map_or_load_heap_region() NOT_CDS_JAVA_HEAP_RETURN; + void fixup_mapped_heap_region() NOT_CDS_JAVA_HEAP_RETURN; void patch_heap_embedded_pointers() NOT_CDS_JAVA_HEAP_RETURN; - void patch_heap_embedded_pointers(MemRegion* regions, int num_regions, - int first_region_idx) NOT_CDS_JAVA_HEAP_RETURN; - bool has_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); - MemRegion get_heap_regions_requested_range() NOT_CDS_JAVA_HEAP_RETURN_(MemRegion()); + bool has_heap_region() NOT_CDS_JAVA_HEAP_RETURN_(false); + MemRegion get_heap_region_requested_range() NOT_CDS_JAVA_HEAP_RETURN_(MemRegion()); bool read_region(int i, char* base, size_t size, bool do_commit); char* map_bitmap_region(); void unmap_region(int i); @@ -566,23 +555,22 @@ public: unsigned int runtime_prefix_len) NOT_CDS_RETURN_(false); bool validate_boot_class_paths() NOT_CDS_RETURN_(false); bool validate_app_class_paths(int shared_app_paths_len) NOT_CDS_RETURN_(false); - bool map_heap_regions(int first, int max, bool is_open_archive, - MemRegion** regions_ret, int* num_regions_ret) NOT_CDS_JAVA_HEAP_RETURN_(false); - void dealloc_heap_regions(MemRegion* regions, int num) NOT_CDS_JAVA_HEAP_RETURN; - bool can_use_heap_regions(); - bool load_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); - bool map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); - void map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN; + bool map_heap_region_impl() NOT_CDS_JAVA_HEAP_RETURN_(false); + void dealloc_heap_region() NOT_CDS_JAVA_HEAP_RETURN; + bool can_use_heap_region(); + bool load_heap_region() NOT_CDS_JAVA_HEAP_RETURN_(false); + bool map_heap_region() NOT_CDS_JAVA_HEAP_RETURN_(false); + void init_heap_region_relocation(); MapArchiveResult map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs); bool relocate_pointers_in_core_regions(intx addr_delta); - static size_t set_bitmaps_offset(GrowableArray *bitmaps, size_t curr_size); - static size_t write_bitmaps(GrowableArray *bitmaps, size_t curr_offset, char* buffer); + + static MemRegion _mapped_heap_memregion; public: - address heap_region_dumptime_address(FileMapRegion* r) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - address heap_region_requested_address(FileMapRegion* r) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - address heap_region_mapped_address(FileMapRegion* r) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - narrowOop encoded_heap_region_dumptime_address(FileMapRegion* r); + address heap_region_dumptime_address() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + address heap_region_requested_address() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + address heap_region_mapped_address() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + narrowOop encoded_heap_region_dumptime_address(); private: diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index cc04f61d0c2..1302d587747 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -82,7 +82,6 @@ struct ArchivableStaticFieldInfo { }; bool HeapShared::_disable_writing = false; -bool HeapShared::_copying_open_region_objects = false; DumpedInternedStrings *HeapShared::_dumped_interned_strings = nullptr; size_t HeapShared::_alloc_count[HeapShared::ALLOC_STAT_SLOTS]; @@ -103,10 +102,7 @@ static const ArchivedKlassSubGraphInfoRecord* _test_class_record = nullptr; // If you add new entries to the following tables, you should know what you're doing! // -// Entry fields for shareable subgraphs archived in the closed archive heap -// region. Warning: Objects in the subgraphs should not have reference fields -// assigned at runtime. -static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = { +static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = { {"java/lang/Integer$IntegerCache", "archivedCache"}, {"java/lang/Long$LongCache", "archivedCache"}, {"java/lang/Byte$ByteCache", "archivedCache"}, @@ -114,10 +110,6 @@ static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = { {"java/lang/Character$CharacterCache", "archivedCache"}, {"java/util/jar/Attributes$Name", "KNOWN_NAMES"}, {"sun/util/locale/BaseLocale", "constantBaseLocales"}, - {nullptr, nullptr}, -}; -// Entry fields for subgraphs archived in the open archive heap region. -static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = { {"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"}, {"java/util/ImmutableCollections", "archivedObjects"}, {"java/lang/ModuleLayer", "EMPTY_LAYER"}, @@ -129,8 +121,8 @@ static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = { {nullptr, nullptr}, }; -// Entry fields for subgraphs archived in the open archive heap region (full module graph). -static ArchivableStaticFieldInfo fmg_open_archive_subgraph_entry_fields[] = { +// full module graph +static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = { {"jdk/internal/loader/ArchivedClassLoaders", "archivedClassLoaders"}, {"jdk/internal/module/ArchivedBootLayer", "archivedBootLayer"}, {"java/lang/Module$ArchivedData", "archivedData"}, @@ -153,9 +145,8 @@ static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], Instan } bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) { - return is_subgraph_root_class_of(closed_archive_subgraph_entry_fields, ik) || - is_subgraph_root_class_of(open_archive_subgraph_entry_fields, ik) || - is_subgraph_root_class_of(fmg_open_archive_subgraph_entry_fields, ik); + return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik) || + is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik); } unsigned HeapShared::oop_hash(oop const& p) { @@ -383,7 +374,7 @@ void HeapShared::archive_java_mirrors() { if (!is_reference_type(bt)) { oop m = _scratch_basic_type_mirrors[i].resolve(); assert(m != nullptr, "sanity"); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, m, /*is_closed_archive=*/ false); + bool success = archive_reachable_objects_from(1, _default_subgraph_info, m); assert(success, "sanity"); log_trace(cds, heap, mirror)( @@ -401,7 +392,7 @@ void HeapShared::archive_java_mirrors() { oop m = scratch_java_mirror(orig_k); if (m != nullptr) { Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, m, /*is_closed_archive=*/ false); + bool success = archive_reachable_objects_from(1, _default_subgraph_info, m); guarantee(success, "scratch mirrors must point to only archivable objects"); buffered_k->set_archived_java_mirror(append_root(m)); ResourceMark rm; @@ -414,8 +405,7 @@ void HeapShared::archive_java_mirrors() { InstanceKlass* ik = InstanceKlass::cast(buffered_k); oop rr = ik->constants()->prepare_resolved_references_for_archiving(); if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) { - bool success = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr, - /*is_closed_archive=*/false); + bool success = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr); assert(success, "must be"); int root_index = append_root(rr); ik->constants()->cache()->set_archived_references(root_index); @@ -427,7 +417,7 @@ void HeapShared::archive_java_mirrors() { void HeapShared::archive_strings() { oop shared_strings_array = StringTable::init_shared_table(_dumped_interned_strings); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, shared_strings_array, /*is_closed_archive=*/ false); + bool success = archive_reachable_objects_from(1, _default_subgraph_info, shared_strings_array); // We must succeed because: // - _dumped_interned_strings do not contain any large strings. // - StringTable::init_shared_table() doesn't create any large arrays. @@ -463,8 +453,7 @@ void HeapShared::mark_native_pointers(oop orig_obj) { // the static fields out of the archived heap. void HeapShared::check_enum_obj(int level, KlassSubGraphInfo* subgraph_info, - oop orig_obj, - bool is_closed_archive) { + oop orig_obj) { assert(level > 1, "must never be called at the first (outermost) level"); Klass* k = orig_obj->klass(); Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); @@ -493,7 +482,7 @@ void HeapShared::check_enum_obj(int level, guarantee(false, "static field %s::%s is of the wrong type", ik->external_name(), fd.name()->as_C_string()); } - bool success = archive_reachable_objects_from(level, subgraph_info, oop_field, is_closed_archive); + bool success = archive_reachable_objects_from(level, subgraph_info, oop_field); assert(success, "VM should have exited with unarchivable objects for _level > 1"); int root_index = append_root(oop_field); log_info(cds, heap)("Archived enum obj @%d %s::%s (" INTPTR_FORMAT ")", @@ -532,10 +521,7 @@ bool HeapShared::initialize_enum_klass(InstanceKlass* k, TRAPS) { return true; } -void HeapShared::archive_objects(GrowableArray* closed_regions, - GrowableArray* open_regions, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps) { +void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { { NoSafepointVerifier nsv; @@ -549,19 +535,13 @@ void HeapShared::archive_objects(GrowableArray* closed_regions, p2i((address)G1CollectedHeap::heap()->reserved().start()), UseCompressedOops ? p2i(CompressedOops::end()) : p2i((address)G1CollectedHeap::heap()->reserved().end())); - log_info(cds)("Dumping objects to closed archive heap region ..."); - copy_closed_objects(); - - _copying_open_region_objects = true; - - log_info(cds)("Dumping objects to open archive heap region ..."); - copy_open_objects(); + copy_objects(); CDSHeapVerifier::verify(); check_default_subgraph_classes(); } - ArchiveHeapWriter::write(_pending_roots, closed_regions, open_regions, closed_bitmaps, open_bitmaps); + ArchiveHeapWriter::write(_pending_roots, heap_info); } void HeapShared::copy_interned_strings() { @@ -570,9 +550,8 @@ void HeapShared::copy_interned_strings() { auto copier = [&] (oop s, bool value_ignored) { assert(s != nullptr, "sanity"); assert(!ArchiveHeapWriter::is_string_too_large_to_archive(s), "large strings must have been filtered"); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, - s, /*is_closed_archive=*/true); - assert(success, "string must be short enough to be archived"); + bool success = archive_reachable_objects_from(1, _default_subgraph_info, s); + assert(success, "must be"); // Prevent string deduplication from changing the value field to // something not in the archive. java_lang_String::set_deduplication_forbidden(s); @@ -582,18 +561,7 @@ void HeapShared::copy_interned_strings() { delete_seen_objects_table(); } -void HeapShared::copy_closed_objects() { - assert(HeapShared::can_write(), "must be"); - - // Archive interned string objects - copy_interned_strings(); - - archive_object_subgraphs(closed_archive_subgraph_entry_fields, - true /* is_closed_archive */, - false /* is_full_module_graph */); -} - -void HeapShared::copy_special_open_objects() { +void HeapShared::copy_special_objects() { // Archive special objects that do not belong to any subgraphs init_seen_objects_table(); archive_java_mirrors(); @@ -601,17 +569,17 @@ void HeapShared::copy_special_open_objects() { delete_seen_objects_table(); } -void HeapShared::copy_open_objects() { +void HeapShared::copy_objects() { assert(HeapShared::can_write(), "must be"); - copy_special_open_objects(); + copy_interned_strings(); + copy_special_objects(); - archive_object_subgraphs(open_archive_subgraph_entry_fields, - false /* is_closed_archive */, + archive_object_subgraphs(archive_subgraph_entry_fields, false /* is_full_module_graph */); + if (MetaspaceShared::use_full_module_graph()) { - archive_object_subgraphs(fmg_open_archive_subgraph_entry_fields, - false /* is_closed_archive */, + archive_object_subgraphs(fmg_archive_subgraph_entry_fields, true /* is_full_module_graph */); Modules::verify_archived_modules(); } @@ -645,8 +613,7 @@ KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) { } // Add an entry field to the current KlassSubGraphInfo. -void KlassSubGraphInfo::add_subgraph_entry_field( - int static_field_offset, oop v, bool is_closed_archive) { +void KlassSubGraphInfo::add_subgraph_entry_field(int static_field_offset, oop v) { assert(DumpSharedSpaces, "dump time only"); if (_subgraph_entry_fields == nullptr) { _subgraph_entry_fields = @@ -836,7 +803,7 @@ struct CopyKlassSubGraphInfoToArchive : StackObj { // Build the records of archived subgraph infos, which include: // - Entry points to all subgraphs from the containing class mirror. The entry // points are static fields in the mirror. For each entry point, the field -// offset, value and is_closed_archive flag are recorded in the sub-graph +// offset, and value are recorded in the sub-graph // info. The value is stored back to the corresponding field at runtime. // - A list of klasses that need to be loaded/initialized before archived // java object sub-graph can be accessed at runtime. @@ -936,9 +903,8 @@ void HeapShared::resolve_classes(JavaThread* current) { if (!ArchiveHeapLoader::is_in_use()) { return; // nothing to do } - resolve_classes_for_subgraphs(current, closed_archive_subgraph_entry_fields); - resolve_classes_for_subgraphs(current, open_archive_subgraph_entry_fields); - resolve_classes_for_subgraphs(current, fmg_open_archive_subgraph_entry_fields); + resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields); + resolve_classes_for_subgraphs(current, fmg_archive_subgraph_entry_fields); } void HeapShared::resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]) { @@ -1115,7 +1081,6 @@ void HeapShared::clear_archived_roots_of(Klass* k) { class WalkOopAndArchiveClosure: public BasicOopIterateClosure { int _level; - bool _is_closed_archive; bool _record_klasses_only; KlassSubGraphInfo* _subgraph_info; oop _referencing_obj; @@ -1126,11 +1091,10 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure { WalkOopAndArchiveClosure* _last; public: WalkOopAndArchiveClosure(int level, - bool is_closed_archive, bool record_klasses_only, KlassSubGraphInfo* subgraph_info, oop orig) : - _level(level), _is_closed_archive(is_closed_archive), + _level(level), _record_klasses_only(record_klasses_only), _subgraph_info(subgraph_info), _referencing_obj(orig) { @@ -1162,7 +1126,7 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure { } bool success = HeapShared::archive_reachable_objects_from( - _level + 1, _subgraph_info, obj, _is_closed_archive); + _level + 1, _subgraph_info, obj); assert(success, "VM should have exited with unarchivable objects for _level > 1"); } } @@ -1178,23 +1142,7 @@ WalkOopAndArchiveClosure* WalkOopAndArchiveClosure::_current = nullptr; HeapShared::CachedOopInfo HeapShared::make_cached_oop_info() { WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current(); oop referrer = (walker == nullptr) ? nullptr : walker->referencing_obj(); - return CachedOopInfo(referrer, _copying_open_region_objects); -} - -void HeapShared::check_closed_region_object(InstanceKlass* k) { - // Check fields in the object - for (JavaFieldStream fs(k); !fs.done(); fs.next()) { - if (!fs.access_flags().is_static()) { - BasicType ft = fs.field_descriptor().field_type(); - if (!fs.access_flags().is_final() && is_reference_type(ft)) { - ResourceMark rm; - log_warning(cds, heap)( - "Please check reference field in %s instance in closed archive heap region: %s %s", - k->external_name(), (fs.name())->as_C_string(), - (fs.signature())->as_C_string()); - } - } - } + return CachedOopInfo(referrer); } // (1) If orig_obj has not been archived yet, archive it. @@ -1203,8 +1151,7 @@ void HeapShared::check_closed_region_object(InstanceKlass* k) { // (3) Record the klasses of all orig_obj and all reachable objects. bool HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, - oop orig_obj, - bool is_closed_archive) { + oop orig_obj) { assert(orig_obj != nullptr, "must be"); if (!JavaClasses::is_supported_for_archiving(orig_obj)) { @@ -1260,14 +1207,10 @@ bool HeapShared::archive_reachable_objects_from(int level, Klass *orig_k = orig_obj->klass(); subgraph_info->add_subgraph_object_klass(orig_k); - WalkOopAndArchiveClosure walker(level, is_closed_archive, record_klasses_only, - subgraph_info, orig_obj); + WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj); orig_obj->oop_iterate(&walker); - if (is_closed_archive && orig_k->is_instance_klass()) { - check_closed_region_object(InstanceKlass::cast(orig_k)); - } - check_enum_obj(level + 1, subgraph_info, orig_obj, is_closed_archive); + check_enum_obj(level + 1, subgraph_info, orig_obj); return true; } @@ -1308,8 +1251,7 @@ bool HeapShared::archive_reachable_objects_from(int level, void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k, const char* klass_name, int field_offset, - const char* field_name, - bool is_closed_archive) { + const char* field_name) { assert(DumpSharedSpaces, "dump time only"); assert(k->is_shared_boot_class(), "must be boot class"); @@ -1327,8 +1269,7 @@ void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k, f->print_on(&out); } - bool success = archive_reachable_objects_from(1, subgraph_info, f, is_closed_archive); - + bool success = archive_reachable_objects_from(1, subgraph_info, f); if (!success) { log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)", klass_name, field_name); @@ -1336,13 +1277,13 @@ void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k, // Note: the field value is not preserved in the archived mirror. // Record the field as a new subGraph entry point. The recorded // information is restored from the archive at runtime. - subgraph_info->add_subgraph_entry_field(field_offset, f, is_closed_archive); + subgraph_info->add_subgraph_entry_field(field_offset, f); log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(f)); } } else { // The field contains null, we still need to record the entry point, // so it can be restored at runtime. - subgraph_info->add_subgraph_entry_field(field_offset, nullptr, false); + subgraph_info->add_subgraph_entry_field(field_offset, nullptr); } } @@ -1572,17 +1513,16 @@ void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], void HeapShared::init_subgraph_entry_fields(TRAPS) { assert(HeapShared::can_write(), "must be"); _dump_time_subgraph_info_table = new (mtClass)DumpTimeKlassSubGraphInfoTable(); - init_subgraph_entry_fields(closed_archive_subgraph_entry_fields, CHECK); - init_subgraph_entry_fields(open_archive_subgraph_entry_fields, CHECK); + init_subgraph_entry_fields(archive_subgraph_entry_fields, CHECK); if (MetaspaceShared::use_full_module_graph()) { - init_subgraph_entry_fields(fmg_open_archive_subgraph_entry_fields, CHECK); + init_subgraph_entry_fields(fmg_archive_subgraph_entry_fields, CHECK); } } #ifndef PRODUCT void HeapShared::setup_test_class(const char* test_class_name) { - ArchivableStaticFieldInfo* p = open_archive_subgraph_entry_fields; - int num_slots = sizeof(open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo); + ArchivableStaticFieldInfo* p = archive_subgraph_entry_fields; + int num_slots = sizeof(archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo); assert(p[num_slots - 2].klass_name == nullptr, "must have empty slot that's patched below"); assert(p[num_slots - 1].klass_name == nullptr, "must have empty slot that marks the end of the list"); @@ -1649,7 +1589,6 @@ void HeapShared::init_for_dumping(TRAPS) { } void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[], - bool is_closed_archive, bool is_full_module_graph) { _num_total_subgraph_recordings = 0; _num_total_walked_objs = 0; @@ -1680,14 +1619,12 @@ void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[], } archive_reachable_objects_from_static_field(f->klass, f->klass_name, - f->offset, f->field_name, - is_closed_archive); + f->offset, f->field_name); } done_recording_subgraph(info->klass, klass_name); } - log_info(cds, heap)("Archived subgraph records in %s archive heap region = %d", - is_closed_archive ? "closed" : "open", + log_info(cds, heap)("Archived subgraph records = %d", _num_total_subgraph_recordings); log_info(cds, heap)(" Walked %d objects", _num_total_walked_objs); log_info(cds, heap)(" Archived %d objects", _num_total_archived_objs); diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 3e60ac9663b..35c90b237a6 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -47,6 +47,7 @@ class KlassToOopHandleTable; class ResourceBitMap; struct ArchivableStaticFieldInfo; +class ArchiveHeapInfo; // A dump time sub-graph info for Klass _k. It includes the entry points // (static fields in _k's mirror) of the archived sub-graphs reachable @@ -61,8 +62,7 @@ class KlassSubGraphInfo: public CHeapObj { // object sub-graphs can be accessed at runtime. GrowableArray* _subgraph_object_klasses; // A list of _k's static fields as the entry points of archived sub-graphs. - // For each entry field, it is a tuple of field_offset, field_value and - // is_closed_archive flag. + // For each entry field, it is a tuple of field_offset, field_value GrowableArray* _subgraph_entry_fields; // Does this KlassSubGraphInfo belong to the archived full module graph @@ -97,8 +97,7 @@ class KlassSubGraphInfo: public CHeapObj { GrowableArray* subgraph_entry_fields() { return _subgraph_entry_fields; } - void add_subgraph_entry_field(int static_field_offset, oop v, - bool is_closed_archive); + void add_subgraph_entry_field(int static_field_offset, oop v); void add_subgraph_object_klass(Klass *orig_k); int num_subgraph_object_klasses() { return _subgraph_object_klasses == nullptr ? 0 : @@ -141,7 +140,7 @@ class HeapShared: AllStatic { friend class VerifySharedOopClosure; public: - // Can this VM write heap regions into the CDS archive? Currently only G1+compressed{oops,cp} + // Can this VM write a heap region into the CDS archive? Currently only G1+compressed{oops,cp} static bool can_write() { CDS_JAVA_HEAP_ONLY( if (_disable_writing) { @@ -165,7 +164,6 @@ public: private: #if INCLUDE_CDS_JAVA_HEAP static bool _disable_writing; - static bool _copying_open_region_objects; static DumpedInternedStrings *_dumped_interned_strings; // statistics @@ -189,22 +187,18 @@ public: // The location of this object inside ArchiveHeapWriter::_buffer size_t _buffer_offset; - bool _in_open_region; public: - CachedOopInfo(oop orig_referrer, bool in_open_region) + CachedOopInfo(oop orig_referrer) : _orig_referrer(orig_referrer), - _buffer_offset(0), _in_open_region(in_open_region) {} + _buffer_offset(0) {} oop orig_referrer() const { return _orig_referrer; } - bool in_open_region() const { return _in_open_region; } void set_buffer_offset(size_t offset) { _buffer_offset = offset; } size_t buffer_offset() const { return _buffer_offset; } }; private: - static void check_enum_obj(int level, - KlassSubGraphInfo* subgraph_info, - oop orig_obj, - bool is_closed_archive); + static void check_enum_obj(int level, KlassSubGraphInfo* subgraph_info, + oop orig_obj); typedef ResourceHashtable* closed_regions, - GrowableArray* open_regions, - GrowableArray* closed_bitmaps, - GrowableArray* open_bitmaps); - static void copy_closed_objects(); - static void copy_open_objects(); - static void copy_special_open_objects(); + static void archive_objects(ArchiveHeapInfo* heap_info); + static void copy_objects(); + static void copy_special_objects(); static bool archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, - oop orig_obj, - bool is_closed_archive); + oop orig_obj); static ResourceBitMap calculate_oopmap(MemRegion region); // marks all the oop pointers static void add_to_dumped_interned_strings(oop string); @@ -380,7 +366,7 @@ private: static void remove_scratch_objects(Klass* k); // We use the HeapShared::roots() array to make sure that objects stored in the - // archived heap regions are not prematurely collected. These roots include: + // archived heap region are not prematurely collected. These roots include: // // - mirrors of classes that have not yet been loaded. // - ConstantPool::resolved_references() of classes that have not yet been loaded. @@ -410,8 +396,7 @@ private: public: static void init_scratch_objects(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; static bool is_heap_region(int idx) { - CDS_JAVA_HEAP_ONLY(return (idx >= MetaspaceShared::first_closed_heap_region && - idx <= MetaspaceShared::last_open_heap_region);) + CDS_JAVA_HEAP_ONLY(return (idx == MetaspaceShared::hp);) NOT_CDS_JAVA_HEAP_RETURN_(false); } diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index b62666a09f0..fe0e022136e 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -98,12 +98,7 @@ bool MetaspaceShared::_use_full_module_graph = true; // The CDS archive is divided into the following regions: // rw - read-write metadata // ro - read-only metadata and read-only tables -// -// ca0 - closed archive heap space #0 -// ca1 - closed archive heap space #1 (may be empty) -// oa0 - open archive heap space #0 -// oa1 - open archive heap space #1 (may be empty) -// +// hp - heap region // bm - bitmap for relocating the above 7 regions. // // The rw and ro regions are linearly allocated, in the order of rw->ro. @@ -119,8 +114,9 @@ bool MetaspaceShared::_use_full_module_graph = true; // [5] SymbolTable, StringTable, SystemDictionary, and a few other read-only data // are copied into the ro region as read-only tables. // -// The ca0/ca1 and oa0/oa1 regions are populated inside HeapShared::archive_objects. -// Their layout is independent of the rw/ro regions. +// The heap region is populated by HeapShared::archive_objects. +// +// The bitmap region is used to relocate the ro/rw/hp regions. static DumpRegion _symbol_region("symbols"); @@ -431,11 +427,7 @@ void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread class VM_PopulateDumpSharedSpace : public VM_Operation { private: - GrowableArray *_closed_heap_regions; - GrowableArray *_open_heap_regions; - - GrowableArray *_closed_heap_bitmaps; - GrowableArray *_open_heap_bitmaps; + ArchiveHeapInfo _heap_info; void dump_java_heap_objects(GrowableArray* klasses) NOT_CDS_JAVA_HEAP_RETURN; void dump_shared_symbol_table(GrowableArray* symbols) { @@ -446,11 +438,7 @@ private: public: - VM_PopulateDumpSharedSpace() : VM_Operation(), - _closed_heap_regions(nullptr), - _open_heap_regions(nullptr), - _closed_heap_bitmaps(nullptr), - _open_heap_bitmaps(nullptr) {} + VM_PopulateDumpSharedSpace() : VM_Operation(), _heap_info() {} bool skip_operation() const { return false; } @@ -550,11 +538,7 @@ void VM_PopulateDumpSharedSpace::doit() { mapinfo->set_serialized_data(serialized_data); mapinfo->set_cloned_vtables(cloned_vtables); mapinfo->open_for_write(); - builder.write_archive(mapinfo, - _closed_heap_regions, - _open_heap_regions, - _closed_heap_bitmaps, - _open_heap_bitmaps); + builder.write_archive(mapinfo, &_heap_info); if (PrintSystemDictionaryAtExit) { SystemDictionary::print(); @@ -874,14 +858,7 @@ void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray* k } } - // The closed and open archive heap space has maximum two regions. - // See FileMapInfo::write_heap_regions() for details. - _closed_heap_regions = new GrowableArray(2); - _open_heap_regions = new GrowableArray(2); - _closed_heap_bitmaps = new GrowableArray(2); - _open_heap_bitmaps = new GrowableArray(2); - HeapShared::archive_objects(_closed_heap_regions, _open_heap_regions, - _closed_heap_bitmaps, _open_heap_bitmaps); + HeapShared::archive_objects(&_heap_info); ArchiveBuilder::OtherROAllocMark mark; HeapShared::write_subgraph_info_table(); } @@ -1177,9 +1154,9 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File assert(ccs_end > cds_base, "Sanity check"); CompressedKlassPointers::initialize(cds_base, ccs_end - cds_base); - // map_heap_regions() compares the current narrow oop and klass encodings + // map_or_load_heap_region() compares the current narrow oop and klass encodings // with the archived ones, so it must be done after all encodings are determined. - static_mapinfo->map_or_load_heap_regions(); + static_mapinfo->map_or_load_heap_region(); } }); log_info(cds)("optimized module handling: %s", MetaspaceShared::use_optimized_module_handling() ? "enabled" : "disabled"); diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index 9e410b257c4..38fa2dbbc5e 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -60,23 +60,9 @@ class MetaspaceShared : AllStatic { rw = 0, // read-write shared space ro = 1, // read-only shared space bm = 2, // relocation bitmaps (freed after file mapping is finished) + hp = 3, // heap region num_core_region = 2, // rw and ro - num_non_heap_regions = 3, // rw and ro and bm - - // java heap regions - first_closed_heap_region = bm + 1, - max_num_closed_heap_regions = 2, - last_closed_heap_region = first_closed_heap_region + max_num_closed_heap_regions - 1, - first_open_heap_region = last_closed_heap_region + 1, - max_num_open_heap_regions = 2, - last_open_heap_region = first_open_heap_region + max_num_open_heap_regions - 1, - max_num_heap_regions = max_num_closed_heap_regions + max_num_open_heap_regions, - - first_archive_heap_region = first_closed_heap_region, - last_archive_heap_region = last_open_heap_region, - - last_valid_region = last_open_heap_region, - n_regions = last_valid_region + 1 // total number of regions + n_regions = 4 // total number of regions }; static void prepare_for_dumping() NOT_CDS_RETURN; @@ -106,8 +92,8 @@ public: static void initialize_shared_spaces() NOT_CDS_RETURN; - // Return true if given address is in the shared metaspace regions (i.e., excluding any - // mapped heap regions.) + // Return true if given address is in the shared metaspace regions (i.e., excluding the + // mapped heap region.) static bool is_in_shared_metaspace(const void* p) { return MetaspaceObj::is_shared((const MetaspaceObj*)p); } diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index dddfa3435ec..c1cece08069 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1121,9 +1121,6 @@ bool java_lang_Class::restore_archived_mirror(Klass *k, // mirror is archived, restore log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); - if (ArchiveHeapLoader::is_mapped()) { - assert(Universe::heap()->is_archived_object(m), "must be archived mirror object"); - } assert(as_Klass(m) == k, "must be"); Handle mirror(THREAD, m); diff --git a/src/hotspot/share/classfile/vmClasses.cpp b/src/hotspot/share/classfile/vmClasses.cpp index 2f004f02f90..82c2ff8fa7b 100644 --- a/src/hotspot/share/classfile/vmClasses.cpp +++ b/src/hotspot/share/classfile/vmClasses.cpp @@ -142,7 +142,7 @@ void vmClasses::resolve_all(TRAPS) { // Object_klass is resolved. See the above resolve_through() // call. No mirror objects are accessed/restored in the above call. // Mirrors are restored after java.lang.Class is loaded. - ArchiveHeapLoader::fixup_regions(); + ArchiveHeapLoader::fixup_region(); // Initialize the constant pool for the Object_class assert(Object_klass()->is_shared(), "must be"); diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index 41859e910e7..3de3617930c 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -97,8 +97,6 @@ void G1Allocator::reuse_retained_old_region(G1EvacInfo* evacuation_info, HeapRegion** retained_old) { HeapRegion* retained_region = *retained_old; *retained_old = NULL; - assert(retained_region == NULL || !retained_region->is_archive(), - "Archive region should not be alloc region (index %u)", retained_region->hrm_index()); // We will discard the current GC alloc region if: // a) it's in the collection set (it can happen!), diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 4e249e3e2de..f3c811a124e 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -511,173 +511,121 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size) { return NULL; } -bool G1CollectedHeap::check_archive_addresses(MemRegion* ranges, size_t count) { - assert(ranges != NULL, "MemRegion array NULL"); - assert(count != 0, "No MemRegions provided"); - MemRegion reserved = _hrm.reserved(); - for (size_t i = 0; i < count; i++) { - if (!reserved.contains(ranges[i].start()) || !reserved.contains(ranges[i].last())) { - return false; - } - } - return true; +bool G1CollectedHeap::check_archive_addresses(MemRegion range) { + return _hrm.reserved().contains(range); } -bool G1CollectedHeap::alloc_archive_regions(MemRegion* ranges, - size_t count, - bool open) { +template +void G1CollectedHeap::iterate_regions_in_range(MemRegion range, const Func& func) { + // Mark each G1 region touched by the range as old, add it to + // the old set, and set top. + HeapRegion* curr_region = _hrm.addr_to_region(range.start()); + HeapRegion* end_region = _hrm.addr_to_region(range.last()); + + while (curr_region != nullptr) { + bool is_last = curr_region == end_region; + HeapRegion* next_region = is_last ? nullptr : _hrm.next_region_in_heap(curr_region); + + func(curr_region, is_last); + + curr_region = next_region; + } +} + +bool G1CollectedHeap::alloc_archive_regions(MemRegion range) { assert(!is_init_completed(), "Expect to be called at JVM init time"); - assert(ranges != NULL, "MemRegion array NULL"); - assert(count != 0, "No MemRegions provided"); MutexLocker x(Heap_lock); MemRegion reserved = _hrm.reserved(); - HeapWord* prev_last_addr = NULL; - HeapRegion* prev_last_region = NULL; // Temporarily disable pretouching of heap pages. This interface is used // when mmap'ing archived heap data in, so pre-touching is wasted. FlagSetting fs(AlwaysPreTouch, false); - // For each specified MemRegion range, allocate the corresponding G1 - // regions and mark them as archive regions. We expect the ranges - // in ascending starting address order, without overlap. - for (size_t i = 0; i < count; i++) { - MemRegion curr_range = ranges[i]; - HeapWord* start_address = curr_range.start(); - size_t word_size = curr_range.word_size(); - HeapWord* last_address = curr_range.last(); - size_t commits = 0; + // For the specified MemRegion range, allocate the corresponding G1 + // region(s) and mark them as old region(s). + HeapWord* start_address = range.start(); + size_t word_size = range.word_size(); + HeapWord* last_address = range.last(); + size_t commits = 0; - guarantee(reserved.contains(start_address) && reserved.contains(last_address), - "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", - p2i(start_address), p2i(last_address)); - guarantee(start_address > prev_last_addr, - "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT , - p2i(start_address), p2i(prev_last_addr)); - prev_last_addr = last_address; + guarantee(reserved.contains(start_address) && reserved.contains(last_address), + "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", + p2i(start_address), p2i(last_address)); - // Check for ranges that start in the same G1 region in which the previous - // range ended, and adjust the start address so we don't try to allocate - // the same region again. If the current range is entirely within that - // region, skip it, just adjusting the recorded top. - HeapRegion* start_region = _hrm.addr_to_region(start_address); - if ((prev_last_region != NULL) && (start_region == prev_last_region)) { - start_address = start_region->end(); - if (start_address > last_address) { - increase_used(word_size * HeapWordSize); - start_region->set_top(last_address + 1); - continue; - } - start_region->set_top(start_address); - curr_range = MemRegion(start_address, last_address + 1); - start_region = _hrm.addr_to_region(start_address); - } - - // Perform the actual region allocation, exiting if it fails. - // Then note how much new space we have allocated. - if (!_hrm.allocate_containing_regions(curr_range, &commits, workers())) { - return false; - } - increase_used(word_size * HeapWordSize); - if (commits != 0) { - log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: " SIZE_FORMAT "B", - HeapRegion::GrainWords * HeapWordSize * commits); - - } - - // Mark each G1 region touched by the range as archive, add it to - // the old set, and set top. - HeapRegion* curr_region = _hrm.addr_to_region(start_address); - HeapRegion* last_region = _hrm.addr_to_region(last_address); - prev_last_region = last_region; - - while (curr_region != NULL) { - assert(curr_region->is_empty() && !curr_region->is_pinned(), - "Region already in use (index %u)", curr_region->hrm_index()); - if (open) { - curr_region->set_open_archive(); - } else { - curr_region->set_closed_archive(); - } - _hr_printer.alloc(curr_region); - _archive_set.add(curr_region); - HeapWord* top; - HeapRegion* next_region; - if (curr_region != last_region) { - top = curr_region->end(); - next_region = _hrm.next_region_in_heap(curr_region); - } else { - top = last_address + 1; - next_region = NULL; - } - curr_region->set_top(top); - curr_region = next_region; - } + // Perform the actual region allocation, exiting if it fails. + // Then note how much new space we have allocated. + if (!_hrm.allocate_containing_regions(range, &commits, workers())) { + return false; } + increase_used(word_size * HeapWordSize); + if (commits != 0) { + log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: " SIZE_FORMAT "B", + HeapRegion::GrainWords * HeapWordSize * commits); + + } + + // Mark each G1 region touched by the range as old, add it to + // the old set, and set top. + auto set_region_to_old = [&] (HeapRegion* r, bool is_last) { + assert(r->is_empty() && !r->is_pinned(), "Region already in use (%u)", r->hrm_index()); + + HeapWord* top = is_last ? last_address + 1 : r->end(); + r->set_top(top); + + r->set_old(); + _hr_printer.alloc(r); + _old_set.add(r); + }; + + iterate_regions_in_range(range, set_region_to_old); return true; } -void G1CollectedHeap::fill_archive_regions(MemRegion* ranges, size_t count) { +void G1CollectedHeap::populate_archive_regions_bot_part(MemRegion range) { + assert(!is_init_completed(), "Expect to be called at JVM init time"); + + iterate_regions_in_range(range, + [&] (HeapRegion* r, bool is_last) { + r->update_bot(); + }); +} + +void G1CollectedHeap::dealloc_archive_regions(MemRegion range) { assert(!is_init_completed(), "Expect to be called at JVM init time"); - assert(ranges != NULL, "MemRegion array NULL"); - assert(count != 0, "No MemRegions provided"); MemRegion reserved = _hrm.reserved(); - HeapWord *prev_last_addr = NULL; - HeapRegion* prev_last_region = NULL; + size_t size_used = 0; + uint shrink_count = 0; - // For each MemRegion, create filler objects, if needed, in the G1 regions - // that contain the address range. The address range actually within the - // MemRegion will not be modified. That is assumed to have been initialized - // elsewhere, probably via an mmap of archived heap data. + // Free the G1 regions that are within the specified range. MutexLocker x(Heap_lock); - for (size_t i = 0; i < count; i++) { - HeapWord* start_address = ranges[i].start(); - HeapWord* last_address = ranges[i].last(); + HeapWord* start_address = range.start(); + HeapWord* last_address = range.last(); - assert(reserved.contains(start_address) && reserved.contains(last_address), - "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", - p2i(start_address), p2i(last_address)); - assert(start_address > prev_last_addr, - "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT , - p2i(start_address), p2i(prev_last_addr)); + assert(reserved.contains(start_address) && reserved.contains(last_address), + "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", + p2i(start_address), p2i(last_address)); + size_used += range.byte_size(); - HeapRegion* start_region = _hrm.addr_to_region(start_address); - HeapRegion* last_region = _hrm.addr_to_region(last_address); - HeapWord* bottom_address = start_region->bottom(); + // Free, empty and uncommit regions with CDS archive content. + auto dealloc_archive_region = [&] (HeapRegion* r, bool is_last) { + guarantee(r->is_old(), "Expected old region at index %u", r->hrm_index()); + _old_set.remove(r); + r->set_free(); + r->set_top(r->bottom()); + _hrm.shrink_at(r->hrm_index(), 1); + shrink_count++; + }; - // Check for a range beginning in the same region in which the - // previous one ended. - if (start_region == prev_last_region) { - bottom_address = prev_last_addr + 1; - } + iterate_regions_in_range(range, dealloc_archive_region); - // Verify that the regions were all marked as archive regions by - // alloc_archive_regions. - HeapRegion* curr_region = start_region; - while (curr_region != NULL) { - guarantee(curr_region->is_archive(), - "Expected archive region at index %u", curr_region->hrm_index()); - if (curr_region != last_region) { - curr_region = _hrm.next_region_in_heap(curr_region); - } else { - curr_region = NULL; - } - } - - prev_last_addr = last_address; - prev_last_region = last_region; - - // Fill the memory below the allocated range with dummy object(s), - // if the region bottom does not match the range start, or if the previous - // range ended within the same G1 region, and there is a gap. - assert(start_address >= bottom_address, "bottom address should not be greater than start address"); - if (start_address > bottom_address) { - size_t fill_size = pointer_delta(start_address, bottom_address); - G1CollectedHeap::fill_with_objects(bottom_address, fill_size); - increase_used(fill_size * HeapWordSize); - } + if (shrink_count != 0) { + log_debug(gc, ergo, heap)("Attempt heap shrinking (CDS archive regions). Total size: " SIZE_FORMAT "B", + HeapRegion::GrainWords * HeapWordSize * shrink_count); + // Explicit uncommit. + uncommit_regions(shrink_count); } + decrease_used(size_used); } inline HeapWord* G1CollectedHeap::attempt_allocation(size_t min_word_size, @@ -705,99 +653,6 @@ inline HeapWord* G1CollectedHeap::attempt_allocation(size_t min_word_size, return result; } -void G1CollectedHeap::populate_archive_regions_bot_part(MemRegion* ranges, size_t count) { - assert(!is_init_completed(), "Expect to be called at JVM init time"); - assert(ranges != NULL, "MemRegion array NULL"); - assert(count != 0, "No MemRegions provided"); - - HeapWord* st = ranges[0].start(); - HeapWord* last = ranges[count-1].last(); - HeapRegion* hr_st = _hrm.addr_to_region(st); - HeapRegion* hr_last = _hrm.addr_to_region(last); - - HeapRegion* hr_curr = hr_st; - while (hr_curr != NULL) { - hr_curr->update_bot(); - if (hr_curr != hr_last) { - hr_curr = _hrm.next_region_in_heap(hr_curr); - } else { - hr_curr = NULL; - } - } -} - -void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) { - assert(!is_init_completed(), "Expect to be called at JVM init time"); - assert(ranges != NULL, "MemRegion array NULL"); - assert(count != 0, "No MemRegions provided"); - MemRegion reserved = _hrm.reserved(); - HeapWord* prev_last_addr = NULL; - HeapRegion* prev_last_region = NULL; - size_t size_used = 0; - uint shrink_count = 0; - - // For each Memregion, free the G1 regions that constitute it, and - // notify mark-sweep that the range is no longer to be considered 'archive.' - MutexLocker x(Heap_lock); - for (size_t i = 0; i < count; i++) { - HeapWord* start_address = ranges[i].start(); - HeapWord* last_address = ranges[i].last(); - - assert(reserved.contains(start_address) && reserved.contains(last_address), - "MemRegion outside of heap [" PTR_FORMAT ", " PTR_FORMAT "]", - p2i(start_address), p2i(last_address)); - assert(start_address > prev_last_addr, - "Ranges not in ascending order: " PTR_FORMAT " <= " PTR_FORMAT , - p2i(start_address), p2i(prev_last_addr)); - size_used += ranges[i].byte_size(); - prev_last_addr = last_address; - - HeapRegion* start_region = _hrm.addr_to_region(start_address); - HeapRegion* last_region = _hrm.addr_to_region(last_address); - - // Check for ranges that start in the same G1 region in which the previous - // range ended, and adjust the start address so we don't try to free - // the same region again. If the current range is entirely within that - // region, skip it. - if (start_region == prev_last_region) { - start_address = start_region->end(); - if (start_address > last_address) { - continue; - } - start_region = _hrm.addr_to_region(start_address); - } - prev_last_region = last_region; - - // After verifying that each region was marked as an archive region by - // alloc_archive_regions, set it free and empty and uncommit it. - HeapRegion* curr_region = start_region; - while (curr_region != NULL) { - guarantee(curr_region->is_archive(), - "Expected archive region at index %u", curr_region->hrm_index()); - uint curr_index = curr_region->hrm_index(); - _archive_set.remove(curr_region); - curr_region->set_free(); - curr_region->set_top(curr_region->bottom()); - if (curr_region != last_region) { - curr_region = _hrm.next_region_in_heap(curr_region); - } else { - curr_region = NULL; - } - - _hrm.shrink_at(curr_index, 1); - shrink_count++; - } - } - - if (shrink_count != 0) { - log_debug(gc, ergo, heap)("Attempt heap shrinking (archive regions). Total size: " SIZE_FORMAT "B", - HeapRegion::GrainWords * HeapWordSize * shrink_count); - // Explicit uncommit. - uncommit_regions(shrink_count); - } - decrease_used(size_used); -} - HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) { ResourceMark rm; // For retrieving the thread names in log messages. @@ -1344,16 +1199,6 @@ public: const char* get_description() { return "Old Regions"; } }; -class ArchiveRegionSetChecker : public HeapRegionSetChecker { -public: - void check_mt_safety() { - guarantee(!Universe::is_fully_initialized() || SafepointSynchronize::is_at_safepoint(), - "May only change archive regions during initialization or safepoint."); - } - bool is_correct_type(HeapRegion* hr) { return hr->is_archive(); } - const char* get_description() { return "Archive Regions"; } -}; - class HumongousRegionSetChecker : public HeapRegionSetChecker { public: void check_mt_safety() { @@ -1388,7 +1233,6 @@ G1CollectedHeap::G1CollectedHeap() : _collection_pause_end(Ticks::now()), _soft_ref_policy(), _old_set("Old Region Set", new OldRegionSetChecker()), - _archive_set("Archive Region Set", new ArchiveRegionSetChecker()), _humongous_set("Humongous Region Set", new HumongousRegionSetChecker()), _bot(NULL), _listener(), @@ -2293,10 +2137,6 @@ bool G1CollectedHeap::supports_concurrent_gc_breakpoints() const { return true; } -bool G1CollectedHeap::is_archived_object(oop object) const { - return object != NULL && heap_region_containing(object)->is_archive(); -} - class PrintRegionClosure: public HeapRegionClosure { outputStream* _st; public: @@ -2378,7 +2218,6 @@ void G1CollectedHeap::print_regions_on(outputStream* st) const { st->print_cr("Heap Regions: E=young(eden), S=young(survivor), O=old, " "HS=humongous(starts), HC=humongous(continues), " "CS=collection set, F=free, " - "OA=open archive, CA=closed archive, " "TAMS=top-at-mark-start, " "PB=parsable bottom"); PrintRegionClosure blk(st); @@ -2809,12 +2648,10 @@ void G1CollectedHeap::free_humongous_region(HeapRegion* hr, } void G1CollectedHeap::remove_from_old_gen_sets(const uint old_regions_removed, - const uint archive_regions_removed, const uint humongous_regions_removed) { - if (old_regions_removed > 0 || archive_regions_removed > 0 || humongous_regions_removed > 0) { + if (old_regions_removed > 0 || humongous_regions_removed > 0) { MutexLocker x(OldSets_lock, Mutex::_no_safepoint_check_flag); _old_set.bulk_remove(old_regions_removed); - _archive_set.bulk_remove(archive_regions_removed); _humongous_set.bulk_remove(humongous_regions_removed); } @@ -2905,9 +2742,7 @@ bool G1CollectedHeap::check_young_list_empty() { // Remove the given HeapRegion from the appropriate region set. void G1CollectedHeap::prepare_region_for_full_compaction(HeapRegion* hr) { - if (hr->is_archive()) { - _archive_set.remove(hr); - } else if (hr->is_humongous()) { + if (hr->is_humongous()) { _humongous_set.remove(hr); } else if (hr->is_old()) { _old_set.remove(hr); @@ -2943,7 +2778,6 @@ private: bool _free_list_only; HeapRegionSet* _old_set; - HeapRegionSet* _archive_set; HeapRegionSet* _humongous_set; HeapRegionManager* _hrm; @@ -2953,15 +2787,13 @@ private: public: RebuildRegionSetsClosure(bool free_list_only, HeapRegionSet* old_set, - HeapRegionSet* archive_set, HeapRegionSet* humongous_set, HeapRegionManager* hrm) : - _free_list_only(free_list_only), _old_set(old_set), _archive_set(archive_set), + _free_list_only(free_list_only), _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm), _total_used(0) { assert(_hrm->num_free_regions() == 0, "pre-condition"); if (!free_list_only) { assert(_old_set->is_empty(), "pre-condition"); - assert(_archive_set->is_empty(), "pre-condition"); assert(_humongous_set->is_empty(), "pre-condition"); } } @@ -2977,11 +2809,9 @@ public: if (r->is_humongous()) { _humongous_set->add(r); - } else if (r->is_archive()) { - _archive_set->add(r); } else { assert(r->is_young() || r->is_free() || r->is_old(), "invariant"); - // We now move all (non-humongous, non-old, non-archive) regions to old gen, + // We now move all (non-humongous, non-old) regions to old gen, // and register them as such. r->move_to_old(); _old_set->add(r); @@ -3006,7 +2836,7 @@ void G1CollectedHeap::rebuild_region_sets(bool free_list_only) { } RebuildRegionSetsClosure cl(free_list_only, - &_old_set, &_archive_set, &_humongous_set, + &_old_set, &_humongous_set, &_hrm); heap_region_iterate(&cl); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 3f2b433c054..06df4dd38aa 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -182,9 +182,8 @@ private: static size_t _humongous_object_threshold_in_words; - // These sets keep track of old, archive and humongous regions respectively. + // These sets keep track of old and humongous regions respectively. HeapRegionSet _old_set; - HeapRegionSet _archive_set; HeapRegionSet _humongous_set; // Young gen memory statistics before GC. @@ -702,31 +701,30 @@ public: FreeRegionList* free_list); // Facility for allocating a fixed range within the heap and marking - // the containing regions as 'archive'. For use at JVM init time, when the - // caller may mmap archived heap data at the specified range(s). - // Verify that the MemRegions specified in the argument array are within the - // reserved heap. - bool check_archive_addresses(MemRegion* range, size_t count); + // the containing regions as 'old'. For use at JVM init time, when the + // caller may mmap archived heap data at the specified range. - // Commit the appropriate G1 regions containing the specified MemRegions - // and mark them as 'archive' regions. The regions in the array must be - // non-overlapping and in order of ascending address. - bool alloc_archive_regions(MemRegion* range, size_t count, bool open); + // Verify that the range is within the reserved heap. + bool check_archive_addresses(MemRegion range); - // Insert any required filler objects in the G1 regions around the specified - // ranges to make the regions parseable. This must be called after - // alloc_archive_regions, and after class loading has occurred. - void fill_archive_regions(MemRegion* range, size_t count); + // Execute func(HeapRegion* r, bool is_last) on every region covered by the + // given range. + template + void iterate_regions_in_range(MemRegion range, const Func& func); + + // Commit the appropriate G1 region(s) containing the specified range + // and mark them as 'old' region(s). + bool alloc_archive_regions(MemRegion range); // Populate the G1BlockOffsetTablePart for archived regions with the given - // memory ranges. - void populate_archive_regions_bot_part(MemRegion* range, size_t count); + // memory range. + void populate_archive_regions_bot_part(MemRegion range); - // For each of the specified MemRegions, uncommit the containing G1 regions + // For the specified range, uncommit the containing G1 regions // which had been allocated by alloc_archive_regions. This should be called - // rather than fill_archive_regions at JVM init time if the archive file - // mapping failed, with the same non-overlapping and sorted MemRegion array. - void dealloc_archive_regions(MemRegion* range, size_t count); + // at JVM init time if the archive heap's contents cannot be used (e.g., if + // CRC check fails). + void dealloc_archive_regions(MemRegion range); private: @@ -1003,10 +1001,8 @@ public: inline void old_set_add(HeapRegion* hr); inline void old_set_remove(HeapRegion* hr); - inline void archive_set_add(HeapRegion* hr); - size_t non_young_capacity_bytes() { - return (old_regions_count() + _archive_set.length() + humongous_regions_count()) * HeapRegion::GrainBytes; + return (old_regions_count() + humongous_regions_count()) * HeapRegion::GrainBytes; } // Determine whether the given region is one that we are using as an @@ -1025,7 +1021,6 @@ public: void start_concurrent_gc_for_metadata_allocation(GCCause::Cause gc_cause); void remove_from_old_gen_sets(const uint old_regions_removed, - const uint archive_regions_removed, const uint humongous_regions_removed); void prepend_to_freelist(FreeRegionList* list); void decrement_summary_bytes(size_t bytes); @@ -1215,7 +1210,6 @@ public: size_t survivor_regions_used_bytes() const { return _survivor.used_bytes(); } uint young_regions_count() const { return _eden.length() + _survivor.length(); } uint old_regions_count() const { return _old_set.length(); } - uint archive_regions_count() const { return _archive_set.length(); } uint humongous_regions_count() const { return _humongous_set.length(); } #ifdef ASSERT @@ -1282,8 +1276,6 @@ public: WorkerThreads* safepoint_workers() override { return _workers; } - bool is_archived_object(oop object) const override; - // The methods below are here for convenience and dispatch the // appropriate method depending on value of the given VerifyOption // parameter. The values for that parameter, and their meanings, diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index f49c804f8b3..39764d63aa3 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -148,10 +148,6 @@ inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) { _old_set.remove(hr); } -inline void G1CollectedHeap::archive_set_add(HeapRegion* hr) { - _archive_set.add(hr); -} - // It dirties the cards that cover the block so that the post // write barrier never queues anything when updating objects on this // block. It is assumed (and in fact we assert) that the block @@ -262,7 +258,7 @@ inline bool G1CollectedHeap::is_obj_dead(const oop obj) const { } inline bool G1CollectedHeap::is_obj_dead_full(const oop obj, const HeapRegion* hr) const { - return !is_marked(obj) && !hr->is_closed_archive(); + return !is_marked(obj); } inline bool G1CollectedHeap::is_obj_dead_full(const oop obj) const { diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp index 587aa336183..715b29d14d5 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -84,9 +84,8 @@ void G1CollectionSetCandidates::verify() const { HeapRegion *cur = _regions[idx]; guarantee(cur != NULL, "Regions after _front_idx %u cannot be NULL but %u is", _front_idx, idx); // The first disjunction filters out regions with objects that were explicitly - // pinned after being added to the collection set candidates. Archive regions - // should never have been added to the collection set though. - guarantee((cur->is_pinned() && !cur->is_archive()) || + // pinned after being added to the collection set candidates. + guarantee(cur->is_pinned() || G1CollectionSetChooser::should_add(cur), "Region %u should be eligible for addition.", cur->hrm_index()); if (prev != NULL) { diff --git a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp index 749b3565c41..3a4abafb50a 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -192,7 +192,7 @@ class G1BuildCandidateRegionsTask : public WorkerTask { // sets for old regions. r->rem_set()->clear(true /* only_cardset */); } else { - assert(r->is_archive() || !r->is_old() || !r->rem_set()->is_tracked(), + assert(!r->is_old() || !r->rem_set()->is_tracked(), "Missed to clear unused remembered set of region %u (%s) that is %s", r->hrm_index(), r->get_type_str(), r->rem_set()->get_state_str()); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index a62bfd88819..513830544bf 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -1329,7 +1329,6 @@ class G1ReclaimEmptyRegionsTask : public WorkerTask { size_t _freed_bytes; FreeRegionList* _local_cleanup_list; uint _old_regions_removed; - uint _archive_regions_removed; uint _humongous_regions_removed; public: @@ -1339,16 +1338,14 @@ class G1ReclaimEmptyRegionsTask : public WorkerTask { _freed_bytes(0), _local_cleanup_list(local_cleanup_list), _old_regions_removed(0), - _archive_regions_removed(0), _humongous_regions_removed(0) { } size_t freed_bytes() { return _freed_bytes; } const uint old_regions_removed() { return _old_regions_removed; } - const uint archive_regions_removed() { return _archive_regions_removed; } const uint humongous_regions_removed() { return _humongous_regions_removed; } bool do_heap_region(HeapRegion *hr) { - if (hr->used() > 0 && hr->live_bytes() == 0 && !hr->is_young() && !hr->is_closed_archive()) { + if (hr->used() > 0 && hr->live_bytes() == 0 && !hr->is_young()) { log_trace(gc)("Reclaimed empty old gen region %u (%s) bot " PTR_FORMAT, hr->hrm_index(), hr->get_short_type_str(), p2i(hr->bottom())); _freed_bytes += hr->used(); @@ -1356,9 +1353,6 @@ class G1ReclaimEmptyRegionsTask : public WorkerTask { if (hr->is_humongous()) { _humongous_regions_removed++; _g1h->free_humongous_region(hr, _local_cleanup_list); - } else if (hr->is_open_archive()) { - _archive_regions_removed++; - _g1h->free_region(hr, _local_cleanup_list); } else { _old_regions_removed++; _g1h->free_region(hr, _local_cleanup_list); @@ -1389,9 +1383,8 @@ public: _g1h->heap_region_par_iterate_from_worker_offset(&cl, &_hrclaimer, worker_id); assert(cl.is_complete(), "Shouldn't have aborted!"); - // Now update the old/archive/humongous region sets + // Now update the old/humongous region sets _g1h->remove_from_old_gen_sets(cl.old_regions_removed(), - cl.archive_regions_removed(), cl.humongous_regions_removed()); { MutexLocker x(G1RareEvent_lock, Mutex::_no_safepoint_check_flag); @@ -1890,7 +1883,6 @@ HeapRegion* G1ConcurrentMark::claim_region(uint worker_id) { assert(_finger >= end, "the finger should have moved forward"); if (limit > bottom) { - assert(!curr_region->is_closed_archive(), "CA regions should be skipped"); return curr_region; } else { assert(limit == bottom, diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp index 1e5bb0de49c..a2d9ed5f5be 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -54,11 +54,6 @@ inline bool G1CMIsAliveClosure::do_object_b(oop obj) { return true; } - // All objects in closed archive regions are live. - if (hr->is_closed_archive()) { - return true; - } - // All objects that are marked are live. return _g1h->is_marked(obj); } @@ -72,7 +67,7 @@ inline bool G1CMSubjectToDiscoveryClosure::do_object_b(oop obj) { return false; } assert(_g1h->is_in_reserved(obj), "Trying to discover obj " PTR_FORMAT " not in heap", p2i(obj)); - return _g1h->heap_region_containing(obj)->is_old_or_humongous_or_archive(); + return _g1h->heap_region_containing(obj)->is_old_or_humongous(); } inline bool G1ConcurrentMark::mark_in_bitmap(uint const worker_id, oop const obj) { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 1fd30111c96..64b9a69defb 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -257,8 +257,6 @@ void G1FullCollector::complete_collection() { void G1FullCollector::before_marking_update_attribute_table(HeapRegion* hr) { if (hr->is_free()) { _region_attr_table.set_free(hr->hrm_index()); - } else if (hr->is_closed_archive()) { - _region_attr_table.set_skip_marking(hr->hrm_index()); } else if (hr->is_pinned()) { _region_attr_table.set_skip_compacting(hr->hrm_index()); } else { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index 619a8d0548b..e20cef20ab5 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -130,7 +130,6 @@ public: inline bool is_compacting(oop obj) const; inline bool is_skip_compacting(uint region_index) const; - inline bool is_skip_marking(oop obj) const; // Are we (potentially) going to compact into this region? inline bool is_compaction_target(uint region_index) const; diff --git a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp index 353143a6219..e36afc01cdb 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp @@ -40,10 +40,6 @@ bool G1FullCollector::is_skip_compacting(uint region_index) const { return _region_attr_table.is_skip_compacting(region_index); } -bool G1FullCollector::is_skip_marking(oop obj) const { - return _region_attr_table.is_skip_marking(cast_from_oop(obj)); -} - bool G1FullCollector::is_compaction_target(uint region_index) const { return _region_attr_table.is_compacting(region_index) || is_free(region_index); } diff --git a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp index 2d09f8e817b..a45c3eb17de 100644 --- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -68,10 +68,8 @@ class G1AdjustRegionClosure : public HeapRegionClosure { // work distribution. oop obj = cast_to_oop(r->humongous_start_region()->bottom()); obj->oop_iterate(&cl, MemRegion(r->bottom(), r->top())); - } else if (!r->is_closed_archive() && !r->is_free()) { - // Closed archive regions never change references and only contain - // references into other closed regions and are always live. Free - // regions do not contain objects to iterate. So skip both. + } else if (!r->is_free()) { + // Free regions do not contain objects to iterate. So skip them. G1AdjustLiveClosure adjust(&cl); r->apply_to_marked_objects(_bitmap, &adjust); } diff --git a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp index ff613c9e4af..de76385c342 100644 --- a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp @@ -31,17 +31,15 @@ // fast access during the full collection. In particular some parts of the // region type information is encoded in these per-region bytes. Value encoding // has been specifically chosen to make required accesses fast. In particular, -// the table specifies whether a Full GC cycle should be compacting, skip -// compacting, or skip marking (liveness analysis) a region. +// the table specifies whether a Full GC cycle should be compacting or skip +// compacting a region. // Reasons for not compacting a region: // (1) the HeapRegion itself has been pinned at the start of Full GC. // (2) the occupancy of the region is too high to be considered eligible for compaction. -// The only examples for skipping marking for regions are Closed Archive regions. class G1FullGCHeapRegionAttr : public G1BiasedMappedArray { static const uint8_t Compacting = 0; // Region will be compacted. static const uint8_t SkipCompacting = 1; // Region should not be compacted, but otherwise handled as usual. - static const uint8_t SkipMarking = 2; // Region contents are not even marked through, but contain live objects. - static const uint8_t Free = 3; // Regions is free. + static const uint8_t Free = 2; // Region is free. static const uint8_t Invalid = 255; @@ -56,15 +54,9 @@ public: void set_invalid(uint idx) { set_by_index(idx, Invalid); } void set_compacting(uint idx) { set_by_index(idx, Compacting); } - void set_skip_marking(uint idx) { set_by_index(idx, SkipMarking); } void set_skip_compacting(uint idx) { set_by_index(idx, SkipCompacting); } void set_free(uint idx) { set_by_index(idx, Free); } - bool is_skip_marking(HeapWord* obj) const { - assert(!is_free(obj), "Should not have objects in free regions."); - return get_by_address(obj) == SkipMarking; - } - bool is_compacting(HeapWord* obj) const { assert(!is_free(obj), "Should not have objects in free regions."); return get_by_address(obj) == Compacting; diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp index 43c2d9d2f1c..8080a1d113e 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp @@ -45,10 +45,6 @@ #include "utilities/debug.hpp" inline bool G1FullGCMarker::mark_object(oop obj) { - if (_collector->is_skip_marking(obj)) { - return false; - } - // Try to mark. if (!_bitmap->par_mark(obj)) { // Lost mark race. @@ -83,11 +79,8 @@ template inline void G1FullGCMarker::mark_and_push(T* p) { oop obj = CompressedOops::decode_not_null(heap_oop); if (mark_object(obj)) { _oop_stack.push(obj); - assert(_bitmap->is_marked(obj), "Must be marked now - map self"); - } else { - assert(_bitmap->is_marked(obj) || _collector->is_skip_marking(obj), - "Must be marked by other or object in skip marking region"); } + assert(_bitmap->is_marked(obj), "Must be marked"); } } diff --git a/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp index 73e5fee3dd8..aa194d16203 100644 --- a/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp @@ -78,7 +78,7 @@ inline void G1AdjustClosure::do_oop(oop* p) { do_oop_work(p); } inline void G1AdjustClosure::do_oop(narrowOop* p) { do_oop_work(p); } inline bool G1IsAliveClosure::do_object_b(oop p) { - return _bitmap->is_marked(p) || _collector->is_skip_marking(p); + return _bitmap->is_marked(p); } template diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp index 59c28e2482a..2007665eb3c 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp @@ -48,8 +48,6 @@ bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion* assert(_collector->is_compaction_target(region_idx), "must be"); assert(!hr->is_pinned(), "must be"); - assert(!hr->is_closed_archive(), "must be"); - assert(!hr->is_open_archive(), "must be"); prepare_for_compaction(hr); diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp index 70fcc4b2c19..f76ecca6e5a 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -92,13 +92,6 @@ inline bool G1DetermineCompactionQueueClosure::do_heap_region(HeapRegion* hr) { } else { _collector->set_has_humongous(); } - } else if (hr->is_open_archive()) { - bool is_empty = _collector->live_words(hr->hrm_index()) == 0; - if (is_empty) { - free_pinned_region(hr); - } - } else if (hr->is_closed_archive()) { - // nothing to do with closed archive region } else { assert(MarkSweepDeadRatio > 0, "only skip compaction for other regions when MarkSweepDeadRatio > 0"); diff --git a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp index b6a46111f14..003cc2b3f2b 100644 --- a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp @@ -40,7 +40,7 @@ bool G1FullGCResetMetadataTask::G1ResetMetadataClosure::do_heap_region(HeapRegio uint const region_idx = hr->hrm_index(); if (!_collector->is_compaction_target(region_idx)) { assert(!hr->is_free(), "all free regions should be compaction targets"); - assert(_collector->is_skip_compacting(region_idx) || hr->is_closed_archive(), "must be"); + assert(_collector->is_skip_compacting(region_idx), "must be"); if (hr->needs_scrubbing_during_full_gc()) { scrub_skip_compacting_region(hr, hr->is_young()); } @@ -90,12 +90,6 @@ void G1FullGCResetMetadataTask::G1ResetMetadataClosure::reset_skip_compacting(He if (hr->is_humongous()) { oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); assert(_collector->mark_bitmap()->is_marked(obj), "must be live"); - } else if (hr->is_open_archive()) { - bool is_empty = (_collector->live_words(hr->hrm_index()) == 0); - assert(!is_empty, "should contain at least one live obj"); - } else if (hr->is_closed_archive()) { - // should early-return above - ShouldNotReachHere(); } else { assert(_collector->live_words(region_index) > _collector->scope()->region_compaction_threshold(), "should be quite full"); diff --git a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp index 1c5690e566d..892a6ec69ea 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp @@ -37,8 +37,6 @@ class G1HeapRegionTraceType : AllStatic { StartsHumongous, ContinuesHumongous, Old, - OpenArchive, - ClosedArchive, G1HeapRegionTypeEndSentinel }; @@ -50,8 +48,6 @@ class G1HeapRegionTraceType : AllStatic { case StartsHumongous: return "Starts Humongous"; case ContinuesHumongous: return "Continues Humongous"; case Old: return "Old"; - case OpenArchive: return "OpenArchive"; - case ClosedArchive: return "ClosedArchive"; default: ShouldNotReachHere(); return NULL; } } diff --git a/src/hotspot/share/gc/g1/g1HeapTransition.cpp b/src/hotspot/share/gc/g1/g1HeapTransition.cpp index 0c534c15317..e84550bf855 100644 --- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp +++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -33,7 +33,6 @@ G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) : _eden_length(g1_heap->eden_regions_count()), _survivor_length(g1_heap->survivor_regions_count()), _old_length(g1_heap->old_regions_count()), - _archive_length(g1_heap->archive_regions_count()), _humongous_length(g1_heap->humongous_regions_count()), _meta_sizes(MetaspaceUtils::get_combined_statistics()), _eden_length_per_node(NULL), @@ -67,19 +66,17 @@ struct DetailedUsage : public StackObj { size_t _eden_used; size_t _survivor_used; size_t _old_used; - size_t _archive_used; size_t _humongous_used; size_t _eden_region_count; size_t _survivor_region_count; size_t _old_region_count; - size_t _archive_region_count; size_t _humongous_region_count; DetailedUsage() : - _eden_used(0), _survivor_used(0), _old_used(0), _archive_used(0), _humongous_used(0), + _eden_used(0), _survivor_used(0), _old_used(0), _humongous_used(0), _eden_region_count(0), _survivor_region_count(0), _old_region_count(0), - _archive_region_count(0), _humongous_region_count(0) {} + _humongous_region_count(0) {} }; class DetailedUsageClosure: public HeapRegionClosure { @@ -89,9 +86,6 @@ public: if (r->is_old()) { _usage._old_used += r->used(); _usage._old_region_count++; - } else if (r->is_archive()) { - _usage._archive_used += r->used(); - _usage._archive_region_count++; } else if (r->is_survivor()) { _usage._survivor_used += r->used(); _usage._survivor_region_count++; @@ -152,8 +146,6 @@ void G1HeapTransition::print() { after._survivor_length, usage._survivor_region_count); assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT, after._old_length, usage._old_region_count); - assert(usage._archive_region_count == after._archive_length, "Expected archive to be " SIZE_FORMAT " but was " SIZE_FORMAT, - after._archive_length, usage._archive_region_count); assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT, after._humongous_length, usage._humongous_region_count); } @@ -172,11 +164,6 @@ void G1HeapTransition::print() { log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", usage._old_used / K, ((after._old_length * HeapRegion::GrainBytes) - usage._old_used) / K); - log_info(gc, heap)("Archive regions: " SIZE_FORMAT "->" SIZE_FORMAT, - _before._archive_length, after._archive_length); - log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", - usage._archive_used / K, ((after._archive_length * HeapRegion::GrainBytes) - usage._archive_used) / K); - log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT, _before._humongous_length, after._humongous_length); log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K", diff --git a/src/hotspot/share/gc/g1/g1HeapTransition.hpp b/src/hotspot/share/gc/g1/g1HeapTransition.hpp index dc7325a26a1..09d901f283c 100644 --- a/src/hotspot/share/gc/g1/g1HeapTransition.hpp +++ b/src/hotspot/share/gc/g1/g1HeapTransition.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -35,7 +35,6 @@ class G1HeapTransition { size_t _eden_length; size_t _survivor_length; size_t _old_length; - size_t _archive_length; size_t _humongous_length; const MetaspaceCombinedStats _meta_sizes; diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp index 8e30eb94a73..8db5ab13237 100644 --- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp @@ -233,99 +233,6 @@ public: size_t live_bytes() { return _live_bytes; } }; -class VerifyArchiveOopClosure: public BasicOopIterateClosure { - HeapRegion* _hr; -public: - VerifyArchiveOopClosure(HeapRegion *hr) : _hr(hr) { } - void do_oop(narrowOop *p) { do_oop_work(p); } - void do_oop( oop *p) { do_oop_work(p); } - - template void do_oop_work(T *p) { - oop obj = RawAccess<>::oop_load(p); - - if (_hr->is_open_archive()) { - guarantee(obj == NULL || G1CollectedHeap::heap()->heap_region_containing(obj)->is_archive(), - "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT, - p2i(p), p2i(obj)); - } else { - assert(_hr->is_closed_archive(), "should be closed archive region"); - guarantee(obj == NULL || G1CollectedHeap::heap()->heap_region_containing(obj)->is_closed_archive(), - "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT, - p2i(p), p2i(obj)); - } - } -}; - -class VerifyObjectInArchiveRegionClosure: public ObjectClosure { - HeapRegion* _hr; -public: - VerifyObjectInArchiveRegionClosure(HeapRegion *hr, bool verbose) - : _hr(hr) { } - // Verify that all object pointers are to archive regions. - void do_object(oop o) { - VerifyArchiveOopClosure checkOop(_hr); - assert(o != NULL, "Should not be here for NULL oops"); - o->oop_iterate(&checkOop); - } -}; - -// Should be only used at CDS dump time -class VerifyReadyForArchivingRegionClosure : public HeapRegionClosure { - bool _seen_free; - bool _has_holes; - bool _has_unexpected_holes; - bool _has_humongous; -public: - bool has_holes() {return _has_holes;} - bool has_unexpected_holes() {return _has_unexpected_holes;} - bool has_humongous() {return _has_humongous;} - - VerifyReadyForArchivingRegionClosure() : HeapRegionClosure() { - _seen_free = false; - _has_holes = false; - _has_unexpected_holes = false; - _has_humongous = false; - } - virtual bool do_heap_region(HeapRegion* hr) { - const char* hole = ""; - - if (hr->is_free()) { - _seen_free = true; - } else { - if (_seen_free) { - _has_holes = true; - if (hr->is_humongous()) { - hole = " hole"; - } else { - _has_unexpected_holes = true; - hole = " hole **** unexpected ****"; - } - } - } - if (hr->is_humongous()) { - _has_humongous = true; - } - log_info(gc, region, cds)("HeapRegion " PTR_FORMAT " %s%s", p2i(hr->bottom()), hr->get_type_str(), hole); - return false; - } -}; - -class VerifyArchivePointerRegionClosure: public HeapRegionClosure { - virtual bool do_heap_region(HeapRegion* r) { - if (r->is_archive()) { - VerifyObjectInArchiveRegionClosure verify_oop_pointers(r, false); - r->object_iterate(&verify_oop_pointers); - } - return false; - } -}; - -void G1HeapVerifier::verify_archive_regions() { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - VerifyArchivePointerRegionClosure cl; - g1h->heap_region_iterate(&cl); -} - class VerifyRegionClosure: public HeapRegionClosure { private: VerifyOption _vo; @@ -346,14 +253,7 @@ public: // Humongous and old regions regions might be of any state, so can't check here. guarantee(!r->is_free() || !r->rem_set()->is_tracked(), "Remembered set for free region %u must be untracked, is %s", r->hrm_index(), r->rem_set()->get_state_str()); - // For archive regions, verify there are no heap pointers to non-pinned regions. - if (r->is_closed_archive()) { - VerifyObjectInArchiveRegionClosure verify_oop_pointers(r, false); - r->object_iterate(&verify_oop_pointers); - } else if (r->is_open_archive()) { - VerifyObjsInRegionClosure verify_open_archive_oop(r, _vo); - r->object_iterate(&verify_open_archive_oop); - } else if (r->is_continues_humongous()) { + if (r->is_continues_humongous()) { // Verify that the continues humongous regions' remembered set state // matches the one from the starts humongous region. if (r->rem_set()->get_state_str() != r->humongous_start_region()->rem_set()->get_state_str()) { @@ -482,22 +382,19 @@ void G1HeapVerifier::verify(VerifyOption vo) { class VerifyRegionListsClosure : public HeapRegionClosure { private: HeapRegionSet* _old_set; - HeapRegionSet* _archive_set; HeapRegionSet* _humongous_set; HeapRegionManager* _hrm; public: uint _old_count; - uint _archive_count; uint _humongous_count; uint _free_count; VerifyRegionListsClosure(HeapRegionSet* old_set, - HeapRegionSet* archive_set, HeapRegionSet* humongous_set, HeapRegionManager* hrm) : - _old_set(old_set), _archive_set(archive_set), _humongous_set(humongous_set), _hrm(hrm), - _old_count(), _archive_count(), _humongous_count(), _free_count(){ } + _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm), + _old_count(), _humongous_count(), _free_count(){ } bool do_heap_region(HeapRegion* hr) { if (hr->is_young()) { @@ -508,24 +405,20 @@ public: } else if (hr->is_empty()) { assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index()); _free_count++; - } else if (hr->is_archive()) { - assert(hr->containing_set() == _archive_set, "Heap region %u is archive but not in the archive set.", hr->hrm_index()); - _archive_count++; } else if (hr->is_old()) { assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index()); _old_count++; } else { // There are no other valid region types. Check for one invalid // one we can identify: pinned without old or humongous set. - assert(!hr->is_pinned(), "Heap region %u is pinned but not old (archive) or humongous.", hr->hrm_index()); + assert(!hr->is_pinned(), "Heap region %u is pinned but not old or humongous.", hr->hrm_index()); ShouldNotReachHere(); } return false; } - void verify_counts(HeapRegionSet* old_set, HeapRegionSet* archive_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) { + void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) { guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count); - guarantee(archive_set->length() == _archive_count, "Archive set count mismatch. Expected %u, actual %u.", archive_set->length(), _archive_count); guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count); guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count); } @@ -540,9 +433,9 @@ void G1HeapVerifier::verify_region_sets() { // Finally, make sure that the region accounting in the lists is // consistent with what we see in the heap. - VerifyRegionListsClosure cl(&_g1h->_old_set, &_g1h->_archive_set, &_g1h->_humongous_set, &_g1h->_hrm); + VerifyRegionListsClosure cl(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm); _g1h->heap_region_iterate(&cl); - cl.verify_counts(&_g1h->_old_set, &_g1h->_archive_set, &_g1h->_humongous_set, &_g1h->_hrm); + cl.verify_counts(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm); } void G1HeapVerifier::prepare_for_verify() { @@ -693,11 +586,6 @@ public: return true; } if (region_attr.is_in_cset()) { - if (hr->is_archive()) { - log_error(gc, verify)("## is_archive in collection set for region %u", i); - _failures = true; - return true; - } if (hr->is_young() != (region_attr.is_young())) { log_error(gc, verify)("## is_young %d / region attr type %s inconsistency for region %u", hr->is_young(), region_attr.get_type_str(), i); diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.hpp b/src/hotspot/share/gc/g1/g1HeapVerifier.hpp index 8d25457e060..86482ac7a20 100644 --- a/src/hotspot/share/gc/g1/g1HeapVerifier.hpp +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.hpp @@ -80,8 +80,6 @@ public: void verify_not_dirty_region(HeapRegion* hr) PRODUCT_RETURN; void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN; void verify_dirty_young_regions() PRODUCT_RETURN; - - static void verify_archive_regions(); }; #endif // SHARE_GC_G1_G1HEAPVERIFIER_HPP diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 8208ca5d3a9..50026661eec 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -199,7 +199,7 @@ private: // collection. Subsumes common checks like filtering out everything but old and // humongous regions outside the collection set. // This is valid because we are not interested in scanning stray remembered set - // entries from free or archive regions. + // entries from free regions. HeapWord** _scan_top; class G1ClearCardTableTask : public G1AbstractSubTask { @@ -327,7 +327,7 @@ public: // as we do not clean up remembered sets before merging heap roots. bool contains_cards_to_process(uint const region_idx) const { HeapRegion* hr = G1CollectedHeap::heap()->region_at_or_null(region_idx); - return (hr != NULL && !hr->in_collection_set() && hr->is_old_or_humongous_or_archive()); + return (hr != NULL && !hr->in_collection_set() && hr->is_old_or_humongous()); } size_t num_visited_cards() const { @@ -426,7 +426,7 @@ public: void add_dirty_region(uint const region) { #ifdef ASSERT HeapRegion* hr = G1CollectedHeap::heap()->region_at(region); - assert(!hr->in_collection_set() && hr->is_old_or_humongous_or_archive(), + assert(!hr->in_collection_set() && hr->is_old_or_humongous(), "Region %u is not suitable for scanning, is %sin collection set or %s", hr->hrm_index(), hr->in_collection_set() ? "" : "not ", hr->get_short_type_str()); #endif @@ -714,7 +714,7 @@ public: } bool do_heap_region(HeapRegion* r) { - assert(!r->in_collection_set() && r->is_old_or_humongous_or_archive(), + assert(!r->in_collection_set() && r->is_old_or_humongous(), "Should only be called on old gen non-collection set regions but region %u is not.", r->hrm_index()); uint const region_idx = r->hrm_index(); @@ -883,7 +883,7 @@ void G1RemSet::prepare_region_for_scan(HeapRegion* r) { // to NULL (don't scan) in the initialization. if (r->in_collection_set()) { assert_scan_top_is_null(hrm_index); - } else if (r->is_old_or_humongous_or_archive()) { + } else if (r->is_old_or_humongous()) { _scan_state->set_scan_top(hrm_index, r->top()); } else { assert_scan_top_is_null(hrm_index); @@ -1476,7 +1476,7 @@ bool G1RemSet::clean_card_before_refine(CardValue** const card_ptr_addr) { // In the normal (non-stale) case, the synchronization between the // enqueueing of the card and processing it here will have ensured // we see the up-to-date region type here. - if (!r->is_old_or_humongous_or_archive()) { + if (!r->is_old_or_humongous()) { return false; } @@ -1485,9 +1485,8 @@ bool G1RemSet::clean_card_before_refine(CardValue** const card_ptr_addr) { // (part of) an object at the end of the allocated space and extend // beyond the end of allocation. - // Non-humongous objects are either allocated in the old regions during GC, - // or mapped in archive regions during startup. So if region is old or - // archive then top is stable. + // Non-humongous objects are either allocated in the old regions during GC. + // So if region is old then top is stable. // Humongous object allocation sets top last; if top has not yet been set, // this is a stale card and we'll end up with an empty intersection. // If this is not a stale card, the synchronization between the @@ -1518,7 +1517,7 @@ void G1RemSet::refine_card_concurrently(CardValue* const card_ptr, // And find the region containing it. HeapRegion* r = _g1h->heap_region_containing(start); // This reload of the top is safe even though it happens after the full - // fence, because top is stable for old, archive and unfiltered humongous + // fence, because top is stable for old and unfiltered humongous // regions, so it must return the same value as the previous load when // cleaning the card. Also cleaning the card and refinement of the card // cannot span across safepoint, so we don't need to worry about top being diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index d8ec513957a..83f6aa23e51 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -187,7 +187,6 @@ private: RegionTypeCounter _humongous; RegionTypeCounter _free; RegionTypeCounter _old; - RegionTypeCounter _archive; RegionTypeCounter _all; size_t _max_rs_mem_sz; @@ -211,7 +210,7 @@ private: public: HRRSStatsIter() : _young("Young"), _humongous("Humongous"), - _free("Free"), _old("Old"), _archive("Archive"), _all("All"), + _free("Free"), _old("Old"), _all("All"), _max_rs_mem_sz(0), _max_rs_mem_sz_region(NULL), _max_code_root_mem_sz(0), _max_code_root_mem_sz_region(NULL) {} @@ -244,8 +243,6 @@ public: current = &_humongous; } else if (r->is_old()) { current = &_old; - } else if (r->is_archive()) { - current = &_archive; } else { ShouldNotReachHere(); } @@ -258,7 +255,7 @@ public: } void print_summary_on(outputStream* out) { - RegionTypeCounter* counters[] = { &_young, &_humongous, &_free, &_old, &_archive, NULL }; + RegionTypeCounter* counters[] = { &_young, &_humongous, &_free, &_old, NULL }; out->print_cr(" Current rem set statistics"); out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT diff --git a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp index cec83231a26..6d1633786e6 100644 --- a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,11 @@ #include "runtime/safepoint.hpp" bool G1RemSetTrackingPolicy::needs_scan_for_rebuild(HeapRegion* r) const { - // All non-free, non-young, non-closed archive regions need to be scanned for references; - // At every gc we gather references to other regions in young, and closed archive - // regions by definition do not have references going outside the closed archive. + // All non-free and non-young regions need to be scanned for references; + // At every gc we gather references to other regions in young. // Free regions trivially do not need scanning because they do not contain live // objects. - return !(r->is_young() || r->is_closed_archive() || r->is_free()); + return !(r->is_young() || r->is_free()); } void G1RemSetTrackingPolicy::update_at_allocate(HeapRegion* r) { @@ -45,9 +44,6 @@ void G1RemSetTrackingPolicy::update_at_allocate(HeapRegion* r) { } else if (r->is_humongous()) { // Collect remembered sets for humongous regions by default to allow eager reclaim. r->rem_set()->set_state_complete(); - } else if (r->is_archive()) { - // Archive regions never move ever. So never build remembered sets for them. - r->rem_set()->set_state_untracked(); } else if (r->is_old()) { // By default, do not create remembered set for new old regions. r->rem_set()->set_state_untracked(); @@ -79,10 +75,6 @@ bool G1RemSetTrackingPolicy::update_humongous_before_rebuild(HeapRegion* r, bool assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(r->is_humongous(), "Region %u should be humongous", r->hrm_index()); - if (r->is_archive()) { - return false; - } - assert(!r->rem_set()->is_updating(), "Remembered set of region %u is updating before rebuild", r->hrm_index()); bool selected_for_rebuild = false; @@ -104,9 +96,8 @@ bool G1RemSetTrackingPolicy::update_before_rebuild(HeapRegion* r, size_t live_by assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(!r->is_humongous(), "Region %u is humongous", r->hrm_index()); - // Only consider updating the remembered set for old gen regions - excluding archive regions - // which never move (but are "Old" regions). - if (!r->is_old() || r->is_archive()) { + // Only consider updating the remembered set for old gen regions. + if (!r->is_old()) { return false; } @@ -137,9 +128,8 @@ bool G1RemSetTrackingPolicy::update_before_rebuild(HeapRegion* r, size_t live_by void G1RemSetTrackingPolicy::update_after_rebuild(HeapRegion* r) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); - if (r->is_old_or_humongous_or_archive()) { + if (r->is_old_or_humongous()) { if (r->rem_set()->is_updating()) { - assert(!r->is_archive(), "Archive region %u with remembered set", r->hrm_index()); r->rem_set()->set_state_complete(); } G1CollectedHeap* g1h = G1CollectedHeap::heap(); diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp index 0d7b21eb70e..a84ea56107f 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp @@ -263,7 +263,7 @@ public: virtual ~EagerlyReclaimHumongousObjectsTask() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); - g1h->remove_from_old_gen_sets(0, 0, _humongous_regions_reclaimed); + g1h->remove_from_old_gen_sets(0, _humongous_regions_reclaimed); g1h->decrement_summary_bytes(_bytes_freed); } diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index 1c47b92b5f7..32cb04decad 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -179,16 +179,6 @@ void HeapRegion::set_old() { _type.set_old(); } -void HeapRegion::set_open_archive() { - report_region_type_change(G1HeapRegionTraceType::OpenArchive); - _type.set_open_archive(); -} - -void HeapRegion::set_closed_archive() { - report_region_type_change(G1HeapRegionTraceType::ClosedArchive); - _type.set_closed_archive(); -} - void HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) { assert(!is_humongous(), "sanity / pre-condition"); assert(top() == bottom(), "should be empty"); diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index 08d6c26f830..b2414988d60 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -375,11 +375,10 @@ public: // During the concurrent scrubbing phase, can there be any areas with unloaded // classes or dead objects in this region? - // This set only includes old and open archive regions - humongous regions only - // contain a single object which is either dead or live, contents of closed archive - // regions never die (so is always contiguous), and young regions are never even + // This set only includes old regions - humongous regions only + // contain a single object which is either dead or live, and young regions are never even // considered during concurrent scrub. - bool needs_scrubbing() const { return is_old() || is_open_archive(); } + bool needs_scrubbing() const { return is_old(); } // Same question as above, during full gc. Full gc needs to scrub any region that // might be skipped for compaction. This includes young generation regions as the // region relabeling to old happens later than scrubbing. @@ -403,19 +402,10 @@ public: bool is_old_or_humongous() const { return _type.is_old_or_humongous(); } - bool is_old_or_humongous_or_archive() const { return _type.is_old_or_humongous_or_archive(); } - // A pinned region contains objects which are not moved by garbage collections. - // Humongous regions and archive regions are pinned. + // Humongous regions are pinned. bool is_pinned() const { return _type.is_pinned(); } - // An archive region is a pinned region, also tagged as old, which - // should not be marked during mark/sweep. This allows the address - // space to be shared by JVM instances. - bool is_archive() const { return _type.is_archive(); } - bool is_open_archive() const { return _type.is_open_archive(); } - bool is_closed_archive() const { return _type.is_closed_archive(); } - void set_free(); void set_eden(); @@ -425,9 +415,6 @@ public: void move_to_old(); void set_old(); - void set_open_archive(); - void set_closed_archive(); - // For a humongous region, region in which it starts. HeapRegion* humongous_start_region() const { return _humongous_start_region; diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index 4b87d0c9284..a506a328792 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -142,11 +142,6 @@ inline bool HeapRegion::block_is_obj(const HeapWord* const p, HeapWord* const pb inline bool HeapRegion::is_obj_dead(const oop obj, HeapWord* const pb) const { assert(is_in_reserved(obj), "Object " PTR_FORMAT " must be in region", p2i(obj)); - // Objects in closed archive regions are always live. - if (is_closed_archive()) { - return false; - } - // From Remark until a region has been concurrently scrubbed, parts of the // region is not guaranteed to be parsable. Use the bitmap for liveness. if (obj_in_unparsable_area(obj, pb)) { @@ -294,10 +289,7 @@ inline void HeapRegion::reset_parsable_bottom() { } inline void HeapRegion::note_start_of_marking() { - assert(!is_closed_archive() || top_at_mark_start() == bottom(), "CA region's TAMS must always be at bottom"); - if (!is_closed_archive()) { - set_top_at_mark_start(top()); - } + set_top_at_mark_start(top()); _gc_efficiency = -1.0; } @@ -496,7 +488,7 @@ HeapWord* HeapRegion::oops_on_memregion_seq_iterate_careful(MemRegion mr, if (is_humongous()) { return do_oops_on_memregion_in_humongous(mr, cl); } - assert(is_old() || is_archive(), "Wrongly trying to iterate over region %u type %s", _hrm_index, get_type_str()); + assert(is_old(), "Wrongly trying to iterate over region %u type %s", _hrm_index, get_type_str()); // Because mr has been trimmed to what's been allocated in this // region, the objects in these parts of the heap have non-NULL diff --git a/src/hotspot/share/gc/g1/heapRegionSet.cpp b/src/hotspot/share/gc/g1/heapRegionSet.cpp index a4fbe33d580..b2ce58c744f 100644 --- a/src/hotspot/share/gc/g1/heapRegionSet.cpp +++ b/src/hotspot/share/gc/g1/heapRegionSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -37,8 +37,7 @@ void HeapRegionSetBase::verify_region(HeapRegion* hr) { assert(_checker == NULL || _checker->is_correct_type(hr), "Wrong type of region %u (%s) and set %s", hr->hrm_index(), hr->get_type_str(), name()); assert(!hr->is_free() || hr->is_empty(), "Free region %u is not empty for set %s", hr->hrm_index(), name()); - assert(!hr->is_empty() || hr->is_free() || hr->is_archive(), - "Empty region %u is not free or archive for set %s", hr->hrm_index(), name()); + assert(!hr->is_empty() || hr->is_free(), "Empty region %u is not free or old for set %s", hr->hrm_index(), name()); } #endif diff --git a/src/hotspot/share/gc/g1/heapRegionType.cpp b/src/hotspot/share/gc/g1/heapRegionType.cpp index 35f11950eb9..9fc733a77b9 100644 --- a/src/hotspot/share/gc/g1/heapRegionType.cpp +++ b/src/hotspot/share/gc/g1/heapRegionType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,6 @@ bool HeapRegionType::is_valid(Tag tag) { case StartsHumongousTag: case ContinuesHumongousTag: case OldTag: - case OpenArchiveTag: - case ClosedArchiveTag: return true; default: return false; @@ -56,8 +54,6 @@ const char* HeapRegionType::get_str() const { case StartsHumongousTag: return "HUMS"; case ContinuesHumongousTag: return "HUMC"; case OldTag: return "OLD"; - case OpenArchiveTag: return "OARC"; - case ClosedArchiveTag: return "CARC"; default: ShouldNotReachHere(); return NULL; // keep some compilers happy @@ -73,8 +69,6 @@ const char* HeapRegionType::get_short_str() const { case StartsHumongousTag: return "HS"; case ContinuesHumongousTag: return "HC"; case OldTag: return "O"; - case OpenArchiveTag: return "OA"; - case ClosedArchiveTag: return "CA"; default: ShouldNotReachHere(); return NULL; // keep some compilers happy @@ -90,8 +84,6 @@ G1HeapRegionTraceType::Type HeapRegionType::get_trace_type() { case StartsHumongousTag: return G1HeapRegionTraceType::StartsHumongous; case ContinuesHumongousTag: return G1HeapRegionTraceType::ContinuesHumongous; case OldTag: return G1HeapRegionTraceType::Old; - case OpenArchiveTag: return G1HeapRegionTraceType::OpenArchive; - case ClosedArchiveTag: return G1HeapRegionTraceType::ClosedArchive; default: ShouldNotReachHere(); return G1HeapRegionTraceType::Free; // keep some compilers happy diff --git a/src/hotspot/share/gc/g1/heapRegionType.hpp b/src/hotspot/share/gc/g1/heapRegionType.hpp index 9e1c79ea0d0..6e366b2820e 100644 --- a/src/hotspot/share/gc/g1/heapRegionType.hpp +++ b/src/hotspot/share/gc/g1/heapRegionType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ private: // We encode the value of the heap region type so the generation can be // determined quickly. The tag is split into two parts: // - // major type (young, old, humongous, archive) : top N-1 bits + // major type (young, old, humongous) : top N-1 bits // minor type (eden / survivor, starts / cont hum, etc.) : bottom 1 bit // // If there's need to increase the number of minor types in the @@ -58,10 +58,6 @@ private: // // 01000 0 [16] Old Mask // - // 10000 0 [32] Archive Mask - // 10100 0 [40] Open Archive - // 10100 1 [41] Closed Archive - // typedef enum { FreeTag = 0, @@ -75,20 +71,7 @@ private: ContinuesHumongousTag = HumongousMask | PinnedMask + 1, OldMask = 16, - OldTag = OldMask, - - // Archive regions are regions with immutable content (i.e. not reclaimed, and - // not allocated into during regular operation). They differ in the kind of references - // allowed for the contained objects: - // - Closed archive regions form a separate self-contained (closed) object graph - // within the set of all of these regions. No references outside of closed - // archive regions are allowed. - // - Open archive regions have no restrictions on the references of their objects. - // Objects within these regions are allowed to have references to objects - // contained in any other kind of regions. - ArchiveMask = 32, - OpenArchiveTag = ArchiveMask | PinnedMask, - ClosedArchiveTag = ArchiveMask | PinnedMask + 1 + OldTag = OldMask } Tag; volatile Tag _tag; @@ -134,18 +117,11 @@ public: bool is_starts_humongous() const { return get() == StartsHumongousTag; } bool is_continues_humongous() const { return get() == ContinuesHumongousTag; } - bool is_archive() const { return (get() & ArchiveMask) != 0; } - bool is_open_archive() const { return get() == OpenArchiveTag; } - bool is_closed_archive() const { return get() == ClosedArchiveTag; } - // is_old regions may or may not also be pinned bool is_old() const { return (get() & OldMask) != 0; } bool is_old_or_humongous() const { return (get() & (OldMask | HumongousMask)) != 0; } - bool is_old_or_humongous_or_archive() const { return (get() & (OldMask | HumongousMask | ArchiveMask)) != 0; } - - // is_pinned regions may be archive or humongous bool is_pinned() const { return (get() & PinnedMask) != 0; } // Setters @@ -180,8 +156,6 @@ public: return true; } } - void set_open_archive() { set_from(OpenArchiveTag, FreeTag); } - void set_closed_archive() { set_from(ClosedArchiveTag, FreeTag); } // Misc diff --git a/src/hotspot/share/gc/g1/vmStructs_g1.hpp b/src/hotspot/share/gc/g1/vmStructs_g1.hpp index bf2a8762937..36a96f46488 100644 --- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp +++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -57,7 +57,6 @@ nonstatic_field(G1CollectedHeap, _hrm, HeapRegionManager) \ nonstatic_field(G1CollectedHeap, _monitoring_support, G1MonitoringSupport*) \ nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \ - nonstatic_field(G1CollectedHeap, _archive_set, HeapRegionSetBase) \ nonstatic_field(G1CollectedHeap, _humongous_set, HeapRegionSetBase) \ \ nonstatic_field(G1MonitoringSupport, _eden_space_committed, size_t) \ @@ -80,7 +79,6 @@ declare_constant(HeapRegionType::SurvTag) \ declare_constant(HeapRegionType::HumongousMask) \ declare_constant(HeapRegionType::PinnedMask) \ - declare_constant(HeapRegionType::ArchiveMask) \ declare_constant(HeapRegionType::StartsHumongousTag) \ declare_constant(HeapRegionType::ContinuesHumongousTag) \ declare_constant(HeapRegionType::OldMask) \ diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index de17e24628f..4c22dccd0f8 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -638,10 +638,6 @@ void CollectedHeap::reset_promotion_should_fail() { #endif // #ifndef PRODUCT -bool CollectedHeap::is_archived_object(oop object) const { - return false; -} - // It's the caller's responsibility to ensure glitch-freedom // (if required). void CollectedHeap::update_capacity_and_used_at_gc() { diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index d03aa76f4cd..e427e6de668 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -513,9 +513,6 @@ class CollectedHeap : public CHeapObj { virtual void pin_object(JavaThread* thread, oop obj) = 0; virtual void unpin_object(JavaThread* thread, oop obj) = 0; - // Is the given object inside a CDS archive area? - virtual bool is_archived_object(oop object) const; - // Support for loading objects from CDS archive into the heap // (usually as a snapshot of the old generation). virtual bool can_load_archived_objects() const { return false; } diff --git a/src/hotspot/share/include/cds.h b/src/hotspot/share/include/cds.h index b9ce48dddaa..af48c1a8c35 100644 --- a/src/hotspot/share/include/cds.h +++ b/src/hotspot/share/include/cds.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,11 +35,11 @@ // // Also, this is a C header file. Do not use C++ here. -#define NUM_CDS_REGIONS 7 // this must be the same as MetaspaceShared::n_regions +#define NUM_CDS_REGIONS 4 // this must be the same as MetaspaceShared::n_regions #define CDS_ARCHIVE_MAGIC 0xf00baba2 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8 #define CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION 13 -#define CURRENT_CDS_ARCHIVE_VERSION 17 +#define CURRENT_CDS_ARCHIVE_VERSION 18 typedef struct CDSFileMapRegion { int _crc; // CRC checksum of this region. diff --git a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp index 1d5113f5a8e..867a0580a12 100644 --- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp +++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp @@ -56,10 +56,7 @@ void InstanceMirrorKlass::oop_oop_iterate(oop obj, OopClosureType* closure) { if (klass != nullptr) { if (klass->class_loader_data() == nullptr) { // This is a mirror that belongs to a shared class that has not be loaded yet. - // It's only reachable via HeapShared::roots(). All of its fields should be zero - // so there's no need to scan. assert(klass->is_shared(), "must be"); - return; } else if (klass->is_instance_klass() && klass->class_loader_data()->has_class_mirror_holder()) { // A non-strong hidden class doesn't have its own class loader, // so when handling the java mirror for the class we need to make sure its class diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index c9a39c7cad6..7d170177ab7 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -231,13 +231,6 @@ jdouble oopDesc::double_field_acquire(int offset) const { return A void oopDesc::release_double_field_put(int offset, jdouble value) { Atomic::release_store(field_addr(offset), value); } #ifdef ASSERT -void oopDesc::verify_forwardee(oop forwardee) { -#if INCLUDE_CDS_JAVA_HEAP - assert(!Universe::heap()->is_archived_object(forwardee) && !Universe::heap()->is_archived_object(this), - "forwarding archive object"); -#endif -} - bool oopDesc::size_might_change() { // UseParallelGC and UseG1GC can change the length field // of an "old copy" of an object array in the young gen so it indicates diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index 9f8e0ce1f2b..a7be060b007 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -257,8 +257,6 @@ class oopDesc { // Forward pointer operations for scavenge inline bool is_forwarded() const; - void verify_forwardee(oop forwardee) NOT_DEBUG_RETURN; - inline void forward_to(oop p); // Like "forward_to", but inserts the forwarding pointer atomically. diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index cf05750e862..4988846f172 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -266,14 +266,12 @@ bool oopDesc::is_forwarded() const { // Used by scavengers void oopDesc::forward_to(oop p) { - verify_forwardee(p); markWord m = markWord::encode_pointer_as_mark(p); assert(m.decode_pointer() == p, "encoding must be reversible"); set_mark(m); } oop oopDesc::forward_to_atomic(oop p, markWord compare, atomic_memory_order order) { - verify_forwardee(p); markWord m = markWord::encode_pointer_as_mark(p); assert(m.decode_pointer() == p, "encoding must be reversible"); markWord old_mark = cas_set_mark(m, compare, order); diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 7e98023e18c..5e0c8f4d7f4 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -2006,11 +2006,6 @@ WB_ENTRY(jboolean, WB_CDSMemoryMappingFailed(JNIEnv* env, jobject wb)) return FileMapInfo::memory_mapping_failed(); WB_END -WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj)) - oop obj_oop = JNIHandles::resolve(obj); - return Universe::heap()->is_archived_object(obj_oop); -WB_END - WB_ENTRY(jboolean, WB_IsSharedInternedString(JNIEnv* env, jobject wb, jobject str)) ResourceMark rm(THREAD); oop str_oop = JNIHandles::resolve(str); @@ -2024,19 +2019,7 @@ WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz)) WB_END WB_ENTRY(jboolean, WB_AreSharedStringsMapped(JNIEnv* env)) - return ArchiveHeapLoader::closed_regions_mapped(); -WB_END - -WB_ENTRY(jobject, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass clazz)) - Klass *k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); - if (k->is_instance_klass()) { - InstanceKlass *ik = InstanceKlass::cast(k); - ConstantPool *cp = ik->constants(); - objArrayOop refs = cp->resolved_references(); - return (jobject)JNIHandles::make_local(THREAD, refs); - } else { - return nullptr; - } + return ArchiveHeapLoader::is_mapped(); WB_END WB_ENTRY(void, WB_LinkClass(JNIEnv* env, jobject wb, jclass clazz)) @@ -2049,7 +2032,7 @@ WB_ENTRY(void, WB_LinkClass(JNIEnv* env, jobject wb, jclass clazz)) WB_END WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env)) - return ArchiveHeapLoader::open_regions_mapped(); + return ArchiveHeapLoader::is_mapped(); WB_END WB_ENTRY(jboolean, WB_IsCDSIncluded(JNIEnv* env)) @@ -2766,11 +2749,9 @@ static JNINativeMethod methods[] = { {CC"getCDSGenericHeaderMinVersion", CC"()I", (void*)&WB_GetCDSGenericHeaderMinVersion}, {CC"getCurrentCDSVersion", CC"()I", (void*)&WB_GetCDSCurrentVersion}, {CC"isSharingEnabled", CC"()Z", (void*)&WB_IsSharingEnabled}, - {CC"isShared", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsShared }, {CC"isSharedInternedString", CC"(Ljava/lang/String;)Z", (void*)&WB_IsSharedInternedString }, {CC"isSharedClass", CC"(Ljava/lang/Class;)Z", (void*)&WB_IsSharedClass }, {CC"areSharedStringsMapped", CC"()Z", (void*)&WB_AreSharedStringsMapped }, - {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences}, {CC"linkClass", CC"(Ljava/lang/Class;)V", (void*)&WB_LinkClass}, {CC"areOpenArchiveHeapObjectsMapped", CC"()Z", (void*)&WB_AreOpenArchiveHeapObjectsMapped}, {CC"isCDSIncluded", CC"()Z", (void*)&WB_IsCDSIncluded }, diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java index 6c52f9c1f2f..3870d2642bf 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -57,8 +57,6 @@ public class G1CollectedHeap extends CollectedHeap { private static AddressField monitoringSupportField; // HeapRegionSet _old_set; private static long oldSetFieldOffset; - // HeapRegionSet _archive_set; - private static long archiveSetFieldOffset; // HeapRegionSet _humongous_set; private static long humongousSetFieldOffset; @@ -77,7 +75,6 @@ public class G1CollectedHeap extends CollectedHeap { summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used"); monitoringSupportField = type.getAddressField("_monitoring_support"); oldSetFieldOffset = type.getField("_old_set").getOffset(); - archiveSetFieldOffset = type.getField("_archive_set").getOffset(); humongousSetFieldOffset = type.getField("_humongous_set").getOffset(); } @@ -108,11 +105,6 @@ public class G1CollectedHeap extends CollectedHeap { return VMObjectFactory.newObject(HeapRegionSetBase.class, oldSetAddr); } - public HeapRegionSetBase archiveSet() { - Address archiveSetAddr = addr.addOffsetTo(archiveSetFieldOffset); - return VMObjectFactory.newObject(HeapRegionSetBase.class, archiveSetAddr); - } - public HeapRegionSetBase humongousSet() { Address humongousSetAddr = addr.addOffsetTo(humongousSetFieldOffset); return VMObjectFactory.newObject(HeapRegionSetBase.class, humongousSetAddr); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java index a923238d11c..7df81b4b7cd 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -46,7 +46,6 @@ public class HeapRegionType extends VMObject { private static int startsHumongousTag; private static int continuesHumongousTag; private static int pinnedMask; - private static int archiveMask; private static int oldMask; private static CIntegerField tagField; private int tag; @@ -70,7 +69,6 @@ public class HeapRegionType extends VMObject { survTag = db.lookupIntConstant("HeapRegionType::SurvTag"); startsHumongousTag = db.lookupIntConstant("HeapRegionType::StartsHumongousTag"); continuesHumongousTag = db.lookupIntConstant("HeapRegionType::ContinuesHumongousTag"); - archiveMask = db.lookupIntConstant("HeapRegionType::ArchiveMask"); humongousMask = db.lookupIntConstant("HeapRegionType::HumongousMask"); pinnedMask = db.lookupIntConstant("HeapRegionType::PinnedMask"); oldMask = db.lookupIntConstant("HeapRegionType::OldMask"); @@ -104,10 +102,6 @@ public class HeapRegionType extends VMObject { return tagField.getValue(addr) == continuesHumongousTag; } - public boolean isArchive() { - return (tagField.getValue(addr) & archiveMask) != 0; - } - public boolean isPinned() { return (tagField.getValue(addr) & pinnedMask) != 0; } @@ -136,9 +130,6 @@ public class HeapRegionType extends VMObject { if (isContinuesHumongous()) { return "ContinuesHumongous"; } - if (isArchive()) { - return "Archive"; - } if (isPinned()) { return "Pinned"; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index f74b0523494..3980a7da8f7 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -248,9 +248,8 @@ public class HeapSummary extends Tool { long edenSpaceRegionNum = monitoringSupport.edenSpaceRegionNum(); long survivorSpaceRegionNum = monitoringSupport.survivorSpaceRegionNum(); HeapRegionSetBase oldSet = g1h.oldSet(); - HeapRegionSetBase archiveSet = g1h.archiveSet(); HeapRegionSetBase humongousSet = g1h.humongousSet(); - long oldGenRegionNum = oldSet.length() + archiveSet.length() + humongousSet.length(); + long oldGenRegionNum = oldSet.length() + humongousSet.length(); printG1Space(tty, "G1 Heap:", g1h.n_regions(), g1h.used(), g1h.capacity()); tty.println("G1 Young Generation:"); diff --git a/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java b/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java index c5baf688745..66cbfbc8d91 100644 --- a/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java +++ b/test/hotspot/jtreg/runtime/cds/SpaceUtilizationCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,27 +56,29 @@ public class SpaceUtilizationCheck { CDSOptions opts = new CDSOptions(); opts.addSuffix(extra_options); OutputAnalyzer output = CDSTestUtils.createArchiveAndCheck(opts); - Pattern pattern = Pattern.compile("(..) space: *([0-9]+).* out of *([0-9]+) bytes .* at 0x([0-9a0-f]+)"); + Pattern pattern = Pattern.compile("(..) space: *([0-9]+).* out of *([0-9]+) bytes .* at 0x([0-9a0-f]+)"); WhiteBox wb = WhiteBox.getWhiteBox(); long reserve_alignment = wb.metaspaceSharedRegionAlignment(); System.out.println("MetaspaceShared::core_region_alignment() = " + reserve_alignment); // Look for output like this. The pattern will only match the first 2 regions, which is what we need to check // - // [4.682s][debug][cds] rw space: 4391632 [ 33.7% of total] out of 4395008 bytes [ 99.9% used] at 0x0000000800007000 - // [4.682s][debug][cds] ro space: 7570632 [ 58.0% of total] out of 7573504 bytes [100.0% used] at 0x0000000800438000 - // [4.682s][debug][cds] bm space: 213528 [ 1.6% of total] out of 213528 bytes [100.0% used] - // [4.682s][debug][cds] ca0 space: 507904 [ 3.9% of total] out of 507904 bytes [100.0% used] at 0x00000000fff00000 - // [4.682s][debug][cds] oa0 space: 327680 [ 2.5% of total] out of 327680 bytes [100.0% used] at 0x00000000ffe00000 - // [4.682s][debug][cds] total : 13036288 [100.0% of total] out of 13049856 bytes [ 99.9% used] + // [0.938s][debug][cds] rw space: 5253952 [ 35.2% of total] out of 5255168 bytes [100.0% used] at 0x0000000800000000 + // [0.938s][debug][cds] ro space: 8353976 [ 55.9% of total] out of 8355840 bytes [100.0% used] at 0x0000000800503000 + // [0.938s][debug][cds] bm space: 262232 [ 1.8% of total] out of 262232 bytes [100.0% used] + // [0.938s][debug][cds] hp space: 1057712 [ 7.1% of total] out of 1057712 bytes [100.0% used] at 0x00007fa24c180090 + // [0.938s][debug][cds] total : 14927872 [100.0% of total] out of 14934960 bytes [100.0% used] long last_region = -1; Hashtable checked = new Hashtable<>(); for (String line : output.getStdout().split("\n")) { - if (line.contains(" space:") && !line.contains("st space:")) { + if (line.contains(" space:")) { Matcher matcher = pattern.matcher(line); if (matcher.find()) { String name = matcher.group(1); + if (!name.equals("rw") && ! name.equals("ro")) { + continue; + } System.out.println("Checking " + name + " in : " + line); checked.put(name, name); long used = Long.parseLong(matcher.group(2)); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java index f1d76fb4d65..2aa4bafdf12 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,10 +50,7 @@ public class SharedArchiveConsistency { "rw", // ReadWrite "ro", // ReadOnly "bm", // relocation bitmaps - "first_closed_archive", - "last_closed_archive", - "first_open_archive", - "last_open_archive" + "hp", // heap }; public static final String HELLO_WORLD = "Hello World"; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java index 40a94a2c18f..43d8568fac5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java @@ -27,10 +27,8 @@ * @summary Test primitive box caches integrity in various scenarios (IntegerCache etc) * @requires vm.cds.write.archived.java.heap * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox * @compile CheckIntegerCacheApp.java * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boxCache.jar CheckIntegerCacheApp - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox * @run driver ArchivedIntegerCacheTest */ @@ -44,8 +42,6 @@ import jdk.test.lib.helpers.ClassFileInstaller; public class ArchivedIntegerCacheTest { public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; String appJar = ClassFileInstaller.getJarPath("boxCache.jar"); Path userDir = Paths.get(CDSTestUtils.getOutputDir()); @@ -55,32 +51,25 @@ public class ArchivedIntegerCacheTest { // Dump default archive // OutputAnalyzer output = TestCommon.dump(appJar, - TestCommon.list("CheckIntegerCacheApp"), - use_whitebox_jar); + TestCommon.list("CheckIntegerCacheApp")); TestCommon.checkDump(output); // Test case 1) // - Default options System.out.println("----------------------- Test case 1 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", + output = TestCommon.exec(appJar, "CheckIntegerCacheApp", - "127", - "true"); + "127"); TestCommon.checkExec(output); // Test case 2) // - Default archive // - Larger -XX:AutoBoxCacheMax System.out.println("----------------------- Test case 2 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", + output = TestCommon.exec(appJar, "-XX:AutoBoxCacheMax=20000", "CheckIntegerCacheApp", - "20000", - "false"); + "20000"); TestCommon.checkExec(output); // @@ -88,22 +77,18 @@ public class ArchivedIntegerCacheTest { // output = TestCommon.dump(appJar, TestCommon.list("CheckIntegerCacheApp"), - "-XX:AutoBoxCacheMax=20000", - use_whitebox_jar); + "-XX:AutoBoxCacheMax=20000"); TestCommon.checkDump(output); // Test case 3) // - Large archived cache // - Default options System.out.println("----------------------- Test case 3 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, + output = TestCommon.exec(appJar, "--module-path", moduleDir.toString(), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", "CheckIntegerCacheApp", - "127", - "true"); + "127"); TestCommon.checkExec(output); @@ -111,30 +96,24 @@ public class ArchivedIntegerCacheTest { // - Large archived cache // - Matching options System.out.println("----------------------- Test case 4 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, + output = TestCommon.exec(appJar, "--module-path", moduleDir.toString(), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", "-XX:AutoBoxCacheMax=20000", "CheckIntegerCacheApp", - "20000", - "true"); + "20000"); TestCommon.checkExec(output); // Test case 5) // - Large archived cache // - Larger requested cache System.out.println("----------------------- Test case 5 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, + output = TestCommon.exec(appJar, "--module-path", moduleDir.toString(), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", "-XX:AutoBoxCacheMax=30000", "CheckIntegerCacheApp", - "30000", - "false"); + "30000"); TestCommon.checkExec(output); // Test case 6) @@ -146,8 +125,7 @@ public class ArchivedIntegerCacheTest { "-XX:NewSize=1g", "-Xlog:cds+heap=info", "-Xlog:gc+region+cds", - "-Xlog:gc+region=trace", - use_whitebox_jar); + "-Xlog:gc+region=trace"); TestCommon.checkDump(output, "Cannot archive the sub-graph referenced from [Ljava.lang.Integer; object"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleComboTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleComboTest.java deleted file mode 100644 index 3b37bfde77a..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleComboTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - */ - -/* - * @test - * @summary Test archived system module sub-graph and verify objects are archived. - * @requires vm.cds.write.archived.java.heap - * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox - * @compile CheckArchivedModuleApp.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar CheckArchivedModuleApp - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox - * @run driver ArchivedModuleComboTest - */ - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.cds.CDSTestUtils; -import jdk.test.lib.helpers.ClassFileInstaller; -import jdk.test.whitebox.WhiteBox; - -public class ArchivedModuleComboTest { - public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = ClassFileInstaller.getJarPath("app.jar"); - - Path userDir = Paths.get(CDSTestUtils.getOutputDir()); - Path moduleDir = Files.createTempDirectory(userDir, "mods"); - - // - // Dump without --module-path, without --show-module-resolution - // - OutputAnalyzer output = TestCommon.dump(appJar, - TestCommon.list("CheckArchivedModuleApp"), - use_whitebox_jar); - TestCommon.checkDump(output); - - // Test case 1) - // - Dump without --module-path, without --show-module-resolution - // - Run from -cp only and without --show-module-resolution - // + archived boot layer module ModuleDescriptors should be used - // + archived boot layer configuration should be used - System.out.println("----------------------- Test case 1 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "yes", - "yes"); - TestCommon.checkExec(output); - - // Test case 2) - // - Dump without --module-path, without --show-module-resolution - // - Run from -cp only and with --show-module-resolution - // + archived boot layer module ModuleDescriptors should be used with - // --show-module-resolution (requires resolution) - // + archived boot layer Configuration should not be disabled - System.out.println("----------------------- Test case 2 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "--show-module-resolution", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "yes", - "no"); - TestCommon.checkExec(output, "root java.base jrt:/java.base"); - - // Test case 3) - // - Dump without --module-path, without --show-module-resolution - // - Run with --module-path - // + archived boot layer module ModuleDescriptors should be disabled - // + archived boot layer Configuration should be disabled - System.out.println("----------------------- Test case 3 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "--module-path", - moduleDir.toString(), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "no", - "no"); - TestCommon.checkExec(output); - - // - // Dump with --module-path specified (test case 4, 5). Use an - // empty directory as it's simple and still triggers the case - // where system module objects are not archived. - // - output = TestCommon.dump(appJar, - TestCommon.list("CheckArchivedModuleApp"), - "--module-path", - moduleDir.toString(), - use_whitebox_jar); - TestCommon.checkDump(output); - - // Test case 4) - // - Dump with --module-path - // - Run from -cp only, no archived boot layer module ModuleDescriptors - // and Configuration should be found. - System.out.println("----------------------- Test case 4 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "no", - "no"); - TestCommon.checkExec(output); - - // Test case 5) - // - Dump with --module-path - // - Run with --module-path, no archived boot layer module ModuleDescriptors - // and Configuration should be found. - System.out.println("----------------------- Test case 5 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "--module-path", - moduleDir.toString(), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "no", - "no"); - TestCommon.checkExec(output); - - // - // Dump without --module-path, with --show-module-resolution - // - output = TestCommon.dump(appJar, - TestCommon.list("CheckArchivedModuleApp"), - "--show-module-resolution", - use_whitebox_jar); - TestCommon.checkDump(output, "root java.base jrt:/java.base"); - - // Test case 6) - // - Dump without --module-path, with --show-module-resolution - // - Run from -cp only and without --show-module-resolution - // + archived boot layer module ModuleDescriptors should be used - // + archived boot layer Configuration should be used - System.out.println("----------------------- Test case 6 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "yes", - "yes"); - TestCommon.checkExec(output); - - // Test case 7) - // - Dump without --module-path, with --show-module-resolution - // - Run from -cp only and with --show-module-resolution - // + archived boot layer module ModuleDescriptors should be used with - // --show-module-resolution (requires resolution) - // + archived boot layer Configuration should be disabled - System.out.println("----------------------- Test case 7 ----------------------"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "--show-module-resolution", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "yes", - "no"); - TestCommon.checkExec(output, "root java.base jrt:/java.base"); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleWithCustomImageTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleWithCustomImageTest.java index fbad2ed459f..410e60f2fe9 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleWithCustomImageTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedModuleWithCustomImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,6 @@ * @requires vm.cds.write.archived.java.heap * @requires vm.flagless * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox - * @compile CheckArchivedModuleApp.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar CheckArchivedModuleApp - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox * @run driver ArchivedModuleWithCustomImageTest */ @@ -99,8 +95,6 @@ public class ArchivedModuleWithCustomImageTest { private static void testArchivedModuleUsingImage(Path image) throws Throwable { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; String appJar = ClassFileInstaller.getJarPath("app.jar"); Path customJava = Paths.get(image.toString(), "bin", "java"); @@ -116,27 +110,6 @@ public class ArchivedModuleWithCustomImageTest { pbDump, "custom.runtime.image.dump"); TestCommon.checkDump(output); - // Test case 1): - // test archived module graph objects are used with custome runtime image - System.out.println("------------------- Test case 1 -------------------"); - String[] runCmd = {customJava.toString(), - use_whitebox_jar, - "-XX:SharedArchiveFile=./ArchivedModuleWithCustomImageTest.jsa", - "-cp", - appJar, - "-Xshare:on", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckArchivedModuleApp", - "yes", - "yes"}; - printCommand(runCmd); - ProcessBuilder pbRun = new ProcessBuilder(); - pbRun.command(runCmd); - output = TestCommon.executeAndLog(pbRun, "custom.runtime.image.run"); - output.shouldHaveExitValue(0); - - // Test case 2): // verify --show-module-resolution output System.out.println("------------------- Test case 2 -------------------"); @@ -147,7 +120,7 @@ public class ArchivedModuleWithCustomImageTest { "--show-module-resolution", "-version"}; printCommand(showModuleCmd1); - pbRun = new ProcessBuilder(); + ProcessBuilder pbRun = new ProcessBuilder(); pbRun.command(showModuleCmd1); output = TestCommon.executeAndLog( pbRun, "custom.runtime.image.showModuleResolution.nocds"); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java deleted file mode 100644 index e771d55828e..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckArchivedModuleApp.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2018, 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.io.File; -import java.lang.module.Configuration; -import java.lang.module.ModuleDescriptor; -import java.util.List; -import java.util.Set; -import jdk.test.whitebox.WhiteBox; - -// -// Test archived system module graph when open archive heap objects are mapped: -// -public class CheckArchivedModuleApp { - static WhiteBox wb; - public static void main(String args[]) throws Exception { - wb = WhiteBox.getWhiteBox(); - - if (!wb.areOpenArchiveHeapObjectsMapped()) { - System.out.println("Archived open_archive_heap objects are not mapped."); - System.out.println("This may happen during normal operation. Test Skipped."); - return; - } - - if (args.length != 2) { - throw new RuntimeException( - "FAILED. Incorrect argument length: " + args.length); - } - - boolean expectArchivedDescriptors = "yes".equals(args[0]); - boolean expectArchivedConfiguration = "yes".equals(args[1]); - // -XX:+EnableJVMCI adds extra system modules, in which case the system - // module objects are not archived. - Boolean enableJVMCI = wb.getBooleanVMFlag("EnableJVMCI"); - if (enableJVMCI != null && enableJVMCI) { - expectArchivedDescriptors = false; - expectArchivedConfiguration = false; - } - - checkModuleDescriptors(expectArchivedDescriptors); - checkConfiguration(expectArchivedConfiguration); - checkEmptyConfiguration(expectArchivedConfiguration); - checkEmptyLayer(); - } - - private static void checkModuleDescriptors(boolean expectArchivedDescriptors) { - Set modules = ModuleLayer.boot().modules(); - for (Module m : modules) { - ModuleDescriptor md = m.getDescriptor(); - String name = md.name(); - if (expectArchivedDescriptors) { - if (wb.isShared(md)) { - System.out.println(name + " is archived. Expected."); - } else { - throw new RuntimeException( - "FAILED. " + name + " is not archived. Expect archived."); - } - } else { - if (!wb.isShared(md)) { - System.out.println(name + " is not archived. Expected."); - } else { - throw new RuntimeException( - "FAILED. " + name + " is archived. Expect not archived."); - } - } - } - } - - private static void checkEmptyConfiguration(boolean expectArchivedConfiguration) { - // Configuration.EMPTY_CONFIGURATION uses the singletons, - // ListN.EMPTY_LIST, SetN.EMPTY_SET and MapN.EMPTY_MAP in - // ImmutableCollections for the 'parents', 'modules' and - // 'graph' fields. The ImmutableCollections singletons - // can be accessed via List.of(), Set.of() and Map.of() APIs. - // Configuration public APIs also allow access to the - // EMPTY_CONFIGURATION's 'parents' and 'modules'. When the - // archived java heap data is enabled at runtime, make sure - // the EMPTY_CONFIGURATION.parents and EMPTY_CONFIGURATION.modules - // are the archived ImmutableCollections singletons. - Configuration emptyCf = Configuration.empty(); - List emptyCfParents = emptyCf.parents(); - Set emptyCfModules = emptyCf.modules(); - if (expectArchivedConfiguration) { - if (emptyCfParents == List.of() && - wb.isShared(emptyCfParents)) { - System.out.println("Empty Configuration has expected parents."); - } else { - throw new RuntimeException( - "FAILED. Unexpected parents for empty Configuration."); - } - if (emptyCfModules == Set.of() && - wb.isShared(emptyCfModules)) { - System.out.println("Empty Configuration has expected module set."); - } else { - throw new RuntimeException( - "FAILED. Unexpected module set for empty Configuration."); - } - } - } - - - - private static void checkConfiguration(boolean expectArchivedConfiguration) { - Configuration cf = ModuleLayer.boot().configuration(); - - if (expectArchivedConfiguration) { - if (wb.isShared(cf)) { - System.out.println("Boot layer configuration is archived. Expected."); - } else { - throw new RuntimeException( - "FAILED. Boot layer configuration is not archived."); - } - } else { - if (!wb.isShared(cf)) { - System.out.println("Boot layer configuration is not archived. Expected."); - } else { - throw new RuntimeException( - "FAILED. Boot layer configuration is archived."); - } - } - } - - private static void checkEmptyLayer() { - // ModuleLayer.EMPTY_FIELD returned by empty() method is singleton. - // Check that with CDS there is still a single instance of EMPTY_LAYER - // and boot() layer parent is THE empty layer. - if (ModuleLayer.empty() != ModuleLayer.boot().parents().get(0)) { - throw new RuntimeException("FAILED. Empty module layer is not singleton"); - } - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorApp.java deleted file mode 100644 index 6e3a5a70cd3..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorApp.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2018, 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.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import jdk.test.whitebox.WhiteBox; - -// -// Test class mirror objects are cached when open archive heap objects are mapped: -// - Well-known shared library classes: -// java.lang.Object -// java.lang.String -// - Shared application class loaded by the system class loader -// - Shared application class loaded user defined class loader -// -public class CheckCachedMirrorApp { - static WhiteBox wb; - public static void main(String args[]) throws Exception { - String path = args[0]; - URL url = new File(path).toURI().toURL(); - URL[] urls = new URL[] {url}; - - URLClassLoader loader = new URLClassLoader(urls); - Class hello = loader.loadClass("Hello"); - System.out.println("Loaded " + hello + " from " + url + " using loader " + loader); - - wb = WhiteBox.getWhiteBox(); - - if (!wb.areOpenArchiveHeapObjectsMapped()) { - System.out.println("Archived open_archive_heap objects are not mapped."); - System.out.println("This may happen during normal operation. Test Skipped."); - return; - } - - // Well-known shared library classes - Class object_class = Object.class; - checkMirror(object_class, true); - Class string_class = String.class; - checkMirror(string_class, true); - - // Shared app class - Class app_class = CheckCachedMirrorApp.class; - checkMirror(app_class, true); - - // Hello is shared class and loaded by the 'loader' defined in current app. - // It should not have cached resolved_references. - Class class_with_user_defined_loader = hello; - checkMirror(class_with_user_defined_loader, false); - } - - static void checkMirror(Class c, boolean mirrorShouldBeArchived) { - System.out.print("Check cached mirror for " + c); - if (wb.isSharedClass(c)) { - // Check if the Class object is cached - if (mirrorShouldBeArchived && wb.isShared(c)) { - System.out.println(c + " mirror is cached. Expected."); - } else if (!mirrorShouldBeArchived && !wb.isShared(c)) { - System.out.println(c + " mirror is not cached. Expected."); - } else if (mirrorShouldBeArchived && !wb.isShared(c)) { - throw new RuntimeException( - "FAILED. " + c + " mirror is not cached."); - } else { - throw new RuntimeException( - "FAILED. " + c + " mirror should not be cached."); - } - } else { - System.out.println("Class " + c + "is not shared, skipping the check for mirror"); - } - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorTest.java deleted file mode 100644 index 8e8cfe51a75..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedMirrorTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - */ - -/* - * @test - * @summary Test archived mirror - * @requires vm.cds.write.archived.java.heap - * @requires vm.cds.custom.loaders - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox - * @compile CheckCachedMirrorApp.java - * @compile ../test-classes/Hello.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar CheckCachedMirrorApp - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox - * @run driver CheckCachedMirrorTest - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.helpers.ClassFileInstaller; -import jdk.test.whitebox.WhiteBox; - -public class CheckCachedMirrorTest { - public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = ClassFileInstaller.getJarPath("app.jar"); - String helloJarPath = ClassFileInstaller.getJarPath("hello.jar"); - - String classlist[] = new String[] { - "CheckCachedMirrorApp", // built-in app loader - "java/lang/Object id: 1", // boot loader - "Hello id: 2 super: 1 source: " + helloJarPath // custom loader - }; - - TestCommon.testDump(appJar, classlist, use_whitebox_jar); - OutputAnalyzer output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-Xlog:cds=debug", - "CheckCachedMirrorApp", - helloJarPath); - TestCommon.checkExec(output); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferences.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferences.java deleted file mode 100644 index a8186bf4a20..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferences.java +++ /dev/null @@ -1,65 +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. - * - */ - -/* - * @test - * @summary Test resolved_references - * @requires vm.cds - * @requires vm.cds.custom.loaders - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox - * @compile CheckCachedResolvedReferencesApp.java - * @compile ../test-classes/Hello.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar CheckCachedResolvedReferencesApp - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox - * @run driver CheckCachedResolvedReferences - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.helpers.ClassFileInstaller; -import jdk.test.whitebox.WhiteBox; - -public class CheckCachedResolvedReferences { - public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = ClassFileInstaller.getJarPath("app.jar"); - String helloJarPath = ClassFileInstaller.getJarPath("hello.jar"); - - String classlist[] = new String[] { - "CheckCachedResolvedReferencesApp", // built-in app loader - "java/lang/Object id: 1", // boot loader - "Hello id: 2 super: 1 source: " + helloJarPath // custom loader - }; - - TestCommon.testDump(appJar, classlist, use_whitebox_jar); - OutputAnalyzer output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "CheckCachedResolvedReferencesApp", - helloJarPath); - TestCommon.checkExec(output); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferencesApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferencesApp.java deleted file mode 100644 index e9e7ff6172f..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckCachedResolvedReferencesApp.java +++ /dev/null @@ -1,77 +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. - * - */ - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import jdk.test.whitebox.WhiteBox; - -public class CheckCachedResolvedReferencesApp { - public static void main(String args[]) throws Exception { - String path = args[0]; - URL url = new File(path).toURI().toURL(); - URL[] urls = new URL[] {url}; - - URLClassLoader loader = new URLClassLoader(urls); - Class hello = loader.loadClass("Hello"); - System.out.println("Loaded " + hello + " from " + url + " using loader " + loader); - - WhiteBox wb = WhiteBox.getWhiteBox(); - - if (!wb.areOpenArchiveHeapObjectsMapped()) { - System.out.println("Archived open_archive_heap objects are not mapped."); - System.out.println("This may happen during normal operation. Test Skipped."); - return; - } - - // CheckCachedResolvedReferencesApp is shared class and loaded by the - // AppClassLoader. It should have cached resolved_references. - if (wb.isSharedClass(CheckCachedResolvedReferencesApp.class)) { - Object refs1 = wb.getResolvedReferences(CheckCachedResolvedReferencesApp.class); - if (refs1 != null && wb.isShared(refs1)) { - System.out.println( - "resolved references from CheckCachedResolvedReferencesApp is cached"); - } else { - throw new RuntimeException( - "FAILED. CheckCachedResolvedReferencesApp has no cached resolved references"); - } - } - - // Hello is shared class and loaded by the 'loader' defined in current app. - // It should not have cached resolved_references. - if (wb.isSharedClass(hello)) { - Object refs2 = wb.getResolvedReferences(hello); - if (refs2 != null) { - if (!wb.isShared(refs2)) { - System.out.println("resolved references from hello is not cached"); - } else { - throw new RuntimeException( - "FAILED. Hello has unexpected cached resolved references"); - } - } else { - throw new RuntimeException("FAILED. Hello has no resolved references"); - } - } - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckIntegerCacheApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckIntegerCacheApp.java index 1e821595555..a1d1655b32f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckIntegerCacheApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/CheckIntegerCacheApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,35 +22,18 @@ * */ -import jdk.test.whitebox.WhiteBox; - // // Help test archived box cache consistency. // -// Takes two arguments: -// 0: the expected maximum value expected to be archived -// 1: if the values are expected to be retrieved from the archive or not -// (only applies to IntegerCache; other caches should always be mapped -// from archive) +// args[0]: the expected maximum value expected to be archived // public class CheckIntegerCacheApp { - static WhiteBox wb; - public static void main(String[] args) throws Exception { - wb = WhiteBox.getWhiteBox(); - - if (!wb.areOpenArchiveHeapObjectsMapped()) { - System.out.println("This may happen during normal operation. Test Skipped."); - return; - } - - if (args.length != 2) { + if (args.length != 1) { throw new RuntimeException( "FAILED. Incorrect argument length: " + args.length); } - boolean archivedExpected = Boolean.parseBoolean(args[1]); - // Base JLS compliance check for (int i = -128; i <= 127; i++) { if (Integer.valueOf(i) != Integer.valueOf(i)) { @@ -69,10 +52,6 @@ public class CheckIntegerCacheApp { throw new RuntimeException( "FAILED. All Long values in range [-128, 127] should be interned in cache: " + i); } - checkArchivedAsExpected(archivedExpected, Integer.valueOf(i)); - checkArchivedAsExpected(true, Byte.valueOf((byte)i)); - checkArchivedAsExpected(true, Short.valueOf((short)i)); - checkArchivedAsExpected(true, Long.valueOf(i)); // Character cache only values 0 through 127 if (i >= 0) { @@ -80,7 +59,6 @@ public class CheckIntegerCacheApp { throw new RuntimeException( "FAILED. All Character values in range [0, 127] should be interned in cache: " + i); } - checkArchivedAsExpected(true, Character.valueOf((char)i)); } } @@ -89,31 +67,10 @@ public class CheckIntegerCacheApp { throw new RuntimeException( "FAILED. Value expected to be retrieved from cache: " + high); } - checkArchivedAsExpected(archivedExpected, Integer.valueOf(high)); if (Integer.valueOf(high + 1) == Integer.valueOf(high + 1)) { throw new RuntimeException( "FAILED. Value not expected to be retrieved from cache: " + high); } - checkArchivedAsExpected(false, Integer.valueOf(high + 1)); - checkArchivedAsExpected(false, Short.valueOf((short)128)); - checkArchivedAsExpected(false, Long.valueOf(128)); - checkArchivedAsExpected(false, Character.valueOf((char)128)); - } - - private static void checkArchivedAsExpected(boolean archivedExpected, Object value) { - if (archivedExpected) { - if (!wb.isShared(value)) { - throw new RuntimeException( - "FAILED. Value expected to be archived: " + value + - " of type " + value.getClass().getName()); - } - } else { - if (wb.isShared(value)) { - throw new RuntimeException( - "FAILED. Value not expected to be archived: " + value + - " of type " + value.getClass().getName()); - } - } } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressApp.java deleted file mode 100644 index c4ef60c8dfe..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressApp.java +++ /dev/null @@ -1,94 +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. - * - */ - -import java.io.*; -import java.util.*; -import jdk.test.lib.Utils; -import jdk.test.whitebox.WhiteBox; - -// All strings in archived classes are shared -public class GCStressApp { - static WhiteBox wb = WhiteBox.getWhiteBox(); - static int[] arr; - - static String get_shared_string() { - String shared_str = "GCStressApp_shared_string"; - return shared_str; - } - - static String get_shared_string1() { - String shared_str1 = "GCStressApp_shared_string1"; - return shared_str1; - } - - static void allocAlot() { - try { - Random random = Utils.getRandomInstance(); - for (int i = 0; i < 1024 * 1024; i++) { - int len = random.nextInt(10000); - arr = new int[len]; - } - } catch (java.lang.OutOfMemoryError e) { } - } - - static void runGC() { - wb.fullGC(); - } - - public static void main(String args[]) throws Exception { - if (!wb.isSharedClass(GCStressApp.class)) { - System.out.println("GCStressApp is not shared. Possibly there was a mapping failure."); - return; - } - - if (!wb.areSharedStringsMapped()) { - System.out.println("Shared strings are not mapped."); - return; - } - - Object refs = wb.getResolvedReferences(GCStressApp.class); - if (wb.isShared(refs)) { - String shared_str = get_shared_string(); - String shared_str1 = get_shared_string1(); - - if (!wb.isShared(shared_str)) { - throw new RuntimeException("FAILED. GCStressApp_shared_string is not shared"); - } - - if (!wb.isShared(shared_str1)) { - throw new RuntimeException("FAILED. GCStressApp_shared_string1 is not shared"); - } - - allocAlot(); - runGC(); - runGC(); - runGC(); - - System.out.println("Passed"); - } else { - System.out.println( - "No cached resolved references. Open archive heap data is not used."); - } - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressTest.java deleted file mode 100644 index 68811a841b0..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/GCStressTest.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. - * - */ - -/* - * @test - * @key randomness - * @summary - * @requires vm.cds.write.archived.java.heap - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox jdk.test.lib.Utils - * @compile GCStressApp.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar gcstress.jar GCStressApp jdk.test.lib.Utils - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox - * @run driver GCStressTest - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.helpers.ClassFileInstaller; - -public class GCStressTest { - public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = ClassFileInstaller.getJarPath("gcstress.jar"); - String appClasses[] = TestCommon.list("GCStressApp"); - - OutputAnalyzer output = TestCommon.dump(appJar, appClasses, - use_whitebox_jar, - "-Xms20M", "-Xmx20M"); - output = TestCommon.exec(appJar, use_whitebox_jar, - "-Xlog:cds=info", - "-Xms20M", "-Xmx20M", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI","GCStressApp"); - TestCommon.checkExec(output); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/MirrorWithReferenceFieldsApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/MirrorWithReferenceFieldsApp.java index 279f4126425..9e4558002cc 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/MirrorWithReferenceFieldsApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/MirrorWithReferenceFieldsApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,17 +64,7 @@ public class MirrorWithReferenceFieldsApp { public void test(WhiteBox wb) { Class c = MirrorWithReferenceFieldsApp.class; if (wb.isSharedClass(c)) { - // Check if the Class object is cached - if (wb.isShared(c)) { - System.out.println(c + " mirror is cached. Expected."); - } else { - throw new RuntimeException( - "FAILED. " + c + " mirror should be cached."); - } - - // Check fields - - if (wb.isShared(archived_field)) { + if (wb.isSharedInternedString(archived_field)) { System.out.println("archived_field is archived as excepted"); } else { throw new RuntimeException( diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/OpenArchiveRegion.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/OpenArchiveRegion.java index 2f24f589c0e..5f59b766442 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/OpenArchiveRegion.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/OpenArchiveRegion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -45,8 +45,8 @@ public class OpenArchiveRegion { // Dump with open archive heap region, requires G1 GC OutputAnalyzer output = TestCommon.dump(appJar, appClasses, "-Xlog:cds=debug"); - TestCommon.checkDump(output, "oa0 space:"); - output.shouldNotContain("oa0 space: 0 ["); + TestCommon.checkDump(output, "hp space:"); + output.shouldNotContain("hp space: 0 ["); output = TestCommon.exec(appJar, "Hello"); TestCommon.checkExec(output, "Hello World"); output = TestCommon.exec(appJar, "-XX:+UseSerialGC", "Hello"); @@ -55,7 +55,7 @@ public class OpenArchiveRegion { // Dump with open archive heap region disabled when G1 GC is not in use output = TestCommon.dump(appJar, appClasses, "-XX:+UseParallelGC"); TestCommon.checkDump(output); - output.shouldNotContain("oa0 space:"); + output.shouldNotContain("hp space:"); output = TestCommon.exec(appJar, "Hello"); TestCommon.checkExec(output, "Hello World"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesApp.java deleted file mode 100644 index aada968ed1b..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesApp.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2018, 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.reflect.Field; -import jdk.test.whitebox.WhiteBox; - -// -// Test primitive type class mirror objects are cached when open archive heap -// objects are mapped. -// -public class PrimitiveTypesApp { - public static void main(String[] args) { - WhiteBox wb = WhiteBox.getWhiteBox(); - if (!wb.areOpenArchiveHeapObjectsMapped()) { - System.out.println("Archived open_archive_heap objects are not mapped."); - System.out.println("This may happen during normal operation. Test Skipped."); - return; - } - - FieldsTest ft = new FieldsTest(); - ft.testBoolean(wb); - ft.testByte(wb); - ft.testChar(wb); - ft.testInt(wb); - ft.testShort(wb); - ft.testLong(wb); - ft.testFloat(wb); - ft.testDouble(wb); - } -} - -class FieldsTest { - public boolean f_boolean; - public byte f_byte; - public char f_char; - public int f_int; - public short f_short; - public long f_long; - public float f_float; - public double f_double; - - FieldsTest() { - f_byte = 1; - f_boolean = false; - f_char = 'a'; - f_int = 1; - f_short = 100; - f_long = 2018L; - f_float = 1.0f; - f_double = 2.5; - } - - void testBoolean(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_boolean"); - f.setBoolean(this, true); - if (!f_boolean) { - throw new RuntimeException("FAILED. Field f_boolean has unexpected value: " + f_boolean); - } - checkPrimitiveType(wb, f, Boolean.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testByte(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_byte"); - f.setByte(this, (byte)9); - if (f_byte != (byte)9) { - throw new RuntimeException("FAILED. Field f_byte has unexpected value: " + f_byte); - } - checkPrimitiveType(wb, f, Byte.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testChar(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_char"); - f.setChar(this, 'b'); - if (f_char != 'b') { - throw new RuntimeException("FAILED. Field f_char has unexpected value: " + f_char); - } - checkPrimitiveType(wb, f, Character.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testInt(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_int"); - f.setInt(this, 9999); - if (f_int != 9999) { - throw new RuntimeException("FAILED. Field f_int has unexpected value: " + f_int); - } - checkPrimitiveType(wb, f, Integer.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testShort(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_short"); - f.setShort(this, (short)99); - if (f_short != 99) { - throw new RuntimeException("FAILED. Field f_short has unexpected value: " + f_short); - } - checkPrimitiveType(wb, f, Short.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testLong(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_long"); - f.setLong(this, 99L); - if (f_long != 99L) { - throw new RuntimeException("FAILED. Field f_long has unexpected value: " + f_long); - } - checkPrimitiveType(wb, f, Long.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testFloat(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_float"); - f.setFloat(this, 9.9f); - if (f_float != 9.9f) { - throw new RuntimeException("FAILED. Field f_float has unexpected value: " + f_float); - } - checkPrimitiveType(wb, f, Float.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void testDouble(WhiteBox wb) { - try { - Field f = this.getClass().getDeclaredField("f_double"); - f.setDouble(this, 9.9); - if (f_double != 9.9) { - throw new RuntimeException("FAILED. Field f_double has unexpected value: " + f_double); - } - checkPrimitiveType(wb, f, Double.TYPE); - } catch (NoSuchFieldException nsfe) { - throw new RuntimeException(nsfe); - } catch (IllegalAccessException iae) { - throw new RuntimeException(iae); - } - } - - void checkPrimitiveType(WhiteBox wb, Field f, Class t) { - Class c = f.getType(); - if (!(c.isPrimitive() && c == t)) { - throw new RuntimeException("FAILED. " + c + " is not primitive type " + t); - } - if (wb.isShared(c)) { - System.out.println(c + " is cached, expected"); - } else { - throw new RuntimeException("FAILED. " + c + " is not cached."); - } - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesTest.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesTest.java deleted file mode 100644 index f94ea15f8b1..00000000000 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/PrimitiveTypesTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2018, 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. - * - */ - -/* - * @test - * @summary Test archived primitive type mirrors - * @requires vm.cds.write.archived.java.heap - * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds - * @build jdk.test.whitebox.WhiteBox - * @compile PrimitiveTypesApp.java - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar PrimitiveTypesApp FieldsTest - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox - * @run driver PrimitiveTypesTest - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.helpers.ClassFileInstaller; -import jdk.test.whitebox.WhiteBox; - -public class PrimitiveTypesTest { - public static void main(String[] args) throws Exception { - String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar"); - String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = ClassFileInstaller.getJarPath("app.jar"); - - String classlist[] = new String[] { - "PrimitiveTypesApp", - "FieldsTest" - }; - - TestCommon.testDump(appJar, classlist, use_whitebox_jar); - OutputAnalyzer output = TestCommon.exec(appJar, use_whitebox_jar, - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-XX:+VerifyAfterGC", - "PrimitiveTypesApp"); - TestCommon.checkExec(output); - } -} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/RedefineClassApp.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/RedefineClassApp.java index 535aa169e96..e247a8158f7 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/RedefineClassApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/RedefineClassApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -91,7 +91,7 @@ public class RedefineClassApp { static void checkArchivedMirrorObject(Class klass) { if (wb.areOpenArchiveHeapObjectsMapped()) { - if (!wb.isShared(klass)) { + if (!wb.isSharedClass(klass)) { failed ++; System.out.println("FAILED. " + klass + " mirror object is not archived"); return; @@ -117,14 +117,10 @@ public class RedefineClassApp { // Call get() before redefine. All strings in archived classes are shared. String res = object.get(); System.out.println("get() returns " + res); - if (res.equals("buzz") && wb.isShared(res)) { - System.out.println("get() returns " + res + ", string is shared"); + if (res.equals("buzz")) { + System.out.println("get() returns " + res); } else { - if (!res.equals("buzz")) { - System.out.println("FAILED. buzz is expected but got " + res); - } else { - System.out.println("FAILED. " + res + " is not shared"); - } + System.out.println("FAILED. buzz is expected but got " + res); failed ++; return; } diff --git a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java index 5cf07cc2c42..38748ec432b 100644 --- a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -75,10 +75,7 @@ public class CDSArchiveUtils { "rw", // ReadWrite "ro", // ReadOnly "bm", // relocation bitmaps - "first_closed_archive", - "last_closed_archive", - "first_open_archive", - "last_open_archive" + "hp", // heap }; private static int num_regions = shared_region_name.length; diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 9481dec801f..a0cb42d4657 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -688,7 +688,6 @@ public class WhiteBox { public native String getDefaultArchivePath(); public native boolean cdsMemoryMappingFailed(); public native boolean isSharingEnabled(); - public native boolean isShared(Object o); public native boolean isSharedClass(Class c); public native boolean areSharedStringsMapped(); public native boolean isSharedInternedString(String s); @@ -696,7 +695,6 @@ public class WhiteBox { public native boolean isJFRIncluded(); public native boolean isDTraceIncluded(); public native boolean canWriteJavaHeapArchive(); - public native Object getResolvedReferences(Class c); public native void linkClass(Class c); public native boolean areOpenArchiveHeapObjectsMapped(); From 117c5b116b0c4e98ad34b3ddd3af844ed247ea09 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 21 Apr 2023 19:17:39 +0000 Subject: [PATCH 084/288] 8279216: Investigate implementation of premultiplied alpha in the Little-CMS 2.13 Reviewed-by: prr --- .../sun/java2d/cmm/lcms/LCMSImageLayout.java | 45 ++- .../sun/java2d/cmm/lcms/LCMSTransform.java | 20 +- .../ColCvtAlphaDifferentSrcDst.java | 126 ++++++++- .../ColorConvertOp/PremultipliedAlpha.java | 264 ++++++++++++++++++ .../cmm/ColorConvertOp/SkipSampleModel.java | 83 ++++++ 5 files changed, 508 insertions(+), 30 deletions(-) create mode 100644 test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java create mode 100644 test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java index 8101c568d0b..d2da59617f1 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java @@ -52,16 +52,22 @@ final class LCMSImageLayout { static int CHANNELS_SH(int x) { return x << 3; } + + static int PREMUL_SH(int x) { + return x << 23; + } private static final int SWAPFIRST = 1 << 14; private static final int DOSWAP = 1 << 10; - private static final int PT_GRAY_8 = CHANNELS_SH(1) | BYTES_SH(1); - private static final int PT_GRAY_16 = CHANNELS_SH(1) | BYTES_SH(2); - private static final int PT_RGB_8 = CHANNELS_SH(3) | BYTES_SH(1); - private static final int PT_RGBA_8 = PT_RGB_8 | EXTRA_SH(1); - private static final int PT_ARGB_8 = PT_RGBA_8 | SWAPFIRST; - private static final int PT_BGR_8 = PT_RGB_8 | DOSWAP; - private static final int PT_ABGR_8 = PT_BGR_8 | EXTRA_SH(1); -// private static final int PT_BGRA_8 = PT_ABGR_8 | SWAPFIRST; + private static final int PT_GRAY_8 = CHANNELS_SH(1) | BYTES_SH(1); + private static final int PT_GRAY_16 = CHANNELS_SH(1) | BYTES_SH(2); + private static final int PT_RGB_8 = CHANNELS_SH(3) | BYTES_SH(1); + private static final int PT_RGBA_8 = PT_RGB_8 | EXTRA_SH(1); + private static final int PT_ARGB_8 = PT_RGBA_8 | SWAPFIRST; + private static final int PT_ARGB_8_PREMUL = PT_ARGB_8 | PREMUL_SH(1); + private static final int PT_BGR_8 = PT_RGB_8 | DOSWAP; + private static final int PT_ABGR_8 = PT_BGR_8 | EXTRA_SH(1); + private static final int PT_ABGR_8_PREMUL = PT_ABGR_8 | PREMUL_SH(1); +// private static final int PT_BGRA_8 = PT_ABGR_8 | SWAPFIRST; private static final int SWAP_ENDIAN = ByteOrder.nativeOrder() == LITTLE_ENDIAN ? DOSWAP : 0; private static final int DT_BYTE = 0; @@ -148,6 +154,9 @@ final class LCMSImageLayout { case BufferedImage.TYPE_INT_RGB: l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN; break; + case BufferedImage.TYPE_INT_ARGB_PRE: + l.pixelType = PT_ARGB_8_PREMUL ^ SWAP_ENDIAN; + break; case BufferedImage.TYPE_INT_ARGB: l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN; break; @@ -160,6 +169,9 @@ final class LCMSImageLayout { case BufferedImage.TYPE_4BYTE_ABGR: l.pixelType = PT_ABGR_8; break; + case BufferedImage.TYPE_4BYTE_ABGR_PRE: + l.pixelType = PT_ABGR_8_PREMUL; + break; case BufferedImage.TYPE_BYTE_GRAY: l.pixelType = PT_GRAY_8; break; @@ -172,10 +184,7 @@ final class LCMSImageLayout { * has to be supported. */ ColorModel cm = image.getColorModel(); - // lcms as of now does not support pre-alpha - if (!cm.isAlphaPremultiplied() - && cm instanceof ComponentColorModel ccm) - { + if (cm instanceof ComponentColorModel ccm) { // verify whether the component size is fine int[] cs = ccm.getComponentSize(); for (int s : cs) { @@ -183,7 +192,7 @@ final class LCMSImageLayout { return null; } } - return createImageLayout(image.getRaster(), cm.hasAlpha()); + return createImageLayout(image.getRaster(), cm); } return null; } @@ -194,6 +203,7 @@ final class LCMSImageLayout { switch (image.getType()) { case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_ARGB: + case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_BGR: do { IntegerComponentRaster intRaster = (IntegerComponentRaster) @@ -209,13 +219,14 @@ final class LCMSImageLayout { case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_4BYTE_ABGR: + case BufferedImage.TYPE_4BYTE_ABGR_PRE: do { ByteComponentRaster byteRaster = (ByteComponentRaster) image.getRaster(); l.nextRowOffset = byteRaster.getScanlineStride(); l.nextPixelOffset = byteRaster.getPixelStride(); - int firstBand = image.getSampleModel().getNumBands() - 1; + int firstBand = byteRaster.getSampleModel().getNumBands() - 1; l.offset = byteRaster.getDataOffset(firstBand); l.dataArray = byteRaster.getDataStorage(); l.dataArrayLength = byteRaster.getDataStorage().length; @@ -320,7 +331,7 @@ final class LCMSImageLayout { return checkIndex(res, Integer.MAX_VALUE); } - static LCMSImageLayout createImageLayout(Raster r, boolean hasAlpha) { + static LCMSImageLayout createImageLayout(Raster r, ColorModel cm) { LCMSImageLayout l = new LCMSImageLayout(); if (r instanceof ByteComponentRaster && r.getSampleModel() instanceof ComponentSampleModel) { @@ -329,8 +340,12 @@ final class LCMSImageLayout { ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel(); int numBands = br.getNumBands(); + boolean hasAlpha = cm != null && cm.hasAlpha(); l.pixelType = (hasAlpha ? CHANNELS_SH(numBands - 1) | EXTRA_SH(1) : CHANNELS_SH(numBands)) | BYTES_SH(1); + if (hasAlpha && cm.isAlphaPremultiplied()) { + l.pixelType |= PREMUL_SH(1); + } int[] bandOffsets = csm.getBandOffsets(); BandOrder order = BandOrder.getBandOrder(bandOffsets); diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index 0d26022617d..077b940d4ca 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -127,19 +127,15 @@ final class LCMSTransform implements ColorTransform { } /** - * Returns {@code true} if lcms may supports this format directly. + * Returns {@code true} if lcms may support this format directly. */ private static boolean isLCMSSupport(BufferedImage src, BufferedImage dst) { - if (!dst.getColorModel().hasAlpha()) { - return true; - } - // lcms as of now does not support pre-alpha - if (src.isAlphaPremultiplied() || dst.isAlphaPremultiplied()) { - return false; - } + boolean dstAlpha = dst.getColorModel().hasAlpha(); + boolean srcAlpha = src.getColorModel().hasAlpha(); + boolean srcPre = srcAlpha && src.getColorModel().isAlphaPremultiplied(); + // lcms does not convert pre-alpha for transparent src if dst is opaque // lcms does not set correct alpha for transparent dst if src is opaque - // is it feature or bug? - return dst.getColorModel().hasAlpha() == src.getColorModel().hasAlpha(); + return !dstAlpha && !srcPre || dstAlpha == srcAlpha; } public void colorConvert(BufferedImage src, BufferedImage dst) { @@ -424,9 +420,9 @@ final class LCMSTransform implements ColorTransform { public void colorConvert(Raster src, WritableRaster dst) { LCMSImageLayout srcIL, dstIL; - dstIL = LCMSImageLayout.createImageLayout(dst, false); + dstIL = LCMSImageLayout.createImageLayout(dst, null); if (dstIL != null) { - srcIL = LCMSImageLayout.createImageLayout(src, false); + srcIL = LCMSImageLayout.createImageLayout(src, null); if (srcIL != null) { doTransform(srcIL, dstIL); return; diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java index 94a18b2a65b..31db9d1a380 100644 --- a/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java @@ -23,11 +23,18 @@ import java.awt.AlphaComposite; import java.awt.Graphics2D; +import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_Profile; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR; import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR; @@ -45,7 +52,7 @@ import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY; /* * @test - * @bug 8012229 8300725 + * @bug 8012229 8300725 8279216 * @summary one more test to check the alpha channel */ public final class ColCvtAlphaDifferentSrcDst { @@ -53,11 +60,19 @@ public final class ColCvtAlphaDifferentSrcDst { private static final int WIDTH = 256; private static final int HEIGHT = 256; + private static final int TYPE_CUSTOM_4BYTE_ABGR_PRE = -1; + private static final int TYPE_CUSTOM_4BYTE_ARGB_PRE = -2; + private static final int TYPE_CUSTOM_4BYTE_RGBA_PRE = -3; + private static final int TYPE_CUSTOM_4BYTE_GABR_PRE = -4; + private static final int TYPE_CUSTOM_INT_ARGB_PRE = -5; + private static final int TYPE_CUSTOM_INT_GABR_PRE = -6; + public static void main(String[] args) throws Exception { differentToOpaqueDst(); differentToTransparentDst(TYPE_INT_ARGB); differentToTransparentDst(TYPE_4BYTE_ABGR); differentToTransparentDst(TYPE_INT_ARGB_PRE); + differentToTransparentDst(TYPE_4BYTE_ABGR_PRE); differentToNullDst(); } @@ -97,7 +112,16 @@ public final class ColCvtAlphaDifferentSrcDst { opaqueDst(TYPE_INT_ARGB, TYPE_INT_BGR); opaqueDst(TYPE_4BYTE_ABGR, TYPE_INT_BGR); - // It is unclear how to hangle pre colors in the opaque DST + // compare the "fast" and "slow" paths + opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ABGR_PRE); + opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ARGB_PRE); + opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_RGBA_PRE); + opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_GABR_PRE); + + opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_ARGB_PRE); + opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_GABR_PRE); + + // It is unclear how to handle pre colors in the opaque DST //opaqueDst(TYPE_INT_ARGB_PRE, TYPE_4BYTE_ABGR_PRE); //opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_INT_BGR); } @@ -196,7 +220,15 @@ public final class ColCvtAlphaDifferentSrcDst { } private static BufferedImage createSrc(int type) { - BufferedImage img = new BufferedImage(WIDTH, HEIGHT, type); + BufferedImage img = switch (type) { + case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE(); + case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE(); + case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE(); + case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE(); + case TYPE_CUSTOM_INT_ARGB_PRE -> TYPE_INT_ARGB_PRE(); + case TYPE_CUSTOM_INT_GABR_PRE -> TYPE_INT_GABR_PRE(); + default -> new BufferedImage(WIDTH, HEIGHT, type); + }; fill(img); return img; } @@ -220,4 +252,92 @@ public final class ColCvtAlphaDifferentSrcDst { } } } + + private static BufferedImage TYPE_4BYTE_RGBA_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {0, 1, 2, 3}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + WIDTH, HEIGHT, + WIDTH * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_ABGR_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {3, 2, 1, 0}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + WIDTH, HEIGHT, + WIDTH * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_ARGB_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {1, 2, 3, 0}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + WIDTH, HEIGHT, + WIDTH * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_GABR_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {3, 0, 2, 1}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + WIDTH, HEIGHT, + WIDTH * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_INT_ARGB_PRE() { + ColorModel colorModel = new DirectColorModel( + ColorSpace.getInstance(ColorSpace.CS_sRGB), + 32, + 0x00ff0000, // Red + 0x0000ff00, // Green + 0x000000ff, // Blue + 0xff000000, // Alpha + true, // Alpha Premultiplied + DataBuffer.TYPE_INT + ); + WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH, + HEIGHT); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_INT_GABR_PRE() { + ColorModel colorModel = new DirectColorModel( + ColorSpace.getInstance(ColorSpace.CS_sRGB), + 32, + 0x000000ff, // Red + 0xff000000, // Green + 0x0000ff00, // Blue + 0x00ff0000, // Alpha + true, // Alpha Premultiplied + DataBuffer.TYPE_INT + ); + WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH, + HEIGHT); + return new BufferedImage(colorModel, raster, true, null); + } } diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java new file mode 100644 index 00000000000..08e072cdb77 --- /dev/null +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/PremultipliedAlpha.java @@ -0,0 +1,264 @@ +/* + * 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.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.util.Arrays; + +import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE; +import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE; + +/** + * @test + * @bug 8279216 + * @summary Verifies implementation of premultiplied alpha + */ +public final class PremultipliedAlpha { + + private static final int SIZE = 256; + + private static final int COLOR_TOLERANCE = 2; + + private enum Type { + TYPE_ARGB_PRE, + TYPE_4BYTE_ABGR_PRE, + TYPE_CUSTOM_ARGB_PRE, + TYPE_CUSTOM_GABR_PRE, + TYPE_CUSTOM_4BYTE_ABGR_PRE, + TYPE_CUSTOM_4BYTE_ARGB_PRE, + TYPE_CUSTOM_4BYTE_RGBA_PRE, + TYPE_CUSTOM_4BYTE_GABR_PRE, + TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE, + TYPE_CUSTOM_4INT_8bit_ARGB_PRE, + } + + private static final ColorSpace[] CSs = { + ColorSpace.getInstance(ColorSpace.CS_CIEXYZ), + ColorSpace.getInstance(ColorSpace.CS_GRAY), + ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), + ColorSpace.getInstance(ColorSpace.CS_PYCC), + ColorSpace.getInstance(ColorSpace.CS_sRGB) + }; + + public static void main(String[] args) { + for (ColorSpace cs : CSs) { + for (Type dst : Type.values()) { + BufferedImage gold = null; + for (Type src : Type.values()) { + BufferedImage from = createSrc(src); + BufferedImage to = createDst(dst); + ColorConvertOp op = new ColorConvertOp(cs, null); + op.filter(from, to); + if (gold == null) { + gold = to; + } else { + validate(gold, to); + } + } + } + } + } + + private static void validate(BufferedImage img1, BufferedImage img2) { + for (int a = 0; a < SIZE; a++) { + for (int c = 0; c < SIZE; c++) { + int[] pixel1 = img1.getRaster().getPixel(c, a, (int[]) null); + int[] pixel2 = img2.getRaster().getPixel(c, a, (int[]) null); + if (pixel1.length != pixel2.length) { + throw new RuntimeException(); + } + for (int i = 0 ; i < pixel1.length; ++i) { + if (Math.abs(pixel1[i] - pixel2[i]) >= COLOR_TOLERANCE) { + System.out.println("c = " + c); + System.out.println("a = " + a); + System.err.println("rgb1 = " + Arrays.toString(pixel1)); + System.err.println("rgb2 = " + Arrays.toString(pixel2)); + throw new RuntimeException(); + } + } + } + } + } + + private static BufferedImage createDst(Type type) { + BufferedImage img = createSrc(type); + Graphics2D g = img.createGraphics(); + g.setComposite(AlphaComposite.Clear); + g.fillRect(0, 0, SIZE, SIZE); + g.dispose(); + return img; + } + + private static BufferedImage createSrc(Type type) { + BufferedImage bi = switch (type) { + case TYPE_ARGB_PRE -> new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB_PRE); + case TYPE_CUSTOM_ARGB_PRE -> TYPE_ARGB_PRE(); + case TYPE_CUSTOM_GABR_PRE -> TYPE_GABR_PRE(); + case TYPE_4BYTE_ABGR_PRE -> new BufferedImage(SIZE, SIZE, TYPE_4BYTE_ABGR_PRE); + case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE(); + case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE(); + case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE(); + case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE(); + case TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE -> TYPE_4USHORT_ARGB_8bit_PRE(); + case TYPE_CUSTOM_4INT_8bit_ARGB_PRE -> TYPE_4INT_ARGB_8bit_PRE(); + }; + fill(bi); + return bi; + } + + private static BufferedImage TYPE_ARGB_PRE() { + ColorModel colorModel = new DirectColorModel( + ColorSpace.getInstance(ColorSpace.CS_sRGB), + 32, + 0x00ff0000, // Red + 0x0000ff00, // Green + 0x000000ff, // Blue + 0xff000000, // Alpha + true, // Alpha Premultiplied + DataBuffer.TYPE_INT + ); + WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE, + SIZE); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_GABR_PRE() { + ColorModel colorModel = new DirectColorModel( + ColorSpace.getInstance(ColorSpace.CS_sRGB), + 32, + 0x000000ff, // Red + 0xff000000, // Green + 0x0000ff00, // Blue + 0x00ff0000, // Alpha + true, // Alpha Premultiplied + DataBuffer.TYPE_INT + ); + WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE, + SIZE); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_RGBA_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {0, 1, 2, 3}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + SIZE, SIZE, + SIZE * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_ABGR_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {3, 2, 1, 0}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + SIZE, SIZE, + SIZE * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_ARGB_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {1, 2, 3, 0}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + SIZE, SIZE, + SIZE * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4BYTE_GABR_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int[] bOffs = {3, 0, 2, 1}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, + SIZE, SIZE, + SIZE * 4, 4, + bOffs, null); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4INT_ARGB_8bit_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_INT); + WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE, + SIZE); + return new BufferedImage(colorModel, raster, true, null); + } + + private static BufferedImage TYPE_4USHORT_ARGB_8bit_PRE() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true, + Transparency.TRANSLUCENT, + DataBuffer.TYPE_USHORT); + WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE, + SIZE); + return new BufferedImage(colorModel, raster, true, null); + } + + private static void fill(BufferedImage image) { +// Graphics2D g = image.createGraphics(); +// g.setComposite(AlphaComposite.Src); + for (int a = 0; a < SIZE; ++a) { + for (int c = 0; c < SIZE; ++c) { + Color c1 = new Color(a, c, c, a); +// g.setColor(c1); +//TODO CANNOT USE fillrect, does not work for custom types! +// g.fillRect(c, a, 1, 1); + image.setRGB(c,a , c1.getRGB()); + } + } +// g.dispose(); + } +} diff --git a/test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java b/test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java new file mode 100644 index 00000000000..75609634d1b --- /dev/null +++ b/test/jdk/sun/java2d/cmm/ColorConvertOp/SkipSampleModel.java @@ -0,0 +1,83 @@ +/* + * 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.image.BufferedImage; +import java.awt.image.ColorConvertOp; +import java.awt.image.SampleModel; + +/** + * @test + * @bug 8279216 + * @summary behavior checked by this test is not specified, this test just + * defends against accidental changes + */ +public final class SkipSampleModel { + + private static int[] TYPES = { + BufferedImage.TYPE_INT_RGB, + BufferedImage.TYPE_INT_ARGB, + BufferedImage.TYPE_INT_ARGB_PRE, + BufferedImage.TYPE_INT_BGR, + BufferedImage.TYPE_3BYTE_BGR, + BufferedImage.TYPE_4BYTE_ABGR, + BufferedImage.TYPE_4BYTE_ABGR_PRE, + BufferedImage.TYPE_USHORT_565_RGB, + BufferedImage.TYPE_USHORT_555_RGB, + BufferedImage.TYPE_BYTE_GRAY, + BufferedImage.TYPE_USHORT_GRAY, + BufferedImage.TYPE_BYTE_BINARY, + BufferedImage.TYPE_BYTE_INDEXED + }; + + private static final ColorSpace[] CSs = { + ColorSpace.getInstance(ColorSpace.CS_CIEXYZ), + ColorSpace.getInstance(ColorSpace.CS_GRAY), + ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), + ColorSpace.getInstance(ColorSpace.CS_PYCC), + ColorSpace.getInstance(ColorSpace.CS_sRGB) + }; + + public static void main(String[] args) { + for (ColorSpace cs : CSs) { + ColorConvertOp op = new ColorConvertOp(cs, null); + for (int srcType : TYPES) { + for (int dstType : TYPES) { + BufferedImage src = new BufferedImage(1, 1, srcType) { + @Override + public SampleModel getSampleModel() { + throw new AssertionError(); + } + }; + BufferedImage dst = new BufferedImage(1, 1, dstType) { + @Override + public SampleModel getSampleModel() { + throw new AssertionError(); + } + }; + op.filter(src, dst); + } + } + } + } +} From cb158ffb8a5be3322c914d93752d12327bc6f352 Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt Date: Fri, 21 Apr 2023 20:51:50 +0000 Subject: [PATCH 085/288] 8296153: Bump minimum boot jdk to JDK 20 Reviewed-by: erikj, darcy, iris --- make/conf/github-actions.conf | 12 ++++++------ make/conf/jib-profiles.js | 2 +- make/conf/version-numbers.conf | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index d99f76ae40c..665b3a701eb 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -29,13 +29,13 @@ GTEST_VERSION=1.13.0 JTREG_VERSION=7.1.1+1 LINUX_X64_BOOT_JDK_EXT=tar.gz -LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk19/877d6127e982470ba2a7faa31cc93d04/36/GPL/openjdk-19_linux-x64_bin.tar.gz -LINUX_X64_BOOT_JDK_SHA256=f47aba585cfc9ecff1ed8e023524e8309f4315ed8b80100b40c7dcc232c12f96 +LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz +LINUX_X64_BOOT_JDK_SHA256=bb863b2d542976d1ae4b7b81af3e78b1e4247a64644350b552d298d8dc5980dc MACOS_X64_BOOT_JDK_EXT=tar.gz -MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk19/877d6127e982470ba2a7faa31cc93d04/36/GPL/openjdk-19_macos-x64_bin.tar.gz -MACOS_X64_BOOT_JDK_SHA256=bfd33f5b2590fd552ae2d9231340c6b4704a872f927dce1c52860b78c49a5a11 +MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-x64_bin.tar.gz +MACOS_X64_BOOT_JDK_SHA256=47cf960d9bb89dbe987535a389f7e26c42de7c984ef5108612d77c81aa8cc6a4 WINDOWS_X64_BOOT_JDK_EXT=zip -WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk19/877d6127e982470ba2a7faa31cc93d04/36/GPL/openjdk-19_windows-x64_bin.zip -WINDOWS_X64_BOOT_JDK_SHA256=8fabcee7c4e8d3b53486777ecd27bb906d67d7c1efd1bf22a8290cf659afa487 +WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_windows-x64_bin.zip +WINDOWS_X64_BOOT_JDK_SHA256=c92fae5e42b9aecf444a66c8ec563c652f60b1e231dfdd33a4f5a3e3603058fb diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 1b866e21207..23192afe7ba 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -390,7 +390,7 @@ var getJibProfilesCommon = function (input, data) { }; }; - common.boot_jdk_version = "19"; + common.boot_jdk_version = "20"; common.boot_jdk_build_number = "36"; common.boot_jdk_home = input.get("boot_jdk", "install_path") + "/jdk-" + common.boot_jdk_version diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 4a3e5133567..6729593b769 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -37,6 +37,6 @@ DEFAULT_VERSION_DATE=2023-09-19 DEFAULT_VERSION_CLASSFILE_MAJOR=65 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="19 20 21" +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="20 21" DEFAULT_JDK_SOURCE_TARGET_VERSION=21 DEFAULT_PROMOTED_VERSION_PRE=ea From b2240bf870cd57983fda0bc3b0e205acfdd1fd2a Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Fri, 21 Apr 2023 22:11:40 +0000 Subject: [PATCH 086/288] 8304696: Duplicate class names in dynamicArchive tests can lead to test failure Reviewed-by: iklam --- .../cds/appcds/dynamicArchive/LinkClassTest.java | 4 ++-- .../dynamicArchive/test-classes/LinkClassApp.java | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java index ea6abe02cee..388c942a9a2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -31,7 +31,7 @@ * /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes * @build LinkClassApp * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 MyShutdown + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 LinkClassApp$MyShutdown * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LinkClassTest */ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java index 1cfb4507450..347c9325393 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -46,13 +46,13 @@ class Child2 extends Parent2 { int get() {return 4;} } -class MyShutdown extends Thread{ - public void run(){ - System.out.println("shut down hook invoked..."); - } -} - class LinkClassApp { + static class MyShutdown extends Thread{ + public void run(){ + System.out.println("shut down hook invoked..."); + } + } + public static void main(String args[]) { Runtime r=Runtime.getRuntime(); r.addShutdownHook(new MyShutdown()); From 9ed456fac87f598af7d71f9c0887234a09e10eed Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Fri, 21 Apr 2023 23:56:04 +0000 Subject: [PATCH 087/288] 8306634: Open source AWT Event related tests Reviewed-by: prr, serb --- test/jdk/java/awt/Component/RepaintTest.java | 81 ++++++++ .../MouseEventAbsoluteCoordsTest.java | 191 ++++++++++++++++++ .../event/OtherEvents/UndecoratedShrink.java | 76 +++++++ .../swing/JInternalFrame/bug4212562.java | 43 ++++ .../jdk/sun/awt/font/DoubleAntialiasTest.java | 104 ++++++++++ 5 files changed, 495 insertions(+) create mode 100644 test/jdk/java/awt/Component/RepaintTest.java create mode 100644 test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java create mode 100644 test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java create mode 100644 test/jdk/javax/swing/JInternalFrame/bug4212562.java create mode 100644 test/jdk/sun/awt/font/DoubleAntialiasTest.java diff --git a/test/jdk/java/awt/Component/RepaintTest.java b/test/jdk/java/awt/Component/RepaintTest.java new file mode 100644 index 00000000000..69d0ff8e3d4 --- /dev/null +++ b/test/jdk/java/awt/Component/RepaintTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; + +/* + * @test + * @bug 4189198 + * @key headful + * @summary updateClient should post a PaintEvent + */ + +public class RepaintTest { + private static volatile Frame frame; + private static volatile Label label; + private static volatile Point frameLoc; + + private static final int FRAME_DIM = 100; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Repaint Tester"); + frame.setSize(FRAME_DIM, FRAME_DIM); + label = new Label("Hi"); + frame.add(label); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + label.setBackground(Color.GREEN); + label.repaint(); + frameLoc = frame.getLocationOnScreen(); + }); + robot.waitForIdle(); + robot.delay(500); + + Color expectedColor = robot.getPixelColor(frameLoc.x + FRAME_DIM / 2, + frameLoc.y + FRAME_DIM / 2); + if (!Color.GREEN.equals(expectedColor)) { + throw new RuntimeException("Test Failed! \n" + + "PaintEvent was not triggered: "); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java b/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java new file mode 100644 index 00000000000..2444861ff54 --- /dev/null +++ b/test/jdk/java/awt/event/MouseEvent/MouseEventAbsoluteCoordsTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/* + * @test + * @bug 4992908 + * @key headful + * @summary Need way to get location of MouseEvent in screen coordinates + */ + +// The test consists of several parts: +// 1. create MouseEvent with new Ctor and checking get(X|Y)OnScreen(), +// getLocationOnScreen(), get(X|Y), getPoint(). +// 2. create MouseEvent with old Ctor and checking get(X|Y)OnScreen(), +// getLocationOnScreen(), get(X|Y), getPoint() . + +public class MouseEventAbsoluteCoordsTest implements MouseListener { + private static Frame frame; + private static Robot robot; + + private static Point mousePositionOnScreen = new Point(200, 200); + private static final Point mousePosition = new Point(100, 100); + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + MouseEventAbsoluteCoordsTest cordsTest = + new MouseEventAbsoluteCoordsTest(); + cordsTest.createTestUI(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void createTestUI() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("MouseEvent Test Frame"); + frame.setSize(200, 200); + frame.setLocation(300, 400); + frame.addMouseListener(this); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + + // use new MouseEvent's Ctor with user-defined absolute + // coordinates + System.out.println("Stage MOUSE_PRESSED"); + postMouseEventNewCtor(MouseEvent.MOUSE_PRESSED); + + System.out.println("Stage MOUSE_RELEASED"); + postMouseEventNewCtor(MouseEvent.MOUSE_RELEASED); + + System.out.println("Stage MOUSE_CLICKED"); + postMouseEventNewCtor(MouseEvent.MOUSE_CLICKED); + + // call syncLocation to get correct on-screen frame position + syncLocationToWindowManager(); + + // now we gonna use old MouseEvent's Ctor thus absolute + // position calculates as frame's location + relative coords + // of the event. + EventQueue.invokeAndWait(() -> mousePositionOnScreen = new Point( + frame.getLocationOnScreen().x + mousePosition.x, + frame.getLocationOnScreen().y + mousePosition.y)); + + System.out.println("Stage MOUSE_PRESSED"); + postMouseEventOldCtor(MouseEvent.MOUSE_PRESSED); + + System.out.println("Stage MOUSE_RELEASED"); + postMouseEventOldCtor(MouseEvent.MOUSE_RELEASED); + + System.out.println("Stage MOUSE_CLICKED"); + postMouseEventOldCtor(MouseEvent.MOUSE_CLICKED); + } + + private static void syncLocationToWindowManager() { + Toolkit.getDefaultToolkit().sync(); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public void mousePressed(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + @Override + public void mouseExited(MouseEvent e) { + System.out.println("mouse exited"); + }; + + @Override + public void mouseReleased(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + @Override + public void mouseEntered(MouseEvent e) { + System.out.println("mouse entered"); + }; + + @Override + public void mouseClicked(MouseEvent e) { + checkEventAbsolutePosition(e, "MousePressed OK"); + }; + + public void postMouseEventNewCtor(int MouseEventType) { + MouseEvent mouseEvt = new MouseEvent(frame, + MouseEventType, + System.currentTimeMillis(), + MouseEvent.BUTTON1_DOWN_MASK, + mousePosition.x, mousePosition.y, + mousePositionOnScreen.x, + mousePositionOnScreen.y, + 1, + false, + MouseEvent.NOBUTTON + ); + frame.dispatchEvent(mouseEvt); + } + + public void postMouseEventOldCtor(int MouseEventType) { + MouseEvent oldMouseEvt = new MouseEvent(frame, + MouseEventType, + System.currentTimeMillis(), + MouseEvent.BUTTON1_DOWN_MASK, + mousePosition.x, mousePosition.y, + 1, + false, + MouseEvent.NOBUTTON + ); + frame.dispatchEvent(oldMouseEvt); + } + + public void checkEventAbsolutePosition(MouseEvent evt, String message) { + if (evt.getXOnScreen() != mousePositionOnScreen.x || + evt.getYOnScreen() != mousePositionOnScreen.y || + !evt.getLocationOnScreen().equals( mousePositionOnScreen)) { + System.out.println("evt.location = "+evt.getLocationOnScreen()); + System.out.println("mouse.location = "+mousePositionOnScreen); + throw new RuntimeException("get(X|Y)OnScreen() or getPointOnScreen() work incorrectly"); + } + + if (evt.getX() != mousePosition.x || + evt.getY() != mousePosition.y || + !evt.getPoint().equals( mousePosition)) { + throw new RuntimeException("get(X|Y)() or getPoint() work incorrectly"); + } + System.out.println(message); + } +} diff --git a/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java b/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java new file mode 100644 index 00000000000..1ac59666ca5 --- /dev/null +++ b/test/jdk/java/awt/event/OtherEvents/UndecoratedShrink.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; + +/* + * @test + * @bug 4418155 + * @key headful + * @summary Checks Undecorated Frame repaints when shrinking + */ + +public class UndecoratedShrink extends Frame { + private static boolean passed = false; + private static UndecoratedShrink frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new UndecoratedShrink(); + frame.setUndecorated(true); + frame.setSize(100, 100); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + frame.setSize(50, 50); + frame.repaint(); + }); + robot.waitForIdle(); + robot.delay(500); + + if (!passed) { + throw new RuntimeException("Test Fails." + + " Frame does not get repainted"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + @Override + public void paint(Graphics g) { + passed = true; + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/bug4212562.java b/test/jdk/javax/swing/JInternalFrame/bug4212562.java new file mode 100644 index 00000000000..e63186139b9 --- /dev/null +++ b/test/jdk/javax/swing/JInternalFrame/bug4212562.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JInternalFrame; + +/* + * @test + * @bug 4212562 + * @summary To check if StackOverflow occurs if foreground is set to null. + */ + +public class bug4212562 { + public static void main(String[] args) { + try { + JInternalFrame jif = new JInternalFrame(); + jif.getContentPane().setForeground(null); + jif.getForeground(); + } catch (Exception e) { + throw new RuntimeException("Following exception occurred" + + " when getForeground() was called", e); + } + } +} diff --git a/test/jdk/sun/awt/font/DoubleAntialiasTest.java b/test/jdk/sun/awt/font/DoubleAntialiasTest.java new file mode 100644 index 00000000000..e9057922895 --- /dev/null +++ b/test/jdk/sun/awt/font/DoubleAntialiasTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Panel; +import java.awt.Robot; + +import static java.awt.RenderingHints.KEY_ANTIALIASING; +import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING; +import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON; +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON; + +/* + * @test + * @bug 4357180 + * @key headful + * @summary When both KEY_ANTIALIASING and KEY_TEXT_ANTIALIASING hints + * were turned on, java aborts with EXCEPTION_ACCESS_VIOLATION + * at attempt to draw characters in Hebrew or Arabic. + * This could happen immediately or after several draws, + * depending on th locale and platform. This test draws + * large number of characters that are among this range repeatedly. + */ + +public class DoubleAntialiasTest extends Panel { + private static Frame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + frame.setTitle("DoubleAntialiasTest"); + frame.add(new DoubleAntialiasTest()); + frame.pack(); + frame.setSize(500, 500); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(2000); + } catch (Exception e) { + throw new RuntimeException("Following exception occurred" + + " when testing Antialiasing Rendering hints: ", e); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + @Override + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + int y = 50; + for (int i = 0; i < 2; i++) { + int k = 5; + for (int j = 0x500; j < 0x700; j++) { + g2.setRenderingHint(KEY_TEXT_ANTIALIASING, + VALUE_TEXT_ANTIALIAS_ON); + g2.setRenderingHint(KEY_ANTIALIASING, + VALUE_ANTIALIAS_ON); + g2.drawString(String.valueOf((char) j), (5 + k), y); + k = k + 15; + } + k = 5; + y += 50; + for (int j = 0x700; j > 0x500; j--) { + g2.setRenderingHint(KEY_TEXT_ANTIALIASING, + VALUE_TEXT_ANTIALIAS_ON); + g2.setRenderingHint(KEY_ANTIALIASING, + VALUE_ANTIALIAS_ON); + g2.drawString(String.valueOf((char) j), (5 + k), y); + k = k + 15; + } + y += 50; + } + } +} From 8d696aea9e1cefca97a760c017a5fde545facaa9 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Sat, 22 Apr 2023 00:14:51 +0000 Subject: [PATCH 088/288] 8306575: Clean up and open source four Dialog related tests Reviewed-by: prr --- .../java/awt/Dialog/DialogDeadlockTest.java | 129 +++++++++++++ .../java/awt/Dialog/DialogLocationTest.java | 182 ++++++++++++++++++ .../java/awt/Dialog/ModalDialogOnNonEdt.java | 136 +++++++++++++ .../java/awt/Dialog/NewMessagePumpTest.java | 140 ++++++++++++++ 4 files changed, 587 insertions(+) create mode 100644 test/jdk/java/awt/Dialog/DialogDeadlockTest.java create mode 100644 test/jdk/java/awt/Dialog/DialogLocationTest.java create mode 100644 test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java create mode 100644 test/jdk/java/awt/Dialog/NewMessagePumpTest.java diff --git a/test/jdk/java/awt/Dialog/DialogDeadlockTest.java b/test/jdk/java/awt/Dialog/DialogDeadlockTest.java new file mode 100644 index 00000000000..87a929053c7 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogDeadlockTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5006427 + @summary Shows many modal dialog and checks if there is a deadlock or thread race. + @key headful + @run main DialogDeadlockTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Window; +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; + +public class DialogDeadlockTest { + public static final int MAX_COUNT = 200; + private static Dialog lastDialog; + private static Runnable r; + private static volatile int count; + private static volatile int cumul; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + DialogDeadlockTest ddt = new DialogDeadlockTest(); + ddt.start(); + } + + public void start() { + final Frame frame = new Frame("abc"); + final List toDispose = new LinkedList<>(); + + try { + frame.setLocation(300, 0); + frame.add(new Button("def")); + frame.pack(); + frame.setVisible(true); + cumul = 0; + + r = new Runnable() { + public void run() { + count++; + if (count < 10) { + Dialog xlastDialog = lastDialog; + cumul += count; + Dialog d = new Dialog(frame, "Dialog " + + cumul, true); + d.setLayout(new BorderLayout()); + d.add(new Button("button " + count), BorderLayout.CENTER); + d.pack(); + toDispose.add(d); + lastDialog = d; + EventQueue.invokeLater(r); + d.setVisible(true); + if (xlastDialog != null) { + xlastDialog.setVisible(false); + } else { + if (cumul < MAX_COUNT) { + count = 0; + lastDialog = null; + EventQueue.invokeLater(r); + } + } + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + } + lastDialog.setVisible(false); + lastDialog = null; + } + } + }; + try { + EventQueue.invokeAndWait(r); + } catch (InterruptedException ignore) { + } catch (Exception e) { + throw new RuntimeException("Unexpected exception: " + + e.getLocalizedMessage()); + } + while (cumul < MAX_COUNT - 1) { + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) {} + } + System.out.println("Test PASSED"); + } finally { + try { + EventQueue.invokeAndWait(() -> { + frame.setVisible(false); + frame.dispose(); + for (Window w: toDispose) { + w.dispose(); + } + }); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/test/jdk/java/awt/Dialog/DialogLocationTest.java b/test/jdk/java/awt/Dialog/DialogLocationTest.java new file mode 100644 index 00000000000..b5f21780a40 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogLocationTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4101437 + @summary Dialog.setLocation(int,int) works unstable when the dialog is visible + @key headful + @run main DialogLocationTest +*/ + +import java.awt.AWTException; +import java.awt.Container; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.Random; + +public class DialogLocationTest extends Panel { + private volatile int count = 0; + private Dialog my_dialog; + private volatile boolean waitingForEvent = false; + private volatile int newX, newY; + Random random = new Random(); + + public void init() { + Container f = getParent(); + + while (!(f instanceof Frame)) { + f = f.getParent(); + } + + my_dialog = new Dialog((Frame) f, "TestDialog"); + my_dialog.setSize(150, 100); + + setSize(200, 200); + } + + public void start() throws InterruptedException, + InvocationTargetException { + Robot robot; + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + my_dialog.setLocationRelativeTo(null); + my_dialog.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + my_dialog.addComponentListener(new CL()); + setDialogLocation(my_dialog); + } catch (AWTException e) { + throw new RuntimeException(e); + } finally { + EventQueue.invokeAndWait(() -> { + my_dialog.setVisible(false); + my_dialog.dispose(); + }); + } + } + + public void setDialogLocation(Dialog dialog) { + int height, width, insetX, insetY; + Point curLoc; + int i; + + Rectangle screen = GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getMaximumWindowBounds(); + height = screen.height; + width = screen.width; + insetX = screen.x; + insetY = screen.y; + + String message = "Failed on iteration %d expect:[%d,%d] " + + "reported:[%d,%d] diff:[%d,%d]"; + + for (i = 0; i < 100; i++) { + newX = random.nextInt(insetX, width - 300); + newY = random.nextInt(insetY, height - 400); + + if (newX == 0 && newY == 0) { + i--; + continue; + } + + waitingForEvent = true; + + EventQueue.invokeLater(() -> { + dialog.setLocation(newX, newY); + }); + + while (waitingForEvent) { + Thread.yield(); + } + + curLoc = dialog.getLocation(); + if (curLoc.x != newX || curLoc.y != newY) { + count++; + System.out.println(message.formatted(i, newX, newY, + curLoc.x, curLoc.y, curLoc.x - newX, curLoc.y - newY)); + System.out.flush(); + } + } + + if (count > 0) { + throw new RuntimeException("Dialog Location was set incorrectly"); + } + } + + public class CL extends ComponentAdapter { + int lastX, lastY; + String message = "Failed in componentMoved() expect:[%d,%d]" + + " reported: [%d,%d] diff [%d,%d]"; + + public void componentMoved(ComponentEvent e) { + if (e.getComponent() == my_dialog) { + Point eventLoc = e.getComponent().getLocation(); + if (lastX != eventLoc.x || lastY != eventLoc.y) { + lastX = eventLoc.x; + lastY = eventLoc.y; + if (newX != 0 && newY != 0 && (eventLoc.x != newX || eventLoc.y != newY)) { + count++; + System.out.println(message.formatted(newX, newY, + eventLoc.x, eventLoc.y, + eventLoc.x - newX, eventLoc.y - newY)); + System.out.flush(); + } + waitingForEvent = false; + } + } + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + Frame frame = new Frame("DialogLocationTest"); + try { + DialogLocationTest test = new DialogLocationTest(); + EventQueue.invokeAndWait(() -> { + frame.add(test); + test.init(); + frame.setVisible(true); + }); + test.start(); + } finally { + EventQueue.invokeLater(() -> { + frame.setVisible(false); + frame.dispose(); + }); + } + } +} + diff --git a/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java b/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java new file mode 100644 index 00000000000..a7a9565d054 --- /dev/null +++ b/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4636311 4645035 + @summary Modal dialog shown on EDT after modal dialog on EDT doesn't receive mouse events + @key headful + @run main ModalDialogOnNonEdt +*/ + +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.EventQueue; +import java.awt.Robot; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.awt.AWTException; +import java.awt.event.MouseEvent; +import java.awt.event.MouseAdapter; +import java.util.ArrayList; +import java.util.List; + +public class ModalDialogOnNonEdt { + + public void start () { + ShowModalDialog showModalDialog = new ShowModalDialog(); + + try { + EventQueue.invokeLater(showModalDialog); + Robot robot = new Robot(); + robot.delay(2000); + + Point origin = ShowModalDialog.lastShownDialog.getLocationOnScreen(); + Dimension dim = ShowModalDialog.lastShownDialog.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + robot.delay(2000); + if (ShowModalDialog.count < 2) { + throw new RuntimeException("TEST FAILED: second modal dialog was not shown"); + } + + /* click on second modal dialog to verify if it receives mouse events */ + synchronized (ShowModalDialog.monitor) { + origin = ShowModalDialog.lastShownDialog.getLocationOnScreen(); + dim = ShowModalDialog.lastShownDialog.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + ShowModalDialog.monitor.wait(2000); + } + + if (ShowModalDialog.count < 3) { + throw new RuntimeException("TEST FAILED: second modal dialog didn't receive mouse events"); + } + + } catch (AWTException e) { + e.printStackTrace(); + throw new RuntimeException("Some AWTException occurred"); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } finally { + for (Window w : ShowModalDialog.toDispose) { + w.setVisible(false); + w.dispose(); + } + } + + System.out.println("TEST PASSED"); + } + + public static void main(String[] args) { + new ModalDialogOnNonEdt().start(); + } +} + +class ShowModalDialog implements Runnable { + static volatile int count = 0; + static Object monitor = new Object(); + static Dialog lastShownDialog; + static List toDispose = new ArrayList<>(); + + public void run() { + count++; + Frame frame = new Frame("Frame #" + count); + toDispose.add(frame); + Dialog dialog = new Dialog(frame, "Modal Dialog #" + count, true); + dialog.setSize(100, 100); + dialog.setLocation(100, 100*count); + dialog.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent me) { + System.out.println(me.toString()); + if (ShowModalDialog.count < 2) { + Runnable runner = new ShowModalDialog(); + new Thread(runner).start(); + } else { + synchronized (monitor) { + ShowModalDialog.count++; + monitor.notifyAll(); + } + } + } + }); + lastShownDialog = dialog; + toDispose.add(dialog); + dialog.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Dialog/NewMessagePumpTest.java b/test/jdk/java/awt/Dialog/NewMessagePumpTest.java new file mode 100644 index 00000000000..084d0f2e43c --- /dev/null +++ b/test/jdk/java/awt/Dialog/NewMessagePumpTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4119383 + @summary Tests total rewrite of modality blocking model + @key headful + @run main/timeout=30 NewMessagePumpTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; + +public class NewMessagePumpTest { + public void start() { + Frame1 frame = new Frame1(); + frame.validate(); + frame.setVisible(true); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + NewMessagePumpTest test = new NewMessagePumpTest(); + EventQueue.invokeAndWait(test::start); + } +} + +class Frame1 extends Frame { + Frame1() { + try { + jbInit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void jbInit() throws Exception { + MyPanel panel1 = new MyPanel(this); + this.setLayout(new BorderLayout()); + this.setSize(new Dimension(400, 300)); + this.setLocationRelativeTo(null); + this.setTitle("Frame Title"); + panel1.setLayout(new BorderLayout()); + this.add(panel1, BorderLayout.CENTER); + } +} + +class Dialog1 extends Dialog { + BorderLayout borderLayout1 = new BorderLayout(); + Button button1 = new Button(); + + Dialog1(Frame f) { + super(f, true); + try { + jbInit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + void jbInit() throws Exception { + button1.setLabel("close"); + button1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + button1_actionPerformed(e); + } + }); + this.setLayout(borderLayout1); + this.add(button1, BorderLayout.NORTH); + } + + void button1_actionPerformed(ActionEvent e) { + dispose(); + } +} + +class MyPanel extends Panel { + Frame frame; + + MyPanel(Frame f) { + frame = f; + } + + public void addNotify() { + super.addNotify(); + System.out.println("AddNotify bringing up modal dialog..."); + final Dialog1 dlg = new Dialog1(frame); + dlg.pack(); + new Thread(() -> { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + EventQueue.invokeAndWait(() -> { + dlg.setVisible(false); + dlg.dispose(); + }); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + }).start(); + dlg.setVisible(true); + frame.setVisible(false); + frame.dispose(); + System.out.println("Test passed"); + } +} From 0f51e6326373ff7d4a4d9a0e3a2788401f73405d Mon Sep 17 00:00:00 2001 From: Afshin Zafari Date: Sun, 23 Apr 2023 15:20:18 +0000 Subject: [PATCH 089/288] 8305590: Remove nothrow exception specifications from operator new Reviewed-by: coleenp, kbarrett --- make/autoconf/flags-cflags.m4 | 2 +- src/hotspot/share/memory/allocation.cpp | 5 --- src/hotspot/share/memory/allocation.hpp | 38 +++++++++---------- src/hotspot/share/prims/jvmtiEnv.cpp | 2 +- src/hotspot/share/prims/jvmtiRawMonitor.hpp | 7 +--- src/hotspot/share/runtime/thread.cpp | 9 ----- src/hotspot/share/runtime/thread.hpp | 8 ---- src/hotspot/share/utilities/growableArray.hpp | 5 ++- 8 files changed, 26 insertions(+), 50 deletions(-) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index c40f3c02106..e9959196acb 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -494,7 +494,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER], fi if test "x$TOOLCHAIN_TYPE" = xgcc; then - TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fcheck-new -fstack-protector" + TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fstack-protector" TOOLCHAIN_CFLAGS_JDK="-pipe -fstack-protector" # reduce lib size on linux in link step, this needs also special compile flags # do this on s390x also for libjvm (where serviceability agent is not supported) diff --git a/src/hotspot/share/memory/allocation.cpp b/src/hotspot/share/memory/allocation.cpp index 55d5eebfabc..64b00a13694 100644 --- a/src/hotspot/share/memory/allocation.cpp +++ b/src/hotspot/share/memory/allocation.cpp @@ -71,11 +71,6 @@ void FreeHeap(void* p) { void* MetaspaceObj::_shared_metaspace_base = nullptr; void* MetaspaceObj::_shared_metaspace_top = nullptr; -void* StackObj::operator new(size_t size) throw() { ShouldNotCallThis(); return 0; } -void StackObj::operator delete(void* p) { ShouldNotCallThis(); } -void* StackObj::operator new [](size_t size) throw() { ShouldNotCallThis(); return 0; } -void StackObj::operator delete [](void* p) { ShouldNotCallThis(); } - void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, TRAPS) throw() { diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index e694a2ac03f..bd3bd27f01d 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -179,13 +179,13 @@ void FreeHeap(void* p); class CHeapObjBase { public: - ALWAYSINLINE void* operator new(size_t size, MEMFLAGS f) throw() { + ALWAYSINLINE void* operator new(size_t size, MEMFLAGS f) { return AllocateHeap(size, f); } ALWAYSINLINE void* operator new(size_t size, MEMFLAGS f, - const NativeCallStack& stack) throw() { + const NativeCallStack& stack) { return AllocateHeap(size, f, stack); } @@ -202,13 +202,13 @@ class CHeapObjBase { return AllocateHeap(size, f, AllocFailStrategy::RETURN_NULL); } - ALWAYSINLINE void* operator new[](size_t size, MEMFLAGS f) throw() { + ALWAYSINLINE void* operator new[](size_t size, MEMFLAGS f) { return AllocateHeap(size, f); } ALWAYSINLINE void* operator new[](size_t size, MEMFLAGS f, - const NativeCallStack& stack) throw() { + const NativeCallStack& stack) { return AllocateHeap(size, f, stack); } @@ -233,12 +233,12 @@ class CHeapObjBase { template class CHeapObj { public: - ALWAYSINLINE void* operator new(size_t size) throw() { + ALWAYSINLINE void* operator new(size_t size) { return CHeapObjBase::operator new(size, F); } ALWAYSINLINE void* operator new(size_t size, - const NativeCallStack& stack) throw() { + const NativeCallStack& stack) { return CHeapObjBase::operator new(size, F, stack); } @@ -251,12 +251,12 @@ class CHeapObj { return CHeapObjBase::operator new(size, F, nt); } - ALWAYSINLINE void* operator new[](size_t size) throw() { + ALWAYSINLINE void* operator new[](size_t size) { return CHeapObjBase::operator new[](size, F); } ALWAYSINLINE void* operator new[](size_t size, - const NativeCallStack& stack) throw() { + const NativeCallStack& stack) { return CHeapObjBase::operator new[](size, F, stack); } @@ -282,11 +282,11 @@ class CHeapObj { // Calling new or delete will result in fatal error. class StackObj { - private: - void* operator new(size_t size) throw(); - void* operator new [](size_t size) throw(); - void operator delete(void* p); - void operator delete [](void* p); + public: + void* operator new(size_t size) = delete; + void* operator new [](size_t size) = delete; + void operator delete(void* p) = delete; + void operator delete [](void* p) = delete; }; // Base class for objects stored in Metaspace. @@ -432,7 +432,7 @@ extern void resource_free_bytes( Thread* thread, char *old, size_t size ); // Base class for objects allocated in the resource area. class ResourceObj { public: - void* operator new(size_t size) throw() { + void* operator new(size_t size) { return resource_allocate_bytes(size); } @@ -500,11 +500,11 @@ protected: void* operator new [](size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) throw() = delete; // Arena allocations - void* operator new(size_t size, Arena *arena) throw(); - void* operator new [](size_t size, Arena *arena) throw() = delete; + void* operator new(size_t size, Arena *arena); + void* operator new [](size_t size, Arena *arena) = delete; // Resource allocations - void* operator new(size_t size) throw() { + void* operator new(size_t size) { address res = (address)resource_allocate_bytes(size); DEBUG_ONLY(set_allocation_type(res, RESOURCE_AREA);) return res; @@ -515,8 +515,8 @@ protected: return res; } - void* operator new [](size_t size) throw() = delete; - void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) throw() = delete; + void* operator new [](size_t size) = delete; + void* operator new [](size_t size, const std::nothrow_t& nothrow_constant) = delete; void operator delete(void* p); void operator delete [](void* p) = delete; diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 295edf689bb..027f55889f8 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -3651,7 +3651,7 @@ JvmtiEnv::IsMethodObsolete(Method* method, jboolean* is_obsolete_ptr) { // monitor_ptr - pre-checked for null jvmtiError JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) { - JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name); + JvmtiRawMonitor* rmonitor = new (std::nothrow) JvmtiRawMonitor(name); NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY); *monitor_ptr = (jrawMonitorID)rmonitor; diff --git a/src/hotspot/share/prims/jvmtiRawMonitor.hpp b/src/hotspot/share/prims/jvmtiRawMonitor.hpp index acbe6aa6fcf..2adc730ff9f 100644 --- a/src/hotspot/share/prims/jvmtiRawMonitor.hpp +++ b/src/hotspot/share/prims/jvmtiRawMonitor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -110,11 +110,6 @@ class JvmtiRawMonitor : public CHeapObj { M_INTERRUPTED // Thread.interrupt() }; - // Non-aborting operator new - void* operator new(size_t size) throw() { - return CHeapObj::operator new(size, std::nothrow); - } - JvmtiRawMonitor(const char* name); ~JvmtiRawMonitor(); diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index 2d8e0291a43..047584ccda1 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -58,15 +58,6 @@ THREAD_LOCAL Thread* Thread::_thr_current = nullptr; #endif // ======= Thread ======== -void* Thread::allocate(size_t size, bool throw_excpt, MEMFLAGS flags) { - return throw_excpt ? AllocateHeap(size, flags, CURRENT_PC) - : AllocateHeap(size, flags, CURRENT_PC, AllocFailStrategy::RETURN_NULL); -} - -void Thread::operator delete(void* p) { - FreeHeap(p); -} - // Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread, // JavaThread diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 6a25070e1d8..e4e7badc788 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -200,14 +200,6 @@ class Thread: public ThreadShadow { // with the calling Thread? static bool is_JavaThread_protected_by_TLH(const JavaThread* target); - void* operator new(size_t size) throw() { return allocate(size, true); } - void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { - return allocate(size, false); } - void operator delete(void* p); - - protected: - static void* allocate(size_t size, bool throw_excpt, MEMFLAGS flags = mtThread); - private: DEBUG_ONLY(bool _suspendible_thread;) diff --git a/src/hotspot/share/utilities/growableArray.hpp b/src/hotspot/share/utilities/growableArray.hpp index be3a0f935d6..b960f004f15 100644 --- a/src/hotspot/share/utilities/growableArray.hpp +++ b/src/hotspot/share/utilities/growableArray.hpp @@ -809,13 +809,16 @@ public: this->clear_and_deallocate(); } - void* operator new(size_t size) throw() { + void* operator new(size_t size) { return AnyObj::operator new(size, F); } void* operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() { return AnyObj::operator new(size, nothrow_constant, F); } + void operator delete(void *p) { + AnyObj::operator delete(p); + } }; // Custom STL-style iterator to iterate over GrowableArrays From 4900517479f12b59cd8f1c31ad94ad7487c522f7 Mon Sep 17 00:00:00 2001 From: Ramkumar Sunderbabu Date: Mon, 24 Apr 2023 02:19:10 +0000 Subject: [PATCH 090/288] 8306636: Disable compiler/c2/Test6905845.java with -XX:TieredStopAtLevel=3 Reviewed-by: kvn --- test/hotspot/jtreg/compiler/c2/Test6905845.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/c2/Test6905845.java b/test/hotspot/jtreg/compiler/c2/Test6905845.java index bd11140dee0..4208790706f 100644 --- a/test/hotspot/jtreg/compiler/c2/Test6905845.java +++ b/test/hotspot/jtreg/compiler/c2/Test6905845.java @@ -26,6 +26,7 @@ * @bug 6905845 * @summary Server VM improperly optimizing away loop. * + * @requires vm.opt.TieredStopAtLevel != 3 * @run main/timeout=480 compiler.c2.Test6905845 */ From f7d45b85a5c664a87c94e0baccd8b9eddce27e2c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 24 Apr 2023 07:51:47 +0000 Subject: [PATCH 091/288] 8306076: Open source AWT misc tests Reviewed-by: serb --- test/jdk/java/awt/CacheTest.java | 48 +++++++++++++ test/jdk/java/awt/Frame/RemoveNotifyTest.java | 70 +++++++++++++++++++ test/jdk/java/awt/Icon/NullIconImageTest.java | 51 ++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 test/jdk/java/awt/CacheTest.java create mode 100644 test/jdk/java/awt/Frame/RemoveNotifyTest.java create mode 100644 test/jdk/java/awt/Icon/NullIconImageTest.java diff --git a/test/jdk/java/awt/CacheTest.java b/test/jdk/java/awt/CacheTest.java new file mode 100644 index 00000000000..9e80bd14336 --- /dev/null +++ b/test/jdk/java/awt/CacheTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4429261 + * @summary Checks AWTKeyStroke is cached + * @run main CacheTest +*/ + +import java.awt.AWTKeyStroke; +import java.awt.EventQueue; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; + +public class CacheTest { + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + if (AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_X, + InputEvent.ALT_DOWN_MASK) != + AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_X, + InputEvent.ALT_DOWN_MASK)) { + throw new RuntimeException("KeyStroke is not cached"); + } + }); + } +}// class CacheTest diff --git a/test/jdk/java/awt/Frame/RemoveNotifyTest.java b/test/jdk/java/awt/Frame/RemoveNotifyTest.java new file mode 100644 index 00000000000..eb848f5e842 --- /dev/null +++ b/test/jdk/java/awt/Frame/RemoveNotifyTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4154099 + @summary Tests that calling removeNotify() on a Frame and then reshowing + the Frame does not crash or lockup + @key headful + @run main RemoveNotifyTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class RemoveNotifyTest { + static Frame f; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + for (int i = 0; i < 100; i++) { + try { + f = new Frame(); + f.setBounds(10, 10, 100, 100); + MenuBar bar = new MenuBar(); + Menu menu = new Menu(); + menu.add(new MenuItem("foo")); + bar.add(menu); + f.setMenuBar(bar); + + for (int j = 0; j < 5; j++) { + f.setVisible(true); + f.removeNotify(); + } + } finally { + if (f != null) { + f.dispose(); + } + } + } + }); + + System.out.println("done"); + + } + + }// class RemoveNotifyTest diff --git a/test/jdk/java/awt/Icon/NullIconImageTest.java b/test/jdk/java/awt/Icon/NullIconImageTest.java new file mode 100644 index 00000000000..5d96cf851cb --- /dev/null +++ b/test/jdk/java/awt/Icon/NullIconImageTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 4633887 + * @summary setting a null Image in setIconImage should not cause exception. + * @key headful + * @run main NullIconImageTest +*/ + +import java.awt.EventQueue; +import java.awt.Frame; + +public class NullIconImageTest { + static Frame f; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + f = new Frame(); + f.setVisible(true); + f.setIconImage(null); // This call should not cause an exception. + } finally { + if (f != null) { + f.dispose(); + } + } + }); + } + + }// class NullIconImageTest From ce493dda9066b70f9541a8e06349fa81f79bb66c Mon Sep 17 00:00:00 2001 From: Leo Korinth Date: Mon, 24 Apr 2023 08:02:40 +0000 Subject: [PATCH 092/288] 8306435: Juggle04/TestDescription.java should be a booleanArr test and not a byteArr one Reviewed-by: tschatzl, lmesnik, shade --- .../vmTestbase/gc/ArrayJuggle/Juggle04/TestDescription.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/vmTestbase/gc/ArrayJuggle/Juggle04/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/ArrayJuggle/Juggle04/TestDescription.java index cf112316472..f6b2c21c18e 100644 --- a/test/hotspot/jtreg/vmTestbase/gc/ArrayJuggle/Juggle04/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/gc/ArrayJuggle/Juggle04/TestDescription.java @@ -35,7 +35,7 @@ * -XX:+HeapDumpOnOutOfMemoryError * -Xlog:gc=debug:gc.log * gc.ArrayJuggle.Juggle01.Juggle01 - * -gp byteArr + * -gp booleanArr * -ms low */ From 4a9f8efa867f84463f054d6624bcc5a89033e152 Mon Sep 17 00:00:00 2001 From: Ivan Walulya Date: Mon, 24 Apr 2023 08:47:23 +0000 Subject: [PATCH 093/288] 8057586: Explicit GC ignored if GCLocker is active Reviewed-by: tschatzl, ayang --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 35 ++- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 3 + .../gc/parallel/parallelScavengeHeap.cpp | 22 +- .../gc/parallel/parallelScavengeHeap.hpp | 2 +- .../parallel/parallelScavengeHeap.inline.hpp | 6 +- .../share/gc/parallel/psParallelCompact.cpp | 6 +- .../share/gc/parallel/psParallelCompact.hpp | 2 +- .../share/gc/parallel/psVMOperations.cpp | 7 +- .../share/gc/parallel/psVMOperations.hpp | 4 +- src/hotspot/share/gc/shared/gcCause.hpp | 6 + .../share/gc/shared/genCollectedHeap.cpp | 25 +- .../jtreg/gc/TestJNICriticalStressTest.java | 232 ++++++++++++++++++ 12 files changed, 328 insertions(+), 22 deletions(-) create mode 100644 test/hotspot/jtreg/gc/TestJNICriticalStressTest.java diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index f3c811a124e..76df081b2ba 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1928,6 +1928,35 @@ bool G1CollectedHeap::try_collect_concurrently(GCCause::Cause cause, } } +bool G1CollectedHeap::try_collect_fullgc(GCCause::Cause cause, + const G1GCCounters& counters_before) { + assert_heap_not_locked(); + + while(true) { + VM_G1CollectFull op(counters_before.total_collections(), + counters_before.total_full_collections(), + cause); + VMThread::execute(&op); + + // Request is trivially finished. + if (!GCCause::is_explicit_full_gc(cause) || op.gc_succeeded()) { + return op.gc_succeeded(); + } + + { + MutexLocker ml(Heap_lock); + if (counters_before.total_full_collections() != total_full_collections()) { + return true; + } + } + + if (GCLocker::is_active_and_needs_gc()) { + // If GCLocker is active, wait until clear before retrying. + GCLocker::stall_until_clear(); + } + } +} + bool G1CollectedHeap::try_collect(GCCause::Cause cause, const G1GCCounters& counters_before) { if (should_do_concurrent_full_gc(cause)) { @@ -1951,11 +1980,7 @@ bool G1CollectedHeap::try_collect(GCCause::Cause cause, return op.gc_succeeded(); } else { // Schedule a Full GC. - VM_G1CollectFull op(counters_before.total_collections(), - counters_before.total_full_collections(), - cause); - VMThread::execute(&op); - return op.gc_succeeded(); + return try_collect_fullgc(cause, counters_before); } } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 06df4dd38aa..59d9f69ed2e 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -283,6 +283,9 @@ private: uint gc_counter, uint old_marking_started_before); + bool try_collect_fullgc(GCCause::Cause cause, + const G1GCCounters& counters_before); + // indicates whether we are in young or mixed GC mode G1CollectorState _collector_state; diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 8d665d6bc60..a2db91ffc96 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -549,8 +549,26 @@ void ParallelScavengeHeap::collect(GCCause::Cause cause) { return; } - VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); - VMThread::execute(&op); + while (true) { + VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); + VMThread::execute(&op); + + if (!GCCause::is_explicit_full_gc(cause) || op.full_gc_succeeded()) { + return; + } + + { + MutexLocker ml(Heap_lock); + if (full_gc_count != total_full_collections()) { + return; + } + } + + if (GCLocker::is_active_and_needs_gc()) { + // If GCLocker is active, wait until clear before retrying. + GCLocker::stall_until_clear(); + } + } } void ParallelScavengeHeap::object_iterate(ObjectClosure* cl) { diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index ab981c5851f..abf87b0e019 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -211,7 +211,7 @@ class ParallelScavengeHeap : public CollectedHeap { // will then attempt a full gc. The second collects the entire heap; if // maximum_compaction is true, it will compact everything and clear all soft // references. - inline void invoke_scavenge(); + inline bool invoke_scavenge(); // Perform a full collection void do_full_collection(bool clear_all_soft_refs) override; diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.inline.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.inline.hpp index e852c11265f..ef5f6dedd29 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.inline.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,8 @@ inline bool ParallelScavengeHeap::should_alloc_in_eden(const size_t size) const return size < eden_size / 2; } -inline void ParallelScavengeHeap::invoke_scavenge() { - PSScavenge::invoke(); +inline bool ParallelScavengeHeap::invoke_scavenge() { + return PSScavenge::invoke(); } inline bool ParallelScavengeHeap::is_in_young(const void* p) const { diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 7130cb7880a..9c0febe90a4 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1678,7 +1678,7 @@ void PSParallelCompact::summary_phase(bool maximum_compaction) // may be true because this method can be called without intervening // activity. For example when the heap space is tight and full measure // are being taken to free space. -void PSParallelCompact::invoke(bool maximum_heap_compaction) { +bool PSParallelCompact::invoke(bool maximum_heap_compaction) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); @@ -1695,8 +1695,8 @@ void PSParallelCompact::invoke(bool maximum_heap_compaction) { const bool clear_all_soft_refs = heap->soft_ref_policy()->should_clear_all_soft_refs(); - PSParallelCompact::invoke_no_policy(clear_all_soft_refs || - maximum_heap_compaction); + return PSParallelCompact::invoke_no_policy(clear_all_soft_refs || + maximum_heap_compaction); } // This method contains no policy. You should probably diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 194dc70ad0a..07c420bc0dd 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -1141,7 +1141,7 @@ class PSParallelCompact : AllStatic { PSParallelCompact(); - static void invoke(bool maximum_heap_compaction); + static bool invoke(bool maximum_heap_compaction); static bool invoke_no_policy(bool maximum_heap_compaction); static void post_initialize(); diff --git a/src/hotspot/share/gc/parallel/psVMOperations.cpp b/src/hotspot/share/gc/parallel/psVMOperations.cpp index a9f99a4dbf5..47eeffb34a5 100644 --- a/src/hotspot/share/gc/parallel/psVMOperations.cpp +++ b/src/hotspot/share/gc/parallel/psVMOperations.cpp @@ -58,7 +58,8 @@ static bool is_cause_full(GCCause::Cause cause) { VM_ParallelGCSystemGC::VM_ParallelGCSystemGC(uint gc_count, uint full_gc_count, GCCause::Cause gc_cause) : - VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause)) + VM_GC_Operation(gc_count, gc_cause, full_gc_count, is_cause_full(gc_cause)), + _full_gc_succeeded(false) { } @@ -70,8 +71,8 @@ void VM_ParallelGCSystemGC::doit() { GCCauseSetter gccs(heap, _gc_cause); if (!_full) { // If (and only if) the scavenge fails, this will invoke a full gc. - heap->invoke_scavenge(); + _full_gc_succeeded = heap->invoke_scavenge(); } else { - heap->do_full_collection(false); + _full_gc_succeeded = PSParallelCompact::invoke(false); } } diff --git a/src/hotspot/share/gc/parallel/psVMOperations.hpp b/src/hotspot/share/gc/parallel/psVMOperations.hpp index 0cddac3d616..cc49eb631c7 100644 --- a/src/hotspot/share/gc/parallel/psVMOperations.hpp +++ b/src/hotspot/share/gc/parallel/psVMOperations.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -40,10 +40,12 @@ class VM_ParallelGCFailedAllocation : public VM_CollectForAllocation { }; class VM_ParallelGCSystemGC: public VM_GC_Operation { + bool _full_gc_succeeded; public: VM_ParallelGCSystemGC(uint gc_count, uint full_gc_count, GCCause::Cause gc_cause); virtual VMOp_Type type() const { return VMOp_ParallelGCSystemGC; } virtual void doit(); + bool full_gc_succeeded() const { return _full_gc_succeeded; } }; #endif // SHARE_GC_PARALLEL_PSVMOPERATIONS_HPP diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index bf794fad9f5..152ca787fc2 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -95,6 +95,12 @@ class GCCause : public AllStatic { cause == GCCause::_dcmd_gc_run); } + inline static bool is_explicit_full_gc(GCCause::Cause cause) { + return (is_user_requested_gc(cause) || + is_serviceability_requested_gc(cause) || + cause == GCCause::_wb_full_gc); + } + inline static bool is_serviceability_requested_gc(GCCause::Cause cause) { return (cause == GCCause::_jvmti_force_gc || diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 56cc45e2e80..8a66487e2bd 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -796,9 +796,28 @@ void GenCollectedHeap::collect(GCCause::Cause cause) { ? YoungGen : OldGen; - VM_GenCollectFull op(gc_count_before, full_gc_count_before, - cause, max_generation); - VMThread::execute(&op); + while (true) { + VM_GenCollectFull op(gc_count_before, full_gc_count_before, + cause, max_generation); + VMThread::execute(&op); + + if (!GCCause::is_explicit_full_gc(cause)) { + return; + } + + { + MutexLocker ml(Heap_lock); + // Read the GC count while holding the Heap_lock + if (full_gc_count_before != total_full_collections()) { + return; + } + } + + if (GCLocker::is_active_and_needs_gc()) { + // If GCLocker is active, wait until clear before retrying. + GCLocker::stall_until_clear(); + } + } } void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) { diff --git a/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java b/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java new file mode 100644 index 00000000000..999435a0bbf --- /dev/null +++ b/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test G1 Full GC execution when JNICritical is active + * @summary Check that Full GC calls are not ignored if concurrent with an active GCLocker. + * @bug 8057586 + * @requires vm.gc.G1 + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @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 -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 G1 + */ + + /* + * @test Parallel Full GC execution when JNICritical is active + * @bug 8057586 + * @requires vm.gc.Parallel + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @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 -XX:+UseParallelGC -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 Parallel + */ + +/* + * @test Serial Full GC execution when JNICritical is active + * @bug 8057586 + * @requires vm.gc.Serial + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @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 -XX:+UseSerialGC -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 Serial + */ + +import jdk.test.lib.Asserts; +import jdk.test.whitebox.WhiteBox; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.Deflater; + +/** + * Test verifies that Full GC calls are not ignored if concurrent with an active GCLocker. + * + * The test checks that at least a full gc is executed in the duration of a WhiteBox.fullGC() call; + * either by the calling thread or a concurrent thread. + */ +public class TestJNICriticalStressTest { + private static final WhiteBox wb = WhiteBox.getWhiteBox(); + + static private final int LARGE_MAP_SIZE = 64 * 1024; + + static private final int MAP_ARRAY_LENGTH = 4; + static private final int MAP_SIZE = 1024; + + static private final int BYTE_ARRAY_LENGTH = 16 * 1024; + + static private final long SYSTEM_GC_PERIOD_MS = 5 * 1000; + static private long gcCountBefore = 0; + static private GarbageCollectorMXBean collector = null; + + static private void println(String str) { System.out.println(str); } + static private void exit(int code) { System.exit(code); } + + static Map populateMap(int size) { + Map map = new HashMap(); + for (int i = 0; i < size; i += 1) { + Integer keyInt = Integer.valueOf(i); + String valStr = "value is [" + i + "]"; + map.put(keyInt,valStr); + } + return map; + } + + static private class AllocatingWorker implements Runnable { + private final Object[] array = new Object[MAP_ARRAY_LENGTH]; + private int arrayIndex = 0; + + private void doStep() { + Map map = populateMap(MAP_SIZE); + array[arrayIndex] = map; + arrayIndex = (arrayIndex + 1) % MAP_ARRAY_LENGTH; + } + + public void run() { + while (true) { + doStep(); + } + } + } + + static private class JNICriticalWorker implements Runnable { + private int count; + + private void doStep() { + byte[] inputArray = new byte[BYTE_ARRAY_LENGTH]; + for (int i = 0; i < inputArray.length; i += 1) { + inputArray[i] = (byte) (count + i); + } + + Deflater deflater = new Deflater(); + deflater.setInput(inputArray); + deflater.finish(); + + byte[] outputArray = new byte[2 * inputArray.length]; + deflater.deflate(outputArray); + deflater.end(); + + count += 1; + } + + public void run() { + while (true) { + doStep(); + } + } + } + + static private class SystemGCWorker implements Runnable { + public void run() { + long fullGcCounts = 0; + while (true) { + try { + Thread.sleep(SYSTEM_GC_PERIOD_MS); + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + long gcCountBefore = collector.getCollectionCount(); + wb.fullGC(); + long gcCountAfter = collector.getCollectionCount(); + + Asserts.assertLessThan(gcCountBefore, gcCountAfter, "Triggered more Full GCs than expected"); + } + } + } + + static public Map largeMap; + + public static void main(String... args) throws Exception { + if (args.length < 4) { + println("usage: JNICriticalStressTest "); + exit(-1); + } + + long durationSec = Long.parseLong(args[0]); + int allocThreadNum = Integer.parseInt(args[1]); + int jniCriticalThreadNum = Integer.parseInt(args[2]); + + StringBuilder OldGCName = new StringBuilder(); + switch (args[3]) { + case "G1": + OldGCName.append("G1 Old Generation"); + break; + case "Parallel": + OldGCName.append("PS MarkSweep"); + break; + case "Serial": + OldGCName.append("MarkSweepCompact"); + break; + default: + throw new RuntimeException("Unsupported GC selected"); + } + + List collectors = ManagementFactory.getGarbageCollectorMXBeans(); + + for (int i = 0; i < collectors.size(); i++) { + if (collectors.get(i).getName().contains(OldGCName.toString())) { + collector = collectors.get(i); + break; + } + } + + if (collector == null) { + throw new RuntimeException(OldGCName.toString() + " not found"); + } + + println("Running for " + durationSec + " secs"); + + largeMap = populateMap(LARGE_MAP_SIZE); + + // Start threads to allocate memory, this will trigger both GCLocker initiated + // garbage collections (GCs) and regular GCs. Thus increasing the likelihood of + // having different types of GCs happening concurrently with the System.gc call. + println("Starting " + allocThreadNum + " allocating threads"); + for (int i = 0; i < allocThreadNum; i += 1) { + new Thread(new AllocatingWorker()).start(); + } + + println("Starting " + jniCriticalThreadNum + " jni critical threads"); + for (int i = 0; i < jniCriticalThreadNum; i += 1) { + new Thread(new JNICriticalWorker()).start(); + } + + new Thread(new SystemGCWorker()).start(); + + long durationMS = (long) (1000 * durationSec); + try { + Thread.sleep(durationMS); + } catch (InterruptedException e) { + e.printStackTrace(); + exit(-1); + } + } +} From 30fa50d15854ffaec2f17882710e9f09f829b77a Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 24 Apr 2023 10:27:16 +0000 Subject: [PATCH 094/288] 8305062: Refactor CardTable::resize_covered_region Reviewed-by: tschatzl, iwalulya --- src/hotspot/share/gc/g1/g1CardTable.cpp | 1 - src/hotspot/share/gc/g1/g1CardTable.hpp | 3 - src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 1 - .../gc/parallel/parallelScavengeHeap.cpp | 18 +- src/hotspot/share/gc/shared/cardTable.cpp | 262 +++++------------- src/hotspot/share/gc/shared/cardTable.hpp | 52 +--- .../share/gc/shared/genCollectedHeap.cpp | 10 +- src/hotspot/share/gc/shared/vmStructs_gc.hpp | 2 - 8 files changed, 98 insertions(+), 251 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CardTable.cpp b/src/hotspot/share/gc/g1/g1CardTable.cpp index 417453be967..0dc845825d6 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.cpp +++ b/src/hotspot/share/gc/g1/g1CardTable.cpp @@ -55,7 +55,6 @@ void G1CardTable::initialize(G1RegionToSpaceMapper* mapper) { HeapWord* low_bound = _whole_heap.start(); HeapWord* high_bound = _whole_heap.end(); - _cur_covered_regions = 1; _covered[0] = _whole_heap; _byte_map = (CardValue*) mapper->reserved().start(); diff --git a/src/hotspot/share/gc/g1/g1CardTable.hpp b/src/hotspot/share/gc/g1/g1CardTable.hpp index a1ffe44e499..2cc796b23b9 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.hpp @@ -115,11 +115,8 @@ public: // Returns how many bytes of the heap a single byte of the Card Table corresponds to. static size_t heap_map_factor() { return _card_size; } - void initialize() override {} void initialize(G1RegionToSpaceMapper* mapper); - void resize_covered_region(MemRegion new_region) override { ShouldNotReachHere(); } - bool is_in_young(const void* p) const override; }; diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 76df081b2ba..7fa45347647 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1383,7 +1383,6 @@ jint G1CollectedHeap::initialize() { // Create the barrier set for the entire reserved region. G1CardTable* ct = new G1CardTable(heap_rs.region()); - ct->initialize(); G1BarrierSet* bs = new G1BarrierSet(ct); bs->initialize(); assert(bs->is_a(BarrierSet::G1BarrierSet), "sanity"); diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index a2db91ffc96..21d885c0ae8 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -69,22 +69,18 @@ jint ParallelScavengeHeap::initialize() { trace_actual_reserved_page_size(reserved_heap_size, heap_rs); initialize_reserved_region(heap_rs); - - PSCardTable* card_table = new PSCardTable(heap_rs.region()); - card_table->initialize(); - CardTableBarrierSet* const barrier_set = new CardTableBarrierSet(card_table); - barrier_set->initialize(); - BarrierSet::set_barrier_set(barrier_set); - - // Make up the generations - assert(MinOldSize <= OldSize && OldSize <= MaxOldSize, "Parameter check"); - assert(MinNewSize <= NewSize && NewSize <= MaxNewSize, "Parameter check"); - // Layout the reserved space for the generations. ReservedSpace old_rs = heap_rs.first_part(MaxOldSize); ReservedSpace young_rs = heap_rs.last_part(MaxOldSize); assert(young_rs.size() == MaxNewSize, "Didn't reserve all of the heap"); + PSCardTable* card_table = new PSCardTable(heap_rs.region()); + card_table->initialize(old_rs.base(), young_rs.base()); + + CardTableBarrierSet* const barrier_set = new CardTableBarrierSet(card_table); + barrier_set->initialize(); + BarrierSet::set_barrier_set(barrier_set); + // Set up WorkerThreads _workers.initialize_workers(); diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index 7d9cd15997d..f83857810df 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -30,6 +30,7 @@ #include "gc/shared/space.inline.hpp" #include "logging/log.hpp" #include "memory/virtualspace.hpp" +#include "runtime/init.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" @@ -73,9 +74,7 @@ CardTable::CardTable(MemRegion whole_heap) : _byte_map_size(0), _byte_map(nullptr), _byte_map_base(nullptr), - _cur_covered_regions(0), - _covered(MemRegion::create_array(_max_covered_regions, mtGC)), - _committed(MemRegion::create_array(_max_covered_regions, mtGC)), + _covered(MemRegion::create_array(max_covered_regions, mtGC)), _guard_region() { assert((uintptr_t(_whole_heap.start()) & (_card_size - 1)) == 0, "heap must start at card boundary"); @@ -83,11 +82,10 @@ CardTable::CardTable(MemRegion whole_heap) : } CardTable::~CardTable() { - MemRegion::destroy_array(_covered, _max_covered_regions); - MemRegion::destroy_array(_committed, _max_covered_regions); + MemRegion::destroy_array(_covered, max_covered_regions); } -void CardTable::initialize() { +void CardTable::initialize(void* region0_start, void* region1_start) { size_t num_cards = cards_required(_whole_heap.word_size()); // each card takes 1 byte; + 1 for the guard card @@ -97,8 +95,6 @@ void CardTable::initialize() { HeapWord* low_bound = _whole_heap.start(); HeapWord* high_bound = _whole_heap.end(); - _cur_covered_regions = 0; - const size_t rs_align = _page_size == os::vm_page_size() ? 0 : MAX2(_page_size, os::vm_allocation_granularity()); ReservedSpace heap_rs(_byte_map_size, rs_align, _page_size); @@ -125,215 +121,99 @@ void CardTable::initialize() { assert(is_aligned(guard_card, _page_size), "must be on its own OS page"); _guard_region = MemRegion((HeapWord*)guard_card, _page_size); + initialize_covered_region(region0_start, region1_start); + log_trace(gc, barrier)("CardTable::CardTable: "); log_trace(gc, barrier)(" &_byte_map[0]: " PTR_FORMAT " &_byte_map[last_valid_index()]: " PTR_FORMAT, - p2i(&_byte_map[0]), p2i(&_byte_map[last_valid_index()])); + p2i(&_byte_map[0]), p2i(&_byte_map[last_valid_index()])); log_trace(gc, barrier)(" _byte_map_base: " PTR_FORMAT, p2i(_byte_map_base)); } -int CardTable::find_covering_region_by_base(HeapWord* base) { - int i; - for (i = 0; i < _cur_covered_regions; i++) { - if (_covered[i].start() == base) return i; - if (_covered[i].start() > base) break; +MemRegion CardTable::committed_for(const MemRegion mr) const { + HeapWord* addr_l = (HeapWord*)align_down(byte_for(mr.start()), _page_size); + HeapWord* addr_r = mr.is_empty() + ? addr_l + : (HeapWord*)align_up(byte_after(mr.last()), _page_size); + + if (mr.start() == _covered[0].start()) { + // In case the card for gen-boundary is not page-size aligned, the crossing page belongs to _covered[1]. + addr_r = MIN2(addr_r, (HeapWord*)align_down(byte_for(_covered[1].start()), _page_size)); } - // If we didn't find it, create a new one. - assert(_cur_covered_regions < _max_covered_regions, - "too many covered regions"); - // Move the ones above up, to maintain sorted order. - for (int j = _cur_covered_regions; j > i; j--) { - _covered[j] = _covered[j-1]; - _committed[j] = _committed[j-1]; - } - int res = i; - _cur_covered_regions++; - _covered[res].set_start(base); - _covered[res].set_word_size(0); - CardValue* ct_start = byte_for(base); - HeapWord* ct_start_aligned = align_down((HeapWord*)ct_start, _page_size); - _committed[res].set_start(ct_start_aligned); - _committed[res].set_word_size(0); - return res; + + return MemRegion(addr_l, addr_r); } -HeapWord* CardTable::largest_prev_committed_end(int ind) const { - HeapWord* max_end = nullptr; - for (int j = 0; j < ind; j++) { - HeapWord* this_end = _committed[j].end(); - if (this_end > max_end) max_end = this_end; - } - return max_end; -} +void CardTable::initialize_covered_region(void* region0_start, void* region1_start) { + assert(_whole_heap.start() == region0_start, "precondition"); + assert(region0_start < region1_start, "precondition"); -MemRegion CardTable::committed_unique_to_self(int self, MemRegion mr) const { - assert(mr.intersection(_guard_region).is_empty(), "precondition"); - MemRegion result = mr; - for (int r = 0; r < _cur_covered_regions; r += 1) { - if (r != self) { - result = result.minus(_committed[r]); - } - } - return result; + assert(_covered[0].start() == nullptr, "precondition"); + assert(_covered[1].start() == nullptr, "precondition"); + + _covered[0] = MemRegion((HeapWord*)region0_start, (size_t)0); + _covered[1] = MemRegion((HeapWord*)region1_start, (size_t)0); } void CardTable::resize_covered_region(MemRegion new_region) { - // We don't change the start of a region, only the end. + assert(UseSerialGC || UseParallelGC, "only these two collectors"); assert(_whole_heap.contains(new_region), - "attempt to cover area not in reserved area"); - // collided is true if the expansion would push into another committed region - debug_only(bool collided = false;) - int const ind = find_covering_region_by_base(new_region.start()); - MemRegion const old_region = _covered[ind]; - assert(old_region.start() == new_region.start(), "just checking"); - if (new_region.word_size() != old_region.word_size()) { - // Commit new or uncommit old pages, if necessary. - MemRegion cur_committed = _committed[ind]; - // Extend the end of this _committed region - // to cover the end of any lower _committed regions. - // This forms overlapping regions, but never interior regions. - HeapWord* const max_prev_end = largest_prev_committed_end(ind); - if (max_prev_end > cur_committed.end()) { - cur_committed.set_end(max_prev_end); - } - // Align the end up to a page size (starts are already aligned). - HeapWord* new_end = (HeapWord*) byte_after(new_region.last()); - HeapWord* new_end_aligned = align_up(new_end, _page_size); - assert(new_end_aligned >= new_end, "align up, but less"); - // Check the other regions (excludes "ind") to ensure that - // the new_end_aligned does not intrude onto the committed - // space of another region. - int ri = 0; - for (ri = ind + 1; ri < _cur_covered_regions; ri++) { - if (new_end_aligned > _committed[ri].start()) { - assert(new_end_aligned <= _committed[ri].end(), - "An earlier committed region can't cover a later committed region"); - // Any region containing the new end - // should start at or beyond the region found (ind) - // for the new end (committed regions are not expected to - // be proper subsets of other committed regions). - assert(_committed[ri].start() >= _committed[ind].start(), - "New end of committed region is inconsistent"); - new_end_aligned = _committed[ri].start(); - // new_end_aligned can be equal to the start of its - // committed region (i.e., of "ind") if a second - // region following "ind" also start at the same location - // as "ind". - assert(new_end_aligned >= _committed[ind].start(), - "New end of committed region is before start"); - debug_only(collided = true;) - // Should only collide with 1 region - break; - } - } -#ifdef ASSERT - for (++ri; ri < _cur_covered_regions; ri++) { - assert(!_committed[ri].contains(new_end_aligned), - "New end of committed region is in a second committed region"); - } -#endif - // The guard page is always committed and should not be committed over. - // "guarded" is used for assertion checking below and recalls the fact - // that the would-be end of the new committed region would have - // penetrated the guard page. - HeapWord* new_end_for_commit = new_end_aligned; + "attempt to cover area not in reserved area"); + assert(_covered[0].start() != nullptr, "precondition"); + assert(_covered[1].start() != nullptr, "precondition"); - DEBUG_ONLY(bool guarded = false;) - if (new_end_for_commit > _guard_region.start()) { - new_end_for_commit = _guard_region.start(); - DEBUG_ONLY(guarded = true;) - } + int idx = new_region.start() == _whole_heap.start() ? 0 : 1; - if (new_end_for_commit > cur_committed.end()) { - // Must commit new pages. - MemRegion const new_committed = - MemRegion(cur_committed.end(), new_end_for_commit); + // We don't allow changes to the start of a region, only the end. + assert(_covered[idx].start() == new_region.start(), "inv"); - assert(!new_committed.is_empty(), "Region should not be empty here"); - os::commit_memory_or_exit((char*)new_committed.start(), - new_committed.byte_size(), _page_size, - !ExecMem, "card table expansion"); - // Use new_end_aligned (as opposed to new_end_for_commit) because - // the cur_committed region may include the guard region. - } else if (new_end_aligned < cur_committed.end()) { - // Must uncommit pages. - MemRegion const uncommit_region = - committed_unique_to_self(ind, MemRegion(new_end_aligned, - cur_committed.end())); - if (!uncommit_region.is_empty()) { - if (!os::uncommit_memory((char*)uncommit_region.start(), - uncommit_region.byte_size())) { - assert(false, "Card table contraction failed"); - // The call failed so don't change the end of the - // committed region. This is better than taking the - // VM down. - new_end_aligned = _committed[ind].end(); - } - } - } - // In any case, we can reset the end of the current committed entry. - _committed[ind].set_end(new_end_aligned); + MemRegion old_committed = committed_for(_covered[idx]); -#ifdef ASSERT - // Check that the last card in the new region is committed according - // to the tables. - bool covered = false; - for (int cr = 0; cr < _cur_covered_regions; cr++) { - if (_committed[cr].contains(new_end - 1)) { - covered = true; - break; - } - } - assert(covered, "Card for end of new region not committed"); -#endif + _covered[idx] = new_region; - // The default of 0 is not necessarily clean cards. - CardValue* entry; - if (old_region.last() < _whole_heap.start()) { - entry = byte_for(_whole_heap.start()); - } else { - entry = byte_after(old_region.last()); - } - assert(index_for(new_region.last()) <= last_valid_index(), - "The guard card will be overwritten"); - // This line commented out cleans the newly expanded region and - // not the aligned up expanded region. - // CardValue* const end = byte_after(new_region.last()); - CardValue* const end = (CardValue*) new_end_for_commit; - assert((end >= byte_after(new_region.last())) || collided || guarded, - "Expect to be beyond new region unless impacting another region"); - // do nothing if we resized downward. -#ifdef ASSERT - for (int ri = 0; ri < _cur_covered_regions; ri++) { - if (ri != ind) { - // The end of the new committed region should not - // be in any existing region unless it matches - // the start of the next region. - assert(!_committed[ri].contains(end) || - (_committed[ri].start() == (HeapWord*) end), - "Overlapping committed regions"); - } - } -#endif - if (entry < end) { - memset(entry, clean_card, pointer_delta(end, entry, sizeof(CardValue))); - } + MemRegion new_committed = committed_for(new_region); + + if (new_committed.word_size() == old_committed.word_size()) { + return; + } + + if (new_committed.word_size() > old_committed.word_size()) { + // Expand. + MemRegion delta = MemRegion(old_committed.end(), + new_committed.word_size() - old_committed.word_size()); + + os::commit_memory_or_exit((char*)delta.start(), + delta.byte_size(), + _page_size, + !ExecMem, + "card table expansion"); + + memset(delta.start(), clean_card, delta.byte_size()); + } else { + // Shrink. + MemRegion delta = MemRegion(new_committed.end(), + old_committed.word_size() - new_committed.word_size()); + bool res = os::uncommit_memory((char*)delta.start(), + delta.byte_size()); + assert(res, "uncommit should succeed"); } - // In any case, the covered size changes. - _covered[ind].set_word_size(new_region.word_size()); log_trace(gc, barrier)("CardTable::resize_covered_region: "); log_trace(gc, barrier)(" _covered[%d].start(): " PTR_FORMAT " _covered[%d].last(): " PTR_FORMAT, - ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last())); - log_trace(gc, barrier)(" _committed[%d].start(): " PTR_FORMAT " _committed[%d].last(): " PTR_FORMAT, - ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last())); + idx, p2i(_covered[idx].start()), idx, p2i(_covered[idx].last())); + log_trace(gc, barrier)(" committed_start: " PTR_FORMAT " committed_last: " PTR_FORMAT, + p2i(new_committed.start()), p2i(new_committed.last())); log_trace(gc, barrier)(" byte_for(start): " PTR_FORMAT " byte_for(last): " PTR_FORMAT, - p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last()))); + p2i(byte_for(_covered[idx].start())), p2i(byte_for(_covered[idx].last()))); log_trace(gc, barrier)(" addr_for(start): " PTR_FORMAT " addr_for(last): " PTR_FORMAT, - p2i(addr_for((CardValue*) _committed[ind].start())), p2i(addr_for((CardValue*) _committed[ind].last()))); + p2i(addr_for((CardValue*) new_committed.start())), p2i(addr_for((CardValue*) new_committed.last()))); +#ifdef ASSERT // Touch the last card of the covered region to show that it // is committed (or SEGV). - debug_only((void) (*byte_for(_covered[ind].last()));) + if (is_init_completed()) { + (void) (*(volatile CardValue*)byte_for(_covered[idx].last())); + } +#endif } // Note that these versions are precise! The scanning code has to handle the @@ -371,7 +251,7 @@ uintx CardTable::ct_max_alignment_constraint() { void CardTable::invalidate(MemRegion mr) { assert(align_down(mr.start(), HeapWordSize) == mr.start(), "Unaligned start"); assert(align_up (mr.end(), HeapWordSize) == mr.end(), "Unaligned end" ); - for (int i = 0; i < _cur_covered_regions; i++) { + for (int i = 0; i < max_covered_regions; i++) { MemRegion mri = mr.intersection(_covered[i]); if (!mri.is_empty()) dirty_MemRegion(mri); } diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp index 7f27b9fdab6..c2c4011ca24 100644 --- a/src/hotspot/share/gc/shared/cardTable.hpp +++ b/src/hotspot/share/gc/shared/cardTable.hpp @@ -49,46 +49,20 @@ protected: CardValue* _byte_map; // the card marking array CardValue* _byte_map_base; - int _cur_covered_regions; - - // The covered regions should be in address order. - MemRegion* _covered; - // The committed regions correspond one-to-one to the covered regions. - // They represent the card-table memory that has been committed to service - // the corresponding covered region. It may be that committed region for - // one covered region corresponds to a larger region because of page-size - // roundings. Thus, a committed region for one covered region may - // actually extend onto the card-table space for the next covered region. - MemRegion* _committed; - - // The last card is a guard card; never committed. - MemRegion _guard_region; - - inline size_t compute_byte_map_size(size_t num_bytes); - - // Finds and return the index of the region, if any, to which the given - // region would be contiguous. If none exists, assign a new region and - // returns its index. Requires that no more than the maximum number of - // covered regions defined in the constructor are ever in use. - int find_covering_region_by_base(HeapWord* base); - - // Returns the leftmost end of a committed region corresponding to a - // covered region before covered region "ind", or else "null" if "ind" is - // the first covered region. - HeapWord* largest_prev_committed_end(int ind) const; - - // Returns the part of the region mr that doesn't intersect with - // any committed region other than self. Used to prevent uncommitting - // regions that are also committed by other regions. Also protects - // against uncommitting the guard region. - MemRegion committed_unique_to_self(int self, MemRegion mr) const; - // Some barrier sets create tables whose elements correspond to parts of // the heap; the CardTableBarrierSet is an example. Such barrier sets will // normally reserve space for such tables, and commit parts of the table // "covering" parts of the heap that are committed. At most one covered // region per generation is needed. - static const int _max_covered_regions = 2; + static constexpr int max_covered_regions = 2; + + // The covered regions should be in address order. + MemRegion* _covered; + + // The last card is a guard card; never committed. + MemRegion _guard_region; + + inline size_t compute_byte_map_size(size_t num_bytes); enum CardValues { clean_card = (CardValue)-1, @@ -108,10 +82,14 @@ protected: size_t last_valid_index() const { return cards_required(_whole_heap.word_size()) - 1; } +private: + void initialize_covered_region(void* region0_start, void* region1_start); + + MemRegion committed_for(const MemRegion mr) const; public: CardTable(MemRegion whole_heap); virtual ~CardTable(); - virtual void initialize(); + void initialize(void* region0_start, void* region1_start); // *** Barrier set functions. @@ -196,7 +174,7 @@ public: } // Resize one of the regions covered by the remembered set. - virtual void resize_covered_region(MemRegion new_region); + void resize_covered_region(MemRegion new_region); // *** Card-table-RemSet-specific things. diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 8a66487e2bd..b2a204c52e2 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -117,17 +117,17 @@ jint GenCollectedHeap::initialize() { initialize_reserved_region(heap_rs); + ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size()); + ReservedSpace old_rs = heap_rs.last_part(_young_gen_spec->max_size()); + _rem_set = create_rem_set(heap_rs.region()); - _rem_set->initialize(); + _rem_set->initialize(young_rs.base(), old_rs.base()); + CardTableBarrierSet *bs = new CardTableBarrierSet(_rem_set); bs->initialize(); BarrierSet::set_barrier_set(bs); - ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size()); _young_gen = _young_gen_spec->init(young_rs, rem_set()); - ReservedSpace old_rs = heap_rs.last_part(_young_gen_spec->max_size()); - - old_rs = old_rs.first_part(_old_gen_spec->max_size()); _old_gen = _old_gen_spec->init(old_rs, rem_set()); GCInitLogger::print(); diff --git a/src/hotspot/share/gc/shared/vmStructs_gc.hpp b/src/hotspot/share/gc/shared/vmStructs_gc.hpp index ecd4045cbdd..8a15735fe18 100644 --- a/src/hotspot/share/gc/shared/vmStructs_gc.hpp +++ b/src/hotspot/share/gc/shared/vmStructs_gc.hpp @@ -90,9 +90,7 @@ nonstatic_field(CardTable, _page_size, const size_t) \ nonstatic_field(CardTable, _byte_map_size, const size_t) \ nonstatic_field(CardTable, _byte_map, CardTable::CardValue*) \ - nonstatic_field(CardTable, _cur_covered_regions, int) \ nonstatic_field(CardTable, _covered, MemRegion*) \ - nonstatic_field(CardTable, _committed, MemRegion*) \ nonstatic_field(CardTable, _guard_region, MemRegion) \ nonstatic_field(CardTable, _byte_map_base, CardTable::CardValue*) \ nonstatic_field(CardTableBarrierSet, _defer_initial_card_mark, bool) \ From 136dad7197a1969b2b1fc325f4336c20386c5d3b Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Mon, 24 Apr 2023 10:56:50 +0000 Subject: [PATCH 095/288] 8306566: Open source several clipboard AWT tests Reviewed-by: serb --- .../FlavorChangeNotificationTest/Common.java | 291 ++++++++++++++++++ .../PrivateClipboardTest.java | 70 +++++ .../SystemClipboardTest.java | 111 +++++++ .../PrivateClipboardTest.java | 121 ++++++++ .../PrivateClipboardTest.java | 118 +++++++ .../SystemClipboardTest.java | 153 +++++++++ 6 files changed, 864 insertions(+) create mode 100644 test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/Common.java create mode 100644 test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/PrivateClipboardTest.java create mode 100644 test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/SystemClipboardTest.java create mode 100644 test/jdk/java/awt/Clipboard/GetAltContentsTest/PrivateClipboardTest.java create mode 100644 test/jdk/java/awt/Clipboard/LostOwnershipChainTest/PrivateClipboardTest.java create mode 100644 test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboardTest.java diff --git a/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/Common.java b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/Common.java new file mode 100644 index 00000000000..516f16db053 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/Common.java @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.FlavorEvent; +import java.awt.datatransfer.FlavorListener; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; + +public class Common {} + +class FlavorListenerImpl implements FlavorListener { + public boolean notified1, notified2; + private int count; + public void flavorsChanged(FlavorEvent evt) { + switch (count) { + case 0: + notified1 = true; + break; + case 1: + notified2 = true; + break; + } + count++; + System.err.println("listener's " + this + + " flavorChanged() called " + count + " time"); + } + public String toString() { + return "notified1=" + notified1 + " notified2=" + notified2 + + " count=" + count; + } +}; + + class Util { + public static void setClipboardContents(Clipboard cb, + Transferable contents, + ClipboardOwner owner) { + while (true) { + try { + cb.setContents(contents, owner); + return; + } catch (IllegalStateException ise) { + ise.printStackTrace(); + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + } + + public static void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + + public static Image createImage() { + int w = 100; + int h = 100; + int[] pix = new int[w * h]; + + int index = 0; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int red = 127; + int green = 127; + int blue = y > h / 2 ? 127 : 0; + int alpha = 255; + if (x < w / 4 && y < h / 4) { + alpha = 0; + red = 0; + } + pix[index++] = (alpha << 24) | (red << 16) | (green << 8) | blue; + } + } + + return Toolkit + .getDefaultToolkit(). + createImage(new java.awt.image.MemoryImageSource( + w, h, pix, 0, w + )); + } + +} + + +class TransferableUnion implements Transferable { + + private static final DataFlavor[] ZERO_LENGTH_ARRAY = new DataFlavor[0]; + + private final Transferable TRANSF1, TRANSF2; + + private final DataFlavor[] FLAVORS; + + + public TransferableUnion(Transferable t1, Transferable t2) { + if (t1 == null) { + throw new NullPointerException("t1"); + } + if (t2 == null) { + throw new NullPointerException("t2"); + } + + this.TRANSF1 = t1; + this.TRANSF2 = t2; + + java.util.Set flavorSet = new java.util.HashSet<>(); + flavorSet.addAll(java.util.Arrays.asList(t1.getTransferDataFlavors())); + flavorSet.addAll(java.util.Arrays.asList(t2.getTransferDataFlavors())); + + FLAVORS = flavorSet.toArray(ZERO_LENGTH_ARRAY); + } + + /** + * Returns an array of flavors in which this Transferable + * can provide the data. + */ + public DataFlavor[] getTransferDataFlavors() { + return FLAVORS.clone(); + } + + /** + * Returns whether the requested flavor is supported by this + * Transferable. + * + * @param flavor the requested flavor for the data + * @throws NullPointerException if flavor is null + */ + public boolean isDataFlavorSupported(DataFlavor flavor) { + if (flavor == null) { + throw new NullPointerException("flavor"); + } + + return TRANSF1.isDataFlavorSupported(flavor) + || TRANSF2.isDataFlavorSupported(flavor); + } + + /** + * Returns the Transferable's data in the requested + * DataFlavor if possible. + * + * @param flavor the requested flavor for the data + * @return the data in the requested flavor + * @throws UnsupportedFlavorException if the requested data flavor is + * not supported by this Transferable + * @throws IOException if an IOException occurs while + * retrieving the data. + * @throws NullPointerException if flavor is null + */ + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, java.io.IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + java.io.IOException ioexc = null; + + if (TRANSF1.isDataFlavorSupported(flavor)) { + try { + return TRANSF1.getTransferData(flavor); + } catch (java.io.IOException exc) { + ioexc = exc; + } + } + + if (TRANSF2.isDataFlavorSupported(flavor)) { + return TRANSF2.getTransferData(flavor); + } + + if (ioexc != null) { + throw ioexc; + } + + // unreachable + return null; + } + +} + +/** + * A Transferable that implements the capability required + * to transfer an Image. + * + * This Transferable properly supports + * DataFlavor.imageFlavor + * and all equivalent flavors. + * No other DataFlavors are supported. + * + * @see java.awt.datatransfer.DataFlavor.imageFlavor + */ +class ImageSelection implements Transferable { + + private static final DataFlavor[] flavors = { DataFlavor.imageFlavor }; + + private Image data; + + /** + * Creates a Transferable capable of transferring + * the specified Image. + */ + public ImageSelection(Image data) { + this.data = data; + } + + /** + * Returns an array of flavors in which this Transferable + * can provide the data. DataFlavor.stringFlavor + * is supported. + * + * @return an array of length one, whose element is DataFlavor. + * imageFlavor + */ + public DataFlavor[] getTransferDataFlavors() { + return flavors.clone(); + } + + /** + * Returns whether the requested flavor is supported by this + * Transferable. + * + * @param flavor the requested flavor for the data + * @return true if flavor is equal to + * DataFlavor.imageFlavor; + * false otherwise + * @throws NullPointerException if flavor is null + */ + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (int i = 0; i < flavors.length; i++) { + if (flavor.equals(flavors[i])) { + return true; + } + } + return false; + } + + /** + * Returns the Transferable's data in the requested + * DataFlavor if possible. If the desired flavor is + * DataFlavor.imageFlavor, or an equivalent flavor, + * the Image representing the selection is + * returned. + * + * @param flavor the requested flavor for the data + * @return the data in the requested flavor, as outlined above + * @throws UnsupportedFlavorException if the requested data flavor is + * not equivalent to DataFlavor.imageFlavor + * @throws IOException if an IOException occurs while + * retrieving the data. By default, ImageSelection + * never throws this exception, but a subclass may. + * @throws NullPointerException if flavor is null + */ + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, java.io.IOException { + if (flavor.equals(DataFlavor.imageFlavor)) { + return data; + } else { + throw new UnsupportedFlavorException(flavor); + } + } + +} // class ImageSelection + diff --git a/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/PrivateClipboardTest.java b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/PrivateClipboardTest.java new file mode 100644 index 00000000000..70e0001ffc2 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/PrivateClipboardTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4259272 + @summary tests that notifications on changes to the set of DataFlavors + available on a private clipboard are delivered properly + @build Common + @run main PrivateClipboardTest +*/ + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +public class PrivateClipboardTest { + + public static void main(String[] args) { + new PrivateClipboardTest().start(); + } + + public void start() { + final Clipboard clipboard = new Clipboard("local"); + + final FlavorListenerImpl listener1 = new FlavorListenerImpl(); + clipboard.addFlavorListener(listener1); + + final FlavorListenerImpl listener2 = new FlavorListenerImpl(); + clipboard.addFlavorListener(listener2); + + Util.setClipboardContents(clipboard, + new StringSelection("text1"), null); + Util.sleep(3000); + + clipboard.removeFlavorListener(listener1); + + Util.setClipboardContents(clipboard, + new TransferableUnion(new StringSelection("text2"), + new ImageSelection(Util.createImage())), null); + Util.sleep(3000); + + System.err.println("listener1: " + listener1 + "\nlistener2: " + listener2); + + if (!(listener1.notified1 && listener2.notified1 && !listener1.notified2 + && listener2.notified2)) { + throw new RuntimeException("notifications about flavor " + + "changes delivered incorrectly!"); + } + } +} diff --git a/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/SystemClipboardTest.java b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/SystemClipboardTest.java new file mode 100644 index 00000000000..ff19005b8aa --- /dev/null +++ b/test/jdk/java/awt/Clipboard/FlavorChangeNotificationTest/SystemClipboardTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4259272 + @summary tests that notifications on changes to the set of DataFlavors + available on the system clipboard are delivered properly + @key headful + @modules java.desktop/sun.awt + @build Common + @run main SystemClipboardTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +import sun.awt.SunToolkit; + +public class SystemClipboardTest { + + private final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + private final FlavorListenerImpl listener1 = new FlavorListenerImpl(); + + private final FlavorListenerImpl listener2 = new FlavorListenerImpl(); + + private boolean isListener2Added; + + + public static void main(String[] args) { + new SystemClipboardTest().start(); + } + + public void start() { + Util.setClipboardContents(clipboard, + new StringSelection("text3"), null); + + clipboard.addFlavorListener(listener1); + + final ThreadGroup threadGroup = new ThreadGroup("Test thread group"); + final Object lock = new Object(); + final Runnable runnable = new Runnable() { + public void run() { + SunToolkit.createNewAppContext(); + clipboard.addFlavorListener(listener2); + synchronized (lock) { + isListener2Added = true; + lock.notifyAll(); + } + } + }; + final Thread thread = new Thread(threadGroup, runnable, "Test thread"); + synchronized (lock) { + thread.start(); + while (!isListener2Added) { + try { + lock.wait(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } + } + + Util.setClipboardContents(clipboard, + new TransferableUnion(new StringSelection("text2"), + new ImageSelection(Util.createImage())), + null); + Util.sleep(3000); + + clipboard.removeFlavorListener(listener1); + // must not remove listener2 from this AppContext + + Util.setClipboardContents(clipboard, + new StringSelection("text3"), null); + Util.sleep(3000); + + System.err.println("listener1: " + listener1 + + "\nlistener2: " + listener2); + + if (!(listener1.notified1 + && listener2.notified1 + && !listener1.notified2 + && listener2.notified2)) { + throw new RuntimeException("notifications about flavor " + + "changes delivered incorrectly!"); + } + } +} \ No newline at end of file diff --git a/test/jdk/java/awt/Clipboard/GetAltContentsTest/PrivateClipboardTest.java b/test/jdk/java/awt/Clipboard/GetAltContentsTest/PrivateClipboardTest.java new file mode 100644 index 00000000000..8edc6da559d --- /dev/null +++ b/test/jdk/java/awt/Clipboard/GetAltContentsTest/PrivateClipboardTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4287795 4790833 + @summary tests new Clipboard methods: getAvailableDataFlavors, + isDataFlavorAvailable, getData + @run main PrivateClipboardTest +*/ + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class PrivateClipboardTest { + + public static void main(String[] args) { + boolean failed = false; + final Clipboard clipboard = new Clipboard("local"); + + if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + failed = true; + System.err.println("FAILURE: isDataFlavorAvailable() returns " + + "true for empty clipboard"); + } + + try { + clipboard.getData(DataFlavor.stringFlavor); + failed = true; + System.err.println("FAILURE: getData() does not throw " + + "UnsupportedFlavorException for empty clipboard"); + } catch (UnsupportedFlavorException exc) { + System.err.println("getData() for empty clipboard throw " + + "UnsupportedFlavorException correctly: " + exc); + } catch (IOException exc) { + failed = true; + exc.printStackTrace(); + } + + if (clipboard.getAvailableDataFlavors() == null || + clipboard.getAvailableDataFlavors().length != 0) { + failed = true; + System.err.println("FAILURE: getAvailableDataFlavors() does not " + + "return zero-length array for empty clipboard: " + + Arrays.toString(clipboard.getAvailableDataFlavors())); + } + + final String contentsText = "contents text"; + + clipboard.setContents(new StringSelection(contentsText), null); + + Transferable contents = clipboard.getContents(null); + Set flavorsT = new HashSet<>( + Arrays.asList(contents.getTransferDataFlavors())); + Set flavorsA = new HashSet<>( + Arrays.asList(clipboard.getAvailableDataFlavors())); + System.err.println("getAvailableDataFlavors(): " + flavorsA); + if (!flavorsA.equals(flavorsT)) { + failed = true; + System.err.println( + "FAILURE: getAvailableDataFlavors() returns incorrect " + + "DataFlavors: " + flavorsA + "\nwhile getContents()." + + "getTransferDataFlavors() return: " + flavorsT); + } + + if (!clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + failed = true; + System.err.println( + "FAILURE: isDataFlavorAvailable(DataFlavor.stringFlavor) " + + "returns false"); + } + + Object data = null; + try { + data = clipboard.getData(DataFlavor.stringFlavor); + } catch (UnsupportedFlavorException exc) { + failed = true; + exc.printStackTrace(); + } catch (IOException exc) { + failed = true; + exc.printStackTrace(); + } + System.err.println("getData(): " + data); + if (!contentsText.equals(data)) { + failed = true; + System.err.println("FAILURE: getData() returns: " + data + + ", that is not equal to: \"" + contentsText + "\""); + } + + if (failed) { + throw new RuntimeException("test failed, for details see output above"); + } + } +} diff --git a/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/PrivateClipboardTest.java b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/PrivateClipboardTest.java new file mode 100644 index 00000000000..bddfa7ad062 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/PrivateClipboardTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4683804 + @summary Tests that in ClipboardOwner.lostOwnership() Clipboard.getContents() + returns actual contents of the clipboard and Clipboard.setContents() + can set contents of the clipboard and its owner. The clipboard is + a private clipboard. +*/ + +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; + +public class PrivateClipboardTest { + + public static void main(String[] args) { + PrivateClipboardOwner.run(); + + if (PrivateClipboardOwner.failed) { + throw new RuntimeException("test failed: can not get actual " + + "contents of the clipboard or set owner of the clipboard"); + } else { + System.err.println("test passed"); + } + } +} + +class PrivateClipboardOwner implements ClipboardOwner { + static boolean failed; + + private static final Object LOCK = new Object(); + + private static final int CHAIN_LENGTH = 5; + private final static Clipboard clipboard = + new Clipboard("PrivateClipboard"); + + private int m, id; + + public PrivateClipboardOwner(int m) { this.m = m; id = m; } + + public void lostOwnership(Clipboard cb, Transferable contents) { + System.err.println(id + " lost clipboard ownership"); + + Transferable t = cb.getContents(null); + String msg = null; + try { + msg = (String)t.getTransferData(DataFlavor.stringFlavor); + } catch (Exception e) { + System.err.println(id + " can't getTransferData: " + e); + } + System.err.println(id + " Clipboard.getContents(): " + msg); + if ( ! msg.equals( "" + (m+1) ) ) { + failed = true; + System.err.println( + "Clipboard.getContents() returned incorrect contents!"); + } + + m += 2; + if (m <= CHAIN_LENGTH) { + System.err.println(id + " Clipboard.setContents(): " + m); + cb.setContents(new StringSelection(m + ""), this); + } + + synchronized (LOCK) { + if (m > CHAIN_LENGTH) { + LOCK.notifyAll(); + } + } + } + + public static void run() { + PrivateClipboardOwner cbo1 = new PrivateClipboardOwner(0); + System.err.println(cbo1.m + " Clipboard.setContents(): " + cbo1.m); + clipboard.setContents(new StringSelection(cbo1.m + ""), cbo1); + + PrivateClipboardOwner cbo2 = new PrivateClipboardOwner(1); + + synchronized (LOCK) { + System.err.println(cbo2.m + " Clipboard.setContents(): " + cbo2.m); + clipboard.setContents(new StringSelection(cbo2.m + ""), cbo2); + try { + LOCK.wait(); + } catch (InterruptedException exc) { + exc.printStackTrace(); + } + } + + if (cbo1.m < CHAIN_LENGTH) { + failed = true; + System.err.println("chain of calls of lostOwnership() broken!"); + } + } +} diff --git a/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboardTest.java b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboardTest.java new file mode 100644 index 00000000000..eb382e99014 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/LostOwnershipChainTest/SystemClipboardTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4683804 + @summary Tests that in ClipboardOwner.lostOwnership() Clipboard.getContents() + returns actual contents of the clipboard and Clipboard.setContents() + can set contents of the clipboard and its owner. The clipboard is + the system clipboard. + @key headful +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; + +public class SystemClipboardTest { + + public static void main(String[] args) { + SystemClipboardOwner.run(); + + if (SystemClipboardOwner.failed) { + throw new RuntimeException("test failed: can not get actual " + + "contents of the clipboard or set owner of the clipboard"); + } else { + System.err.println("test passed"); + } + } +} + + +class SystemClipboardOwner implements ClipboardOwner { + static boolean failed; + + private static final Object LOCK = new Object(); + + private static final int CHAIN_LENGTH = 5; + private final static Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + private int m, id; + + public SystemClipboardOwner(int m) { this.m = m; id = m; } + + public void lostOwnership(Clipboard cb, Transferable contents) { + System.err.println(id + " lost clipboard ownership"); + + Transferable t = getClipboardContents(cb, null); + String msg = null; + try { + msg = (String)t.getTransferData(DataFlavor.stringFlavor); + } catch (Exception e) { + System.err.println(id + " can't getTransferData: " + e); + } + System.err.println(id + " Clipboard.getContents(): " + msg); + if ( ! msg.equals( "" + (m+1) ) ) { + failed = true; + System.err.println( + "Clipboard.getContents() returned incorrect contents!"); + } + + m += 2; + if (m <= CHAIN_LENGTH) { + System.err.println(id + " Clipboard.setContents(): " + m); + setClipboardContents(cb, new StringSelection(m + ""), this); + } + + synchronized (LOCK) { + if (m > CHAIN_LENGTH) { + LOCK.notifyAll(); + } + } + } + + public static void run() { + SystemClipboardOwner cbo1 = new SystemClipboardOwner(0); + System.err.println(cbo1.m + " Clipboard.setContents(): " + cbo1.m); + setClipboardContents(clipboard, + new StringSelection(cbo1.m + ""), cbo1); + + SystemClipboardOwner cbo2 = new SystemClipboardOwner(1); + synchronized (LOCK) { + System.err.println(cbo2.m + " Clipboard.setContents(): " + cbo2.m); + setClipboardContents(clipboard, + new StringSelection(cbo2.m + ""), cbo2); + try { + LOCK.wait(); + } catch (InterruptedException exc) { + exc.printStackTrace(); + } + } + + if (cbo1.m < CHAIN_LENGTH) { + failed = true; + System.err.println("chain of calls of lostOwnership() broken!"); + } + } + + private static void setClipboardContents(Clipboard cb, + Transferable contents, + ClipboardOwner owner) { + synchronized (cb) { + while (true) { + try { + cb.setContents(contents, owner); + return; + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } + + private static Transferable getClipboardContents(Clipboard cb, + Object requestor) { + synchronized (cb) { + while (true) { + try { + return cb.getContents(requestor); + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } + +} From f239695b5670bfbc251430d2f7e632804894a8bc Mon Sep 17 00:00:00 2001 From: Vladimir Kempik Date: Mon, 24 Apr 2023 11:31:49 +0000 Subject: [PATCH 096/288] 8305056: Avoid unaligned access in emit_intX methods if it's unsupported Reviewed-by: aph --- src/hotspot/share/asm/codeBuffer.hpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 616265ca6c0..029691c95fd 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -35,6 +35,11 @@ #include "utilities/resizeableResourceHash.hpp" #include "utilities/macros.hpp" +template +static inline void put_native(address p, T x) { + memcpy((void*)p, &x, sizeof x); +} + class PhaseCFG; class Compile; class BufferBlob; @@ -218,7 +223,10 @@ class CodeSection { set_end(curr); } - void emit_int16(uint16_t x) { *((uint16_t*) end()) = x; set_end(end() + sizeof(uint16_t)); } + template + void emit_native(T x) { put_native(end(), x); set_end(end() + sizeof x); } + + void emit_int16(uint16_t x) { emit_native(x); } void emit_int16(uint8_t x1, uint8_t x2) { address curr = end(); *((uint8_t*) curr++) = x1; @@ -234,11 +242,7 @@ class CodeSection { set_end(curr); } - void emit_int32(uint32_t x) { - address curr = end(); - *((uint32_t*) curr) = x; - set_end(curr + sizeof(uint32_t)); - } + void emit_int32(uint32_t x) { emit_native(x); } void emit_int32(uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) { address curr = end(); *((uint8_t*) curr++) = x1; @@ -248,11 +252,10 @@ class CodeSection { set_end(curr); } - void emit_int64( uint64_t x) { *((uint64_t*) end()) = x; set_end(end() + sizeof(uint64_t)); } - - void emit_float( jfloat x) { *((jfloat*) end()) = x; set_end(end() + sizeof(jfloat)); } - void emit_double(jdouble x) { *((jdouble*) end()) = x; set_end(end() + sizeof(jdouble)); } - void emit_address(address x) { *((address*) end()) = x; set_end(end() + sizeof(address)); } + void emit_int64(uint64_t x) { emit_native(x); } + void emit_float(jfloat x) { emit_native(x); } + void emit_double(jdouble x) { emit_native(x); } + void emit_address(address x) { emit_native(x); } // Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.) void initialize_shared_locs(relocInfo* buf, int length); From 7400aff3b8a0294dcbb6e89e9d8aad984f29fe92 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 24 Apr 2023 12:55:15 +0000 Subject: [PATCH 097/288] 8305252: make_method_handle_intrinsic may call java code under a lock Reviewed-by: dholmes, matsaave, iklam --- .../share/classfile/systemDictionary.cpp | 76 ++++++++++++------- src/hotspot/share/runtime/mutexLocker.cpp | 8 +- src/hotspot/share/runtime/mutexLocker.hpp | 3 +- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 3dec3cb1b4a..9702c4ae9f9 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1583,11 +1583,13 @@ void SystemDictionary::methods_do(void f(Method*)) { } auto doit = [&] (InvokeMethodKey key, Method* method) { - f(method); + if (method != nullptr) { + f(method); + } }; { - MutexLocker ml(InvokeMethodTable_lock); + MutexLocker ml(InvokeMethodIntrinsicTable_lock); _invoke_method_intrinsic_table.iterate_all(doit); } @@ -1939,40 +1941,62 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, iid != vmIntrinsics::_invokeGeneric, "must be a known MH intrinsic iid=%d: %s", iid_as_int, vmIntrinsics::name_at(iid)); + InvokeMethodKey key(signature, iid_as_int); + Method** met = nullptr; + + // We only want one entry in the table for this (signature/id, method) pair but the code + // to create the intrinsic method needs to be outside the lock. + // The first thread claims the entry by adding the key and the other threads wait, until the + // Method has been added as the value. { - MutexLocker ml(THREAD, InvokeMethodTable_lock); - InvokeMethodKey key(signature, iid_as_int); - Method** met = _invoke_method_intrinsic_table.get(key); - if (met != nullptr) { - return *met; + MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock); + while (met == nullptr) { + bool created; + met = _invoke_method_intrinsic_table.put_if_absent(key, &created); + if (met != nullptr && *met != nullptr) { + return *met; + } else if (!created) { + // Second thread waits for first to actually create the entry and returns + // it after notify. Loop until method return is non-null. + ml.wait(); + } } + } - bool throw_error = false; - // This function could get an OOM but it is safe to call inside of a lock because - // throwing OutOfMemoryError doesn't call Java code. - methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL); - if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) { - // Generate a compiled form of the MH intrinsic - // linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version. - AdapterHandlerLibrary::create_native_wrapper(m); - // Check if have the compiled code. - throw_error = (!m->has_compiled_code()); - } + methodHandle m = Method::make_method_handle_intrinsic(iid, signature, THREAD); + bool throw_error = HAS_PENDING_EXCEPTION; + if (!throw_error && (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative)) { + // Generate a compiled form of the MH intrinsic + // linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version. + AdapterHandlerLibrary::create_native_wrapper(m); + // Check if have the compiled code. + throw_error = (!m->has_compiled_code()); + } - if (!throw_error) { + { + MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock); + if (throw_error) { + // Remove the entry and let another thread try, or get the same exception. + bool removed = _invoke_method_intrinsic_table.remove(key); + assert(removed, "must be the owner"); + ml.notify_all(); + } else { signature->make_permanent(); // The signature is never unloaded. - bool created = _invoke_method_intrinsic_table.put(key, m()); - assert(created, "must be since we still hold the lock"); assert(Arguments::is_interpreter_only() || (m->has_compiled_code() && m->code()->entry_point() == m->from_compiled_entry()), "MH intrinsic invariant"); + *met = m(); // insert the element + ml.notify_all(); return m(); } } - // Throw error outside of the lock. - THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), - "Out of space in CodeCache for method handle intrinsic"); + // Throw VirtualMachineError or the pending exception in the JavaThread + if (throw_error && !HAS_PENDING_EXCEPTION) { + THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), + "Out of space in CodeCache for method handle intrinsic"); + } + return nullptr; } // Helper for unpacking the return value from linkMethod and linkCallSite. @@ -2115,7 +2139,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, Handle empty; OopHandle* o; { - MutexLocker ml(THREAD, InvokeMethodTable_lock); + MutexLocker ml(THREAD, InvokeMethodTypeTable_lock); o = _invoke_method_type_table.get(signature); } @@ -2184,7 +2208,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, if (can_be_cached) { // We can cache this MethodType inside the JVM. - MutexLocker ml(THREAD, InvokeMethodTable_lock); + MutexLocker ml(THREAD, InvokeMethodTypeTable_lock); bool created = false; assert(method_type != nullptr, "unexpected null"); OopHandle* h = _invoke_method_type_table.get(signature); diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 0e3c4797b93..5be72c4e663 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -39,7 +39,8 @@ Mutex* Patching_lock = nullptr; Mutex* CompiledMethod_lock = nullptr; Monitor* SystemDictionary_lock = nullptr; -Mutex* InvokeMethodTable_lock = nullptr; +Mutex* InvokeMethodTypeTable_lock = nullptr; +Monitor* InvokeMethodIntrinsicTable_lock = nullptr; Mutex* SharedDictionary_lock = nullptr; Monitor* ClassInitError_lock = nullptr; Mutex* Module_lock = nullptr; @@ -254,7 +255,9 @@ void mutex_init() { } MUTEX_DEFN(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2); // used for creating jmethodIDs. - MUTEX_DEFN(InvokeMethodTable_lock , PaddedMutex , safepoint); + MUTEX_DEFN(InvokeMethodTypeTable_lock , PaddedMutex , safepoint); + MUTEX_DEFN(InvokeMethodIntrinsicTable_lock , PaddedMonitor, safepoint); + MUTEX_DEFN(AdapterHandlerLibrary_lock , PaddedMutex , safepoint); MUTEX_DEFN(SharedDictionary_lock , PaddedMutex , safepoint); MUTEX_DEFN(VMStatistic_lock , PaddedMutex , safepoint); MUTEX_DEFN(SignatureHandlerLibrary_lock , PaddedMutex , safepoint); @@ -344,7 +347,6 @@ void mutex_init() { MUTEX_DEFL(Threads_lock , PaddedMonitor, CompileThread_lock, true); MUTEX_DEFL(Compile_lock , PaddedMutex , MethodCompileQueue_lock); - MUTEX_DEFL(AdapterHandlerLibrary_lock , PaddedMutex , InvokeMethodTable_lock); MUTEX_DEFL(Heap_lock , PaddedMonitor, AdapterHandlerLibrary_lock); MUTEX_DEFL(PerfDataMemAlloc_lock , PaddedMutex , Heap_lock); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 64b527f97b2..46329eb830e 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -34,7 +34,8 @@ extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code extern Mutex* CompiledMethod_lock; // a lock used to guard a compiled method and OSR queues extern Monitor* SystemDictionary_lock; // a lock on the system dictionary -extern Mutex* InvokeMethodTable_lock; +extern Mutex* InvokeMethodTypeTable_lock; +extern Monitor* InvokeMethodIntrinsicTable_lock; extern Mutex* SharedDictionary_lock; // a lock on the CDS shared dictionary extern Monitor* ClassInitError_lock; // a lock on the class initialization error table extern Mutex* Module_lock; // a lock on module and package related data structures From 62acc882bff32da287ac3ea22ebe43b90a724489 Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Mon, 24 Apr 2023 14:13:53 +0000 Subject: [PATCH 098/288] 8306476: CDS ArchiveHeapTestClass.java test asserts when vm_exit is called on VM thread Reviewed-by: ccheung --- src/hotspot/share/cds/metaspaceShared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index fe0e022136e..cfcbc6cc666 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -899,7 +899,7 @@ void MetaspaceShared::unrecoverable_writing_error(const char* message) { if (message != nullptr) { log_error(cds)("%s", message); } - vm_exit(1); + vm_direct_exit(1); } // We have finished dumping the static archive. At this point, there may be pending VM From d980cb48793f2bb662aece545fb00724c12a5613 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Mon, 24 Apr 2023 15:00:09 +0000 Subject: [PATCH 099/288] 8306658: GHA: MSVC installation could be optional since it might already be pre-installed Reviewed-by: shade, goetz --- .github/workflows/build-windows.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index cc5abb20319..6a56df295ba 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -98,12 +98,26 @@ jobs: id: gtest uses: ./.github/actions/get-gtest + - name: 'Check toolchain installed' + 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 }} + if [ $? -eq 0 ]; then + echo "Toolchain is already installed" + echo "toolchain-installed=true" >> $GITHUB_OUTPUT + else + echo "Toolchain is not yet installed" + echo "toolchain-installed=false" >> $GITHUB_OUTPUT + fi + - name: 'Install toolchain and dependencies' 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' \ --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} + if: steps.toolchain-check.outputs.toolchain-installed != 'true' - name: 'Configure' run: > From b2ccc9731e3a183bc6f31480c7d12f110633ea2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Mon, 24 Apr 2023 15:13:24 +0000 Subject: [PATCH 100/288] 8306444: Don't leak memory in PhaseChaitin::PhaseChaitin Reviewed-by: kvn, roland --- src/hotspot/share/opto/chaitin.cpp | 47 +++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 765ee800224..2f13a8bbd57 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -221,41 +221,60 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher, bool sc _high_frequency_lrg = MIN2(double(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency()); // Build a list of basic blocks, sorted by frequency - _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks()); // Experiment with sorting strategies to speed compilation + uint nr_blocks = _cfg.number_of_blocks(); double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket Block **buckets[NUMBUCKS]; // Array of buckets uint buckcnt[NUMBUCKS]; // Array of bucket counters double buckval[NUMBUCKS]; // Array of bucket value cutoffs + + // The space which our buckets point into. + Block** start = NEW_RESOURCE_ARRAY(Block *, nr_blocks*NUMBUCKS); + for (uint i = 0; i < NUMBUCKS; i++) { - buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks()); + buckets[i] = &start[i*nr_blocks]; buckcnt[i] = 0; // Bump by three orders of magnitude each time cutoff *= 0.001; buckval[i] = cutoff; - for (uint j = 0; j < _cfg.number_of_blocks(); j++) { - buckets[i][j] = nullptr; - } } + // Sort blocks into buckets - for (uint i = 0; i < _cfg.number_of_blocks(); i++) { + for (uint i = 0; i < nr_blocks; i++) { for (uint j = 0; j < NUMBUCKS; j++) { - if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) { + double bval = buckval[j]; + Block* blk = _cfg.get_block(i); + if (j == NUMBUCKS - 1 || blk->_freq > bval) { + uint cnt = buckcnt[j]; // Assign block to end of list for appropriate bucket - buckets[j][buckcnt[j]++] = _cfg.get_block(i); + buckets[j][cnt] = blk; + buckcnt[j] = cnt+1; break; // kick out of inner loop } } } - // Dump buckets into final block array + + // Squash the partially filled buckets together into the first one. + static_assert(NUMBUCKS >= 2, "must"); // If this isn't true then it'll mess up the squashing. + Block** offset = &buckets[0][buckcnt[0]]; + for (int i = 1; i < NUMBUCKS; i++) { + ::memmove(offset, buckets[i], buckcnt[i]*sizeof(Block*)); + offset += buckcnt[i]; + } + assert((&buckets[0][0] + nr_blocks) == offset, "should be"); + + // Free the now unused memory + FREE_RESOURCE_ARRAY(Block*, buckets[1], (NUMBUCKS-1)*nr_blocks); + // Finally, point the _blks to our memory + _blks = buckets[0]; + +#ifdef ASSERT uint blkcnt = 0; for (uint i = 0; i < NUMBUCKS; i++) { - for (uint j = 0; j < buckcnt[i]; j++) { - _blks[blkcnt++] = buckets[i][j]; - } + blkcnt += buckcnt[i]; } - - assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled"); + assert(blkcnt == nr_blocks, "Block array not totally filled"); +#endif } // union 2 sets together. From 2763cf14e6a174511ae8af471690ef18b10b3998 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Mon, 24 Apr 2023 15:36:19 +0000 Subject: [PATCH 101/288] 8304896: Update to use jtreg 7.2 Reviewed-by: erikj, lmesnik, iris --- make/autoconf/lib-tests.m4 | 2 +- make/conf/github-actions.conf | 2 +- make/conf/jib-profiles.js | 4 ++-- 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 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4 index 6af9045a136..aa02ac4ef97 100644 --- a/make/autoconf/lib-tests.m4 +++ b/make/autoconf/lib-tests.m4 @@ -28,7 +28,7 @@ ################################################################################ # Minimum supported versions -JTREG_MINIMUM_VERSION=7.1.1 +JTREG_MINIMUM_VERSION=7.2 GTEST_MINIMUM_VERSION=1.13.0 ############################################################################### diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 665b3a701eb..35d26baaccb 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.13.0 -JTREG_VERSION=7.1.1+1 +JTREG_VERSION=7.2+1 LINUX_X64_BOOT_JDK_EXT=tar.gz LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 23192afe7ba..d3b5aa2459d 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1150,9 +1150,9 @@ var getJibProfilesDependencies = function (input, common) { jtreg: { server: "jpg", product: "jtreg", - version: "7.1.1", + version: "7.2", build_number: "1", - file: "bundles/jtreg-7.1.1+1.zip", + file: "bundles/jtreg-7.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/hotspot/jtreg/TEST.ROOT b/test/hotspot/jtreg/TEST.ROOT index 8b16798e3d7..6669b9a3816 100644 --- a/test/hotspot/jtreg/TEST.ROOT +++ b/test/hotspot/jtreg/TEST.ROOT @@ -80,7 +80,7 @@ requires.properties= \ jdk.containerized # Minimum jtreg version -requiredVersion=7.1.1+1 +requiredVersion=7.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 fe569a3b5d1..3b1b13fdcfd 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.1.1+1 +requiredVersion=7.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 2c20eb886dd..526d68cd29e 100644 --- a/test/jdk/TEST.ROOT +++ b/test/jdk/TEST.ROOT @@ -72,7 +72,7 @@ requires.properties= \ jdk.containerized # Minimum jtreg version -requiredVersion=7.1.1+1 +requiredVersion=7.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 04485c0d7ed..0e0ece858ab 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.1.1+1 +requiredVersion=7.2+1 # Use new module options useNewOptions=true diff --git a/test/lib-test/TEST.ROOT b/test/lib-test/TEST.ROOT index 306d2bd7c6e..65c9b6d5402 100644 --- a/test/lib-test/TEST.ROOT +++ b/test/lib-test/TEST.ROOT @@ -29,7 +29,7 @@ keys=randomness # Minimum jtreg version -requiredVersion=7.1.1+1 +requiredVersion=7.2+1 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them From f32adaf89fede5262db2cb5517fc649a87e0714d Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 24 Apr 2023 15:37:35 +0000 Subject: [PATCH 102/288] 8304836: Make MALLOC_MIN4 macro more robust Reviewed-by: bchristi --- src/java.base/share/native/libjava/jni_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c index 43a2ac5440a..1090170dff3 100644 --- a/src/java.base/share/native/libjava/jni_util.c +++ b/src/java.base/share/native/libjava/jni_util.c @@ -39,7 +39,7 @@ * negative, or the size is INT_MAX as the macro adds 1 * that overflows into negative value. */ -#define MALLOC_MIN4(len) ((unsigned)(len) >= INT_MAX ? \ +#define MALLOC_MIN4(len) ((len) >= INT_MAX || (len) < 0 ? \ NULL : \ ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1))) From 4b23bef51df9c1a5bc8f43748a8d6c8d99995656 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Mon, 24 Apr 2023 16:10:44 +0000 Subject: [PATCH 103/288] 8301377: adjust timeout for JLI GetObjectSizeIntrinsicsTest.java subtest again 8302607: increase timeout for ContinuousCallSiteTargetChange.java 8305502: adjust timeouts in three more M&M tests Reviewed-by: naoto, lmesnik, thartmann --- .../jtreg/compiler/jsr292/ContinuousCallSiteTargetChange.java | 4 ++-- .../monitoring/stress/classload/load007/TestDescription.java | 4 ++-- .../monitoring/stress/classload/load011/TestDescription.java | 4 ++-- .../monitoring/stress/classload/load012/TestDescription.java | 4 ++-- .../jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/compiler/jsr292/ContinuousCallSiteTargetChange.java b/test/hotspot/jtreg/compiler/jsr292/ContinuousCallSiteTargetChange.java index e77df166da1..e8e6551e453 100644 --- a/test/hotspot/jtreg/compiler/jsr292/ContinuousCallSiteTargetChange.java +++ b/test/hotspot/jtreg/compiler/jsr292/ContinuousCallSiteTargetChange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -28,7 +28,7 @@ * * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run driver compiler.jsr292.ContinuousCallSiteTargetChange + * @run driver/timeout=180 compiler.jsr292.ContinuousCallSiteTargetChange */ package compiler.jsr292; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TestDescription.java index 5080c8cb223..93bfe9f2c27 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load007/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -47,7 +47,7 @@ * /test/lib * @comment generate and compile LoadableClassXXX classes * @run driver nsk.monitoring.stress.classload.GenClassesBuilder - * @run main/othervm + * @run main/othervm/timeout=180 * -XX:-UseGCOverheadLimit * nsk.monitoring.stress.classload.load001 * classes diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TestDescription.java index 6b188c7e99f..97615b68290 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load011/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -45,7 +45,7 @@ * /test/lib * @comment generate and compile LoadableClassXXX classes * @run driver nsk.monitoring.stress.classload.GenClassesBuilder - * @run main/othervm + * @run main/othervm/timeout=180 * -XX:-UseGCOverheadLimit * nsk.monitoring.stress.classload.load001 * classes diff --git a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TestDescription.java b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TestDescription.java index 4f314677adb..e56cfe387e2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TestDescription.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/load012/TestDescription.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -45,7 +45,7 @@ * /test/lib * @comment generate and compile LoadableClassXXX classes * @run driver nsk.monitoring.stress.classload.GenClassesBuilder - * @run main/othervm + * @run main/othervm/timeout=180 * -XX:-UseGCOverheadLimit * nsk.monitoring.stress.classload.load001 * classes diff --git a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java index c80e3304613..fc3b1a66d2a 100644 --- a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java +++ b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java @@ -278,7 +278,7 @@ * * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * - * @run main/othervm/timeout=240 -Xmx8g + * @run main/othervm/timeout=300 -Xmx8g * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -Xint * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large From 41d6be4d807921a91339029ae96e8dc14561bea6 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 24 Apr 2023 16:33:54 +0000 Subject: [PATCH 104/288] 8301065: Handle control characters in java_lang_String::print Reviewed-by: iklam, dholmes --- src/hotspot/share/classfile/javaClasses.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index c1cece08069..d38c32b234e 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -765,8 +765,13 @@ void java_lang_String::print(oop java_string, outputStream* st) { st->print("\""); for (int index = 0; index < length; index++) { - st->print("%c", (!is_latin1) ? value->char_at(index) : - ((jchar) value->byte_at(index)) & 0xff ); + jchar c = (!is_latin1) ? value->char_at(index) : + ((jchar) value->byte_at(index)) & 0xff; + if (c < ' ') { + st->print("\\x%02X", c); // print control characters e.g. \x0A + } else { + st->print("%c", c); + } } st->print("\""); } From 6b81342c2215041dbb7e9020a67cdc56976c97b1 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 24 Apr 2023 17:02:59 +0000 Subject: [PATCH 105/288] 8305994: Guarantee eventual async monitor deflation Reviewed-by: simonis, stuefe, dcubed --- src/hotspot/share/runtime/globals.hpp | 7 + .../share/runtime/monitorDeflationThread.cpp | 9 +- src/hotspot/share/runtime/synchronizer.cpp | 49 +++- .../GuaranteedAsyncDeflationIntervalTest.java | 212 ++++++++++++++++++ 4 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index c67b17ae3fb..3422185e3fa 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -713,6 +713,13 @@ const int ObjectAlignmentInBytes = 8; "MonitorUsedDeflationThreshold is exceeded (0 is off).") \ range(0, max_jint) \ \ + /* notice: the max range value here is max_jint, not max_intx */ \ + /* because of overflow issue */ \ + product(intx, GuaranteedAsyncDeflationInterval, 60000, DIAGNOSTIC, \ + "Async deflate idle monitors every so many milliseconds even " \ + "when MonitorUsedDeflationThreshold is NOT exceeded (0 is off).") \ + range(0, max_jint) \ + \ product(size_t, AvgMonitorsPerThreadEstimate, 1024, DIAGNOSTIC, \ "Used to estimate a variable ceiling based on number of threads " \ "for use with MonitorUsedDeflationThreshold (0 is off).") \ diff --git a/src/hotspot/share/runtime/monitorDeflationThread.cpp b/src/hotspot/share/runtime/monitorDeflationThread.cpp index 2f800f296b1..25a7a82ca2f 100644 --- a/src/hotspot/share/runtime/monitorDeflationThread.cpp +++ b/src/hotspot/share/runtime/monitorDeflationThread.cpp @@ -47,6 +47,11 @@ void MonitorDeflationThread::initialize() { } void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAPS) { + + // We wait for GuaranteedSafepointInterval so that is_async_deflation_needed() is checked + // at the same interval, unless GuaranteedAsyncDeflationInterval is lower. + const intx wait_time = MIN2(GuaranteedSafepointInterval, GuaranteedAsyncDeflationInterval); + while (true) { { // Need state transition ThreadBlockInVM so that this thread @@ -58,9 +63,7 @@ void MonitorDeflationThread::monitor_deflation_thread_entry(JavaThread* jt, TRAP MonitorLocker ml(MonitorDeflation_lock, Mutex::_no_safepoint_check_flag); while (!ObjectSynchronizer::is_async_deflation_needed()) { // Wait until notified that there is some work to do. - // We wait for GuaranteedSafepointInterval so that - // is_async_deflation_needed() is checked at the same interval. - ml.wait(GuaranteedSafepointInterval); + ml.wait(wait_time); } } diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 196892c65dc..8aca915ff78 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -262,6 +262,9 @@ void ObjectSynchronizer::initialize() { } // Start the ceiling with the estimate for one thread. set_in_use_list_ceiling(AvgMonitorsPerThreadEstimate); + + // Start the timer for deflations, so it does not trigger immediately. + _last_async_deflation_time_ns = os::javaTimeNanos(); } MonitorList ObjectSynchronizer::_in_use_list; @@ -290,6 +293,7 @@ bool volatile ObjectSynchronizer::_is_async_deflation_requested = false; bool volatile ObjectSynchronizer::_is_final_audit = false; jlong ObjectSynchronizer::_last_async_deflation_time_ns = 0; static uintx _no_progress_cnt = 0; +static bool _no_progress_skip_increment = false; // =====================> Quick functions @@ -1080,7 +1084,14 @@ static bool monitors_used_above_threshold(MonitorList* list) { // Check if our monitor usage is above the threshold: size_t monitor_usage = (monitors_used * 100LL) / ceiling; - return int(monitor_usage) > MonitorUsedDeflationThreshold; + if (int(monitor_usage) > MonitorUsedDeflationThreshold) { + log_info(monitorinflation)("monitors_used=" SIZE_FORMAT ", ceiling=" SIZE_FORMAT + ", monitor_usage=" SIZE_FORMAT ", threshold=" INTX_FORMAT, + monitors_used, ceiling, monitor_usage, MonitorUsedDeflationThreshold); + return true; + } + + return false; } size_t ObjectSynchronizer::in_use_list_ceiling() { @@ -1102,17 +1113,49 @@ void ObjectSynchronizer::set_in_use_list_ceiling(size_t new_value) { bool ObjectSynchronizer::is_async_deflation_needed() { if (is_async_deflation_requested()) { // Async deflation request. + log_info(monitorinflation)("Async deflation needed: explicit request"); return true; } + + jlong time_since_last = time_since_last_async_deflation_ms(); + if (AsyncDeflationInterval > 0 && - time_since_last_async_deflation_ms() > AsyncDeflationInterval && + time_since_last > AsyncDeflationInterval && monitors_used_above_threshold(&_in_use_list)) { // It's been longer than our specified deflate interval and there // are too many monitors in use. We don't deflate more frequently // than AsyncDeflationInterval (unless is_async_deflation_requested) // in order to not swamp the MonitorDeflationThread. + log_info(monitorinflation)("Async deflation needed: monitors used are above the threshold"); return true; } + + if (GuaranteedAsyncDeflationInterval > 0 && + time_since_last > GuaranteedAsyncDeflationInterval) { + // It's been longer than our specified guaranteed deflate interval. + // We need to clean up the used monitors even if the threshold is + // not reached, to keep the memory utilization at bay when many threads + // touched many monitors. + log_info(monitorinflation)("Async deflation needed: guaranteed interval (" INTX_FORMAT " ms) " + "is greater than time since last deflation (" JLONG_FORMAT " ms)", + GuaranteedAsyncDeflationInterval, time_since_last); + + // If this deflation has no progress, then it should not affect the no-progress + // tracking, otherwise threshold heuristics would think it was triggered, experienced + // no progress, and needs to backoff more aggressively. In this "no progress" case, + // the generic code would bump the no-progress counter, and we compensate for that + // by telling it to skip the update. + // + // If this deflation has progress, then it should let non-progress tracking + // know about this, otherwise the threshold heuristics would kick in, potentially + // experience no-progress due to aggressive cleanup by this deflation, and think + // it is still in no-progress stride. In this "progress" case, the generic code would + // zero the counter, and we allow it to happen. + _no_progress_skip_increment = true; + + return true; + } + return false; } @@ -1530,6 +1573,8 @@ size_t ObjectSynchronizer::deflate_idle_monitors(ObjectMonitorsHashtable* table) if (deflated_count != 0) { _no_progress_cnt = 0; + } else if (_no_progress_skip_increment) { + _no_progress_skip_increment = false; } else { _no_progress_cnt++; } diff --git a/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java b/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java new file mode 100644 index 00000000000..59957005789 --- /dev/null +++ b/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java @@ -0,0 +1,212 @@ +/* + * 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 jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +/* + * @test id=allDisabled + * @bug 8305994 + * @summary Test the GuaranteedAsyncDeflationInterval option + * @requires vm.flagless + * @library /test/lib + * @run driver GuaranteedAsyncDeflationIntervalTest allDisabled + */ + +/* + * @test id=guaranteedNoMUDT + * @requires vm.flagless + * @library /test/lib + * @run driver GuaranteedAsyncDeflationIntervalTest guaranteedNoMUDT + */ + +/* + * @test id=guaranteedNoADI + * @requires vm.flagless + * @library /test/lib + * @run driver GuaranteedAsyncDeflationIntervalTest guaranteedNoADI + */ + +/* + * @test id=allEnabled + * @requires vm.flagless + * @library /test/lib + * @run driver GuaranteedAsyncDeflationIntervalTest allEnabled + */ + +public class GuaranteedAsyncDeflationIntervalTest { + + public static class Test { + // Inflate a lot of monitors, so that threshold heuristics definitely fires + public static final int MONITORS = 10_000; + + public static Object[] monitors; + + public static void main(String... args) throws Exception { + monitors = new Object[MONITORS]; + for (int i = 0; i < MONITORS; i++) { + Object o = new Object(); + synchronized (o) { + try { + o.wait(1); // Inflate! + } catch (InterruptedException ie) { + } + } + monitors[i] = o; + } + + try { + Thread.sleep(10_000); + } catch (InterruptedException ie) { + } + } + } + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + throw new IllegalArgumentException("Expect the test label"); + } + + String test = args[0]; + switch (test) { + case "allDisabled": + testAllDisabled(); + break; + case "guaranteedNoMUDT": + testGuaranteedNoMUDT(); + break; + case "guaranteedNoADI": + testGuaranteedNoADI(); + break; + case "allEnabled": + testAllEnabled(); + break; + default: + throw new IllegalArgumentException("Unknown test: " + test); + } + } + + static final String MSG_THRESHOLD = "Async deflation needed: monitors used are above the threshold"; + static final String MSG_GUARANTEED = "Async deflation needed: guaranteed interval"; + + // Try with all heuristics disabled + public static void testAllDisabled() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xmx100M", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:GuaranteedAsyncDeflationInterval=0", + "-XX:AsyncDeflationInterval=0", + "-XX:MonitorUsedDeflationThreshold=0", + "-Xlog:monitorinflation=info", + "GuaranteedAsyncDeflationIntervalTest$Test"); + + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + oa.shouldHaveExitValue(0); + + oa.shouldNotContain(MSG_THRESHOLD); + oa.shouldNotContain(MSG_GUARANTEED); + assertNoDeflations(oa); + } + + // Try with guaranteed interval only enabled, threshold heuristics disabled via MUDT + public static void testGuaranteedNoMUDT() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xmx100M", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:MonitorUsedDeflationThreshold=0", + "-Xlog:monitorinflation=info", + "GuaranteedAsyncDeflationIntervalTest$Test"); + + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + oa.shouldHaveExitValue(0); + + oa.shouldNotContain(MSG_THRESHOLD); + oa.shouldContain(MSG_GUARANTEED); + assertDeflations(oa); + } + + // Try with guaranteed interval only enabled, threshold heuristics disabled via ADI + public static void testGuaranteedNoADI() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xmx100M", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:GuaranteedAsyncDeflationInterval=100", + "-XX:AsyncDeflationInterval=0", + "-Xlog:monitorinflation=info", + "GuaranteedAsyncDeflationIntervalTest$Test"); + + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + oa.shouldHaveExitValue(0); + + oa.shouldNotContain(MSG_THRESHOLD); + oa.shouldContain(MSG_GUARANTEED); + assertDeflations(oa); + } + + // Try with both threshold heuristics and guaranteed interval enabled + public static void testAllEnabled() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xmx100M", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:GuaranteedAsyncDeflationInterval=5000", + "-XX:MonitorUsedDeflationThreshold=10", + "-Xlog:monitorinflation=info", + "GuaranteedAsyncDeflationIntervalTest$Test"); + + OutputAnalyzer oa = new OutputAnalyzer(pb.start()); + oa.shouldHaveExitValue(0); + + oa.shouldContain(MSG_THRESHOLD); + oa.shouldContain(MSG_GUARANTEED); + assertDeflations(oa); + } + + private static void assertNoDeflations(OutputAnalyzer oa) { + for (String line : oa.asLines()) { + if (line.contains("Starting the final audit")) { + // Final deflations started, with no prior deflations, good. + return; + } + if (line.contains("begin deflating")) { + // Deflations detected before final ones, bad + oa.reportDiagnosticSummary(); + throw new IllegalStateException("FAILED"); + } + } + } + + private static void assertDeflations(OutputAnalyzer oa) { + for (String line : oa.asLines()) { + if (line.contains("Starting the final audit")) { + // Final deflations started, with no prior deflations, bad. + oa.reportDiagnosticSummary(); + throw new IllegalStateException("FAILED"); + } + if (line.contains("begin deflating")) { + // Deflations detected before final ones, good + return; + } + } + } +} From 314db55f6dde033f62481b62f10dd11030473569 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Mon, 24 Apr 2023 17:25:32 +0000 Subject: [PATCH 106/288] 8304818: Prune HttpURLConnection cache when corresponding Authenticator is garbage collected Reviewed-by: dfuchs, djelinski --- .../share/classes/java/net/Authenticator.java | 12 +- .../classes/sun/net/www/http/HttpClient.java | 23 +- .../sun/net/www/protocol/http/AuthCache.java | 10 +- .../net/www/protocol/http/AuthCacheImpl.java | 25 +- .../net/www/protocol/http/AuthCacheValue.java | 15 +- .../www/protocol/http/AuthenticationInfo.java | 152 +++----- .../www/protocol/http/AuthenticatorKeys.java | 76 ---- .../protocol/http/BasicAuthentication.java | 24 +- .../protocol/http/DigestAuthentication.java | 12 +- .../www/protocol/http/HttpURLConnection.java | 70 ++-- .../http/NTLMAuthenticationProxy.java | 36 +- .../http/NegotiateAuthentication.java | 6 +- .../net/www/protocol/https/HttpsClient.java | 11 +- .../http/ntlm/NTLMAuthentication.java | 15 +- .../http/ntlm/NTLMAuthentication.java | 14 +- test/jdk/java/net/Authenticator/B4933582.java | 337 ------------------ .../HTTPSetAuthenticatorTest.java | 5 +- .../sun/net/www/protocol/http/AuthCache.java | 177 +++++++++ 18 files changed, 340 insertions(+), 680 deletions(-) delete mode 100644 src/java.base/share/classes/sun/net/www/protocol/http/AuthenticatorKeys.java delete mode 100644 test/jdk/java/net/Authenticator/B4933582.java create mode 100644 test/jdk/sun/net/www/protocol/http/AuthCache.java diff --git a/src/java.base/share/classes/java/net/Authenticator.java b/src/java.base/share/classes/java/net/Authenticator.java index 8e78f84336f..c164c598db9 100644 --- a/src/java.base/share/classes/java/net/Authenticator.java +++ b/src/java.base/share/classes/java/net/Authenticator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,8 +25,6 @@ package java.net; -import sun.net.www.protocol.http.AuthenticatorKeys; - /** * The class Authenticator represents an object that knows how to obtain * authentication for a network connection. Usually, it will do this @@ -72,7 +70,6 @@ class Authenticator { private String requestingScheme; private URL requestingURL; private RequestorType requestingAuthType; - private final String key = AuthenticatorKeys.computeKey(this); /** * Constructor for subclasses to call. @@ -576,11 +573,4 @@ class Authenticator { protected RequestorType getRequestorType () { return requestingAuthType; } - - static String getKey(Authenticator a) { - return a.key; - } - static { - AuthenticatorKeys.setAuthenticatorKeyAccess(Authenticator::getKey); - } } diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index 31f32b44da6..a1c9e972990 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -38,7 +38,7 @@ import sun.net.www.MessageHeader; import sun.net.www.HeaderParser; import sun.net.www.MeteredStream; import sun.net.www.ParseUtil; -import sun.net.www.protocol.http.AuthenticatorKeys; +import sun.net.www.protocol.http.AuthCacheImpl; import sun.net.www.protocol.http.HttpURLConnection; import sun.util.logging.PlatformLogger; import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; @@ -116,6 +116,8 @@ public class HttpClient extends NetworkClient { The default value is 'true'. */ private static final boolean cacheSPNEGOProp; + protected volatile AuthCacheImpl authcache; + volatile boolean keepingAlive; /* this is a keep-alive connection */ volatile boolean disableKeepAlive;/* keep-alive has been disabled for this connection - this will be used when @@ -167,8 +169,6 @@ public class HttpClient extends NetworkClient { } } - protected volatile String authenticatorKey; - /** * A NOP method kept for backwards binary compatibility * @deprecated -- system properties are no longer cached. @@ -349,10 +349,11 @@ public class HttpClient extends NetworkClient { } } if (ret != null) { - String ak = httpuc == null ? AuthenticatorKeys.DEFAULT - : httpuc.getAuthenticatorKey(); + AuthCacheImpl ak = httpuc == null + ? AuthCacheImpl.getDefault() + : httpuc.getAuthCache(); boolean compatible = Objects.equals(ret.proxy, p) - && Objects.equals(ret.getAuthenticatorKey(), ak); + && Objects.equals(ret.getAuthCache(), ak); if (compatible) { ret.lock(); try { @@ -384,7 +385,7 @@ public class HttpClient extends NetworkClient { if (ret == null) { ret = new HttpClient(url, p, to); if (httpuc != null) { - ret.authenticatorKey = httpuc.getAuthenticatorKey(); + ret.authcache = httpuc.getAuthCache(); } } else { @SuppressWarnings("removal") @@ -422,10 +423,8 @@ public class HttpClient extends NetworkClient { to, useCache, httpuc); } - public final String getAuthenticatorKey() { - String k = authenticatorKey; - if (k == null) return AuthenticatorKeys.DEFAULT; - return k; + public final AuthCacheImpl getAuthCache() { + return authcache == null ? AuthCacheImpl.getDefault() : authcache; } /* return it to the cache as still usable, if: diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCache.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCache.java index 5ca44fa64e6..92cf996a4ce 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCache.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -38,8 +38,7 @@ public interface AuthCache { /** * Put an entry in the cache. pkey is a string specified as follows: * - * A:[B:]C:D:E[:F][;key=value] Between 4 and 6 fields separated by ":", - * and an optional semicolon-separated key=value list postfix, + * A:[B:]C:D:E[:F] Between 4 and 6 fields separated by ":", * where the fields have the following meaning: * A is "s" or "p" for server or proxy authentication respectively * B is optional and is the {@link AuthScheme}, e.g. BASIC, DIGEST, NTLM, etc @@ -48,11 +47,6 @@ public interface AuthCache { * E is the port number * F is optional and if present is the realm * - * The semi-colon separated key=value list postfix can be used to - * provide additional contextual information, thus allowing - * to separate AuthCacheValue instances obtained from different - * contexts. - * * Generally, two entries are created for each AuthCacheValue, * one including the realm and one without the realm. * Also, for some schemes (digest) multiple entries may be created diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheImpl.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheImpl.java index 1fac8291fe7..2f7206c93ad 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheImpl.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,9 +25,13 @@ package sun.net.www.protocol.http; +import java.net.Authenticator; +import java.util.Collections; import java.util.LinkedList; import java.util.ListIterator; import java.util.HashMap; +import java.util.Map; +import java.util.WeakHashMap; /** * @author Michael McMahon @@ -105,4 +109,23 @@ public class AuthCacheImpl implements AuthCache { } } } + + private static final Map caches = + Collections.synchronizedMap(new WeakHashMap<>()); + + /** + * The default cache is stored under null key which is never garbage + * collected. + */ + public static AuthCacheImpl getDefault() { + return getAuthCacheFor(null); + } + + /** + * Atomically check if a cache exists for given Authenticator and return it + * or create one and return it + */ + public static AuthCacheImpl getAuthCacheFor(Authenticator auth) { + return caches.computeIfAbsent(auth, (k) -> new AuthCacheImpl()); + } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheValue.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheValue.java index 9931ab9a607..c339f012b12 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheValue.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthCacheValue.java @@ -25,7 +25,6 @@ package sun.net.www.protocol.http; -import java.io.Serializable; import java.net.PasswordAuthentication; /** @@ -35,25 +34,13 @@ import java.net.PasswordAuthentication; * @author Michael McMahon */ -public abstract class AuthCacheValue implements Serializable { - - @java.io.Serial - static final long serialVersionUID = 735249334068211611L; +public abstract class AuthCacheValue { public enum Type { Proxy, Server }; - /** - * Caches authentication info entered by user. See cacheKey() - */ - protected static AuthCache cache = new AuthCacheImpl(); - - public static void setAuthCache (AuthCache map) { - cache = map; - } - /* Package private ctor to prevent extension outside package */ AuthCacheValue() {} diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java index 8fb6a1fac13..8134b994812 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -33,7 +33,7 @@ import java.util.HashMap; import java.util.Objects; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Function; +import java.util.function.BiFunction; import sun.net.www.HeaderParser; @@ -55,9 +55,6 @@ import sun.net.www.HeaderParser; public abstract class AuthenticationInfo extends AuthCacheValue implements Cloneable { - @java.io.Serial - static final long serialVersionUID = -2588378268010453259L; - // Constants saying what kind of authorization this is. This determines // the namespace in the hash table lookup. public static final char SERVER_AUTHENTICATION = 's'; @@ -76,7 +73,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone /* AuthCacheValue: */ - protected transient PasswordAuthentication pw; + protected PasswordAuthentication pw; public PasswordAuthentication credentials() { return pw; @@ -135,8 +132,10 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * and returns the cached authentication value. * Otherwise, returns the cached authentication value, which may be null. */ - private static AuthenticationInfo requestAuthentication(String key, Function cache) { - AuthenticationInfo cached = cache.apply(key); + private static AuthenticationInfo requestAuthentication( + String key, AuthCacheImpl acache, BiFunction cachefunc) + { + AuthenticationInfo cached = cachefunc.apply(key, acache); if (cached != null || !serializeAuth) { // either we already have a value in the cache, and we can // use that immediately, or the serializeAuth behavior is disabled, @@ -147,7 +146,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone try { // check again after locking, and if available // just return the cached value. - cached = cache.apply(key); + cached = cachefunc.apply(key, acache); if (cached != null) return cached; // Otherwise, if no request is in progress, record this @@ -166,7 +165,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone requestLock.unlock(); } /* entry may be in cache now. */ - return cache.apply(key); + return cachefunc.apply(key, acache); } /* signal completion of an authentication (whether it succeeded or not) @@ -186,10 +185,6 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone } } - //public String toString () { - //return ("{"+type+":"+authScheme+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}"); - //} - // REMIND: This cache just grows forever. We should put in a bounded // cache, or maybe something using WeakRef's. @@ -218,18 +213,9 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone /** The shortest path from the URL we authenticated against. */ String path; - /** - * A key identifying the authenticator from which the credentials - * were obtained. - * {@link AuthenticatorKeys#DEFAULT} identifies the {@linkplain - * java.net.Authenticator#setDefault(java.net.Authenticator) default} - * authenticator. - */ - String authenticatorKey; - /** Use this constructor only for proxy entries */ public AuthenticationInfo(char type, AuthScheme authScheme, String host, - int port, String realm, String authenticatorKey) { + int port, String realm) { this.type = type; this.authScheme = authScheme; this.protocol = ""; @@ -237,7 +223,6 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone this.port = port; this.realm = realm; this.path = null; - this.authenticatorKey = Objects.requireNonNull(authenticatorKey); } public Object clone() { @@ -253,8 +238,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * Constructor used to limit the authorization to the path within * the URL. Use this constructor for origin server entries. */ - public AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm, - String authenticatorKey) { + public AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm) { this.type = type; this.authScheme = authScheme; this.protocol = url.getProtocol().toLowerCase(); @@ -271,16 +255,6 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone else { this.path = reducePath (urlPath); } - this.authenticatorKey = Objects.requireNonNull(authenticatorKey); - } - - /** - * The {@linkplain java.net.Authenticator#getKey(java.net.Authenticator) key} - * of the authenticator that was used to obtain the credentials. - * @return The authenticator's key. - */ - public final String getAuthenticatorKey() { - return authenticatorKey; } /* @@ -305,15 +279,14 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * don't yet know the realm * (i.e. when we're preemptively setting the auth). */ - static AuthenticationInfo getServerAuth(URL url, String authenticatorKey) { + static AuthenticationInfo getServerAuth(URL url, AuthCacheImpl cache) { int port = url.getPort(); if (port == -1) { port = url.getDefaultPort(); } String key = SERVER_AUTHENTICATION + ":" + url.getProtocol().toLowerCase() - + ":" + url.getHost().toLowerCase() + ":" + port - + ";auth=" + authenticatorKey; - return getAuth(key, url); + + ":" + url.getHost().toLowerCase() + ":" + port; + return getAuth(key, url, cache); } /** @@ -322,8 +295,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * In this case we do not use the path because the protection space * is identified by the host:port:realm only */ - static String getServerAuthKey(URL url, String realm, AuthScheme scheme, - String authenticatorKey) { + static String getServerAuthKey(URL url, String realm, AuthScheme scheme) { int port = url.getPort(); if (port == -1) { port = url.getDefaultPort(); @@ -331,30 +303,29 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone String key = SERVER_AUTHENTICATION + ":" + scheme + ":" + url.getProtocol().toLowerCase() + ":" + url.getHost().toLowerCase() - + ":" + port + ":" + realm - + ";auth=" + authenticatorKey; + + ":" + port + ":" + realm; return key; } - private static AuthenticationInfo getCachedServerAuth(String key) { - return getAuth(key, null); + private static AuthenticationInfo getCachedServerAuth(String key, AuthCacheImpl cache) { + return getAuth(key, null, cache); } - static AuthenticationInfo getServerAuth(String key) { - if (!serializeAuth) return getCachedServerAuth(key); - return requestAuthentication(key, AuthenticationInfo::getCachedServerAuth); + static AuthenticationInfo getServerAuth(String key, AuthCacheImpl cache) { + if (!serializeAuth) return getCachedServerAuth(key, cache); + return requestAuthentication(key, cache, AuthenticationInfo::getCachedServerAuth); } - /** * Return the AuthenticationInfo object from the cache if it's path is * a substring of the supplied URLs path. */ - static AuthenticationInfo getAuth(String key, URL url) { + static AuthenticationInfo getAuth(String key, URL url, AuthCacheImpl acache) { + Objects.requireNonNull(acache); if (url == null) { - return (AuthenticationInfo)cache.get (key, null); + return (AuthenticationInfo)acache.get (key, null); } else { - return (AuthenticationInfo)cache.get (key, url.getPath()); + return (AuthenticationInfo)acache.get (key, url.getPath()); } } @@ -363,11 +334,10 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * for preemptive header-setting. Note, the protocol field is always * blank for proxies. */ - static AuthenticationInfo getProxyAuth(String host, int port, - String authenticatorKey) { - String key = PROXY_AUTHENTICATION + "::" + host.toLowerCase() + ":" + port - + ";auth=" + authenticatorKey; - AuthenticationInfo result = (AuthenticationInfo) cache.get(key, null); + static AuthenticationInfo getProxyAuth(String host, int port, AuthCacheImpl acache) { + Objects.requireNonNull(acache); + String key = PROXY_AUTHENTICATION + "::" + host.toLowerCase() + ":" + port; + AuthenticationInfo result = (AuthenticationInfo) acache.get(key, null); return result; } @@ -376,34 +346,34 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * Used in response to a challenge. Note, the protocol field is always * blank for proxies. */ - static String getProxyAuthKey(String host, int port, String realm, - AuthScheme scheme, String authenticatorKey) { + static String getProxyAuthKey(String host, int port, String realm, AuthScheme scheme) { String key = PROXY_AUTHENTICATION + ":" + scheme + "::" + host.toLowerCase() - + ":" + port + ":" + realm - + ";auth=" + authenticatorKey; + + ":" + port + ":" + realm; return key; } - private static AuthenticationInfo getCachedProxyAuth(String key) { - return (AuthenticationInfo) cache.get(key, null); + private static AuthenticationInfo getCachedProxyAuth(String key, AuthCacheImpl acache) { + Objects.requireNonNull(acache); + return (AuthenticationInfo) acache.get(key, null); } - static AuthenticationInfo getProxyAuth(String key) { - if (!serializeAuth) return getCachedProxyAuth(key); - return requestAuthentication(key, AuthenticationInfo::getCachedProxyAuth); + static AuthenticationInfo getProxyAuth(String key, AuthCacheImpl acache) { + if (!serializeAuth) return getCachedProxyAuth(key, acache); + return requestAuthentication(key, acache, AuthenticationInfo::getCachedProxyAuth); } /** * Add this authentication to the cache */ - void addToCache() { + void addToCache(AuthCacheImpl authcache) { + Objects.requireNonNull(authcache); String key = cacheKey(true); if (useAuthCache()) { - cache.put(key, this); + authcache.put(key, this); if (supportsPreemptiveAuthorization()) { - cache.put(cacheKey(false), this); + authcache.put(cacheKey(false), this); } } endAuthRequest(key); @@ -419,10 +389,11 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone /** * Remove this authentication from the cache */ - void removeFromCache() { - cache.remove(cacheKey(true), this); + void removeFromCache(AuthCacheImpl authcache) { + Objects.requireNonNull(authcache); + authcache.remove(cacheKey(true), this); if (supportsPreemptiveAuthorization()) { - cache.remove(cacheKey(false), this); + authcache.remove(cacheKey(false), this); } } @@ -483,43 +454,14 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone String cacheKey(boolean includeRealm) { // This must be kept in sync with the getXXXAuth() methods in this // class. - String authenticatorKey = getAuthenticatorKey(); if (includeRealm) { return type + ":" + authScheme + ":" + protocol + ":" - + host + ":" + port + ":" + realm - + ";auth=" + authenticatorKey; + + host + ":" + port + ":" + realm; } else { - return type + ":" + protocol + ":" + host + ":" + port - + ";auth=" + authenticatorKey; + return type + ":" + protocol + ":" + host + ":" + port; } } - String s1, s2; /* used for serialization of pw */ - - @java.io.Serial - // should be safe to keep synchronized here - private synchronized void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject (); - pw = new PasswordAuthentication (s1, s2.toCharArray()); - s1 = null; s2= null; - if (authenticatorKey == null) { - authenticatorKey = AuthenticatorKeys.DEFAULT; - } - } - - @java.io.Serial - // should be safe to keep synchronized here - private synchronized void writeObject(java.io.ObjectOutputStream s) - throws IOException - { - Objects.requireNonNull(authenticatorKey); - s1 = pw.getUserName(); - s2 = new String (pw.getPassword()); - s.defaultWriteObject (); - } - /** * Releases any system or cryptographic resources. * It is up to implementors to override disposeContext() diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticatorKeys.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticatorKeys.java deleted file mode 100644 index 3ae256ca50f..00000000000 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticatorKeys.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * 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.www.protocol.http; - -import java.net.Authenticator; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A class used to tie a key to an authenticator instance. - */ -public final class AuthenticatorKeys { - private AuthenticatorKeys() { - throw new InternalError("Trying to instantiate static class"); - } - - public static final String DEFAULT = "default"; - private static final AtomicLong IDS = new AtomicLong(); - - public static String computeKey(Authenticator a) { - return System.identityHashCode(a) + "-" + IDS.incrementAndGet() - + "@" + a.getClass().getName(); - } - - /** - * Returns a key for the given authenticator. - * - * @param authenticator The authenticator; {@code null} should be - * passed when the {@linkplain - * Authenticator#setDefault(java.net.Authenticator) default} - * authenticator is meant. - * @return A key for the given authenticator, {@link #DEFAULT} for - * {@code null}. - */ - public static String getKey(Authenticator authenticator) { - if (authenticator == null) { - return DEFAULT; - } - return authenticatorKeyAccess.getKey(authenticator); - } - - @FunctionalInterface - public interface AuthenticatorKeyAccess { - public String getKey(Authenticator a); - } - - private static AuthenticatorKeyAccess authenticatorKeyAccess; - public static void setAuthenticatorKeyAccess(AuthenticatorKeyAccess access) { - if (authenticatorKeyAccess == null && access != null) { - authenticatorKeyAccess = access; - } - } - -} diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java index 4dce36840c4..73d5ff98b3a 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -63,10 +63,9 @@ class BasicAuthentication extends AuthenticationInfo { */ public BasicAuthentication(boolean isProxy, String host, int port, String realm, PasswordAuthentication pw, - boolean isUTF8, String authenticatorKey) { + boolean isUTF8) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, - AuthScheme.BASIC, host, port, realm, - Objects.requireNonNull(authenticatorKey)); + AuthScheme.BASIC, host, port, realm); this.auth = authValueFrom(pw, isUTF8); this.pw = pw; } @@ -75,11 +74,9 @@ class BasicAuthentication extends AuthenticationInfo { * Create a BasicAuthentication */ public BasicAuthentication(boolean isProxy, String host, int port, - String realm, String auth, - String authenticatorKey) { + String realm, String auth) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, - AuthScheme.BASIC, host, port, realm, - Objects.requireNonNull(authenticatorKey)); + AuthScheme.BASIC, host, port, realm); this.auth = "Basic " + auth; } @@ -87,11 +84,9 @@ class BasicAuthentication extends AuthenticationInfo { * Create a BasicAuthentication */ public BasicAuthentication(boolean isProxy, URL url, String realm, - PasswordAuthentication pw, boolean isUTF8, - String authenticatorKey) { + PasswordAuthentication pw, boolean isUTF8) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, - AuthScheme.BASIC, url, realm, - Objects.requireNonNull(authenticatorKey)); + AuthScheme.BASIC, url, realm); this.auth = authValueFrom(pw, isUTF8); this.pw = pw; } @@ -116,10 +111,9 @@ class BasicAuthentication extends AuthenticationInfo { * Create a BasicAuthentication */ public BasicAuthentication(boolean isProxy, URL url, String realm, - String auth, String authenticatorKey) { + String auth) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, - AuthScheme.BASIC, url, realm, - Objects.requireNonNull(authenticatorKey)); + AuthScheme.BASIC, url, realm); this.auth = "Basic " + auth; } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java index 0c25025cd09..705c3d4976f 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -296,12 +296,11 @@ class DigestAuthentication extends AuthenticationInfo { */ public DigestAuthentication(boolean isProxy, URL url, String realm, String authMethod, PasswordAuthentication pw, - Parameters params, String authenticatorKey) { + Parameters params){ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, AuthScheme.DIGEST, url, - realm, - Objects.requireNonNull(authenticatorKey)); + realm); this.authMethod = authMethod; this.pw = pw; this.params = params; @@ -309,13 +308,12 @@ class DigestAuthentication extends AuthenticationInfo { public DigestAuthentication(boolean isProxy, String host, int port, String realm, String authMethod, PasswordAuthentication pw, - Parameters params, String authenticatorKey) { + Parameters params) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, AuthScheme.DIGEST, host, port, - realm, - Objects.requireNonNull(authenticatorKey)); + realm); this.authMethod = authMethod; this.pw = pw; this.params = params; diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index b677278459a..8388b11124b 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -310,7 +310,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { protected Handler handler; protected Proxy instProxy; protected volatile Authenticator authenticator; - protected volatile String authenticatorKey; + protected volatile AuthCacheImpl authCache = AuthCacheImpl.getDefault(); private CookieHandler cookieHandler; private final ResponseCache cacheHandler; @@ -447,7 +447,6 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return connectionLock.isHeldByCurrentThread(); } - /* * privileged request password authentication * @@ -539,16 +538,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { "Authenticator must be set before connecting"); } authenticator = Objects.requireNonNull(auth); - authenticatorKey = AuthenticatorKeys.getKey(authenticator); + authCache = AuthCacheImpl.getAuthCacheFor(authenticator); } finally { unlock(); } } - public String getAuthenticatorKey() { - String k = authenticatorKey; - if (k == null) return AuthenticatorKeys.getKey(authenticator); - return k; + public AuthCacheImpl getAuthCache() { + return authCache; } /* @@ -684,8 +681,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { requests.setIfNotSet("If-Modified-Since", fo.format(date)); } // check for preemptive authorization - AuthenticationInfo sauth = AuthenticationInfo.getServerAuth(url, - getAuthenticatorKey()); + AuthenticationInfo sauth = AuthenticationInfo.getServerAuth(url, authCache); if (sauth != null && sauth.supportsPreemptiveAuthorization() ) { // Sets "Authorization" requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method)); @@ -1769,7 +1765,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { // cache proxy authentication info if (proxyAuthentication != null) { // cache auth info on success, domain header not relevant. - proxyAuthentication.addToCache(); + proxyAuthentication.addToCache(authCache); } if (respCode == HTTP_UNAUTHORIZED) { @@ -1817,7 +1813,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { setCookieHeader(); continue; } else { - serverAuthentication.removeFromCache(); + serverAuthentication.removeFromCache(authCache); } } serverAuthentication = getServerAuthentication(srvHdr); @@ -1858,11 +1854,11 @@ public class HttpURLConnection extends java.net.HttpURLConnection { // remove the entry and create a new one BasicAuthentication a = (BasicAuthentication) serverAuthentication.clone(); - serverAuthentication.removeFromCache(); + serverAuthentication.removeFromCache(authCache); a.path = npath; serverAuthentication = a; } - serverAuthentication.addToCache(); + serverAuthentication.addToCache(authCache); } else { // what we cache is based on the domain list in the request DigestAuthentication srv = (DigestAuthentication) @@ -1878,8 +1874,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URL u = newURL (url, path); DigestAuthentication d = new DigestAuthentication ( false, u, realm, "Digest", pw, - digestparams, srv.authenticatorKey); - d.addToCache (); + digestparams); + d.addToCache (authCache); } catch (Exception e) {} } } @@ -2090,7 +2086,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { currentProxyCredentials = proxyAuthentication; return proxyAuthentication; } else { - proxyAuthentication.removeFromCache(); + proxyAuthentication.removeFromCache(authCache); } } proxyAuthentication = getHttpProxyAuthentication(auth); @@ -2231,7 +2227,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { // cache proxy authentication info if (proxyAuthentication != null) { // cache auth info on success, domain header not relevant. - proxyAuthentication.addToCache(); + proxyAuthentication.addToCache(authCache); } if (respCode == HTTP_OK) { @@ -2333,7 +2329,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { AuthenticationInfo pauth = AuthenticationInfo.getProxyAuth(http.getProxyHostUsed(), http.getProxyPortUsed(), - getAuthenticatorKey()); + authCache); if (pauth != null && pauth.supportsPreemptiveAuthorization()) { String value; if (pauth instanceof DigestAuthentication) { @@ -2393,9 +2389,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (realm == null) realm = ""; - proxyAuthKey = AuthenticationInfo.getProxyAuthKey(host, port, realm, - authScheme, getAuthenticatorKey()); - ret = AuthenticationInfo.getProxyAuth(proxyAuthKey); + proxyAuthKey = AuthenticationInfo.getProxyAuthKey(host, port, realm, authScheme); + ret = AuthenticationInfo.getProxyAuth(proxyAuthKey, authCache); if (ret == null) { switch (authScheme) { case BASIC: @@ -2418,8 +2413,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { host, addr, port, "http", realm, scheme, url, RequestorType.PROXY); if (a != null) { - ret = new BasicAuthentication(true, host, port, realm, a, - isUTF8, getAuthenticatorKey()); + ret = new BasicAuthentication(true, host, port, realm, a, isUTF8); } break; case DIGEST: @@ -2431,8 +2425,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { DigestAuthentication.Parameters params = new DigestAuthentication.Parameters(); ret = new DigestAuthentication(true, host, port, realm, - scheme, a, params, - getAuthenticatorKey()); + scheme, a, params); } break; case NTLM: @@ -2471,8 +2464,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ if (tryTransparentNTLMProxy || (!tryTransparentNTLMProxy && a != null)) { - ret = NTLMAuthenticationProxy.proxy.create(true, host, - port, a, getAuthenticatorKey()); + ret = NTLMAuthenticationProxy.proxy.create(true, host, port, a); } /* set to false so that we do not try again */ @@ -2504,8 +2496,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URL u = new URL("http", host, port, "/"); String a = defaultAuth.authString(u, scheme, realm); if (a != null) { - ret = new BasicAuthentication (true, host, port, realm, a, - getAuthenticatorKey()); + ret = new BasicAuthentication (true, host, port, realm, a); // not in cache by default - cache on success } } catch (java.net.MalformedURLException ignored) { @@ -2566,9 +2557,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { domain = p.findValue ("domain"); if (realm == null) realm = ""; - serverAuthKey = AuthenticationInfo.getServerAuthKey(url, realm, authScheme, - getAuthenticatorKey()); - ret = AuthenticationInfo.getServerAuth(serverAuthKey); + serverAuthKey = AuthenticationInfo.getServerAuthKey(url, realm, authScheme); + ret = AuthenticationInfo.getServerAuth(serverAuthKey, authCache); InetAddress addr = null; if (ret == null) { try { @@ -2597,8 +2587,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { url.getHost(), addr, port, url.getProtocol(), realm, scheme, url, RequestorType.SERVER); if (a != null) { - ret = new BasicAuthentication(false, url, realm, a, - isUTF8, getAuthenticatorKey()); + ret = new BasicAuthentication(false, url, realm, a, isUTF8); } break; case DIGEST: @@ -2609,8 +2598,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (a != null) { digestparams = new DigestAuthentication.Parameters(); ret = new DigestAuthentication(false, url, realm, scheme, - a, digestparams, - getAuthenticatorKey()); + a, digestparams); } break; case NTLM: @@ -2655,8 +2643,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ if (tryTransparentNTLMServer || (!tryTransparentNTLMServer && a != null)) { - ret = NTLMAuthenticationProxy.proxy.create(false, - url1, a, getAuthenticatorKey()); + ret = NTLMAuthenticationProxy.proxy.create(false, url1, a); } /* set to false so that we do not try again */ @@ -2680,8 +2667,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { && defaultAuth.schemeSupported(scheme)) { String a = defaultAuth.authString(url, scheme, realm); if (a != null) { - ret = new BasicAuthentication (false, url, realm, a, - getAuthenticatorKey()); + ret = new BasicAuthentication (false, url, realm, a); // not in cache by default - cache on success } } @@ -2932,7 +2918,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { // check for preemptive authorization AuthenticationInfo sauth = - AuthenticationInfo.getServerAuth(url, getAuthenticatorKey()); + AuthenticationInfo.getServerAuth(url, authCache); if (sauth != null && sauth.supportsPreemptiveAuthorization() ) { // Sets "Authorization" requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method)); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java b/src/java.base/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java index 07057c61db1..cd83d951c83 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/NTLMAuthenticationProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -45,22 +45,21 @@ class NTLMAuthenticationProxy { static final boolean supported = proxy != null ? true : false; static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth() : false; + private final Constructor threeArgCtr; private final Constructor fourArgCtr; - private final Constructor sixArgCtr; - private NTLMAuthenticationProxy(Constructor fourArgCtr, - Constructor sixArgCtr) { + private NTLMAuthenticationProxy(Constructor threeArgCtr, + Constructor fourArgCtr) { + this.threeArgCtr = threeArgCtr; this.fourArgCtr = fourArgCtr; - this.sixArgCtr = sixArgCtr; } AuthenticationInfo create(boolean isProxy, URL url, - PasswordAuthentication pw, - String authenticatorKey) { + PasswordAuthentication pw) { try { - return fourArgCtr.newInstance(isProxy, url, pw, authenticatorKey); + return threeArgCtr.newInstance(isProxy, url, pw); } catch (ReflectiveOperationException roe) { finest(roe); } @@ -71,10 +70,9 @@ class NTLMAuthenticationProxy { AuthenticationInfo create(boolean isProxy, String host, int port, - PasswordAuthentication pw, - String authenticatorKey) { + PasswordAuthentication pw) { try { - return sixArgCtr.newInstance(isProxy, host, port, pw, authenticatorKey); + return fourArgCtr.newInstance(isProxy, host, port, pw); } catch (ReflectiveOperationException roe) { finest(roe); } @@ -117,23 +115,21 @@ class NTLMAuthenticationProxy { @SuppressWarnings("unchecked") private static NTLMAuthenticationProxy tryLoadNTLMAuthentication() { Class cl; - Constructor fourArg, sixArg; + Constructor threeArg, fourArg; try { cl = (Class)Class.forName(clazzStr, true, null); if (cl != null) { - fourArg = cl.getConstructor(boolean.class, + threeArg = cl.getConstructor(boolean.class, URL.class, - PasswordAuthentication.class, - String.class); - sixArg = cl.getConstructor(boolean.class, + PasswordAuthentication.class); + fourArg = cl.getConstructor(boolean.class, String.class, int.class, - PasswordAuthentication.class, - String.class); + PasswordAuthentication.class); supportsTA = cl.getDeclaredMethod(supportsTAStr); isTrustedSite = cl.getDeclaredMethod(isTrustedSiteStr, java.net.URL.class); - return new NTLMAuthenticationProxy(fourArg, - sixArg); + return new NTLMAuthenticationProxy(threeArg, + fourArg); } } catch (ClassNotFoundException cnfe) { finest(cnfe); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 97aa5233833..676020a11ba 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,9 +80,7 @@ class NegotiateAuthentication extends AuthenticationInfo { public NegotiateAuthentication(HttpCallerInfo hci) { super(RequestorType.PROXY==hci.authType ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, hci.scheme.equalsIgnoreCase("Negotiate") ? NEGOTIATE : KERBEROS, - hci.url, - "", - AuthenticatorKeys.getKey(hci.authenticator)); + hci.url, ""); this.hci = hci; } 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 d6af0df8383..9bc28a353ab 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -46,7 +46,7 @@ import java.util.StringTokenizer; import javax.net.ssl.*; import sun.net.www.http.HttpClient; -import sun.net.www.protocol.http.AuthenticatorKeys; +import sun.net.www.protocol.http.AuthCacheImpl; import sun.net.www.protocol.http.HttpURLConnection; import sun.security.action.*; @@ -335,11 +335,10 @@ final class HttpsClient extends HttpClient } if (ret != null) { - String ak = httpuc == null ? AuthenticatorKeys.DEFAULT - : httpuc.getAuthenticatorKey(); + AuthCacheImpl ak = httpuc == null ? null : httpuc.getAuthCache(); boolean compatible = ((ret.proxy != null && ret.proxy.equals(p)) || (ret.proxy == null && p == Proxy.NO_PROXY)) - && Objects.equals(ret.getAuthenticatorKey(), ak); + && Objects.equals(ret.getAuthCache(), ak); if (compatible) { ret.lock(); @@ -377,7 +376,7 @@ final class HttpsClient extends HttpClient if (ret == null) { ret = new HttpsClient(sf, url, p, connectTimeout); if (httpuc != null) { - ret.authenticatorKey = httpuc.getAuthenticatorKey(); + ret.authcache = httpuc.getAuthCache(); } } else { @SuppressWarnings("removal") diff --git a/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index 19d169bb1f8..72ef34c5f0f 100644 --- a/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,13 +131,10 @@ public class NTLMAuthentication extends AuthenticationInfo { * If this notation is not used, then the domain will be taken * from a system property: "http.auth.ntlm.domain". */ - public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw, - String authenticatorKey) { + public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, AuthScheme.NTLM, - url, - "", - Objects.requireNonNull(authenticatorKey)); + url, ""); init (pw); } @@ -174,14 +171,12 @@ public class NTLMAuthentication extends AuthenticationInfo { * Constructor used for proxy entries */ public NTLMAuthentication(boolean isProxy, String host, int port, - PasswordAuthentication pw, - String authenticatorKey) { + PasswordAuthentication pw) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, AuthScheme.NTLM, host, port, - "", - Objects.requireNonNull(authenticatorKey)); + ""); init (pw); } diff --git a/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index d528d7265a7..d9eaabe2b4f 100644 --- a/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -119,13 +119,11 @@ public class NTLMAuthentication extends AuthenticationInfo { * If this notation is not used, then the domain will be taken * from a system property: "http.auth.ntlm.domain". */ - public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw, - String authenticatorKey) { + public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) { super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, AuthScheme.NTLM, url, - "", - Objects.requireNonNull(authenticatorKey)); + ""); init (pw); } @@ -155,14 +153,12 @@ public class NTLMAuthentication extends AuthenticationInfo { * Constructor used for proxy entries */ public NTLMAuthentication(boolean isProxy, String host, int port, - PasswordAuthentication pw, - String authenticatorKey) { + PasswordAuthentication pw) { super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, AuthScheme.NTLM, host, port, - "", - Objects.requireNonNull(authenticatorKey)); + ""); init (pw); } diff --git a/test/jdk/java/net/Authenticator/B4933582.java b/test/jdk/java/net/Authenticator/B4933582.java deleted file mode 100644 index be6584a297d..00000000000 --- a/test/jdk/java/net/Authenticator/B4933582.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -// Note: this test saves a cache.ser file in the scratch directory, -// which the cache implementation will load its configuration -// from. Therefore adding several @run lines does not work. - -/* - * @test - * @bug 4933582 - * @key intermittent - * @library /test/lib - * @modules java.base/sun.net.www - * java.base/sun.net.www.protocol.http - * - * @run main/othervm B4933582 - */ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.PrintWriter; -import java.net.Authenticator; -import java.net.BindException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; -import java.net.ProxySelector; -import java.net.URL; -import java.net.URLConnection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.concurrent.Executors; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; -import jdk.test.lib.net.URIBuilder; -import sun.net.www.protocol.http.AuthCacheImpl; -import sun.net.www.protocol.http.AuthCacheValue; - -public class B4933582 implements HttpHandler { - - static int count = 0; - static String authstring; - - void errorReply (HttpExchange req, String reply) throws IOException { - req.getResponseHeaders().set("Connection", "close"); - req.getResponseHeaders().set("WWW-Authenticate", reply); - req.sendResponseHeaders(401, -1); - } - - void okReply (HttpExchange req) throws IOException { - req.sendResponseHeaders(200, 0); - try(PrintWriter pw = new PrintWriter(req.getResponseBody())) { - pw.print("Hello ."); - } - } - - static volatile boolean firstTime = true; - - public void handle (HttpExchange req) { - try { - if(req.getRequestHeaders().get("Authorization") != null) { - authstring = req.getRequestHeaders().get("Authorization").get(0); - System.out.println(authstring); - } - if (firstTime) { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"wallyworld\""); - break; - case 1: - /* client stores a username/pw for wallyworld - */ - save (authstring); - okReply (req); - break; - } - } else { - /* check the auth string is premptively set from last time */ - String savedauth = retrieve(); - if (savedauth.equals (authstring)) { - okReply (req); - } else { - System.out.println ("savedauth = " + savedauth); - System.out.println ("authstring = " + authstring); - errorReply (req, "Basic realm=\"wallyworld\""); - } - } - count ++; - } catch (IOException e) { - e.printStackTrace(); - } - } - - void save (String s) { - try { - FileOutputStream f = new FileOutputStream ("auth.save"); - ObjectOutputStream os = new ObjectOutputStream (f); - os.writeObject (s); - } catch (IOException e) { - assert false; - } - } - - String retrieve () { - String s = null; - try { - FileInputStream f = new FileInputStream ("auth.save"); - ObjectInputStream is = new ObjectInputStream (f); - s = (String) is.readObject(); - } catch (Exception e) { - assert false; - } - return s; - } - - static void read (InputStream is) throws IOException { - int c; - System.out.println ("reading"); - while ((c=is.read()) != -1) { - System.out.write (c); - } - System.out.println (""); - System.out.println ("finished reading"); - } - - static void client (String u) throws Exception { - URL url = new URL (u); - System.out.println ("client opening connection to: " + u); - URLConnection urlc = url.openConnection (); - try(InputStream is = urlc.getInputStream ()) { - read (is); - } - } - - static HttpServer server; - - public static void main (String[] args) throws Exception { - B4933582 b4933582 = new B4933582(); - MyAuthenticator auth = new MyAuthenticator (); - Authenticator.setDefault (auth); - ProxySelector.setDefault(ProxySelector.of(null)); // no proxy - InetAddress loopback = InetAddress.getLoopbackAddress(); - CacheImpl cache; - try { - server = HttpServer.create(new InetSocketAddress(loopback, 0), 10); - server.createContext("/", b4933582); - server.setExecutor(Executors.newSingleThreadExecutor()); - server.start(); - cache = new CacheImpl (server.getAddress().getPort()); - AuthCacheValue.setAuthCache (cache); - String serverURL = URIBuilder.newBuilder() - .scheme("http") - .loopback() - .port(server.getAddress().getPort()) - .path("/") - .build() - .toString(); - client(serverURL + "d1/foo.html"); - } finally { - if (server != null) { - server.stop(1); - } - } - - int f = auth.getCount(); - if (f != 1) { - except("Authenticator was called " + f + " times. Should be 1"); - } - - firstTime = false; - - int retries = 0; - cache = new CacheImpl(); - while (true) { - try { - server = HttpServer.create(new InetSocketAddress(loopback, cache.getPort()), 10); - server.createContext("/", b4933582); - server.setExecutor(Executors.newSingleThreadExecutor()); - server.start(); - break; - } catch (BindException e) { - if (retries++ < 5) { - Thread.sleep(200L); - System.out.println("BindException \"" + e.getMessage() - + "\", retrying..."); - continue; - } else { - throw e; - } - } - } - - try { - AuthCacheValue.setAuthCache(cache); - String serverURL = URIBuilder.newBuilder() - .scheme("http") - .loopback() - .port(server.getAddress().getPort()) - .path("/") - .build() - .toString(); - client(serverURL + "d1/foo.html"); - } finally { - if (server != null) { - server.stop(1); - } - } - - f = auth.getCount(); - if (f != 1) { - except("Authenticator was called " + f + " times. Should be 1"); - } - } - - public static void except (String s) { - server.stop(1); - throw new RuntimeException (s); - } - - static class MyAuthenticator extends Authenticator { - MyAuthenticator () { - super (); - } - - volatile int count = 0; - - public PasswordAuthentication getPasswordAuthentication () { - PasswordAuthentication pw; - pw = new PasswordAuthentication ("user", "pass1".toCharArray()); - count ++; - return pw; - } - - public int getCount () { - return (count); - } - } - - static class CacheImpl extends AuthCacheImpl { - HashMap> map; - int port; // need to store the port number the server is using - - CacheImpl () throws IOException { - this (-1); - } - - CacheImpl (int port) throws IOException { - super(); - this.port = port; - File src = new File ("cache.ser"); - if (src.exists()) { - try (ObjectInputStream is = new ObjectInputStream( - new FileInputStream(src))) { - map = (HashMap>)is - .readObject(); - this.port = (Integer)is.readObject (); - System.out.println ("read port from file " + port); - } catch (ClassNotFoundException e) { - assert false; - } - System.out.println ("setMap from cache.ser"); - } else { - map = new HashMap<>(); - } - setMap (map); - } - - int getPort () { - return port; - } - - private void writeMap () { - File dst = new File("cache.ser"); - try { - dst.delete(); - if (!dst.createNewFile()) { - return; - } - } catch (IOException e) { - } - - try (ObjectOutputStream os = new ObjectOutputStream( - new FileOutputStream(dst))) { - os.writeObject(map); - os.writeObject(port); - System.out.println("wrote port " + port); - } catch (IOException e) { - } - } - - public void put (String pkey, AuthCacheValue value) { - System.out.println ("put: " + pkey + " " + value); - super.put (pkey, value); - writeMap(); - } - - public AuthCacheValue get (String pkey, String skey) { - System.out.println ("get: " + pkey + " " + skey); - AuthCacheValue i = super.get (pkey, skey); - System.out.println ("---> " + i); - return i; - } - - public void remove (String pkey, AuthCacheValue value) { - System.out.println ("remove: " + pkey + " " + value); - super.remove (pkey, value); - writeMap(); - } - } -} diff --git a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java index 6145f48523d..4d6a74e760b 100644 --- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java +++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -121,7 +121,6 @@ public class HTTPSetAuthenticatorTest extends HTTPTest { ? 0 : EXPECTED_AUTH_CALLS_PER_TEST; int count; int defaultCount = AUTHENTICATOR.count.get(); - // Connect to the server with a GET request, then with a // POST that contains "Hello World!" // Uses authenticator #1 @@ -283,7 +282,7 @@ public class HTTPSetAuthenticatorTest extends HTTPTest { } static String toString(Authenticator a) { - return sun.net.www.protocol.http.AuthenticatorKeys.getKey(a); + return a == null ? "null" : a.toString(); } } diff --git a/test/jdk/sun/net/www/protocol/http/AuthCache.java b/test/jdk/sun/net/www/protocol/http/AuthCache.java new file mode 100644 index 00000000000..fb9872bc820 --- /dev/null +++ b/test/jdk/sun/net/www/protocol/http/AuthCache.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8304818 + * @modules java.base/sun.net.www.protocol.http + * @library /test/lib + * @build jdk.test.lib.util.ForceGC + * @run main/othervm AuthCache + */ + +import com.sun.net.httpserver.BasicAuthenticator; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.lang.ref.PhantomReference; +import java.net.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import jdk.test.lib.util.ForceGC; + +public class AuthCache { + static class ClientAuth extends Authenticator { + private final String realm; + private final String username; + private final String password; + private AtomicBoolean wasCalled = new AtomicBoolean(); + + private String errorMsg; + + ClientAuth(String realm, String username, String password) { + this.realm = realm; + this.username = username; + this.password = password; + } + + /** + * returns true if getPasswordAuthentication() was called + * since the last time this method was called. The wasCalled + * flag is cleared after each call. + * If an error occurred, a RuntimeException is thrown + * @return + */ + public synchronized boolean wasCalled() { + if (errorMsg != null) + throw new RuntimeException(errorMsg); + + return wasCalled.getAndSet(false); + } + protected synchronized PasswordAuthentication getPasswordAuthentication() { + if (!getRequestingPrompt().equals(realm)) { + errorMsg = String.format("Error: %s expected as realm, received %s", realm, getRequestingPrompt()); + } + wasCalled.set(true); + return new PasswordAuthentication(username, password.toCharArray()); + } + } + + static final HttpHandler handler = (HttpExchange exch) -> { + exch.sendResponseHeaders(200, -1); + exch.close(); + }; + + static class ServerAuth extends BasicAuthenticator { + private final String user, pass; + + ServerAuth(String realm, String user, String pass) { + super(realm); + this.user = user; + this.pass = pass; + } + + @Override + public boolean checkCredentials(String username, String password) { + return username.equals(user) && password.equals(pass); + } + } + + /** + * Creates two Authenticators and two realms ("r1" and "r2") + * "r1" uses context "/path1" credentials = user1/pass1 + * "r2" uses context "/path2" credentials = user2/pass2 + * + * 1) Send request to "r1" and "r2" expect both authenticators to be called + * cache size should be 4 + * + * 2) Send request to "r1" and "r2". Authenticators should not be called (cache) + * + * 3) Clear reference to "r1" and call gc. + * cache size should be 2 + * + * 4) Send request to "r1" and "r2". "r1" auth should be called, but not "r2" + * cache size should be 4 + */ + public static void main(String[] args) throws IOException { + var clauth1 = new ClientAuth("r1", "user1", "pass1"); + PhantomReference ref = new PhantomReference<>(clauth1, null); + var clauth2 = new ClientAuth("r2", "user2", "pass2"); + var server = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0); + var ctx1 = server.createContext("/path1", handler); + ctx1.setAuthenticator(new ServerAuth("r1", "user1", "pass1")); + + var ctx2 = server.createContext("/path2", handler); + ctx2.setAuthenticator(new ServerAuth("r2", "user2", "pass2")); + var addr = server.getAddress(); + var url1 = URI.create("http://" + addr.getHostName() + ":" + addr.getPort() + "/path1/").toURL(); + var url2 = URI.create("http://" + addr.getHostName() + ":" + addr.getPort() + "/path2/").toURL(); + server.start(); + + sendRequest(url1, url2, clauth1, clauth2, true, true); + sendRequest(url1, url2, clauth1, clauth2, false, false); + clauth1 = null; + ForceGC.wait(() -> ref.refersTo(null)); + delay(1); + clauth1 = new ClientAuth("r1", "user1", "pass1"); + sendRequest(url1, url2, clauth1, clauth2, true, false); + System.out.println("Passed"); + server.stop(0); + } + + static void delay(int seconds) { + try { + Thread.sleep(seconds * 1000); + } catch (InterruptedException e) { + } + } + + static void sendRequest(URL u1, URL u2, ClientAuth a1, ClientAuth a2, boolean auth1Called, boolean auth2Called) throws IOException { + var urlc1 = (HttpURLConnection)u1.openConnection(); + urlc1.setAuthenticator(a1); + var urlc2 = (HttpURLConnection)u2.openConnection(); + urlc2.setAuthenticator(a2); + + var is1 = urlc1.getInputStream(); + is1.readAllBytes(); + is1.close(); + var is2 = urlc2.getInputStream(); + is2.readAllBytes(); + is2.close(); + urlc1 = urlc2 = null; + + boolean a1Called = a1.wasCalled(); + boolean a2Called = a2.wasCalled(); + if (a1Called && !auth1Called) + throw new RuntimeException("a1Called && !auth1Called"); + if (!a1Called && auth1Called) + throw new RuntimeException("!a1Called && auth1Called"); + if (a2Called && !auth2Called) + throw new RuntimeException("a2Called && !auth2Called"); + if (!a2Called && auth2Called) + throw new RuntimeException("!a2Called && auth2Called"); + } +} From 937dd3456c68d72ef300d0947de5f67041676d83 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 24 Apr 2023 19:29:42 +0000 Subject: [PATCH 107/288] 8306775: Problemlist runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java Reviewed-by: dcubed --- test/hotspot/jtreg/ProblemList.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 289102d7633..6d4ce15ce62 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -101,6 +101,10 @@ runtime/CompressedOops/CompressedClassPointers.java 8305765 generic-all runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/Thread/TestAlwaysPreTouchStacks.java 8305416 generic-all runtime/ErrorHandling/TestDwarf.java 8305489 linux-all +runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#allDisabled 8306774 generic-all +runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#guaranteedNoADI 8306774 generic-all +runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#allEnabled 8306774 generic-all +runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#guaranteedNoMUDT 8306774 generic-all applications/jcstress/copy.java 8229852 linux-all From 328e512d12f6fd1d37cf1778ba68fa7b8ff1b8e3 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Mon, 24 Apr 2023 19:35:51 +0000 Subject: [PATCH 108/288] 8306780: ProblemList java/lang/Thread/virtual/HoldsLock.java#id0 in Xcomp Reviewed-by: darcy --- test/jdk/ProblemList-Xcomp.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index 59a7fad67e9..66bd2c63574 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -28,4 +28,4 @@ ############################################################################# java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all - +java/lang/Thread/virtual/HoldsLock.java 8305919 generic-all From 0dc03c9d544ac431a8932c4fee3f5f82b8fb64d2 Mon Sep 17 00:00:00 2001 From: Tyler Steele Date: Mon, 24 Apr 2023 20:32:49 +0000 Subject: [PATCH 109/288] 8305922: [aix,linux] Avoid comparing 'this' to nullptr Reviewed-by: mdoerr, dholmes --- src/hotspot/os/aix/osThread_aix.cpp | 1 - src/hotspot/os/linux/osThread_linux.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/hotspot/os/aix/osThread_aix.cpp b/src/hotspot/os/aix/osThread_aix.cpp index ba564899253..4049d6b58b7 100644 --- a/src/hotspot/os/aix/osThread_aix.cpp +++ b/src/hotspot/os/aix/osThread_aix.cpp @@ -34,7 +34,6 @@ #include "runtime/vmThread.hpp" void OSThread::pd_initialize() { - assert(this != nullptr, "check"); _thread_id = 0; _kernel_thread_id = 0; _siginfo = nullptr; diff --git a/src/hotspot/os/linux/osThread_linux.cpp b/src/hotspot/os/linux/osThread_linux.cpp index eb4d062511c..9c77cb32f6d 100644 --- a/src/hotspot/os/linux/osThread_linux.cpp +++ b/src/hotspot/os/linux/osThread_linux.cpp @@ -30,7 +30,6 @@ #include void OSThread::pd_initialize() { - assert(this != nullptr, "check"); _thread_id = 0; _pthread_id = 0; _siginfo = nullptr; From 2ea62c136925299d4b767a0149419e7e9de3629a Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 24 Apr 2023 21:23:56 +0000 Subject: [PATCH 110/288] 8303276: Secondary assertion failure in AdapterHandlerLibrary::contains during crash reporting Reviewed-by: iklam, stuefe --- src/hotspot/share/classfile/classLoaderDataGraph.cpp | 3 +-- src/hotspot/share/runtime/mutexLocker.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index 7a1c499b9e3..c4241749fcf 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -45,7 +45,6 @@ #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" -#include "utilities/vmError.hpp" volatile size_t ClassLoaderDataGraph::_num_array_classes = 0; volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0; @@ -476,7 +475,7 @@ bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { #endif // PRODUCT bool ClassLoaderDataGraph::is_valid(ClassLoaderData* loader_data) { - DEBUG_ONLY( if (!VMError::is_error_reported()) { assert_locked_or_safepoint(ClassLoaderDataGraph_lock); } ) + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); if (loader_data != nullptr) { if (loader_data == ClassLoaderData::the_null_class_loader_data()) { return true; diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 5be72c4e663..a46f0ba0063 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -30,9 +30,9 @@ #include "memory/universe.hpp" #include "runtime/javaThread.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/os.inline.hpp" #include "runtime/safepoint.hpp" #include "runtime/vmThread.hpp" +#include "utilities/vmError.hpp" // Mutexes used in the VM (see comment in mutexLocker.hpp): @@ -166,7 +166,7 @@ static int _num_mutex; #ifdef ASSERT void assert_locked_or_safepoint(const Mutex* lock) { - if (DebuggingContext::is_enabled()) return; + if (DebuggingContext::is_enabled() || VMError::is_error_reported()) return; // check if this thread owns the lock (common case) assert(lock != nullptr, "Need non-null lock"); if (lock->owned_by_self()) return; @@ -177,7 +177,7 @@ void assert_locked_or_safepoint(const Mutex* lock) { // a weaker assertion than the above void assert_locked_or_safepoint_weak(const Mutex* lock) { - if (DebuggingContext::is_enabled()) return; + if (DebuggingContext::is_enabled() || VMError::is_error_reported()) return; assert(lock != nullptr, "Need non-null lock"); if (lock->is_locked()) return; if (SafepointSynchronize::is_at_safepoint()) return; @@ -187,7 +187,7 @@ void assert_locked_or_safepoint_weak(const Mutex* lock) { // a stronger assertion than the above void assert_lock_strong(const Mutex* lock) { - if (DebuggingContext::is_enabled()) return; + if (DebuggingContext::is_enabled() || VMError::is_error_reported()) return; assert(lock != nullptr, "Need non-null lock"); if (lock->owned_by_self()) return; fatal("must own lock %s", lock->name()); From b5362dadc59570d1f7fd7899be5ec11187168a16 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 25 Apr 2023 02:45:22 +0000 Subject: [PATCH 111/288] 8306484: Open source several AWT Choice jtreg tests Reviewed-by: serb --- .../awt/Choice/ChoiceConsumeMouseEvents.java | 125 +++++++ .../java/awt/Choice/ChoiceFocusLostTest.java | 116 ++++++ .../jdk/java/awt/Choice/ChoiceFreezeTest.java | 132 +++++++ .../awt/Choice/ChoiceGeneratesItemEvents.java | 129 +++++++ .../awt/Choice/ChoiceHandleMouseEvent.java | 206 +++++++++++ .../awt/Choice/ChoiceHandleMouseEvent_2.java | 340 ++++++++++++++++++ 6 files changed, 1048 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java create mode 100644 test/jdk/java/awt/Choice/ChoiceFocusLostTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceFreezeTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java create mode 100644 test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java create mode 100644 test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java diff --git a/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java b/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java new file mode 100644 index 00000000000..c257cf9ff08 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6251988 + @summary PIT: Choice consumes MouseReleased, MouseClicked events when clicking it with left button, + @key headful +*/ + +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceConsumeMouseEvents { + + static volatile Frame frame; + static volatile Robot robot; + static volatile Choice choice1 = new Choice(); + static volatile boolean mousePressed = false; + static volatile boolean mouseReleased = false; + static volatile boolean mouseClicked = false; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + for (int i = 1; i<10; i++){ + choice1.add("item-0"+i); + } + choice1.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + mousePressed = true; + System.out.println(me); + } + public void mouseReleased(MouseEvent me) { + mouseReleased = true; + System.out.println(me); + } + public void mouseClicked(MouseEvent me) { + mouseClicked = true; + System.out.println(me); + } + }); + + frame = new Frame("ChoiceConsumeMouseEvents"); + frame.add(choice1); + frame.setSize(400, 400); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + static void runTest() { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK, 0); + robot.delay(100); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK, 100); + } catch (Throwable e) { + throw new RuntimeException("Test failed. Exception thrown: "+e); + } + } + + static void testMouseClick(int button, int delay) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(button); + robot.delay(delay); + robot.mouseRelease(button); + robot.delay(200); + if (!(mousePressed && + mouseReleased && + mouseClicked)) + { + throw new RuntimeException("Test failed. Choice should generate PRESSED, RELEASED, CLICKED events"); + } else { + System.out.println("Test passed. Choice generated MouseDragged PRESSED, RELEASED, CLICKED events"); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java b/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java new file mode 100644 index 00000000000..75ff15ea8fc --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4338368 + @summary Tests that choice doesn't throw spurious mouse events when losing focus + @key headful +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceFocusLostTest { + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(1000); + if (!client.isPassed()) { + throw new RuntimeException("Test failed: choice fires spurious events"); + } else { + System.out.println("Test passed."); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static volatile Frame frame; + static volatile ChoiceBug client; + + static void createUI() { + frame = new Frame("ChoiceFocusLostTest"); + client = new ChoiceBug(); + frame.add(client); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} + +class ChoiceBug extends Panel { + + volatile boolean passed = true; + + public ChoiceBug() { + Choice choice = new Choice(); + choice.add("item-1"); + choice.add("item-2"); + Button button = new Button("Button"); + add(choice); + add(button); + choice.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent me) { + passed = false; + } + public void mouseClicked(MouseEvent me) { + passed = false; + } + }); + choice.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Focus Gained"); + System.out.println(fe); + } + public void focusLost(FocusEvent fe) { + System.out.println("Got expected FocusLost event."); + System.out.println(fe); + } + }); + setSize(400, 400); + choice.requestFocus(); + } + + public boolean isPassed() { + return passed; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceFreezeTest.java b/test/jdk/java/awt/Choice/ChoiceFreezeTest.java new file mode 100644 index 00000000000..af7082a54f5 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceFreezeTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4303064 + @summary Tests that choice doesn't freeze display when its container is + disabled and enabled after. + @key headful +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceFreezeTest { + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static volatile Frame frame; + static volatile ChoiceFreezeBug client; + + static void createUI() { + frame = new Frame("ChoiceFreezeTest"); + client = new ChoiceFreezeBug(); + frame.add(client); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + client.init(); + } + + static void runTest() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(2000); + robot.mouseMove(client.choice.getLocationOnScreen().x + 1, client.choice.getLocationOnScreen().y + 1); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.mouseMove(client.button.getLocationOnScreen().x + 3, client.button.getLocationOnScreen().y + 3); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(6000); + + if (!client.isPassed()) { + throw new RuntimeException("Test failed: display is frozen."); + } + } +} + +class ChoiceFreezeBug extends Panel { + + volatile Button button; + volatile Choice choice; + volatile ChoiceMouseListener listener = new ChoiceMouseListener(); + + public ChoiceFreezeBug() { + choice = new Choice(); + choice.addItem("Item 1"); + choice.addItem("Item 2"); + button = new Button("Button"); + add(choice); + add(button); + button.addMouseListener(listener); + setEnabled(false); + } + + void init() { + setEnabled(true); + choice.requestFocus(); + } + + public boolean isPassed() { + return listener.isPassed(); + } +} + +class ChoiceMouseListener extends MouseAdapter { + + volatile boolean passed = false; + + public void mouseReleased(MouseEvent e) { + passed = true; + } + + public void mousePressed(MouseEvent e) { + passed = true; + } + + public boolean isPassed() { + return passed; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java b/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java new file mode 100644 index 00000000000..1d4a3702d50 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6239941 + @summary Choice triggers ItemEvent when selecting an item with right mouse button, Xtoolkit + @key headful + @requires (os.family == "linux") +*/ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; + +public class ChoiceGeneratesItemEvents implements ItemListener { + + public static void main(String[] args) throws Exception { + if (!System.getProperty("os.name").toLowerCase().startsWith("linux")) { + System.out.println("This test is for Linux only"); + return; + } + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + + } + } + } + + static volatile Frame frame; + static volatile Robot robot; + static volatile Choice choice1; + static volatile boolean passed = true; + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++){ + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + choice1.addItemListener(new ChoiceGeneratesItemEvents()); + frame = new Frame("ChoiceGeneratesItemEvents"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + testMousePressOnChoice(InputEvent.BUTTON2_DOWN_MASK); + testMousePressOnChoice(InputEvent.BUTTON3_DOWN_MASK); + if (!passed) { + throw new RuntimeException("Test failed."); + } else { + System.out.println("Test passed. "); + } + } + + static void testMousePressOnChoice(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(2000); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 2 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (!color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice wasn't open with LEFTMOUSE button." +button); + } + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + 5*choice1.getHeight()); + robot.delay(200); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + public void itemStateChanged(ItemEvent ie) { + System.err.println("Opened Choice generated ItemEvent on RIGHT/MIDDLE mouse press." +ie); + passed = false; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java b/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java new file mode 100644 index 00000000000..1fd80a2b849 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5003166 + @summary REG:Mouse button not validated before bringing up the drop-down menu for choice + @key headful + @requires (os.family == "linux" | os.family == "windows") +*/ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceHandleMouseEvent { + static Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + + public static void main(String[] args) throws Exception { + String os = System.getProperty("os.name").toLowerCase(); + if (!os.startsWith("windows") && !os.startsWith("linux")) { + System.out.println("This test is only for Windows and Linux"); + return; + } + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + choice1.add("item-01"); + choice1.add("item-02"); + choice1.add("item-03"); + choice1.add("item-04"); + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + frame = new Frame("ChoiceHandleMouseEvent"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + /* + * Stage 1: Choice should only opens with LEFTMOUSE click. + * Should only pass on Windows or XAWT. + * Choice on motif might be opened only by click on small box + * in the right side. + */ + testPressMouseButton(InputEvent.BUTTON2_DOWN_MASK); + testPressMouseButton(InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 1: Choice should only opens with LEFT BUTTON."); + + /* + * Stage 2: Choice should only change its value if pressed + * mouse button is LEFTMOUSE. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testPressMouseButton_2(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testPressMouseButton_2(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 2: Choice should not change its value if pressed mouse buttonis not left."); + + /* + * Stage 3: Choice should only react on drags with LEFTMOUSE button. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testDragMouseButton(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testDragMouseButton(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 3: Choice should only react on drags with LEFTMOUSE button."); + } + + static void testPressMouseButton(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice opens with "+button); + } else { + System.out.println("Stage 1 passed."+ button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void testPressMouseButton_2(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + 2 * choice1.getHeight()); + robot.mousePress(button); + robot.mouseRelease(button); + + System.out.println(); + + if (choice1.getSelectedIndex() == 0) { + System.out.println("Stage 2 passed." + openButton +":"+button); + } else { + throw new RuntimeException("Stage 2 failed." + openButton +":"+button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void testDragMouseButton(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + robot.mousePress(button); + dragMouse(pt.x + choice1.getWidth()/2, pt.y + + choice1.getHeight()/2, + pt.x + choice1.getWidth()/2, + pt.y + 2 * choice1.getHeight()); + robot.mouseRelease(button); + + if (choice1.getSelectedIndex() == 0 ){ + System.out.println("Stage 3 passed." + openButton +":"+button); + // System.out.println("choice1.getSelectedIndex()" + choice1.getSelectedIndex()); + } else { + throw new RuntimeException("Stage 3 failed." + openButton +":"+button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void dragMouse(int x0, int y0, int x1, int y1) { + int curX = x0; + int curY = y0; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; + + while (curX != x1){ + curX += dx; + robot.mouseMove(curX, curY); + } + while (curY != y1 ){ + curY += dy; + robot.mouseMove(curX, curY); + } + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java b/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java new file mode 100644 index 00000000000..ba726b682d2 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6239944 + @summary PIT: Right clicking on the scrollbar of the choice's dropdown disposes the drop-down, on XToolkit + @key headful + @requires (os.family == "linux" | os.family == "windows") +*/ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceHandleMouseEvent_2 { + + static Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + static boolean isWindows; + + public static void main(String[] args) throws Exception { + String os = System.getProperty("os.name").toLowerCase(); + if (!os.startsWith("windows") && !os.startsWith("linux")) { + System.out.println("This test is only for Windows and Linux"); + return; + } + isWindows = os.startsWith("windows"); + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<50; i++) { + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + frame = new Frame("ChoiceHandleMouseEvent_2"); + frame.setBackground(Color.green); + Panel panel = new Panel(); + panel.setBackground(Color.green); + panel.add(choice1); + frame.add(panel); + frame.setSize(300,300); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + + /* + * Stage 1. Choice should be closed if user dragged mouse + * outside of Choice after opening it. + * Should only pass on Windows or XAWT. + * Choice on motif might be opened only by click on small box + * in the right side. + */ + testDragMouseButtonOut(InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 1: Choice should be closed if mouse dragged out."); + + /* + * Stage 2: Choice should be closed if LeftMouse drag finished + * on Scrollbar. This involeves only one + * MousePress and one MouseRelease event + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testDragMouseButtonOnSB(InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 2: Choice should be closed if " + + "LeftMouse drag finished on Scrollbar."); + + /* + * Stage 3: Pressing RIGHT/MIDDLE MouseButton on Scrollbar + * shouldn't close Choice's pop-down menu. + * Pressing LEFT MouseButton shouldn't close it too. It should + * scroll it. + * This is an unstable test because we doesn't have an API to + * get Scrollbar from Choice. There is a possibility not to + * hit the scrollbar that couldn't been predicted. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testPressOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testPressOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 3: Choice correctly reacts on mouse click on its Scrollbar."); + + /* + * Stage 4: Choice should close its popdown menu if user opened a Choice then + * releases Mouse and then presses Mouse again and dragged it on Choice's Scrollbar + * This involves only one MousePress and one MouseRelease + * event, so it differs from Stage 2. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu or scrollbar + testDragMouseOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 4: Choice should close if user opened a " + + "Choice then releases Mouse and then presses Mouse again " + + "and drag it on Choice's Scrollbar ."); + } + + + //Stage 4 + static void testDragMouseOnScrollbar(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + /*X-coordinate should be closer to right edge of Choice, so + divider 4 is used. */ + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth() - choice1.getHeight()/4, pt.y + 5*choice1.getHeight()); + robot.mouseRelease(button); + robot.delay(200); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (color.equals(Color.red)) { + throw new RuntimeException( + "Test failed. Choice didn't close after drag without firstPress on ScrollBar " + button); + } else { + System.out.println("Stage 4 passed."+ button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + //stage 3 + static void testPressOnScrollbar(int openButton, int button) { + if (!isWindows) { + return; // Windows-only tests. + } + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + /*X-coordinate should be closer to right edge of Choice, so + divide by 4 is used. */ + int px = pt.x + choice1.getWidth() - choice1.getHeight()/4; + int py = pt.y + 5*choice1.getHeight(); + robot.mouseMove(px, py); + robot.delay(200); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + System.out.println("x= "+px); + System.out.println("y= "+py); + + /* + This is for Windows only. + On XP theme choice become closed on RightMouseClick over a scrollbar. + A system menu is opened after that. On Classic theme Choice doesn't react on it at all. + */ + boolean isXPTheme = false; + Object themeObject = Toolkit.getDefaultToolkit().getDesktopProperty("win.xpstyle.themeActive"); + // it returns null when Classic theme is active but we should + // check it's boolean value anyway if event it's not null. + if (themeObject != null) { + isXPTheme = ((Boolean)themeObject).booleanValue(); + } + System.out.println("isXPTheme="+isXPTheme); + px = pt.x + choice1.getWidth()/2; + py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + System.out.println("GREEN="+Color.green); + if (isXPTheme && button == InputEvent.BUTTON3_DOWN_MASK) { + if (!color.equals(Color.green)) { + throw new RuntimeException("Stage 3 failed(XP theme). " + + "Choice wasn't closed with pressing button on its Scrollbar" + openButton +":"+button); + } else { + System.out.println("Stage 3 passed(XP theme)." + openButton +":"+button); + } + } else { + if (!color.equals(Color.red)) { + throw new RuntimeException("Stage 3 failed(classic theme). " + + "Choice is being closed with pressing button on its Scrollbar" + openButton +":"+button); + } else { + System.out.println("Stage 3 passed(classic theme)." + openButton +":"+button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + // Stage 1 + static void testDragMouseButtonOut(int button) { + Point pt = choice1.getLocationOnScreen(); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth()*2, pt.y + choice1.getHeight()/2); + robot.mouseRelease(button); + robot.delay(200); + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + // fix 6268989: On Windows Choice shouldn't been closed if + // Mouse dragged outside of Choice after one mouse press. + if (isWindows) { + if (color.equals(Color.red)) { + System.out.println("Stage 1 passed. On Windows Choice shouldn't be " + + "closed if Mouse dragged outside of Choice after one mouse press "+button); + } else { + throw new RuntimeException("Test failed. Choice on Windows shouldn't be " + + "closed after drag outside of Choice after one mouse press "+button); + } + } else { + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice didn't close " + + "after drag outside of Choice "+button); + } else { + System.out.println("Stage 1 passed."+ button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + //stage 2 + static void testDragMouseButtonOnSB(int button) { + Point pt = choice1.getLocationOnScreen(); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + /*X-coordinate should be closer to right edge of Choice, so + divider 4 is used. */ + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth() - choice1.getHeight()/4, pt.y + 5*choice1.getHeight()); + robot.mouseRelease(button); + robot.delay(200); + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (isWindows) { + if (color.equals(Color.red)) { + System.out.println("Stage 2 passed. On Windows Choice shouldn't be " + + " closed if Mouse dragged on its scrollbar "+button); + } else { + throw new RuntimeException("Test failed. On Windows Choice shouldn't be " + + " closed if Mouse dragged on its scrollbar "+button); + } + } else { + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice didn't close after drag on ScrollBar "+button); + } else { + System.out.println("Stage 2 passed."+ button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + static void dragMouse(int x0, int y0, int x1, int y1) { + int curX = x0; + int curY = y0; + int dx = x0 < x1 ? 1 : -1; + int dy = y0 < y1 ? 1 : -1; + + while (curX != x1) { + curX += dx; + robot.mouseMove(curX, curY); + } + while (curY != y1) { + curY += dy; + robot.mouseMove(curX, curY); + } + } +} From f39641ccbd670853b3c021dd4e490151cbc77ed6 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 25 Apr 2023 02:46:13 +0000 Subject: [PATCH 112/288] 8306682: Open source a few more AWT Choice tests Reviewed-by: serb --- .../awt/Choice/ChoiceMouseEventOutbounds.java | 145 +++++++++++++++++ test/jdk/java/awt/Choice/ChoiceMoveTest.java | 106 +++++++++++++ .../awt/Choice/ChoiceStaysOpenedOnTAB.java | 150 ++++++++++++++++++ .../java/awt/Choice/DragOffNoSelectTest.java | 134 ++++++++++++++++ 4 files changed, 535 insertions(+) create mode 100644 test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java create mode 100644 test/jdk/java/awt/Choice/ChoiceMoveTest.java create mode 100644 test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java create mode 100644 test/jdk/java/awt/Choice/DragOffNoSelectTest.java diff --git a/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java b/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java new file mode 100644 index 00000000000..31b8eb97ef0 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6272965 + @summary PIT: Choice triggers MousePressed when pressing mouse outside comp while drop-down is active, XTkt + @key headful +*/ + +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceMouseEventOutbounds { + + static final int DELAY = 100; + static volatile Choice choice1; + static volatile Frame frame; + static volatile Robot robot; + static volatile boolean mousePressed = false; + static volatile boolean mouseReleased = false; + static volatile boolean mouseClicked = false; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++) { + choice1.add("item "+i); + } + + choice1.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + mousePressed = true; + System.out.println(me); + } + public void mouseReleased(MouseEvent me) { + mouseReleased = true; + System.out.println(me); + } + public void mouseClicked(MouseEvent me) { + mouseClicked = true; + System.out.println(me); + } + }); + + frame = new Frame("ChoiceMouseEventOutbounds"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + static void runTest() throws Exception { + // On Windows, Choice will not close its pop-down menu on a RIGHT + // MousePress outside of the Choice. So this scenario isn't + // tested here for that reason. + + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(DELAY*10); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY); + testMouseClick(InputEvent.BUTTON2_DOWN_MASK); + robot.delay(DELAY); + testMouseClick(InputEvent.BUTTON3_DOWN_MASK); + + System.out.println("Test passed: Choice doesn't generate MOUSEPRESS/CLICK/RELEASE outside Choice."); + } + + static void testMouseClick(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(DELAY); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY*3); + + //they are true because we just pressed mouse + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + + //move mouse outside Choice + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y - choice1.getHeight()); + robot.delay(DELAY*3); + robot.mousePress(button); + robot.delay(DELAY); + robot.mouseRelease(button); + + if (mousePressed || mouseReleased || mouseClicked) { + System.out.println("ERROR: "+ mousePressed+","+mouseReleased +","+mouseClicked); + throw new RuntimeException( + "Test failed. Choice shouldn't generate PRESSED, RELEASED, CLICKED events outside "+ button); + } else { + System.out.println( + "Test passed. Choice didn't generated MouseDragged PRESSED, RELEASED, CLICKED events outside "+ button); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(DELAY); + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceMoveTest.java b/test/jdk/java/awt/Choice/ChoiceMoveTest.java new file mode 100644 index 00000000000..878781bb523 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceMoveTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4323906 + @summary Test that Choice location is not updated erroneously + @key headful +*/ + +/** + * summary: The test adds a Choice to a Container with BorderLayout, and + * adds the Container to a Frame with null Layout. When + * the Container is moved in the x direction, the Choice should + * not move in the y direction. + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.Frame; + +public class ChoiceMoveTest { + + static volatile Frame frame; + static volatile Container c; + static volatile Choice ch; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + frame = new Frame("Choice Move Test"); + frame.setSize(500, 500); + frame.setLayout(null); + + c = new Container(); + c.setBackground(Color.green); + frame.add(c); + c.setSize(200, 200); + c.setLocation(100, 100); + c.setLayout(new BorderLayout()); + + ch = new Choice(); + ch.setSize(100, 27); + c.add(ch, BorderLayout.SOUTH); + frame.setVisible(true); + frame.validate(); + } + + static void runTest () throws Exception { + Thread.sleep(1000); + // If this test ever gives us problems, try putting getLocation() in a + // ComponentListener. + int xbefore = ch.getLocation().x; + int ybefore = ch.getLocation().y; + System.out.println("Choice location before: " + xbefore + ", " + ybefore); + + c.setLocation(200, 100); + Thread.sleep(1000); + + java.awt.Toolkit.getDefaultToolkit().sync(); + Thread.sleep(1000); + int xafter = ch.getLocation().x; + int yafter = ch.getLocation().y; + System.out.println("Choice location after: " + xafter + ", " + yafter); + + if (ybefore != yafter) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test failed - Choice should not move in the y direction."); + } + else { + System.out.println("Test passed."); + } + } +} diff --git a/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java b/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java new file mode 100644 index 00000000000..9703a4b52a9 --- /dev/null +++ b/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6239938 + @summary Choice drop-down does not disappear when it loses focus, on XToolkit + @key headful + @requires (os.family == "linux") +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceStaysOpenedOnTAB { + + static volatile Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + + public static void main(String[] args) throws Exception { + + if (!System.getProperty("os.name").toLowerCase().startsWith("linux")) { + System.out.println("This test is for Linux only"); + return; + } + + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++) { + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + Button b1 = new Button("FirstButton"); + Button b2 = new Button("SecondButton"); + frame = new Frame("ChoiceStaysOpenedOnTAB"); + Panel panel = new Panel(); + panel.add(b1); + panel.add(choice1); + panel.add(b2); + frame.add(panel); + frame.setSize(400,400); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + + /* + * Choice should not lose focus while it is opened with + * TAB/Shitf-TAB KeyPress on XAWT. + * Should only pass on XAWT. + */ + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(1000); + + testTABKeyPress(InputEvent.BUTTON1_DOWN_MASK, KeyEvent.VK_TAB, false); + testTABKeyPress(InputEvent.BUTTON1_DOWN_MASK, KeyEvent.VK_TAB, true); + System.out.println("Passed : Choice should not lose focus on TAB key press while it is opened."); + } + + static void testTABKeyPress(int openButton, int keyButton, boolean isShiftUsed) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + Color color = robot.getPixelColor(pt.x + choice1.getWidth()/2, + pt.y + 3 * choice1.getHeight()); + if (!color.equals(Color.red)) { + throw new RuntimeException( + "Choice wasn't opened with LEFTMOUSE button" + openButton +":"+keyButton+":"+isShiftUsed); + } + robot.delay(200); + if (isShiftUsed) { + robot.keyPress(KeyEvent.VK_SHIFT); + } + robot.keyPress(keyButton); + robot.keyRelease(keyButton); + + if (isShiftUsed) { + robot.keyRelease(KeyEvent.VK_SHIFT); + } + + robot.delay(200); + if (!choice1.isFocusOwner()) { + System.out.println("Choice has focus=="+choice1.isFocusOwner()); + throw new RuntimeException( + "Choice has no focus after pressing TAB/Shitf+TAB" + openButton +":"+keyButton+":"+isShiftUsed); + } + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("color got "+color); + if (!color.equals(Color.red)) { + throw new RuntimeException( + "Choice closed after TAB/Shift+TAB key press" + openButton +":"+keyButton+":"+isShiftUsed); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } +} diff --git a/test/jdk/java/awt/Choice/DragOffNoSelectTest.java b/test/jdk/java/awt/Choice/DragOffNoSelectTest.java new file mode 100644 index 00000000000..587fc701e93 --- /dev/null +++ b/test/jdk/java/awt/Choice/DragOffNoSelectTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4902933 + @summary Test that dragging off an unfurled Choice prevents selecting a new item + @key headful +*/ + +import java.awt.Choice; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; + +public class DragOffNoSelectTest implements WindowListener, Runnable { + + static volatile DragOffNoSelectTest testInstance; + static volatile Frame frame; + static volatile Choice theChoice; + static volatile Robot robot; + static final String firstItem = new String("First Choice Item"); + + static volatile Object lock = new Object(); + + public static void main(String[] args) throws Exception { + testInstance = new DragOffNoSelectTest(); + robot = new Robot(); + robot.setAutoDelay(500); + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + frame = new Frame("DragOffNoSelectTest"); + theChoice = new Choice(); + theChoice.add(firstItem); + for (int i = 0; i < 10; i++) { + theChoice.add(new String("Choice Item " + i)); + } + frame.add(theChoice); + frame.addWindowListener(testInstance); + frame.setSize(400, 400); + frame.setLocationRelativeTo(null); + + frame.setVisible(true); + frame.validate(); + } + + static void runTest() throws Exception { + robot.mouseMove(10, 30); + synchronized (lock) { + try { + lock.wait(120000); + } + catch (InterruptedException e) {} + } + robot.waitForIdle(); + + if (!firstItem.equals(theChoice.getSelectedItem())) { + throw new RuntimeException("TEST FAILED - new item was selected"); + } + } + + public void run() { + robot.delay(1000); + // get loc of Choice on screen + Point loc = theChoice.getLocationOnScreen(); + // get bounds of Choice + Dimension size = theChoice.getSize(); + robot.mouseMove(loc.x + size.width - 10, loc.y + size.height / 2); + + robot.setAutoDelay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + robot.mouseMove(loc.x + size.width / 2, loc.y + size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 2*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 3*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + 2*size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + 3*size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + synchronized(lock) { + lock.notify(); + } + } + + public void windowOpened(WindowEvent e) { + System.out.println("windowActivated()"); + Thread testThread = new Thread(testInstance); + testThread.start(); + } + public void windowActivated(WindowEvent e) { } + public void windowDeactivated(WindowEvent e) {} + public void windowClosed(WindowEvent e) {} + public void windowClosing(WindowEvent e) {} + public void windowIconified(WindowEvent e) {} + public void windowDeiconified(WindowEvent e) {} + +} + From 2471919020169aac4499ef40ed37eabd98c90da7 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Tue, 25 Apr 2023 04:16:58 +0000 Subject: [PATCH 113/288] 8304036: Use CommandLine class from shared module Reviewed-by: jjg, mchung --- make/CompileInterimLangtools.gmk | 6 +- make/CompileToolsJdk.gmk | 8 +- make/autoconf/spec.gmk.in | 2 + make/modules/jdk.compiler/Gendata.gmk | 3 +- make/modules/jdk.javadoc/Gendata.gmk | 3 +- .../com/sun/tools/javac/main/CommandLine.java | 295 ------------------ .../com/sun/tools/javac/main/Main.java | 6 +- .../share/classes/module-info.java | 3 +- .../share/classes/module-info.java | 13 +- .../jdk/javadoc/internal/tool/Start.java | 5 +- .../share/classes/module-info.java | 3 +- .../tools/javac/main/AtFileTest.java | 5 +- .../tools/javac/main/EnvVariableTest.java | 9 +- .../tools/jdeps/listdeps/ListModuleDeps.java | 3 +- 14 files changed, 48 insertions(+), 316 deletions(-) delete mode 100644 src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java diff --git a/make/CompileInterimLangtools.gmk b/make/CompileInterimLangtools.gmk index 0be8aa46ded..51263fde3bd 100644 --- a/make/CompileInterimLangtools.gmk +++ b/make/CompileInterimLangtools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -109,7 +109,9 @@ define SetupInterimModule $$(INTERIM_LANGTOOLS_ADD_EXPORTS) \ --patch-module java.base=$(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim \ --add-exports java.base/jdk.internal.javac=java.compiler.interim \ - --add-exports java.base/jdk.internal.javac=jdk.compiler.interim, \ + --add-exports java.base/jdk.internal.javac=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim, \ )) $1_DEPS_INTERIM := $$(addsuffix .interim, $$(filter \ diff --git a/make/CompileToolsJdk.gmk b/make/CompileToolsJdk.gmk index dceca481451..13101c7cccf 100644 --- a/make/CompileToolsJdk.gmk +++ b/make/CompileToolsJdk.gmk @@ -57,7 +57,9 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_JDK, \ JAVAC_FLAGS := \ --add-exports java.desktop/sun.awt=ALL-UNNAMED \ --add-exports java.base/sun.text=ALL-UNNAMED \ - --add-exports java.base/sun.security.util=ALL-UNNAMED, \ + --add-exports java.base/sun.security.util=ALL-UNNAMED \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim, \ )) TARGETS += $(BUILD_TOOLS_JDK) @@ -90,7 +92,9 @@ $(eval $(call SetupJavaCompilation, COMPILE_DEPEND, \ --add-exports jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED, \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim, \ )) DEPEND_SERVICE_PROVIDER := $(BUILDTOOLS_OUTPUTDIR)/depend/META-INF/services/com.sun.source.util.Plugin diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 550c196ed89..6be074f95e0 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -692,6 +692,8 @@ INTERIM_LANGTOOLS_ADD_EXPORTS := \ --add-exports java.base/sun.invoke.util=jdk.compiler.interim \ --add-exports java.base/jdk.internal.javac=java.compiler.interim \ --add-exports java.base/jdk.internal.javac=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim \ # INTERIM_LANGTOOLS_MODULES_COMMA := $(strip $(subst $(SPACE),$(COMMA),$(strip \ $(INTERIM_LANGTOOLS_MODULES)))) diff --git a/make/modules/jdk.compiler/Gendata.gmk b/make/modules/jdk.compiler/Gendata.gmk index 24d4707c54a..e005e703f2c 100644 --- a/make/modules/jdk.compiler/Gendata.gmk +++ b/make/modules/jdk.compiler/Gendata.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 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 @@ -45,6 +45,7 @@ CT_DATA_DESCRIPTION += $(MODULE_SRC)/share/data/symbols/symbols COMPILECREATESYMBOLS_ADD_EXPORTS := \ --add-exports java.base/jdk.internal.javac=java.compiler.interim,jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim,jdk.javadoc.interim \ --add-exports jdk.compiler.interim/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.code=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.util=ALL-UNNAMED \ diff --git a/make/modules/jdk.javadoc/Gendata.gmk b/make/modules/jdk.javadoc/Gendata.gmk index 501b0540c53..412559c5fe1 100644 --- a/make/modules/jdk.javadoc/Gendata.gmk +++ b/make/modules/jdk.javadoc/Gendata.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 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 @@ -43,6 +43,7 @@ CT_DATA_DESCRIPTION += $(TOPDIR)/src/jdk.compiler/share/data/symbols/symbols COMPILECREATESYMBOLS_ADD_EXPORTS := \ --add-exports java.base/jdk.internal=java.compiler.interim,jdk.compiler.interim \ + --add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim,jdk.javadoc.interim \ --add-exports jdk.compiler.interim/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.code=ALL-UNNAMED \ --add-exports jdk.compiler.interim/com.sun.tools.javac.util=ALL-UNNAMED \ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java deleted file mode 100644 index ec6f711f9bc..00000000000 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 1999, 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 com.sun.tools.javac.main; - -import java.io.IOException; -import java.io.Reader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Various utility methods for processing Java tool command line arguments. - * - *

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 or - * deletion without notice. - */ -public class CommandLine { - /** - * Process Win32-style command files for the specified command line - * arguments and return the resulting arguments. A command file argument - * is of the form '@file' where 'file' is the name of the file whose - * contents are to be parsed for additional arguments. The contents of - * the command file are parsed using StreamTokenizer and the original - * '@file' argument replaced with the resulting tokens. Recursive command - * files are not supported. The '@' character itself can be quoted with - * the sequence '@@'. - * @param args the arguments that may contain @files - * @return the arguments, with @files expanded - * @throws IOException if there is a problem reading any of the @files - */ - public static List parse(List args) throws IOException { - List newArgs = new ArrayList<>(); - appendParsedCommandArgs(newArgs, args); - return newArgs; - } - - private static void appendParsedCommandArgs(List newArgs, List args) throws IOException { - for (String arg : args) { - if (arg.length() > 1 && arg.charAt(0) == '@') { - arg = arg.substring(1); - if (arg.charAt(0) == '@') { - newArgs.add(arg); - } else { - loadCmdFile(arg, newArgs); - } - } else { - newArgs.add(arg); - } - } - } - - /** - * Process the given environment variable and appends any Win32-style - * command files for the specified command line arguments and return - * the resulting arguments. A command file argument - * is of the form '@file' where 'file' is the name of the file whose - * contents are to be parsed for additional arguments. The contents of - * the command file are parsed using StreamTokenizer and the original - * '@file' argument replaced with the resulting tokens. Recursive command - * files are not supported. The '@' character itself can be quoted with - * the sequence '@@'. - * @param envVariable the env variable to process - * @param args the arguments that may contain @files - * @return the arguments, with environment variable's content and expansion of @files - * @throws IOException if there is a problem reading any of the @files - * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote - */ - public static List parse(String envVariable, List args) - throws IOException, UnmatchedQuote { - - List inArgs = new ArrayList<>(); - appendParsedEnvVariables(inArgs, envVariable); - inArgs.addAll(args); - List newArgs = new ArrayList<>(); - appendParsedCommandArgs(newArgs, inArgs); - return newArgs; - } - - private static void loadCmdFile(String name, List args) throws IOException { - try (Reader r = Files.newBufferedReader(Paths.get(name), Charset.defaultCharset())) { - Tokenizer t = new Tokenizer(r); - String s; - while ((s = t.nextToken()) != null) { - args.add(s); - } - } - } - - public static class Tokenizer { - private final Reader in; - private int ch; - - public Tokenizer(Reader in) throws IOException { - this.in = in; - ch = in.read(); - } - - public String nextToken() throws IOException { - skipWhite(); - if (ch == -1) { - return null; - } - - StringBuilder sb = new StringBuilder(); - char quoteChar = 0; - - while (ch != -1) { - switch (ch) { - case ' ': - case '\t': - case '\f': - if (quoteChar == 0) { - return sb.toString(); - } - sb.append((char) ch); - break; - - case '\n': - case '\r': - return sb.toString(); - - case '\'': - case '"': - if (quoteChar == 0) { - quoteChar = (char) ch; - } else if (quoteChar == ch) { - quoteChar = 0; - } else { - sb.append((char) ch); - } - break; - - case '\\': - if (quoteChar != 0) { - ch = in.read(); - switch (ch) { - case '\n': - case '\r': - while (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f') { - ch = in.read(); - } - continue; - - case 'n': - ch = '\n'; - break; - case 'r': - ch = '\r'; - break; - case 't': - ch = '\t'; - break; - case 'f': - ch = '\f'; - break; - } - } - sb.append((char) ch); - break; - - default: - sb.append((char) ch); - } - - ch = in.read(); - } - - return sb.toString(); - } - - void skipWhite() throws IOException { - while (ch != -1) { - switch (ch) { - case ' ': - case '\t': - case '\n': - case '\r': - case '\f': - break; - - case '#': - ch = in.read(); - while (ch != '\n' && ch != '\r' && ch != -1) { - ch = in.read(); - } - break; - - default: - return; - } - - ch = in.read(); - } - } - } - - @SuppressWarnings("fallthrough") - private static void appendParsedEnvVariables(List newArgs, String envVariable) - throws UnmatchedQuote { - - if (envVariable == null) { - return; - } - String in = System.getenv(envVariable); - if (in == null || in.trim().isEmpty()) { - return; - } - - final char NUL = (char)0; - final int len = in.length(); - - int pos = 0; - StringBuilder sb = new StringBuilder(); - char quote = NUL; - char ch; - - loop: - while (pos < len) { - ch = in.charAt(pos); - switch (ch) { - case '\"': case '\'': - if (quote == NUL) { - quote = ch; - } else if (quote == ch) { - quote = NUL; - } else { - sb.append(ch); - } - pos++; - break; - case '\f': case '\n': case '\r': case '\t': case ' ': - if (quote == NUL) { - newArgs.add(sb.toString()); - sb.setLength(0); - while (ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') { - pos++; - if (pos >= len) { - break loop; - } - ch = in.charAt(pos); - } - break; - } - // fall through - default: - sb.append(ch); - pos++; - } - } - if (sb.length() != 0) { - newArgs.add(sb.toString()); - } - if (quote != NUL) { - throw new UnmatchedQuote(envVariable); - } - } - - public static class UnmatchedQuote extends Exception { - private static final long serialVersionUID = 0; - - public final String variableName; - - UnmatchedQuote(String variable) { - this.variableName = variable; - } - } -} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java index 10e8ac7c854..df4ba222139 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -52,7 +52,6 @@ import com.sun.tools.javac.file.CacheFSInfo; import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.jvm.Target; -import com.sun.tools.javac.main.CommandLine.UnmatchedQuote; import com.sun.tools.javac.platform.PlatformDescription; import com.sun.tools.javac.processing.AnnotationProcessingError; import com.sun.tools.javac.resources.CompilerProperties.Errors; @@ -61,6 +60,9 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo; import com.sun.tools.javac.util.Log.PrefixKind; import com.sun.tools.javac.util.Log.WriterKind; +import jdk.internal.opt.CommandLine; +import jdk.internal.opt.CommandLine.UnmatchedQuote; + /** This class provides a command line interface to the javac compiler. * *

This is NOT part of any supported API. diff --git a/src/jdk.compiler/share/classes/module-info.java b/src/jdk.compiler/share/classes/module-info.java index 4c0cca06929..79f2b8f2704 100644 --- a/src/jdk.compiler/share/classes/module-info.java +++ b/src/jdk.compiler/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -217,6 +217,7 @@ import javax.tools.StandardLocation; */ module jdk.compiler { requires transitive java.compiler; + requires jdk.internal.opt; requires jdk.zipfs; exports com.sun.source.doctree; diff --git a/src/jdk.internal.opt/share/classes/module-info.java b/src/jdk.internal.opt/share/classes/module-info.java index 778970a65e1..67ed1410560 100644 --- a/src/jdk.internal.opt/share/classes/module-info.java +++ b/src/jdk.internal.opt/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -29,6 +29,13 @@ * @since 9 */ module jdk.internal.opt { - exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell; - exports jdk.internal.opt to jdk.jartool, jdk.jlink, jdk.jpackage; + exports jdk.internal.joptsimple to + jdk.jlink, + jdk.jshell; + exports jdk.internal.opt to + jdk.compiler, + jdk.jartool, + jdk.javadoc, + jdk.jlink, + jdk.jpackage; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java index 7237778d0da..3f06cf1ae20 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -50,12 +50,13 @@ import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.main.Arguments; -import com.sun.tools.javac.main.CommandLine; import com.sun.tools.javac.util.ClientCodeException; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.StringUtils; +import jdk.internal.opt.CommandLine; + import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet.Option; import jdk.javadoc.doclet.DocletEnvironment; diff --git a/src/jdk.javadoc/share/classes/module-info.java b/src/jdk.javadoc/share/classes/module-info.java index db25f03e918..ee84482204a 100644 --- a/src/jdk.javadoc/share/classes/module-info.java +++ b/src/jdk.javadoc/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,6 +61,7 @@ module jdk.javadoc { requires transitive java.compiler; requires transitive jdk.compiler; + requires jdk.internal.opt; exports jdk.javadoc.doclet; diff --git a/test/langtools/tools/javac/main/AtFileTest.java b/test/langtools/tools/javac/main/AtFileTest.java index 0308b66b1be..b76de252b45 100644 --- a/test/langtools/tools/javac/main/AtFileTest.java +++ b/test/langtools/tools/javac/main/AtFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,6 +26,7 @@ * @bug 8166472 8162810 * @summary Align javac support for at-files with launcher support * @modules jdk.compiler/com.sun.tools.javac.main + * @modules jdk.internal.opt/jdk.internal.opt */ import java.io.IOException; @@ -34,7 +35,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.sun.tools.javac.main.CommandLine.Tokenizer; +import jdk.internal.opt.CommandLine.Tokenizer; public class AtFileTest { diff --git a/test/langtools/tools/javac/main/EnvVariableTest.java b/test/langtools/tools/javac/main/EnvVariableTest.java index cba7f7f02be..87574c3ba6e 100644 --- a/test/langtools/tools/javac/main/EnvVariableTest.java +++ b/test/langtools/tools/javac/main/EnvVariableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -27,6 +27,7 @@ * @summary Check JDK_JAVA_OPTIONS parsing behavior * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.main + * @modules jdk.internal.opt/jdk.internal.opt * @build toolbox.ToolBox toolbox.TestRunner * @run main EnvVariableTest */ @@ -41,7 +42,7 @@ import java.util.List; import toolbox.*; -import com.sun.tools.javac.main.CommandLine; +import jdk.internal.opt.CommandLine; public class EnvVariableTest extends TestRunner { final String testClasses; @@ -118,7 +119,9 @@ public class EnvVariableTest extends TestRunner { void test(String full, String... expectedArgs) throws Exception { task.envVar("JDK_JAVAC_OPTIONS", full); - task.args("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + task.args( + "--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "--add-exports", "jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED", "-cp", testClasses, "EnvVariableTest$Tester"); Task.Result tr = task.run(Task.Expect.SUCCESS); String expected = Tester.arrayToString(expectedArgs); diff --git a/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java b/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java index 0f014f4bc36..a9e9f78b28d 100644 --- a/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java +++ b/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -97,6 +97,7 @@ public class ListModuleDeps { "java.base/jdk.internal.misc", "java.base/sun.reflect.annotation", "java.compiler", + "jdk.internal.opt/jdk.internal.opt", } }, }; From 8063aa2e4a71d3f9f7867563bae92a4f75097b2a Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 25 Apr 2023 04:19:32 +0000 Subject: [PATCH 114/288] 8306695: Divide by zero in G1Policy::logged_cards_processing_time Reviewed-by: iwalulya, tschatzl --- src/hotspot/share/gc/g1/g1Policy.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index c37bc12b86a..368c5f47d8d 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -722,8 +722,15 @@ double G1Policy::logged_cards_processing_time() const { size_t logged_dirty_cards = phase_times()->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards); size_t scan_heap_roots_cards = phase_times()->sum_thread_work_items(G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ScanHRScannedCards) + phase_times()->sum_thread_work_items(G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::ScanHRScannedCards); - // This may happen if there are duplicate cards in different log buffers. - if (logged_dirty_cards > scan_heap_roots_cards) { + // Approximate the time spent processing cards from log buffers by scaling + // the total processing time by the ratio of logged cards to total cards + // processed. There might be duplicate cards in different log buffers, + // leading to an overestimate. That effect should be relatively small + // unless there are few cards to process, because cards in buffers are + // dirtied to limit duplication. Also need to avoid scaling when both + // counts are zero, which happens especially during early GCs. So ascribe + // all of the time to the logged cards unless there are more total cards. + if (logged_dirty_cards >= scan_heap_roots_cards) { return all_cards_processing_time + average_time_ms(G1GCPhaseTimes::MergeLB); } return (all_cards_processing_time * logged_dirty_cards / scan_heap_roots_cards) + average_time_ms(G1GCPhaseTimes::MergeLB); From 31a73b0d7088d10a5ffb5541d66806a92b681ef9 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Tue, 25 Apr 2023 04:54:56 +0000 Subject: [PATCH 115/288] 8306714: Open source few Swing event and AbstractAction tests Reviewed-by: serb, prr --- test/jdk/javax/swing/Action/bug4186951.java | 82 +++++++++++++++++++++ test/jdk/javax/swing/Action/bug4211425.java | 47 ++++++++++++ test/jdk/javax/swing/Action/bug4211454.java | 49 ++++++++++++ test/jdk/javax/swing/Action/bug4244034.java | 59 +++++++++++++++ test/jdk/javax/swing/event/bug4143690.java | 48 ++++++++++++ test/jdk/javax/swing/event/bug4160240.java | 44 +++++++++++ 6 files changed, 329 insertions(+) create mode 100644 test/jdk/javax/swing/Action/bug4186951.java create mode 100644 test/jdk/javax/swing/Action/bug4211425.java create mode 100644 test/jdk/javax/swing/Action/bug4211454.java create mode 100644 test/jdk/javax/swing/Action/bug4244034.java create mode 100644 test/jdk/javax/swing/event/bug4143690.java create mode 100644 test/jdk/javax/swing/event/bug4160240.java diff --git a/test/jdk/javax/swing/Action/bug4186951.java b/test/jdk/javax/swing/Action/bug4186951.java new file mode 100644 index 00000000000..3d3529f9470 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4186951.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4186951 + @summary Bulletproofing for AbstractAction.ArrayTable Serialization. + @run main bug4186951 +*/ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.SwingUtilities; + +public class bug4186951 { + public static void main(String[] args) throws Exception { + AbstractAction ma = new MyAction(); + MyClassSer mcs = new MyClassSer(); + ma.putValue("serializable",mcs); + MyClassNonSer mcn = new MyClassNonSer(); + ma.putValue("non-serializable",mcn); + FileOutputStream fos = new FileOutputStream("file.test"); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(ma); + FileInputStream fis = new FileInputStream("file.test"); + ObjectInputStream ois = new ObjectInputStream(fis); + ma = (MyAction)ois.readObject(); + File fil = new File("file.test"); + if (fil!=null) { + fil.delete(); + } + if (!((MyClassSer)ma.getValue("serializable")).equals(mcs)) { + throw new RuntimeException("Serialisable class " + + " wasn't serialized..."); + } + if ((MyClassNonSer)ma.getValue("non-serializable") != null) { + throw new RuntimeException("Serialisation occurs for " + + " non-serialisable class..."); + } + } + + static class MyAction extends AbstractAction { + public void actionPerformed(ActionEvent e) {} + } + + static class MyClassSer implements Serializable { + String str = "default_string"; + public boolean equals(MyClassSer s) { + return str.equals(s.str); + } + } + + static class MyClassNonSer { + String str = "default_string"; + } + +} diff --git a/test/jdk/javax/swing/Action/bug4211425.java b/test/jdk/javax/swing/Action/bug4211425.java new file mode 100644 index 00000000000..8046ab0a81c --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4211425.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4211425 + @summary Verifies ClassCastException in AbstractAction + @run main bug4211425 +*/ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class bug4211425 { + + public static void main(String[] args) { + AbstractAction at = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Action!"); + } + }; + for (int i = 0; i < 10; i++) { + at.putValue("key " + i, "name"); + at.putValue("key " + i, "name"); // Adding another with same key + // tickles this bug + } + } +} diff --git a/test/jdk/javax/swing/Action/bug4211454.java b/test/jdk/javax/swing/Action/bug4211454.java new file mode 100644 index 00000000000..9db82ba0602 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4211454.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4211454 + @summary Verifies ClassCastException in AbstractAction + @run main bug4211454 +*/ + +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; + +public class bug4211454 { + + public static void main(String[] args) { + AbstractAction at = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Action!"); + } + }; + for (int i = 0; i<9; i++) { + at.putValue("key " + i, "name"); + } + for (int i = 9; i>3; i--) { + at.putValue("key " + i, null); + at.putValue("Not a key " + i, null); + } + } +} diff --git a/test/jdk/javax/swing/Action/bug4244034.java b/test/jdk/javax/swing/Action/bug4244034.java new file mode 100644 index 00000000000..9efb11c8204 --- /dev/null +++ b/test/jdk/javax/swing/Action/bug4244034.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4244034 + @summary Tests that AbstractAction has method getKeys() + @run main bug4244034 +*/ + +import java.util.Arrays; +import java.util.List; +import java.awt.event.ActionEvent; +import javax.swing.Action; +import javax.swing.AbstractAction; + +public class bug4244034 { + + /** Auxilliary class extending AbstractAction + */ + static class NullAction extends AbstractAction { + public void actionPerformed(ActionEvent e) {} + } + + public static void main(String[] args) { + AbstractAction action = new NullAction(); + action.putValue(Action.SHORT_DESCRIPTION, "my short descr"); + action.putValue(Action.LONG_DESCRIPTION, "my long descr"); + action.putValue(Action.NAME, "my name"); + + Object[] keys = action.getKeys(); + List keysList = Arrays.asList(keys); + if (! keysList.contains(Action.SHORT_DESCRIPTION) || + ! keysList.contains(Action.LONG_DESCRIPTION) || + ! keysList.contains(Action.NAME)) { + + throw new Error("Failed: getKeys() works improperly"); + } + } +} diff --git a/test/jdk/javax/swing/event/bug4143690.java b/test/jdk/javax/swing/event/bug4143690.java new file mode 100644 index 00000000000..971d1984656 --- /dev/null +++ b/test/jdk/javax/swing/event/bug4143690.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4143690 + @summary Tests that TreeSelectionEvent has isAddedPath(int) method + @run main bug4143690 +*/ + +import javax.swing.event.TreeSelectionEvent; +import javax.swing.tree.TreePath; + +public class bug4143690 { + + public static void main(String[] argv) throws Exception { + bug4143690 test = new bug4143690(); + TreePath p = new TreePath(""); + TreeSelectionEvent e = new TreeSelectionEvent(test, p, true, p, p); + + TreePath[] paths = e.getPaths(); + for(int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + if (e.isAddedPath(i) != true) { + throw new RuntimeException("Incorrect isAddedPath(int)..."); + } + } + } +} diff --git a/test/jdk/javax/swing/event/bug4160240.java b/test/jdk/javax/swing/event/bug4160240.java new file mode 100644 index 00000000000..4a3654271dc --- /dev/null +++ b/test/jdk/javax/swing/event/bug4160240.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4160240 + @summary InternalFrameEvent has getInternalFrame() method. + @run main bug4160240 +*/ + +import javax.swing.JInternalFrame; +import javax.swing.event.InternalFrameEvent; + +public class bug4160240 { + + public static void main(String[] argv) throws Exception { + JInternalFrame jif = new JInternalFrame(); + InternalFrameEvent ife = new InternalFrameEvent(jif, + InternalFrameEvent.INTERNAL_FRAME_OPENED); + if (ife.getInternalFrame() != jif) { + throw new RuntimeException("JInternalFrame.getInternalFrame " + + " doesn't work correctly..."); + } + } +} From 2985738f1584735fee34bbe706014f43ec369bdd Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 25 Apr 2023 05:59:09 +0000 Subject: [PATCH 116/288] 8306773: Problemlist jdk/incubator/vector/ShortMaxVectorTests.java on x86_32 Reviewed-by: kvn --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 4897c11fc3f..b488180402c 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -737,6 +737,8 @@ javax/rmi/ssl/SSLSocketParametersTest.sh 8162906 generic- jdk/incubator/concurrent/ScopedValue/StressStackOverflow.java 8303498 linux-s390x +jdk/incubator/vector/ShortMaxVectorTests.java 8306592 generic-i586 + ############################################################################ # jdk_jfr From f968da97a5a5c68c28ad29d13fdfbe3a4adf5ef7 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Tue, 25 Apr 2023 06:56:32 +0000 Subject: [PATCH 117/288] 8305352: updateIconImages may lead to deadlock after JDK-8276849 Reviewed-by: aivanov, serb --- .../windows/classes/sun/awt/windows/WWindowPeer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java index 1eec7180d4e..7b82229c02c 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java @@ -600,7 +600,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, newDev.addDisplayChangedListener(this); } - updateIconImages(); + if (((Window)target).isVisible()) { + updateIconImages(); + } AWTAccessor.getComponentAccessor(). setGraphicsConfiguration((Component)target, winGraphicsConfig); From d53a5eed0f64d97e1f688ed4cde006ae2a676231 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Tue, 25 Apr 2023 08:55:00 +0000 Subject: [PATCH 118/288] 8306067: Open source AWT Graphics,GridBagLayout related tests Reviewed-by: serb --- .../java/awt/Graphics/DrawNullStringTest.java | 57 ++++++++ .../java/awt/Graphics/GetGraphicsTest.java | 50 +++++++ .../GridBagLayoutButtonsOverlapTest.java | 123 ++++++++++++++++++ .../GridBagLayoutOutOfBoundsTest.java | 69 ++++++++++ 4 files changed, 299 insertions(+) create mode 100644 test/jdk/java/awt/Graphics/DrawNullStringTest.java create mode 100644 test/jdk/java/awt/Graphics/GetGraphicsTest.java create mode 100644 test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java create mode 100644 test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java diff --git a/test/jdk/java/awt/Graphics/DrawNullStringTest.java b/test/jdk/java/awt/Graphics/DrawNullStringTest.java new file mode 100644 index 00000000000..7ae2d066fa9 --- /dev/null +++ b/test/jdk/java/awt/Graphics/DrawNullStringTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4166809 + * @summary Make sure NPE is thrown when calling + * Graphics.drawString(null, int, int) + * @run main DrawNullStringTest + */ +import java.awt.image.BufferedImage; +import java.awt.EventQueue; +import java.awt.Graphics; + +public class DrawNullStringTest { + static String s = null; + static boolean passed = false; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + BufferedImage img = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_RGB); + Graphics g = (Graphics)(img.getGraphics()); + try { + g.drawString(s, 30, 30); + } catch (NullPointerException npe) { + System.out.println("NPE thrown - test passes"); + passed = true; + } + + if (passed == false) { + throw new Error("No Exception was thrown - should be an NPE"); + } + }); + } + + }// class DrawNullStringTest diff --git a/test/jdk/java/awt/Graphics/GetGraphicsTest.java b/test/jdk/java/awt/Graphics/GetGraphicsTest.java new file mode 100644 index 00000000000..19285c7d803 --- /dev/null +++ b/test/jdk/java/awt/Graphics/GetGraphicsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 4746122 + * @summary Checks getGraphics doesn't throw NullPointerExcepton for invalid colors and font. + * @run main GetGraphicsTest +*/ + +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; + +public class GetGraphicsTest extends Frame { + public Color getBackground() { + return null; + } + public Color getForeground() { + return null; + } + public Font getFont() { + return null; + } + + public static void main(String[] args) throws Exception { + GetGraphicsTest test = new GetGraphicsTest(); + Graphics g = test.getGraphics(); + } +}// class GetGraphicsTest diff --git a/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java b/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java new file mode 100644 index 00000000000..dda70992889 --- /dev/null +++ b/test/jdk/java/awt/GridBagLayout/GridBagLayoutButtonsOverlapTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4930685 + @summary Test effect of GridBagConstraints on padding / layout + @key headful + @run main GridBagLayoutButtonsOverlapTest +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; + +public class GridBagLayoutButtonsOverlapTest { + public static GridBagLayout gridbag; + public static GridBagConstraints c; + public static Button b1; + public static Button b2; + public static Button b4; + public static Button b5; + public static Button b6; + public static Button b7; + public static Button b8; + public static Button b9; + public static Button b10; + public static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + createUI(); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } + + public static void createUI() { + frame = new Frame(); + gridbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + frame.setFont(new Font(Font.DIALOG, Font.PLAIN, 14)); + frame.setLayout(gridbag); + c.fill = GridBagConstraints.BOTH; + c.weightx = 1.0; + b1 = makeButton("button1", gridbag, c); + b2 = makeButton("button2", gridbag, c); + + c.gridwidth = GridBagConstraints.REMAINDER; + b4 = makeButton("button4", gridbag, c); + + c.weightx = 0.0; + b5 = makeButton("button5", gridbag, c); + + c.gridwidth = GridBagConstraints.RELATIVE; + b6 = makeButton("button6", gridbag, c); + + c.gridwidth = GridBagConstraints.REMAINDER; + b7 = makeButton("button7", gridbag, c); + + c.gridwidth = 1; + c.gridheight = 2; + c.weighty = 1.0; + b8 = makeButton("button8", gridbag, c); + + c.weighty = 0.0; + c.gridwidth = GridBagConstraints.REMAINDER; + c.gridheight = 1; + b9 = makeButton("button9", gridbag, c); + b10 = makeButton("button10", gridbag, c); + } + + public static void test() { + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + + int b1Corner = b1.getLocation().y + b1.getHeight(); + int b5Corner = b5.getLocation().y; + if (b1Corner > b5Corner) { //they are equals each other in best case + throw new RuntimeException("Buttons are overlapped when container is small enough"); + } + System.out.println("Test passed."); + } + + protected static Button makeButton(String name, + GridBagLayout gridbag, + GridBagConstraints c) { + Button button = new Button(name); + gridbag.setConstraints(button, c); + frame.add(button); + return button; + } + +}// class diff --git a/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java b/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java new file mode 100644 index 00000000000..1f68dbb8620 --- /dev/null +++ b/test/jdk/java/awt/GridBagLayout/GridBagLayoutOutOfBoundsTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5055696 + @summary REGRESSION: GridBagLayout throws ArrayIndexOutOfBoundsExceptions + @key headful + @run main GridBagLayoutOutOfBoundsTest +*/ +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import java.awt.Panel; + +public class GridBagLayoutOutOfBoundsTest { + final static int L=2; + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + frame = new Frame("GridBagLayoutOutOfBoundsTestFrame"); + frame.validate(); + GridBagLayout layout = new GridBagLayout(); + frame.setLayout(layout); + GridBagConstraints gridBagConstraints; + + Button[] mb = new Button[L]; + for (int i = 0; i Date: Tue, 25 Apr 2023 10:27:22 +0000 Subject: [PATCH 119/288] 8306766: Reduce heap size for TestJNICriticalStressTest Reviewed-by: ayang, tschatzl --- test/hotspot/jtreg/gc/TestJNICriticalStressTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java b/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java index 999435a0bbf..31f092fc48b 100644 --- a/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java +++ b/test/hotspot/jtreg/gc/TestJNICriticalStressTest.java @@ -30,7 +30,7 @@ * @library /test/lib * @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 -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 G1 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xms1g -Xmx1g -Xlog:gc TestJNICriticalStressTest 30 4 4 G1 */ /* @@ -41,7 +41,7 @@ * @library /test/lib * @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 -XX:+UseParallelGC -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 Parallel + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseParallelGC -Xms1g -Xmx1g -Xlog:gc TestJNICriticalStressTest 30 4 4 Parallel */ /* @@ -52,7 +52,7 @@ * @library /test/lib * @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 -XX:+UseSerialGC -Xms3g -Xmx3g -Xmn2g -Xlog:gc TestJNICriticalStressTest 30 4 4 Serial + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseSerialGC -Xms1g -Xmx1g -Xlog:gc TestJNICriticalStressTest 30 4 4 Serial */ import jdk.test.lib.Asserts; From a4a5385831b58e66fe3f34cef618643f9be68c9e Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 25 Apr 2023 10:39:45 +0000 Subject: [PATCH 120/288] 8306733: Remove template parameter of G1DetermineCompactionQueueClosure::free_pinned_region Reviewed-by: ayang, iwalulya --- src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp | 3 +-- .../share/gc/g1/g1FullGCPrepareTask.inline.hpp | 11 +++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp index aeefd9fb530..7f09f0553e9 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp @@ -42,8 +42,7 @@ class G1DetermineCompactionQueueClosure : public HeapRegionClosure { G1FullCollector* _collector; uint _cur_worker; - template - inline void free_pinned_region(HeapRegion* hr); + inline void free_empty_humongous_region(HeapRegion* hr); inline bool should_compact(HeapRegion* hr) const; diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp index f76ecca6e5a..97d4ef63847 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -33,13 +33,8 @@ #include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/heapRegion.inline.hpp" -template -void G1DetermineCompactionQueueClosure::free_pinned_region(HeapRegion* hr) { - if (is_humongous) { - _g1h->free_humongous_region(hr, nullptr); - } else { - _g1h->free_region(hr, nullptr); - } +void G1DetermineCompactionQueueClosure::free_empty_humongous_region(HeapRegion* hr) { + _g1h->free_humongous_region(hr, nullptr); _collector->set_free(hr->hrm_index()); add_to_compaction_queue(hr); } @@ -88,7 +83,7 @@ inline bool G1DetermineCompactionQueueClosure::do_heap_region(HeapRegion* hr) { oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); bool is_empty = !_collector->mark_bitmap()->is_marked(obj); if (is_empty) { - free_pinned_region(hr); + free_empty_humongous_region(hr); } else { _collector->set_has_humongous(); } From 9d1fe6565c6c355399578aa7aa211885342deb02 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 25 Apr 2023 13:35:38 +0000 Subject: [PATCH 121/288] 8306740: G1: Change G1CardSetHashTableScan to lambda Reviewed-by: kbarrett, tschatzl --- src/hotspot/share/gc/g1/g1CardSet.cpp | 34 +++++++++++---------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CardSet.cpp b/src/hotspot/share/gc/g1/g1CardSet.cpp index a2eb4bbe442..10c26eda2c8 100644 --- a/src/hotspot/share/gc/g1/g1CardSet.cpp +++ b/src/hotspot/share/gc/g1/g1CardSet.cpp @@ -276,18 +276,6 @@ class G1CardSetHashTable : public CHeapObj { G1CardSetHashTableValue* value() const { return _value; } }; - class G1CardSetHashTableScan : public StackObj { - G1CardSet::ContainerPtrClosure* _scan_f; - public: - explicit G1CardSetHashTableScan(G1CardSet::ContainerPtrClosure* f) : _scan_f(f) { } - - bool operator()(G1CardSetHashTableValue* value) { - _scan_f->do_containerptr(value->_region_idx, value->_num_occupied, value->_container); - return true; - } - }; - - public: static const size_t InitialLogTableSize = 2; @@ -335,14 +323,14 @@ public: return found.value(); } - void iterate_safepoint(G1CardSet::ContainerPtrClosure* cl2) { - G1CardSetHashTableScan cl(cl2); - _table_scanner.do_safepoint_scan(cl); + template + void iterate_safepoint(SCAN_FUNC& scan_f) { + _table_scanner.do_safepoint_scan(scan_f); } - void iterate(G1CardSet::ContainerPtrClosure* cl2) { - G1CardSetHashTableScan cl(cl2); - _table.do_scan(Thread::current(), cl); + template + void iterate(SCAN_FUNC& scan_f) { + _table.do_scan(Thread::current(), scan_f); } void reset() { @@ -924,10 +912,16 @@ void G1CardSet::iterate_cards_during_transfer(ContainerPtr const container, Card } void G1CardSet::iterate_containers(ContainerPtrClosure* cl, bool at_safepoint) { + auto do_value = + [&] (G1CardSetHashTableValue* value) { + cl->do_containerptr(value->_region_idx, value->_num_occupied, value->_container); + return true; + }; + if (at_safepoint) { - _table->iterate_safepoint(cl); + _table->iterate_safepoint(do_value); } else { - _table->iterate(cl); + _table->iterate(do_value); } } From 5f50e991ca072d86f1d4c2ae4657daec115eab2b Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Tue, 25 Apr 2023 14:07:28 +0000 Subject: [PATCH 122/288] 8306770: (fs) Remove obsolete os.version check from sun.nio.fs.BsdFileStore.supportsFileAttributeView Reviewed-by: bpb, iris, lancea, alanb --- .../classes/sun/nio/fs/BsdFileStore.java | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java b/src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java index 3f5de6bbefa..e7d488de005 100644 --- a/src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java +++ b/src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -29,7 +29,6 @@ import java.nio.file.attribute.FileAttributeView; import java.nio.file.attribute.UserDefinedFileAttributeView; import java.io.IOException; import java.util.Arrays; -import sun.security.action.GetPropertyAction; /** * Bsd implementation of FileStore @@ -93,11 +92,8 @@ class BsdFileStore // typical macOS file system types that are known to support xattr String fstype = entry().fstype(); - if ("hfs".equals(fstype)) + if ("hfs".equals(fstype) || "apfs".equals(fstype)) { return true; - if ("apfs".equals(fstype)) { - // fgetxattr broken on APFS prior to 10.14 - return isOsVersionGte(10, 14); } // probe file system capabilities @@ -113,17 +109,4 @@ class BsdFileStore return supportsFileAttributeView(UserDefinedFileAttributeView.class); return super.supportsFileAttributeView(name); } - - /** - * Returns true if the OS major/minor version is greater than, or equal, to the - * given major/minor version. - */ - private static boolean isOsVersionGte(int requiredMajor, int requiredMinor) { - String osVersion = GetPropertyAction.privilegedGetProperty("os.version"); - String[] vers = Util.split(osVersion, '.'); - int majorVersion = Integer.parseInt(vers[0]); - int minorVersion = Integer.parseInt(vers[1]); - return (majorVersion > requiredMajor) - || (majorVersion == requiredMajor && minorVersion >= requiredMinor); - } } From bad6aa68e4d491e819ab22e91dd5d65bb094120e Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Tue, 25 Apr 2023 14:20:50 +0000 Subject: [PATCH 123/288] 8289735: UTIL_LOOKUP_PROGS fails on pathes with space Reviewed-by: erikj, mbaesken --- make/autoconf/basic.m4 | 1 + make/autoconf/basic_tools.m4 | 38 ++++++++++++++++++++++++------------ make/autoconf/configure.ac | 1 + make/autoconf/platform.m4 | 3 ++- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index 2ec792f78b4..f02c0e33707 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -60,6 +60,7 @@ AC_DEFUN([BASIC_CHECK_LEFTOVER_OVERRIDDEN], ############################################################################### # Setup basic configuration paths, and platform-specific stuff related to PATHs. +# Make sure to only use tools set up in BASIC_SETUP_FUNDAMENTAL_TOOLS. AC_DEFUN_ONCE([BASIC_SETUP_PATHS], [ # Save the current directory this script was started from diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index c21ca52e477..cd9f37a3f32 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -29,8 +29,8 @@ RECOMMENDED_PANDOC_VERSION=2.19.2 ############################################################################### -# Setup the most fundamental tools that relies on not much else to set up, -# but is used by much of the early bootstrap code. +# Setup the most fundamental tools, used for setting up build platform and +# path handling. AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], [ # Bootstrapping: These tools are needed by UTIL_LOOKUP_PROGS @@ -42,7 +42,27 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_CHECK_NONEMPTY(FILE) AC_PATH_PROGS(LDD, ldd) - # First are all the fundamental required tools. + # Required tools + UTIL_REQUIRE_PROGS(ECHO, echo) + UTIL_REQUIRE_PROGS(TR, tr) + UTIL_REQUIRE_PROGS(UNAME, uname) + UTIL_REQUIRE_PROGS(WC, wc) + + # Required tools with some special treatment + UTIL_REQUIRE_SPECIAL(EGREP, [AC_PROG_EGREP]) + UTIL_REQUIRE_SPECIAL(SED, [AC_PROG_SED]) + + # Tools only needed on some platforms + UTIL_LOOKUP_PROGS(PATHTOOL, cygpath wslpath) + UTIL_LOOKUP_PROGS(CMD, cmd.exe, $PATH:/cygdrive/c/windows/system32:/mnt/c/windows/system32:/c/windows/system32) +]) + +############################################################################### +# Setup further tools that should be resolved early but after setting up +# build platform and path handling. +AC_DEFUN_ONCE([BASIC_SETUP_TOOLS], +[ + # Required tools UTIL_REQUIRE_PROGS(BASH, bash) UTIL_REQUIRE_PROGS(CAT, cat) UTIL_REQUIRE_PROGS(CHMOD, chmod) @@ -50,7 +70,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_REQUIRE_PROGS(CUT, cut) UTIL_REQUIRE_PROGS(DATE, date) UTIL_REQUIRE_PROGS(DIFF, gdiff diff) - UTIL_REQUIRE_PROGS(ECHO, echo) UTIL_REQUIRE_PROGS(EXPR, expr) UTIL_REQUIRE_PROGS(FIND, find) UTIL_REQUIRE_PROGS(GUNZIP, gunzip) @@ -72,16 +91,11 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_REQUIRE_PROGS(TAR, gtar tar) UTIL_REQUIRE_PROGS(TEE, tee) UTIL_REQUIRE_PROGS(TOUCH, touch) - UTIL_REQUIRE_PROGS(TR, tr) - UTIL_REQUIRE_PROGS(UNAME, uname) - UTIL_REQUIRE_PROGS(WC, wc) UTIL_REQUIRE_PROGS(XARGS, xargs) - # Then required tools that require some special treatment. + # Required tools with some special treatment UTIL_REQUIRE_SPECIAL(GREP, [AC_PROG_GREP]) - UTIL_REQUIRE_SPECIAL(EGREP, [AC_PROG_EGREP]) UTIL_REQUIRE_SPECIAL(FGREP, [AC_PROG_FGREP]) - UTIL_REQUIRE_SPECIAL(SED, [AC_PROG_SED]) # Optional tools, we can do without them UTIL_LOOKUP_PROGS(DF, df) @@ -90,10 +104,8 @@ AC_DEFUN_ONCE([BASIC_SETUP_FUNDAMENTAL_TOOLS], UTIL_LOOKUP_PROGS(READLINK, greadlink readlink) UTIL_LOOKUP_PROGS(WHOAMI, whoami) - # These are only needed on some platforms - UTIL_LOOKUP_PROGS(PATHTOOL, cygpath wslpath) + # Tools only needed on some platforms UTIL_LOOKUP_PROGS(LSB_RELEASE, lsb_release) - UTIL_LOOKUP_PROGS(CMD, cmd.exe, $PATH:/cygdrive/c/windows/system32:/mnt/c/windows/system32:/c/windows/system32) # For compare.sh only UTIL_LOOKUP_PROGS(CMP, cmp) diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index 2d6cb000d43..7c5d7b13ada 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -86,6 +86,7 @@ PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET # Continue setting up basic stuff. Most remaining code require fundamental tools. BASIC_SETUP_PATHS +BASIC_SETUP_TOOLS BASIC_SETUP_BUILD_ENV # Check if it's a pure open build or if custom sources are to be used. diff --git a/make/autoconf/platform.m4 b/make/autoconf/platform.m4 index babb24a9b0c..4a13dad24b5 100644 --- a/make/autoconf/platform.m4 +++ b/make/autoconf/platform.m4 @@ -640,6 +640,7 @@ AC_DEFUN([PLATFORM_SET_MODULE_TARGET_OS_VALUES], ]) #%%% Build and target systems %%% +# Make sure to only use tools set up in BASIC_SETUP_FUNDAMENTAL_TOOLS. AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET], [ # Figure out the build and target systems. # Note that in autoconf terminology, "build" is obvious, but "target" @@ -723,7 +724,7 @@ AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_ENDIANNESS], [ ############################################################################### # - # Is the target little of big endian? + # Is the target little or big endian? # AC_C_BIGENDIAN([ENDIAN="big"],[ENDIAN="little"],[ENDIAN="unknown"],[ENDIAN="universal_endianness"]) From 17ce0976e442d5fabb14daed40fa9a768989f02e Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Tue, 25 Apr 2023 15:19:08 +0000 Subject: [PATCH 124/288] 8266571: Sequenced Collections Reviewed-by: alanb --- .../share/classes/java/util/AbstractMap.java | 50 +- .../share/classes/java/util/ArrayDeque.java | 5 +- .../share/classes/java/util/ArrayList.java | 84 +- .../share/classes/java/util/Collection.java | 19 +- .../share/classes/java/util/Collections.java | 317 ++++++- .../share/classes/java/util/Deque.java | 15 +- .../share/classes/java/util/HashSet.java | 4 +- .../java/util/ImmutableCollections.java | 5 + .../classes/java/util/LinkedHashMap.java | 569 +++++++++-- .../classes/java/util/LinkedHashSet.java | 124 ++- .../share/classes/java/util/LinkedList.java | 272 +++++- .../share/classes/java/util/List.java | 131 ++- .../share/classes/java/util/Map.java | 12 +- .../share/classes/java/util/NavigableMap.java | 16 + .../share/classes/java/util/NavigableSet.java | 54 ++ .../java/util/ReverseOrderDequeView.java | 279 ++++++ .../java/util/ReverseOrderListView.java | 405 ++++++++ .../java/util/ReverseOrderSortedMapView.java | 473 ++++++++++ .../java/util/ReverseOrderSortedSetView.java | 373 ++++++++ .../java/util/SequencedCollection.java | 203 ++++ .../share/classes/java/util/SequencedMap.java | 331 +++++++ .../share/classes/java/util/SequencedSet.java | 58 ++ .../share/classes/java/util/SortedMap.java | 48 +- .../share/classes/java/util/SortedSet.java | 112 ++- .../share/classes/java/util/TreeMap.java | 30 +- .../share/classes/java/util/TreeSet.java | 30 +- .../concurrent/ConcurrentSkipListMap.java | 24 + .../concurrent/ConcurrentSkipListSet.java | 24 + .../util/concurrent/CopyOnWriteArrayList.java | 492 ++++++++++ .../jdk/internal/util/ArraysSupport.java | 51 + test/jdk/TEST.groups | 1 + test/jdk/java/util/Collection/MOAT.java | 107 ++- test/jdk/java/util/Collections/Wrappers.java | 32 +- .../java/util/SequencedCollection/Basic.java | 857 +++++++++++++++++ .../util/SequencedCollection/BasicMap.java | 892 ++++++++++++++++++ .../util/SequencedCollection/SimpleDeque.java | 200 ++++ .../util/SequencedCollection/SimpleList.java | 152 +++ .../SequencedCollection/SimpleSortedMap.java | 134 +++ .../SequencedCollection/SimpleSortedSet.java | 139 +++ .../internal/util/ArraysSupport/Reverse.java | 78 ++ .../tools/javac/api/TestJavacTaskScanner.java | 4 +- .../processing/model/type/BoundsTest.java | 4 +- 42 files changed, 7060 insertions(+), 150 deletions(-) create mode 100644 src/java.base/share/classes/java/util/ReverseOrderDequeView.java create mode 100644 src/java.base/share/classes/java/util/ReverseOrderListView.java create mode 100644 src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java create mode 100644 src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java create mode 100644 src/java.base/share/classes/java/util/SequencedCollection.java create mode 100644 src/java.base/share/classes/java/util/SequencedMap.java create mode 100644 src/java.base/share/classes/java/util/SequencedSet.java create mode 100644 test/jdk/java/util/SequencedCollection/Basic.java create mode 100644 test/jdk/java/util/SequencedCollection/BasicMap.java create mode 100644 test/jdk/java/util/SequencedCollection/SimpleDeque.java create mode 100644 test/jdk/java/util/SequencedCollection/SimpleList.java create mode 100644 test/jdk/java/util/SequencedCollection/SimpleSortedMap.java create mode 100644 test/jdk/java/util/SequencedCollection/SimpleSortedSet.java create mode 100644 test/jdk/jdk/internal/util/ArraysSupport/Reverse.java diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index 8e9414f8ef5..b0d311f6565 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,6 +25,11 @@ package java.util; +import java.util.stream.Stream; +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.function.Predicate; + /** * This class provides a skeletal implementation of the {@code Map} * interface, to minimize the effort required to implement this interface. @@ -875,7 +880,48 @@ public abstract class AbstractMap implements Map { public String toString() { return key + "=" + value; } - } + /** + * Delegates all Collection methods to the provided non-sequenced map view, + * except add() and addAll(), which throw UOE. This provides the common + * implementation of each of the sequenced views of the SequencedMap. + * Each view implementation is a subclass that provides an instance of the + * non-sequenced view as a delegate and an implementation of reversed(). + * Each view also inherits the default implementations for the sequenced + * methods from SequencedCollection or SequencedSet. + *

+ * Ideally this would be a private class within SequencedMap, but private + * classes aren't permitted within interfaces. + * + * @param the view's element type + */ + /* non-public */ abstract static class ViewCollection implements Collection { + UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } + final Collection view; + + ViewCollection(Collection view) { this.view = view; } + + public boolean add(E t) { throw uoe(); } + public boolean addAll(Collection c) { throw uoe(); } + public void clear() { view.clear(); } + public boolean contains(Object o) { return view.contains(o); } + public boolean containsAll(Collection c) { return view.containsAll(c); } + public boolean equals(Object o) { return view.equals(o); } + public void forEach(Consumer c) { view.forEach(c); } + public int hashCode() { return view.hashCode(); } + public boolean isEmpty() { return view.isEmpty(); } + public Iterator iterator() { return view.iterator(); } + public Stream parallelStream() { return view.parallelStream(); } + public boolean remove(Object o) { return view.remove(o); } + public boolean removeAll(Collection c) { return view.removeAll(c); } + public boolean removeIf(Predicate filter) { return view.removeIf(filter); } + public boolean retainAll(Collection c) { return view.retainAll(c); } + public int size() { return view.size(); } + public Spliterator spliterator() { return view.spliterator(); } + public Stream stream() { return view.stream(); } + public Object[] toArray() { return view.toArray(); } + public T[] toArray(IntFunction generator) { return view.toArray(generator); } + public T[] toArray(T[] a) { return view.toArray(a); } + } } diff --git a/src/java.base/share/classes/java/util/ArrayDeque.java b/src/java.base/share/classes/java/util/ArrayDeque.java index 603ebceb757..eb459b80517 100644 --- a/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/src/java.base/share/classes/java/util/ArrayDeque.java @@ -74,9 +74,8 @@ import jdk.internal.access.SharedSecrets; * exception for its correctness: the fail-fast behavior of iterators * should be used only to detect bugs. * - *

This class and its iterator implement all of the - * optional methods of the {@link Collection} and {@link - * Iterator} interfaces. + *

This class and its iterator implement all of the optional methods of the + * {@link Collection}, {@link SequencedCollection}, and {@link Iterator} interfaces. * *

This class is a member of the * diff --git a/src/java.base/share/classes/java/util/ArrayList.java b/src/java.base/share/classes/java/util/ArrayList.java index a36dcd8a796..1f27572ef16 100644 --- a/src/java.base/share/classes/java/util/ArrayList.java +++ b/src/java.base/share/classes/java/util/ArrayList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -428,6 +428,35 @@ public class ArrayList extends AbstractList return elementData(index); } + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getFirst() { + if (size == 0) { + throw new NoSuchElementException(); + } else { + return elementData(0); + } + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getLast() { + int last = size - 1; + if (last < 0) { + throw new NoSuchElementException(); + } else { + return elementData(last); + } + } + /** * Replaces the element at the specified position in this list with * the specified element. @@ -491,6 +520,24 @@ public class ArrayList extends AbstractList size = s + 1; } + /** + * {@inheritDoc} + * + * @since 21 + */ + public void addFirst(E element) { + add(0, element); + } + + /** + * {@inheritDoc} + * + * @since 21 + */ + public void addLast(E element) { + add(element); + } + /** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their @@ -510,6 +557,41 @@ public class ArrayList extends AbstractList return oldValue; } + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeFirst() { + if (size == 0) { + throw new NoSuchElementException(); + } else { + Object[] es = elementData; + @SuppressWarnings("unchecked") E oldValue = (E) es[0]; + fastRemove(es, 0); + return oldValue; + } + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeLast() { + int last = size - 1; + if (last < 0) { + throw new NoSuchElementException(); + } else { + Object[] es = elementData; + @SuppressWarnings("unchecked") E oldValue = (E) es[last]; + fastRemove(es, last); + return oldValue; + } + } + /** * {@inheritDoc} */ diff --git a/src/java.base/share/classes/java/util/Collection.java b/src/java.base/share/classes/java/util/Collection.java index fbaa1881a89..0f63f0b26a4 100644 --- a/src/java.base/share/classes/java/util/Collection.java +++ b/src/java.base/share/classes/java/util/Collection.java @@ -33,8 +33,11 @@ import java.util.stream.StreamSupport; /** * The root interface in the collection hierarchy. A collection * represents a group of objects, known as its elements. Some - * collections allow duplicate elements and others do not. Some are ordered - * and others unordered. The JDK does not provide any direct + * collections allow duplicate elements and others do not. Some are ordered, + * and others are unordered. Collections that have a defined + * encounter order + * are generally subtypes of the {@link SequencedCollection} interface. + * The JDK does not provide any direct * implementations of this interface: it provides implementations of more * specific subinterfaces like {@code Set} and {@code List}. This interface * is typically used to pass collections around and manipulate them where @@ -121,8 +124,9 @@ import java.util.stream.StreamSupport; * Other examples of view collections include collections that provide a * different representation of the same elements, for example, as * provided by {@link List#subList List.subList}, - * {@link NavigableSet#subSet NavigableSet.subSet}, or - * {@link Map#entrySet Map.entrySet}. + * {@link NavigableSet#subSet NavigableSet.subSet}, + * {@link Map#entrySet Map.entrySet}, or + * {@link SequencedCollection#reversed SequencedCollection.reversed}. * Any changes made to the backing collection are visible in the view collection. * Correspondingly, any changes made to the view collection — if changes * are permitted — are written through to the backing collection. @@ -202,7 +206,8 @@ import java.util.stream.StreamSupport; * serializability of such collections is described in the specification of the method * that creates them, or in some other suitable place. In cases where the serializability * of a collection is not specified, there is no guarantee about the serializability of such - * collections. In particular, many view collections are not serializable. + * collections. In particular, many view collections are not serializable, + * even if the original collection is serializable. * *

A collection implementation that implements the {@code Serializable} interface cannot * be guaranteed to be serializable. The reason is that in general, collections @@ -501,7 +506,9 @@ public interface Collection extends Iterable { * the specified collection is modified while the operation is in progress. * (This implies that the behavior of this call is undefined if the * specified collection is this collection, and this collection is - * nonempty.) + * nonempty.) If the specified collection has a defined + * encounter order, + * processing of its elements generally occurs in that order. * * @param c collection containing elements to be added to this collection * @return {@code true} if this collection changed as a result of the call diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 4425b4483c0..f45d297f300 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -369,9 +369,15 @@ public class Collections { * * This method runs in linear time. * + * @apiNote + * This method mutates the specified list in-place. To obtain a + * reverse-ordered view of a list without mutating it, use the + * {@link List#reversed List.reversed} method. + * * @param list the list whose elements are to be reversed. * @throws UnsupportedOperationException if the specified list or * its list-iterator does not support the {@code set} operation. + * @see List#reversed List.reversed */ @SuppressWarnings({"rawtypes", "unchecked"}) public static void reverse(List list) { @@ -1130,6 +1136,87 @@ public class Collections { } } + /** + * Returns an unmodifiable view of the + * specified {@code SequencedCollection}. Query operations on the returned collection + * "read through" to the specified collection, and attempts to modify the returned + * collection, whether direct or via its iterator, result in an + * {@code UnsupportedOperationException}.

+ * + * The returned collection does not pass the {@code hashCode} and + * {@code equals} operations through to the backing collection, but relies on + * {@code Object}'s {@code equals} and {@code hashCode} methods. This + * is necessary to preserve the contracts of these operations in the case + * that the backing collection is a set or a list.

+ * + * The returned collection will be serializable if the specified collection + * is serializable. + * + * @implNote This method may return its argument if the argument is already unmodifiable. + * @param the class of the objects in the collection + * @param c the collection for which an unmodifiable view is to be + * returned. + * @return an unmodifiable view of the specified collection. + * @since 21 + */ + @SuppressWarnings("unchecked") + public static SequencedCollection unmodifiableSequencedCollection(SequencedCollection c) { + if (c.getClass() == UnmodifiableSequencedCollection.class) { + return (SequencedCollection) c; + } + return new UnmodifiableSequencedCollection<>(c); + } + + /** + * @serial include + */ + static class UnmodifiableSequencedCollection extends UnmodifiableCollection + implements SequencedCollection, Serializable { + + @java.io.Serial + private static final long serialVersionUID = -6060065079711684830L; + + UnmodifiableSequencedCollection(SequencedCollection c) { + super(c); + } + + @SuppressWarnings("unchecked") + private SequencedCollection sc() { + return (SequencedCollection) c; + } + + // Even though this wrapper class is serializable, the reversed view is effectively + // not serializable because it points to the reversed collection view, which usually isn't + // serializable. + public SequencedCollection reversed() { + return new UnmodifiableSequencedCollection<>(sc().reversed()); + } + + public void addFirst(E e) { + throw new UnsupportedOperationException(); + } + + public void addLast(E e) { + throw new UnsupportedOperationException(); + } + + public E getFirst() { + return sc().getFirst(); + } + + public E getLast() { + return sc().getLast(); + } + + public E removeFirst() { + throw new UnsupportedOperationException(); + } + + public E removeLast() { + throw new UnsupportedOperationException(); + } + } + /** * Returns an unmodifiable view of the * specified set. Query operations on the returned set "read through" to the specified @@ -1166,6 +1253,56 @@ public class Collections { public int hashCode() {return c.hashCode();} } + /** + * Returns an unmodifiable view of the + * specified {@code SequencedSet}. Query operations on the returned set + * "read through" to the specified set, and attempts to modify the returned + * set, whether direct or via its iterator, result in an + * {@code UnsupportedOperationException}.

+ * + * The returned set will be serializable if the specified set + * is serializable. + * + * @implNote This method may return its argument if the argument is already unmodifiable. + * @param the class of the objects in the set + * @param s the set for which an unmodifiable view is to be returned. + * @return an unmodifiable view of the specified sequenced set. + * @since 21 + */ + @SuppressWarnings("unchecked") + public static SequencedSet unmodifiableSequencedSet(SequencedSet s) { + // Not checking for subclasses because of heap pollution and information leakage. + if (s.getClass() == UnmodifiableSequencedSet.class) { + return (SequencedSet) s; + } + return new UnmodifiableSequencedSet<>(s); + } + + /** + * @serial include + */ + static class UnmodifiableSequencedSet extends UnmodifiableSequencedCollection + implements SequencedSet, Serializable { + @java.io.Serial + private static final long serialVersionUID = -2153469532349793522L; + + UnmodifiableSequencedSet(SequencedSet s) {super(s);} + public boolean equals(Object o) {return o == this || c.equals(o);} + public int hashCode() {return c.hashCode();} + + @SuppressWarnings("unchecked") + private SequencedSet ss() { + return (SequencedSet) c; + } + + // Even though this wrapper class is serializable, the reversed view is effectively + // not serializable because it points to the reversed set view, which usually isn't + // serializable. + public SequencedSet reversed() { + return new UnmodifiableSequencedSet<>(ss().reversed()); + } + } + /** * Returns an unmodifiable view of the * specified sorted set. Query operations on the returned sorted set "read @@ -1504,7 +1641,7 @@ public class Collections { private static final long serialVersionUID = -1034234728574286014L; @SuppressWarnings("serial") // Conditionally serializable - private final Map m; + final Map m; UnmodifiableMap(Map m) { if (m==null) @@ -1828,6 +1965,72 @@ public class Collections { } } + /** + * Returns an unmodifiable view of the + * specified {@code SequencedMap}. Query operations on the returned map + * "read through" to the specified map, and attempts to modify the returned + * map, whether direct or via its collection views, result in an + * {@code UnsupportedOperationException}.

+ * + * The returned map will be serializable if the specified map + * is serializable. + * + * @implNote This method may return its argument if the argument is already unmodifiable. + * @param the class of the map keys + * @param the class of the map values + * @param m the map for which an unmodifiable view is to be returned. + * @return an unmodifiable view of the specified map. + * @since 21 + */ + @SuppressWarnings("unchecked") + public static SequencedMap unmodifiableSequencedMap(SequencedMap m) { + // Not checking for subclasses because of heap pollution and information leakage. + if (m.getClass() == UnmodifiableSequencedMap.class) { + return (SequencedMap) m; + } + return new UnmodifiableSequencedMap<>(m); + } + + /** + * @serial include + */ + private static class UnmodifiableSequencedMap extends UnmodifiableMap implements SequencedMap, Serializable { + @java.io.Serial + private static final long serialVersionUID = -8171676257373950636L; + + UnmodifiableSequencedMap(Map m) { + super(m); + } + + @SuppressWarnings("unchecked") + private SequencedMap sm() { + return (SequencedMap) m; + } + + // Even though this wrapper class is serializable, the reversed view is effectively + // not serializable because it points to the reversed map view, which usually isn't + // serializable. + public SequencedMap reversed() { + return new UnmodifiableSequencedMap<>(sm().reversed()); + } + + public Entry pollFirstEntry() { + throw new UnsupportedOperationException(); + } + + public Entry pollLastEntry() { + throw new UnsupportedOperationException(); + } + + public V putFirst(K k, V v) { + throw new UnsupportedOperationException(); + } + + public V putLast(K k, V v) { + throw new UnsupportedOperationException(); + } + } + /** * Returns an unmodifiable view of the * specified sorted map. Query operations on the returned sorted map "read through" @@ -5326,6 +5529,14 @@ public class Collections { * * The returned comparator is serializable. * + * @apiNote + * This method returns a {@code Comparator} that is suitable for sorting + * elements in reverse order. To obtain a reverse-ordered view of a + * sequenced collection, use the {@link SequencedCollection#reversed + * SequencedCollection.reversed} method. Or, to obtain a reverse-ordered + * view of a sequenced map, use the {@link SequencedMap#reversed + * SequencedMap.reversed} method. + * * @param the class of the objects compared by the comparator * @return A comparator that imposes the reverse of the natural * ordering on a collection of objects that implement @@ -5372,6 +5583,14 @@ public class Collections { *

The returned comparator is serializable (assuming the specified * comparator is also serializable or {@code null}). * + * @apiNote + * This method returns a {@code Comparator} that is suitable for sorting + * elements in reverse order. To obtain a reverse-ordered view of a + * sequenced collection, use the {@link SequencedCollection#reversed + * SequencedCollection.reversed} method. Or, to obtain a reverse-ordered + * view of a sequenced map, use the {@link SequencedMap#reversed + * SequencedMap.reversed} method. + * * @param the class of the objects compared by the comparator * @param cmp a comparator who's ordering is to be reversed by the returned * comparator or {@code null} @@ -5682,6 +5901,8 @@ public class Collections { * @since 1.6 */ public static Set newSetFromMap(Map map) { + if (! map.isEmpty()) // implicit null check + throw new IllegalArgumentException("Map is non-empty"); return new SetFromMap<>(map); } @@ -5692,12 +5913,10 @@ public class Collections { implements Set, Serializable { @SuppressWarnings("serial") // Conditionally serializable - private final Map m; // The backing map + final Map m; // The backing map private transient Set s; // Its keySet SetFromMap(Map map) { - if (!map.isEmpty()) - throw new IllegalArgumentException("Map is non-empty"); m = map; s = map.keySet(); } @@ -5746,6 +5965,91 @@ public class Collections { stream.defaultReadObject(); s = m.keySet(); } + + @java.io.Serial + private void readObjectNoData() throws java.io.ObjectStreamException { + throw new java.io.InvalidObjectException("missing SetFromMap data"); + } + } + + /** + * Returns a sequenced set backed by the specified map. The resulting set displays + * the same ordering, concurrency, and performance characteristics as the + * backing map. In essence, this factory method provides a {@link SequencedSet} + * implementation corresponding to any {@link SequencedMap} implementation. + * + *

Each method invocation on the set returned by this method results in + * exactly one method invocation on the backing map or its {@code keySet} + * view, with one exception. The {@code addAll} method is implemented + * as a sequence of {@code put} invocations on the backing map. + * + *

The specified map must be empty at the time this method is invoked, + * and should not be accessed directly after this method returns. These + * conditions are ensured if the map is created empty, passed directly + * to this method, and no reference to the map is retained. + * + * @apiNote + * The following example code creates a {@code SequencedSet} from a + * {@code LinkedHashMap}. This differs from a {@code LinkedHashSet} + * in that the map's {@code removeEldestEntry} is overridden to provide + * an eviction policy, which is not possible with a {@code LinkedHashSet}. + * + * {@snippet : + * SequencedSet set = Collections.newSequencedSetFromMap( + * new LinkedHashMap() { + * protected boolean removeEldestEntry(Map.Entry e) { + * return this.size() > 5; + * } + * }); + * } + * + * @param the class of the map keys and of the objects in the + * returned set + * @param map the backing map + * @return the set backed by the map + * @throws IllegalArgumentException if {@code map} is not empty + * @since 21 + */ + public static SequencedSet newSequencedSetFromMap(SequencedMap map) { + if (! map.isEmpty()) // implicit null check + throw new IllegalArgumentException("Map is non-empty"); + return new SequencedSetFromMap<>(map); + } + + /** + * @serial include + */ + private static class SequencedSetFromMap extends SetFromMap implements SequencedSet { + private E nsee(Map.Entry e) { + if (e == null) { + throw new NoSuchElementException(); + } else { + return e.getKey(); + } + } + + private SequencedMap map() { + return (SequencedMap) super.m; + } + + SequencedSetFromMap(SequencedMap map) { + super(map); + } + + // Even though this wrapper class is serializable, the reversed view is effectively + // not serializable because it points to the reversed map view, which usually isn't + // serializable. + public SequencedSet reversed() { return new SequencedSetFromMap<>(map().reversed()); } + + public void addFirst(E e) { map().putFirst(e, Boolean.TRUE); } + public void addLast(E e) { map().putLast(e, Boolean.TRUE); } + public E getFirst() { return nsee(map().firstEntry()); } + public E getLast() { return nsee(map().lastEntry()); } + public E removeFirst() { return nsee(map().pollFirstEntry()); } + public E removeLast() { return nsee(map().pollLastEntry()); } + + @java.io.Serial + private static final long serialVersionUID = -3943479744841433802L; } /** @@ -5761,6 +6065,11 @@ public class Collections { * implemented as a sequence of {@link Deque#addFirst addFirst} * invocations on the backing deque. * + * @apiNote + * This method provides a view that inverts the sense of certain operations, + * but it doesn't reverse the encounter order. To obtain a reverse-ordered + * view, use the {@link Deque#reversed Deque.reversed} method. + * * @param the class of the objects in the deque * @param deque the deque * @return the queue diff --git a/src/java.base/share/classes/java/util/Deque.java b/src/java.base/share/classes/java/util/Deque.java index 90d7292c31a..13a2e150d97 100644 --- a/src/java.base/share/classes/java/util/Deque.java +++ b/src/java.base/share/classes/java/util/Deque.java @@ -201,7 +201,7 @@ package java.util; * @since 1.6 * @param the type of elements held in this deque */ -public interface Deque extends Queue { +public interface Deque extends Queue, SequencedCollection { /** * Inserts the specified element at the front of this deque if it is * possible to do so immediately without violating capacity restrictions, @@ -613,4 +613,17 @@ public interface Deque extends Queue { */ Iterator descendingIterator(); + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns an instance of a reverse-ordered + * Deque that delegates its operations to this Deque. + * + * @return a reverse-ordered view of this collection, as a {@code Deque} + * @since 21 + */ + default Deque reversed() { + return ReverseOrderDequeView.of(this); + } } diff --git a/src/java.base/share/classes/java/util/HashSet.java b/src/java.base/share/classes/java/util/HashSet.java index 9d4cdb346f2..e59bf7b089a 100644 --- a/src/java.base/share/classes/java/util/HashSet.java +++ b/src/java.base/share/classes/java/util/HashSet.java @@ -94,10 +94,10 @@ public class HashSet @java.io.Serial static final long serialVersionUID = -5024744406713321676L; - private transient HashMap map; + transient HashMap map; // Dummy value to associate with an Object in the backing Map - private static final Object PRESENT = new Object(); + static final Object PRESENT = new Object(); /** * Constructs a new, empty set; the backing {@code HashMap} instance has diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index 3de7e1d5eae..398ebb14a54 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -331,6 +331,11 @@ class ImmutableCollections { return indexOf(o) >= 0; } + @Override + public List reversed() { + return ReverseOrderListView.of(this, false); + } + IndexOutOfBoundsException outOfBounds(int index) { return new IndexOutOfBoundsException("Index: " + index + " Size: " + size()); } diff --git a/src/java.base/share/classes/java/util/LinkedHashMap.java b/src/java.base/share/classes/java/util/LinkedHashMap.java index 1984043f0d0..d4052f396bf 100644 --- a/src/java.base/share/classes/java/util/LinkedHashMap.java +++ b/src/java.base/share/classes/java/util/LinkedHashMap.java @@ -29,18 +29,23 @@ import java.util.function.Consumer; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.io.IOException; +import java.util.function.Function; /** *

Hash table and linked list implementation of the {@code Map} interface, - * with predictable iteration order. This implementation differs from - * {@code HashMap} in that it maintains a doubly-linked list running through - * all of its entries. This linked list defines the iteration ordering, + * with well-defined encounter order. This implementation differs from + * {@code HashMap} in that it maintains a doubly-linked list running through all of + * its entries. This linked list defines the encounter order (the order of iteration), * which is normally the order in which keys were inserted into the map - * (insertion-order). Note that insertion order is not affected - * if a key is re-inserted into the map. (A key {@code k} is - * reinserted into a map {@code m} if {@code m.put(k, v)} is invoked when + * (insertion-order). The least recently inserted entry (the eldest) is + * first, and the youngest entry is last. Note that encounter order is not affected + * if a key is re-inserted into the map with the {@code put} method. (A key + * {@code k} is reinserted into a map {@code m} if {@code m.put(k, v)} is invoked when * {@code m.containsKey(k)} would return {@code true} immediately prior to - * the invocation.) + * the invocation.) The reverse-ordered view of this map is in the opposite order, with + * the youngest entry appearing first and the eldest entry appearing last. + * The encounter order of entries already in the map can be changed by using + * the {@link #putFirst putFirst} and {@link #putLast putLast} methods. * *

This implementation spares its clients from the unspecified, generally * chaotic ordering provided by {@link HashMap} (and {@link Hashtable}), @@ -59,7 +64,7 @@ import java.io.IOException; * order they were presented.) * *

A special {@link #LinkedHashMap(int,float,boolean) constructor} is - * provided to create a linked hash map whose order of iteration is the order + * provided to create a linked hash map whose encounter order is the order * in which its entries were last accessed, from least-recently accessed to * most-recently (access-order). This kind of map is well-suited to * building LRU caches. Invoking the {@code put}, {@code putIfAbsent}, @@ -70,16 +75,24 @@ import java.io.IOException; * of the entry if the value is replaced. The {@code putAll} method generates one * entry access for each mapping in the specified map, in the order that * key-value mappings are provided by the specified map's entry set iterator. - * No other methods generate entry accesses. In particular, operations - * on collection-views do not affect the order of iteration of the - * backing map. + * No other methods generate entry accesses. Invoking these methods on the + * reversed view generates accesses to entries on the backing map. Note that in the + * reversed view, an access to an entry moves it first in encounter order. + * Explicit-positioning methods such as {@code putFirst} or {@code lastEntry}, whether on + * the map or on its reverse-ordered view, perform the positioning operation and + * do not generate entry accesses. Operations on the {@code keySet}, {@code values}, + * and {@code entrySet} views or on their sequenced counterparts do not affect + * the encounter order of the backing map. * *

The {@link #removeEldestEntry(Map.Entry)} method may be overridden to * impose a policy for removing stale mappings automatically when new mappings - * are added to the map. + * are added to the map. Alternatively, since the "eldest" entry is the first + * entry in encounter order, programs can inspect and remove stale mappings through + * use of the {@link #firstEntry firstEntry} and {@link #pollFirstEntry pollFirstEntry} + * methods. * - *

This class provides all of the optional {@code Map} operations, and - * permits null elements. Like {@code HashMap}, it provides constant-time + *

This class provides all of the optional {@code Map} and {@code SequencedMap} operations, + * and it permits null elements. Like {@code HashMap}, it provides constant-time * performance for the basic operations ({@code add}, {@code contains} and * {@code remove}), assuming the hash function disperses elements * properly among the buckets. Performance is likely to be just slightly @@ -162,7 +175,7 @@ import java.io.IOException; */ public class LinkedHashMap extends HashMap - implements Map + implements SequencedMap { /* @@ -220,14 +233,25 @@ public class LinkedHashMap // internal utilities // link at the end of list - private void linkNodeLast(LinkedHashMap.Entry p) { - LinkedHashMap.Entry last = tail; - tail = p; - if (last == null) + private void linkNodeAtEnd(LinkedHashMap.Entry p) { + if (putMode == PUT_FIRST) { + LinkedHashMap.Entry first = head; head = p; - else { - p.before = last; - last.after = p; + if (first == null) + tail = p; + else { + p.after = first; + first.before = p; + } + } else { + LinkedHashMap.Entry last = tail; + tail = p; + if (last == null) + head = p; + else { + p.before = last; + last.after = p; + } } } @@ -256,7 +280,7 @@ public class LinkedHashMap Node newNode(int hash, K key, V value, Node e) { LinkedHashMap.Entry p = new LinkedHashMap.Entry<>(hash, key, value, e); - linkNodeLast(p); + linkNodeAtEnd(p); return p; } @@ -270,7 +294,7 @@ public class LinkedHashMap TreeNode newTreeNode(int hash, K key, V value, Node next) { TreeNode p = new TreeNode<>(hash, key, value, next); - linkNodeLast(p); + linkNodeAtEnd(p); return p; } @@ -303,9 +327,17 @@ public class LinkedHashMap } } - void afterNodeAccess(Node e) { // move node to last + static final int PUT_NORM = 0; + static final int PUT_FIRST = 1; + static final int PUT_LAST = 2; + int putMode = PUT_NORM; + + // Called after update, but not after insertion + void afterNodeAccess(Node e) { LinkedHashMap.Entry last; - if (accessOrder && (last = tail) != e) { + LinkedHashMap.Entry first; + if ((putMode == PUT_LAST || (putMode == PUT_NORM && accessOrder)) && (last = tail) != e) { + // move node to last LinkedHashMap.Entry p = (LinkedHashMap.Entry)e, b = p.before, a = p.after; p.after = null; @@ -325,6 +357,61 @@ public class LinkedHashMap } tail = p; ++modCount; + } else if (putMode == PUT_FIRST && (first = head) != e) { + // move node to first + LinkedHashMap.Entry p = + (LinkedHashMap.Entry)e, b = p.before, a = p.after; + p.before = null; + if (a == null) + tail = b; + else + a.before = b; + if (b != null) + b.after = a; + else + first = a; + if (first == null) + tail = p; + else { + p.after = first; + first.before = p; + } + head = p; + ++modCount; + } + } + + /** + * {@inheritDoc} + *

+ * If this map already contains a mapping for this key, the mapping is relocated if necessary + * so that it is first in encounter order. + * + * @since 21 + */ + public V putFirst(K k, V v) { + try { + putMode = PUT_FIRST; + return this.put(k, v); + } finally { + putMode = PUT_NORM; + } + } + + /** + * {@inheritDoc} + *

+ * If this map already contains a mapping for this key, the mapping is relocated if necessary + * so that it is last in encounter order. + * + * @since 21 + */ + public V putLast(K k, V v) { + try { + putMode = PUT_LAST; + return this.put(k, v); + } finally { + putMode = PUT_NORM; } } @@ -519,8 +606,9 @@ public class LinkedHashMap } /** - * Returns a {@link Set} view of the keys contained in this map. - * The set is backed by the map, so changes to the map are + * Returns a {@link Set} view of the keys contained in this map. The encounter + * order of the keys in the view matches the encounter order of mappings of + * this map. The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own {@code remove} operation), the results of @@ -537,39 +625,79 @@ public class LinkedHashMap * @return a set view of the keys contained in this map */ public Set keySet() { + return sequencedKeySet(); + } + + /** + * {@inheritDoc} + *

+ * The returned view has the same characteristics as specified for the view + * returned by the {@link #keySet keySet} method. + * + * @return {@inheritDoc} + * @since 21 + */ + public SequencedSet sequencedKeySet() { Set ks = keySet; if (ks == null) { - ks = new LinkedKeySet(); - keySet = ks; + SequencedSet sks = new LinkedKeySet(false); + keySet = sks; + return sks; + } else { + // The cast should never fail, since the only assignment of non-null to keySet is + // above, and assignments in AbstractMap and HashMap are in overridden methods. + return (SequencedSet) ks; } - return ks; } - @Override + static Node nsee(Node node) { + if (node == null) + throw new NoSuchElementException(); + else + return node; + } + final T[] keysToArray(T[] a) { + return keysToArray(a, false); + } + + final T[] keysToArray(T[] a, boolean reversed) { Object[] r = a; int idx = 0; - for (LinkedHashMap.Entry e = head; e != null; e = e.after) { - r[idx++] = e.key; + if (reversed) { + for (LinkedHashMap.Entry e = tail; e != null; e = e.before) { + r[idx++] = e.key; + } + } else { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) { + r[idx++] = e.key; + } } return a; } - @Override - final T[] valuesToArray(T[] a) { + final T[] valuesToArray(T[] a, boolean reversed) { Object[] r = a; int idx = 0; - for (LinkedHashMap.Entry e = head; e != null; e = e.after) { - r[idx++] = e.value; + if (reversed) { + for (LinkedHashMap.Entry e = tail; e != null; e = e.before) { + r[idx++] = e.value; + } + } else { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) { + r[idx++] = e.value; + } } return a; } - final class LinkedKeySet extends AbstractSet { + final class LinkedKeySet extends AbstractSet implements SequencedSet { + final boolean reversed; + LinkedKeySet(boolean reversed) { this.reversed = reversed; } public final int size() { return size; } public final void clear() { LinkedHashMap.this.clear(); } public final Iterator iterator() { - return new LinkedKeyIterator(); + return new LinkedKeyIterator(reversed); } public final boolean contains(Object o) { return containsKey(o); } public final boolean remove(Object key) { @@ -582,27 +710,54 @@ public class LinkedHashMap } public Object[] toArray() { - return keysToArray(new Object[size]); + return keysToArray(new Object[size], reversed); } public T[] toArray(T[] a) { - return keysToArray(prepareArray(a)); + return keysToArray(prepareArray(a), reversed); } public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); int mc = modCount; - for (LinkedHashMap.Entry e = head; e != null; e = e.after) - action.accept(e.key); + if (reversed) { + for (LinkedHashMap.Entry e = tail; e != null; e = e.before) + action.accept(e.key); + } else { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e.key); + } if (modCount != mc) throw new ConcurrentModificationException(); } + public final void addFirst(K k) { throw new UnsupportedOperationException(); } + public final void addLast(K k) { throw new UnsupportedOperationException(); } + public final K getFirst() { return nsee(reversed ? tail : head).key; } + public final K getLast() { return nsee(reversed ? head : tail).key; } + public final K removeFirst() { + var node = nsee(reversed ? tail : head); + removeNode(node.hash, node.key, null, false, false); + return node.key; + } + public final K removeLast() { + var node = nsee(reversed ? head : tail); + removeNode(node.hash, node.key, null, false, false); + return node.key; + } + public SequencedSet reversed() { + if (reversed) { + return LinkedHashMap.this.sequencedKeySet(); + } else { + return new LinkedKeySet(true); + } + } } /** - * Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are + * Returns a {@link Collection} view of the values contained in this map. The + * encounter order of values in the view matches the encounter order of entries in + * this map. The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. If the map is * modified while an iteration over the collection is in progress * (except through the iterator's own {@code remove} operation), @@ -619,19 +774,38 @@ public class LinkedHashMap * @return a view of the values contained in this map */ public Collection values() { - Collection vs = values; - if (vs == null) { - vs = new LinkedValues(); - values = vs; - } - return vs; + return sequencedValues(); } - final class LinkedValues extends AbstractCollection { + /** + * {@inheritDoc} + *

+ * The returned view has the same characteristics as specified for the view + * returned by the {@link #values values} method. + * + * @return {@inheritDoc} + * @since 21 + */ + public SequencedCollection sequencedValues() { + Collection vs = values; + if (vs == null) { + SequencedCollection svs = new LinkedValues(false); + values = svs; + return svs; + } else { + // The cast should never fail, since the only assignment of non-null to values is + // above, and assignments in AbstractMap and HashMap are in overridden methods. + return (SequencedCollection) vs; + } + } + + final class LinkedValues extends AbstractCollection implements SequencedCollection { + final boolean reversed; + LinkedValues(boolean reversed) { this.reversed = reversed; } public final int size() { return size; } public final void clear() { LinkedHashMap.this.clear(); } public final Iterator iterator() { - return new LinkedValueIterator(); + return new LinkedValueIterator(reversed); } public final boolean contains(Object o) { return containsValue(o); } public final Spliterator spliterator() { @@ -640,26 +814,53 @@ public class LinkedHashMap } public Object[] toArray() { - return valuesToArray(new Object[size]); + return valuesToArray(new Object[size], reversed); } public T[] toArray(T[] a) { - return valuesToArray(prepareArray(a)); + return valuesToArray(prepareArray(a), reversed); } public final void forEach(Consumer action) { if (action == null) throw new NullPointerException(); int mc = modCount; - for (LinkedHashMap.Entry e = head; e != null; e = e.after) - action.accept(e.value); + if (reversed) { + for (LinkedHashMap.Entry e = tail; e != null; e = e.before) + action.accept(e.value); + } else { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e.value); + } if (modCount != mc) throw new ConcurrentModificationException(); } + public final void addFirst(V v) { throw new UnsupportedOperationException(); } + public final void addLast(V v) { throw new UnsupportedOperationException(); } + public final V getFirst() { return nsee(reversed ? tail : head).value; } + public final V getLast() { return nsee(reversed ? head : tail).value; } + public final V removeFirst() { + var node = nsee(reversed ? tail : head); + removeNode(node.hash, node.key, null, false, false); + return node.value; + } + public final V removeLast() { + var node = nsee(reversed ? head : tail); + removeNode(node.hash, node.key, null, false, false); + return node.value; + } + public SequencedCollection reversed() { + if (reversed) { + return LinkedHashMap.this.sequencedValues(); + } else { + return new LinkedValues(true); + } + } } /** - * Returns a {@link Set} view of the mappings contained in this map. + * Returns a {@link Set} view of the mappings contained in this map. The encounter + * order of the view matches the encounter order of entries of this map. * The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through @@ -678,15 +879,39 @@ public class LinkedHashMap * @return a set view of the mappings contained in this map */ public Set> entrySet() { - Set> es; - return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es; + return sequencedEntrySet(); } - final class LinkedEntrySet extends AbstractSet> { + /** + * {@inheritDoc} + *

+ * The returned view has the same characteristics as specified for the view + * returned by the {@link #entrySet entrySet} method. + * + * @return {@inheritDoc} + * @since 21 + */ + public SequencedSet> sequencedEntrySet() { + Set> es = entrySet; + if (es == null) { + SequencedSet> ses = new LinkedEntrySet(false); + entrySet = ses; + return ses; + } else { + // The cast should never fail, since the only assignment of non-null to entrySet is + // above, and assignments in HashMap are in overridden methods. + return (SequencedSet>) es; + } + } + + final class LinkedEntrySet extends AbstractSet> + implements SequencedSet> { + final boolean reversed; + LinkedEntrySet(boolean reversed) { this.reversed = reversed; } public final int size() { return size; } public final void clear() { LinkedHashMap.this.clear(); } public final Iterator> iterator() { - return new LinkedEntryIterator(); + return new LinkedEntryIterator(reversed); } public final boolean contains(Object o) { if (!(o instanceof Map.Entry e)) @@ -712,11 +937,43 @@ public class LinkedHashMap if (action == null) throw new NullPointerException(); int mc = modCount; - for (LinkedHashMap.Entry e = head; e != null; e = e.after) - action.accept(e); + if (reversed) { + for (LinkedHashMap.Entry e = tail; e != null; e = e.before) + action.accept(e); + } else { + for (LinkedHashMap.Entry e = head; e != null; e = e.after) + action.accept(e); + } if (modCount != mc) throw new ConcurrentModificationException(); } + final Node nsee(Node e) { + if (e == null) + throw new NoSuchElementException(); + else + return e; + } + public final void addFirst(Map.Entry e) { throw new UnsupportedOperationException(); } + public final void addLast(Map.Entry e) { throw new UnsupportedOperationException(); } + public final Map.Entry getFirst() { return nsee(reversed ? tail : head); } + public final Map.Entry getLast() { return nsee(reversed ? head : tail); } + public final Map.Entry removeFirst() { + var node = nsee(reversed ? tail : head); + removeNode(node.hash, node.key, null, false, false); + return node; + } + public final Map.Entry removeLast() { + var node = nsee(reversed ? head : tail); + removeNode(node.hash, node.key, null, false, false); + return node; + } + public SequencedSet> reversed() { + if (reversed) { + return LinkedHashMap.this.sequencedEntrySet(); + } else { + return new LinkedEntrySet(true); + } + } } // Map overrides @@ -747,9 +1004,11 @@ public class LinkedHashMap LinkedHashMap.Entry next; LinkedHashMap.Entry current; int expectedModCount; + boolean reversed; - LinkedHashIterator() { - next = head; + LinkedHashIterator(boolean reversed) { + this.reversed = reversed; + next = reversed ? tail : head; expectedModCount = modCount; current = null; } @@ -765,7 +1024,7 @@ public class LinkedHashMap if (e == null) throw new NoSuchElementException(); current = e; - next = e.after; + next = reversed ? e.before : e.after; return e; } @@ -783,16 +1042,19 @@ public class LinkedHashMap final class LinkedKeyIterator extends LinkedHashIterator implements Iterator { + LinkedKeyIterator(boolean reversed) { super(reversed); } public final K next() { return nextNode().getKey(); } } final class LinkedValueIterator extends LinkedHashIterator implements Iterator { + LinkedValueIterator(boolean reversed) { super(reversed); } public final V next() { return nextNode().value; } } final class LinkedEntryIterator extends LinkedHashIterator implements Iterator> { + LinkedEntryIterator(boolean reversed) { super(reversed); } public final Map.Entry next() { return nextNode(); } } @@ -816,4 +1078,175 @@ public class LinkedHashMap return new LinkedHashMap<>(HashMap.calculateHashMapCapacity(numMappings)); } + // Reversed View + + /** + * {@inheritDoc} + *

+ * Modifications to the reversed view and its map views are permitted and will be + * propagated to this map. In addition, modifications to this map will be visible + * in the reversed view and its map views. + * + * @return {@inheritDoc} + * @since 21 + */ + public SequencedMap reversed() { + return new ReversedLinkedHashMapView<>(this); + } + + static class ReversedLinkedHashMapView extends AbstractMap + implements SequencedMap { + final LinkedHashMap base; + + ReversedLinkedHashMapView(LinkedHashMap lhm) { + base = lhm; + } + + // Object + // inherit toString() from AbstractMap; it depends on entrySet() + + public boolean equals(Object o) { + return base.equals(o); + } + + public int hashCode() { + return base.hashCode(); + } + + // Map + + public int size() { + return base.size(); + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public boolean containsKey(Object key) { + return base.containsKey(key); + } + + public boolean containsValue(Object value) { + return base.containsValue(value); + } + + public V get(Object key) { + return base.get(key); + } + + public V put(K key, V value) { + return base.put(key, value); + } + + public V remove(Object key) { + return base.remove(key); + } + + public void putAll(Map m) { + base.putAll(m); + } + + public void clear() { + base.clear(); + } + + public Set keySet() { + return base.sequencedKeySet().reversed(); + } + + public Collection values() { + return base.sequencedValues().reversed(); + } + + public Set> entrySet() { + return base.sequencedEntrySet().reversed(); + } + + public V getOrDefault(Object key, V defaultValue) { + return base.getOrDefault(key, defaultValue); + } + + public void forEach(BiConsumer action) { + if (action == null) + throw new NullPointerException(); + int mc = base.modCount; + for (LinkedHashMap.Entry e = base.tail; e != null; e = e.before) + action.accept(e.key, e.value); + if (base.modCount != mc) + throw new ConcurrentModificationException(); + } + + public void replaceAll(BiFunction function) { + if (function == null) + throw new NullPointerException(); + int mc = base.modCount; + for (LinkedHashMap.Entry e = base.tail; e != null; e = e.before) + e.value = function.apply(e.key, e.value); + if (base.modCount != mc) + throw new ConcurrentModificationException(); + } + + public V putIfAbsent(K key, V value) { + return base.putIfAbsent(key, value); + } + + public boolean remove(Object key, Object value) { + return base.remove(key, value); + } + + public boolean replace(K key, V oldValue, V newValue) { + return base.replace(key, oldValue, newValue); + } + + public V replace(K key, V value) { + return base.replace(key, value); + } + + public V computeIfAbsent(K key, Function mappingFunction) { + return base.computeIfAbsent(key, mappingFunction); + } + + public V computeIfPresent(K key, BiFunction remappingFunction) { + return base.computeIfPresent(key, remappingFunction); + } + + public V compute(K key, BiFunction remappingFunction) { + return base.compute(key, remappingFunction); + } + + public V merge(K key, V value, BiFunction remappingFunction) { + return base.merge(key, value, remappingFunction); + } + + // SequencedMap + + public SequencedMap reversed() { + return base; + } + + public Entry firstEntry() { + return base.lastEntry(); + } + + public Entry lastEntry() { + return base.firstEntry(); + } + + public Entry pollFirstEntry() { + return base.pollLastEntry(); + } + + public Entry pollLastEntry() { + return base.pollFirstEntry(); + } + + public V putFirst(K k, V v) { + return base.putLast(k, v); + } + + public V putLast(K k, V v) { + return base.putFirst(k, v); + } + } } diff --git a/src/java.base/share/classes/java/util/LinkedHashSet.java b/src/java.base/share/classes/java/util/LinkedHashSet.java index 330e37f8be3..fd9b52e2589 100644 --- a/src/java.base/share/classes/java/util/LinkedHashSet.java +++ b/src/java.base/share/classes/java/util/LinkedHashSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -27,15 +27,19 @@ package java.util; /** *

Hash table and linked list implementation of the {@code Set} interface, - * with predictable iteration order. This implementation differs from + * with well-defined encounter order. This implementation differs from * {@code HashSet} in that it maintains a doubly-linked list running through - * all of its entries. This linked list defines the iteration ordering, - * which is the order in which elements were inserted into the set - * (insertion-order). Note that insertion order is not affected - * if an element is re-inserted into the set. (An element {@code e} - * is reinserted into a set {@code s} if {@code s.add(e)} is invoked when - * {@code s.contains(e)} would return {@code true} immediately prior to - * the invocation.) + * all of its entries. This linked list defines the encounter order (iteration + * order), which is the order in which elements were inserted into the set + * (insertion-order). The least recently inserted element (the eldest) is + * first, and the youngest element is last. Note that encounter order is not affected + * if an element is re-inserted into the set with the {@code add} method. + * (An element {@code e} is reinserted into a set {@code s} if {@code s.add(e)} is + * invoked when {@code s.contains(e)} would return {@code true} immediately prior to + * the invocation.) The reverse-ordered view of this set is in the opposite order, with + * the youngest element appearing first and the eldest element appearing last. The encounter + * order of elements already in the set can be changed by using the + * {@link #addFirst addFirst} and {@link #addLast addLast} methods. * *

This implementation spares its clients from the unspecified, generally * chaotic ordering provided by {@link HashSet}, without incurring the @@ -53,8 +57,8 @@ package java.util; * the copy. (Clients generally appreciate having things returned in the same * order they were presented.) * - *

This class provides all of the optional {@code Set} operations, and - * permits null elements. Like {@code HashSet}, it provides constant-time + *

This class provides all of the optional {@link Set} and {@link SequencedSet} + * operations, and it permits null elements. Like {@code HashSet}, it provides constant-time * performance for the basic operations ({@code add}, {@code contains} and * {@code remove}), assuming the hash function disperses elements * properly among the buckets. Performance is likely to be just slightly @@ -117,7 +121,7 @@ package java.util; public class LinkedHashSet extends HashSet - implements Set, Cloneable, java.io.Serializable { + implements SequencedSet, Cloneable, java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -2851667679971038690L; @@ -221,4 +225,100 @@ public class LinkedHashSet return new LinkedHashSet<>(HashMap.calculateHashMapCapacity(numElements)); } + @SuppressWarnings("unchecked") + LinkedHashMap map() { + return (LinkedHashMap) map; + } + + /** + * {@inheritDoc} + *

+ * If this set already contains the element, it is relocated if necessary so that it is + * first in encounter order. + * + * @since 21 + */ + public void addFirst(E e) { + map().putFirst(e, PRESENT); + } + + /** + * {@inheritDoc} + *

+ * If this set already contains the element, it is relocated if necessary so that it is + * last in encounter order. + * + * @since 21 + */ + public void addLast(E e) { + map().putLast(e, PRESENT); + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getFirst() { + return map().sequencedKeySet().getFirst(); + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getLast() { + return map().sequencedKeySet().getLast(); + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeFirst() { + return map().sequencedKeySet().removeFirst(); + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeLast() { + return map().sequencedKeySet().removeLast(); + } + + /** + * {@inheritDoc} + *

+ * Modifications to the reversed view are permitted and will be propagated to this set. + * In addition, modifications to this set will be visible in the reversed view. + * + * @return {@inheritDoc} + * @since 21 + */ + public SequencedSet reversed() { + class ReverseLinkedHashSetView extends AbstractSet implements SequencedSet { + public int size() { return LinkedHashSet.this.size(); } + public Iterator iterator() { return map().sequencedKeySet().reversed().iterator(); } + public boolean add(E e) { return LinkedHashSet.this.add(e); } + public void addFirst(E e) { LinkedHashSet.this.addLast(e); } + public void addLast(E e) { LinkedHashSet.this.addFirst(e); } + public E getFirst() { return LinkedHashSet.this.getLast(); } + public E getLast() { return LinkedHashSet.this.getFirst(); } + public E removeFirst() { return LinkedHashSet.this.removeLast(); } + public E removeLast() { return LinkedHashSet.this.removeFirst(); } + public SequencedSet reversed() { return LinkedHashSet.this; } + public Object[] toArray() { return map().keysToArray(new Object[map.size()], true); } + public T[] toArray(T[] a) { return map().keysToArray(map.prepareArray(a), true); } + } + + return new ReverseLinkedHashSetView(); + } } diff --git a/src/java.base/share/classes/java/util/LinkedList.java b/src/java.base/share/classes/java/util/LinkedList.java index a504b4e8390..d7c67c98628 100644 --- a/src/java.base/share/classes/java/util/LinkedList.java +++ b/src/java.base/share/classes/java/util/LinkedList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,14 @@ package java.util; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; /** * Doubly-linked list implementation of the {@code List} and {@code Deque} @@ -1266,4 +1273,267 @@ public class LinkedList } } + /** + * {@inheritDoc} + *

+ * Modifications to the reversed view are permitted and will be propagated to this list. + * In addition, modifications to this list will be visible in the reversed view. + * + * @return {@inheritDoc} + * @since 21 + */ + public LinkedList reversed() { + return new ReverseOrderLinkedListView<>(this, super.reversed(), Deque.super.reversed()); + } + + // all operations are delegated to the reverse-ordered views. + // TODO audit all overridden methods + @SuppressWarnings("serial") + static class ReverseOrderLinkedListView extends LinkedList implements java.io.Externalizable { + final LinkedList list; + final List rlist; + final Deque rdeque; + + ReverseOrderLinkedListView(LinkedList list, List rlist, Deque rdeque) { + this.list = list; + this.rlist = rlist; + this.rdeque = rdeque; + } + + public String toString() { + return rlist.toString(); + } + + public boolean retainAll(Collection c) { + return rlist.retainAll(c); + } + + public boolean removeAll(Collection c) { + return rlist.removeAll(c); + } + + public boolean containsAll(Collection c) { + return rlist.containsAll(c); + } + + public boolean isEmpty() { + return rlist.isEmpty(); + } + + public Stream parallelStream() { + return rlist.parallelStream(); + } + + public Stream stream() { + return rlist.stream(); + } + + public boolean removeIf(Predicate filter) { + return rlist.removeIf(filter); + } + + public T[] toArray(IntFunction generator) { + return rlist.toArray(generator); + } + + public void forEach(Consumer action) { + rlist.forEach(action); + } + + public Iterator iterator() { + return rlist.iterator(); + } + + public int hashCode() { + return rlist.hashCode(); + } + + public boolean equals(Object o) { + return rlist.equals(o); + } + + public List subList(int fromIndex, int toIndex) { + return rlist.subList(fromIndex, toIndex); + } + + public ListIterator listIterator() { + return rlist.listIterator(); + } + + public void sort(Comparator c) { + rlist.sort(c); + } + + public void replaceAll(UnaryOperator operator) { + rlist.replaceAll(operator); + } + + public LinkedList reversed() { + return list; + } + + public Spliterator spliterator() { + return rlist.spliterator(); + } + + public T[] toArray(T[] a) { + return rlist.toArray(a); + } + + public Object[] toArray() { + return rlist.toArray(); + } + + public Iterator descendingIterator() { + return rdeque.descendingIterator(); + } + + public ListIterator listIterator(int index) { + return rlist.listIterator(index); + } + + public boolean removeLastOccurrence(Object o) { + return rdeque.removeLastOccurrence(o); + } + + public boolean removeFirstOccurrence(Object o) { + return rdeque.removeFirstOccurrence(o); + } + + public E pop() { + return rdeque.pop(); + } + + public void push(E e) { + rdeque.push(e); + } + + public E pollLast() { + return rdeque.pollLast(); + } + + public E pollFirst() { + return rdeque.pollFirst(); + } + + public E peekLast() { + return rdeque.peekLast(); + } + + public E peekFirst() { + return rdeque.peekFirst(); + } + + public boolean offerLast(E e) { + return rdeque.offerLast(e); + } + + public boolean offerFirst(E e) { + return rdeque.offerFirst(e); + } + + public boolean offer(E e) { + return rdeque.offer(e); + } + + public E remove() { + return rdeque.remove(); + } + + public E poll() { + return rdeque.poll(); + } + + public E element() { + return rdeque.element(); + } + + public E peek() { + return rdeque.peek(); + } + + public int lastIndexOf(Object o) { + return rlist.lastIndexOf(o); + } + + public int indexOf(Object o) { + return rlist.indexOf(o); + } + + public E remove(int index) { + return rlist.remove(index); + } + + public void add(int index, E element) { + rlist.add(index, element); + } + + public E set(int index, E element) { + return rlist.set(index, element); + } + + public E get(int index) { + return rlist.get(index); + } + + public void clear() { + rlist.clear(); + } + + public boolean addAll(int index, Collection c) { + return rlist.addAll(index, c); + } + + public boolean addAll(Collection c) { + return rlist.addAll(c); + } + + public boolean remove(Object o) { + return rlist.remove(o); + } + + public boolean add(E e) { + return rlist.add(e); + } + + public int size() { + return rlist.size(); + } + + public boolean contains(Object o) { + return rlist.contains(o); + } + + public void addLast(E e) { + rdeque.addLast(e); + } + + public void addFirst(E e) { + rdeque.addFirst(e); + } + + public E removeLast() { + return rdeque.removeLast(); + } + + public E removeFirst() { + return rdeque.removeFirst(); + } + + public E getLast() { + return rdeque.getLast(); + } + + public E getFirst() { + return rdeque.getFirst(); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + throw new java.io.InvalidObjectException("not serializable"); + } + + public void writeExternal(ObjectOutput out) throws IOException { + throw new java.io.InvalidObjectException("not serializable"); + } + } } diff --git a/src/java.base/share/classes/java/util/List.java b/src/java.base/share/classes/java/util/List.java index 285aa8b536d..e9576455ca7 100644 --- a/src/java.base/share/classes/java/util/List.java +++ b/src/java.base/share/classes/java/util/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -28,10 +28,9 @@ package java.util; import java.util.function.UnaryOperator; /** - * An ordered collection (also known as a sequence). The user of this - * interface has precise control over where in the list each element is - * inserted. The user can access elements by their integer index (position in - * the list), and search for elements in the list.

+ * An ordered collection, where the user has precise control over where in the + * list each element is inserted. The user can access elements by their integer + * index (position in the list), and search for elements in the list.

* * Unlike sets, lists typically allow duplicate elements. More formally, * lists typically allow pairs of elements {@code e1} and {@code e2} @@ -139,7 +138,7 @@ import java.util.function.UnaryOperator; * @since 1.2 */ -public interface List extends Collection { +public interface List extends SequencedCollection { // Query Operations /** @@ -781,6 +780,126 @@ public interface List extends Collection { } } + // ========== SequencedCollection ========== + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface calls {@code add(0, e)}. + * + * @throws NullPointerException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default void addFirst(E e) { + this.add(0, e); + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface calls {@code add(e)}. + * + * @throws NullPointerException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default void addLast(E e) { + this.add(e); + } + + /** + * {@inheritDoc} + * + * @implSpec + * If this List is not empty, the implementation in this interface returns the result + * of calling {@code get(0)}. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + default E getFirst() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.get(0); + } + } + + /** + * {@inheritDoc} + * + * @implSpec + * If this List is not empty, the implementation in this interface returns the result + * of calling {@code get(size() - 1)}. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + default E getLast() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.get(this.size() - 1); + } + } + + /** + * {@inheritDoc} + * + * @implSpec + * If this List is not empty, the implementation in this interface returns the result + * of calling {@code remove(0)}. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeFirst() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.remove(0); + } + } + + /** + * {@inheritDoc} + * + * @implSpec + * If this List is not empty, the implementation in this interface returns the result + * of calling {@code remove(size() - 1)}. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeLast() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.remove(this.size() - 1); + } + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns an instance of a reverse-ordered + * List that delegates its operations to this List. + * + * @return a reverse-ordered view of this collection, as a {@code List} + * @since 21 + */ + default List reversed() { + return ReverseOrderListView.of(this, true); // we must assume it's modifiable + } + + // ========== static methods ========== + /** * Returns an unmodifiable list containing zero elements. * diff --git a/src/java.base/share/classes/java/util/Map.java b/src/java.base/share/classes/java/util/Map.java index 4e8a2496e2a..a36b8187106 100644 --- a/src/java.base/share/classes/java/util/Map.java +++ b/src/java.base/share/classes/java/util/Map.java @@ -42,8 +42,10 @@ import java.io.Serializable; * or set of key-value mappings. The order of a map is defined as * the order in which the iterators on the map's collection views return their * elements. Some map implementations, like the {@code TreeMap} class, make - * specific guarantees as to their order; others, like the {@code HashMap} - * class, do not. + * specific guarantees as to their encounter order; others, like the + * {@code HashMap} class, do not. Maps with a defined + * encounter order + * are generally subtypes of the {@link SequencedMap} interface. * *

Note: great care must be exercised if mutable objects are used as map * keys. The behavior of a map is not specified if the value of an object is @@ -304,8 +306,10 @@ public interface Map { * (optional operation). The effect of this call is equivalent to that * of calling {@link #put(Object,Object) put(k, v)} on this map once * for each mapping from key {@code k} to value {@code v} in the - * specified map. The behavior of this operation is undefined if the - * specified map is modified while the operation is in progress. + * specified map. The behavior of this operation is undefined if the specified map + * is modified while the operation is in progress. If the specified map has a defined + * encounter order, + * processing of its mappings generally occurs in that order. * * @param m mappings to be stored in this map * @throws UnsupportedOperationException if the {@code putAll} operation diff --git a/src/java.base/share/classes/java/util/NavigableMap.java b/src/java.base/share/classes/java/util/NavigableMap.java index 2e5b03b3474..92abc278dd8 100644 --- a/src/java.base/share/classes/java/util/NavigableMap.java +++ b/src/java.base/share/classes/java/util/NavigableMap.java @@ -429,4 +429,20 @@ public interface NavigableMap extends SortedMap { * @throws IllegalArgumentException {@inheritDoc} */ SortedMap tailMap(K fromKey); + + /** + * {@inheritDoc} + *

+ * This method is equivalent to {@link #descendingMap descendingMap}. + * + * @implSpec + * The implementation in this interface returns the result of calling the + * {@code descendingMap} method. + * + * @return a reverse-ordered view of this map, as a {@code NavigableMap} + * @since 21 + */ + default NavigableMap reversed() { + return this.descendingMap(); + } } diff --git a/src/java.base/share/classes/java/util/NavigableSet.java b/src/java.base/share/classes/java/util/NavigableSet.java index 49cd130243b..8d7da4eddd3 100644 --- a/src/java.base/share/classes/java/util/NavigableSet.java +++ b/src/java.base/share/classes/java/util/NavigableSet.java @@ -320,4 +320,58 @@ public interface NavigableSet extends SortedSet { * @throws IllegalArgumentException {@inheritDoc} */ SortedSet tailSet(E fromElement); + + /** + * {@inheritDoc} + * + * @implSpec + * If this set is not empty, the implementation in this interface returns the result of calling + * the {@code pollFirst} method. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeFirst() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.pollFirst(); + } + } + + /** + * {@inheritDoc} + * + * @implSpec + * If this set is not empty, the implementation in this interface returns the result of calling + * the {@code pollLast} method. Otherwise, it throws {@code NoSuchElementException}. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeLast() { + if (this.isEmpty()) { + throw new NoSuchElementException(); + } else { + return this.pollLast(); + } + } + + /** + * {@inheritDoc} + *

+ * This method is equivalent to {@link #descendingSet descendingSet}. + * + * @implSpec + * The implementation in this interface returns the result of calling the + * {@code descendingSet} method. + * + * @return a reverse-ordered view of this collection, as a {@code NavigableSet} + * @since 21 + */ + default NavigableSet reversed() { + return this.descendingSet(); + } } diff --git a/src/java.base/share/classes/java/util/ReverseOrderDequeView.java b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java new file mode 100644 index 00000000000..a580ad8f7db --- /dev/null +++ b/src/java.base/share/classes/java/util/ReverseOrderDequeView.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import jdk.internal.util.ArraysSupport; + +/** + * Provides a reverse-ordered view of any Deque. Not serializable. + */ +class ReverseOrderDequeView implements Deque { + final Deque base; + + private ReverseOrderDequeView(Deque deque) { + base = deque; + } + + public static Deque of(Deque deque) { + if (deque instanceof ReverseOrderDequeView rodv) { + return rodv.base; + } else { + return new ReverseOrderDequeView<>(deque); + } + } + + // ========== Iterable ========== + + public void forEach(Consumer action) { + for (E e : this) + action.accept(e); + } + + public Iterator iterator() { + return base.descendingIterator(); + } + + public Spliterator spliterator() { + return Spliterators.spliteratorUnknownSize(base.descendingIterator(), 0); + } + + // ========== Collection ========== + + public boolean add(E e) { + base.addFirst(e); + return true; + } + + public boolean addAll(Collection c) { + boolean modified = false; + for (E e : c) { + base.addFirst(e); + modified = true; + } + return modified; + } + + public void clear() { + base.clear(); + } + + public boolean contains(Object o) { + return base.contains(o); + } + + public boolean containsAll(Collection c) { + return base.containsAll(c); + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + // copied from AbstractCollection + public boolean remove(Object o) { + Iterator it = iterator(); + if (o==null) { + while (it.hasNext()) { + if (it.next()==null) { + it.remove(); + return true; + } + } + } else { + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + // copied from AbstractCollection + public boolean removeAll(Collection c) { + Objects.requireNonNull(c); + boolean modified = false; + Iterator it = iterator(); + while (it.hasNext()) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + // copied from AbstractCollection + public boolean retainAll(Collection c) { + Objects.requireNonNull(c); + boolean modified = false; + Iterator it = iterator(); + while (it.hasNext()) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public int size() { + return base.size(); + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + public Object[] toArray() { + return ArraysSupport.reverse(base.toArray()); + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + return ArraysSupport.toArrayReversed(base, a); + } + + public T[] toArray(IntFunction generator) { + return ArraysSupport.reverse(base.toArray(generator)); + } + + // copied from AbstractCollection + public String toString() { + Iterator it = iterator(); + if (! it.hasNext()) + return "[]"; + + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (;;) { + E e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (! it.hasNext()) + return sb.append(']').toString(); + sb.append(',').append(' '); + } + } + + // ========== Deque and Queue ========== + + public void addFirst(E e) { + base.addLast(e); + } + + public void addLast(E e) { + base.addFirst(e); + } + + public Iterator descendingIterator() { + return base.iterator(); + } + + public E element() { + return base.getLast(); + } + + public E getFirst() { + return base.getLast(); + } + + public E getLast() { + return base.getFirst(); + } + + public boolean offer(E e) { + return base.offerFirst(e); + } + + public boolean offerFirst(E e) { + return base.offerLast(e); + } + + public boolean offerLast(E e) { + return base.offerFirst(e); + } + + public E peek() { + return base.peekLast(); + } + + public E peekFirst() { + return base.peekLast(); + } + + public E peekLast() { + return base.peekFirst(); + } + + public E poll() { + return base.pollLast(); + } + + public E pollFirst() { + return base.pollLast(); + } + + public E pollLast() { + return base.pollFirst(); + } + + public E pop() { + return base.removeLast(); + } + + public void push(E e) { + base.addLast(e); + } + + public E remove() { + return base.removeLast(); + } + + public E removeFirst() { + return base.removeLast(); + } + + public E removeLast() { + return base.removeFirst(); + } + + public boolean removeFirstOccurrence(Object o) { + return base.removeLastOccurrence(o); + } + + public boolean removeLastOccurrence(Object o) { + return base.removeFirstOccurrence(o); + } +} diff --git a/src/java.base/share/classes/java/util/ReverseOrderListView.java b/src/java.base/share/classes/java/util/ReverseOrderListView.java new file mode 100644 index 00000000000..0f7409bef16 --- /dev/null +++ b/src/java.base/share/classes/java/util/ReverseOrderListView.java @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import jdk.internal.util.ArraysSupport; + +/** + * Provides a reverse-ordered view of a List. Not serializable. + */ +class ReverseOrderListView implements List { + + final List base; + final boolean modifiable; + + public static List of(List list, boolean modifiable) { + if (list instanceof ReverseOrderListView rolv) { + return rolv.base; + } else if (list instanceof RandomAccess) { + return new ReverseOrderListView.Rand<>(list, modifiable); + } else { + return new ReverseOrderListView<>(list, modifiable); + } + } + + static class Rand extends ReverseOrderListView implements RandomAccess { + Rand(List list, boolean modifiable) { + super(list, modifiable); + } + } + + private ReverseOrderListView(List list, boolean modifiable) { + this.base = list; + this.modifiable = modifiable; + } + + /** + * Throws if this list is unmodifiable. This should be called from every mutator + * method. For bulk ops (addAll, removeAll, etc.) this throws unconditionally. + * In contrast, if the base list inherits a bulk op implementation from AbstractList, + * it might not throw if no actual mutation would be attempted (e.g., addAll on an + * empty collection). Arguably calling this is unnecessary for individual ops, + * for which the base list should always throw, but it's easier to verify the right + * behavior if every mutator of this class always checks. + */ + void checkModifiable() { + if (! modifiable) { + throw new UnsupportedOperationException(); + } + } + + class DescendingIterator implements Iterator { + final ListIterator it = base.listIterator(base.size()); + public boolean hasNext() { return it.hasPrevious(); } + public E next() { return it.previous(); } + public void remove() { + checkModifiable(); + it.remove(); + // TODO - make sure ListIterator is positioned correctly afterward + } + } + + class DescendingListIterator implements ListIterator { + final ListIterator it; + + DescendingListIterator(int size, int pos) { + if (pos < 0 || pos > size) + throw new IndexOutOfBoundsException(); + it = base.listIterator(size - pos); + } + + public boolean hasNext() { + return it.hasPrevious(); + } + + public E next() { + return it.previous(); + } + + public boolean hasPrevious() { + return it.hasNext(); + } + + public E previous() { + return it.next(); + } + + public int nextIndex() { + return base.size() - it.nextIndex(); + } + + public int previousIndex() { + return nextIndex() - 1; + } + + public void remove() { + checkModifiable(); + it.remove(); + } + + public void set(E e) { + checkModifiable(); + it.set(e); + } + + public void add(E e) { + checkModifiable(); + it.add(e); + it.previous(); + } + } + + // ========== Iterable ========== + + public void forEach(Consumer action) { + for (E e : this) + action.accept(e); + } + + public Iterator iterator() { + return new DescendingIterator(); + } + + public Spliterator spliterator() { + // TODO can probably improve this + return Spliterators.spliteratorUnknownSize(new DescendingIterator(), 0); + } + + // ========== Collection ========== + + public boolean add(E e) { + checkModifiable(); + base.add(0, e); + return true; + } + + public boolean addAll(Collection c) { + checkModifiable(); + + @SuppressWarnings("unchecked") + E[] adds = (E[]) c.toArray(); + if (adds.length == 0) { + return false; + } else { + base.addAll(0, Arrays.asList(ArraysSupport.reverse(adds))); + return true; + } + } + + public void clear() { + checkModifiable(); + base.clear(); + } + + public boolean contains(Object o) { + return base.contains(o); + } + + public boolean containsAll(Collection c) { + return base.containsAll(c); + } + + // copied from AbstractList + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof List)) + return false; + + ListIterator e1 = listIterator(); + ListIterator e2 = ((List) o).listIterator(); + while (e1.hasNext() && e2.hasNext()) { + E o1 = e1.next(); + Object o2 = e2.next(); + if (!(o1==null ? o2==null : o1.equals(o2))) + return false; + } + return !(e1.hasNext() || e2.hasNext()); + } + + // copied from AbstractList + public int hashCode() { + int hashCode = 1; + for (E e : this) + hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); + return hashCode; + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + // copied from AbstractCollection + public boolean remove(Object o) { + checkModifiable(); + Iterator it = iterator(); + if (o==null) { + while (it.hasNext()) { + if (it.next()==null) { + it.remove(); + return true; + } + } + } else { + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + // copied from AbstractCollection + public boolean removeAll(Collection c) { + checkModifiable(); + Objects.requireNonNull(c); + boolean modified = false; + Iterator it = iterator(); + while (it.hasNext()) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + // copied from AbstractCollection + public boolean retainAll(Collection c) { + checkModifiable(); + Objects.requireNonNull(c); + boolean modified = false; + Iterator it = iterator(); + while (it.hasNext()) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public int size() { + return base.size(); + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + public Object[] toArray() { + return ArraysSupport.reverse(base.toArray()); + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + return ArraysSupport.toArrayReversed(base, a); + } + + public T[] toArray(IntFunction generator) { + return ArraysSupport.reverse(base.toArray(generator)); + } + + // copied from AbstractCollection + public String toString() { + Iterator it = iterator(); + if (! it.hasNext()) + return "[]"; + + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (;;) { + E e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (! it.hasNext()) + return sb.append(']').toString(); + sb.append(',').append(' '); + } + } + + // ========== List ========== + + public void add(int index, E element) { + checkModifiable(); + int size = base.size(); + checkClosedRange(index, size); + base.add(size - index, element); + } + + public boolean addAll(int index, Collection c) { + checkModifiable(); + int size = base.size(); + checkClosedRange(index, size); + @SuppressWarnings("unchecked") + E[] adds = (E[]) c.toArray(); + if (adds.length == 0) { + return false; + } else { + base.addAll(size - index, Arrays.asList(ArraysSupport.reverse(adds))); + return true; + } + } + + public E get(int i) { + int size = base.size(); + Objects.checkIndex(i, size); + return base.get(size - i - 1); + } + + public int indexOf(Object o) { + int i = base.lastIndexOf(o); + return i == -1 ? -1 : base.size() - i - 1; + } + + public int lastIndexOf(Object o) { + int i = base.indexOf(o); + return i == -1 ? -1 : base.size() - i - 1; + } + + public ListIterator listIterator() { + return new DescendingListIterator(base.size(), 0); + } + + public ListIterator listIterator(int index) { + int size = base.size(); + checkClosedRange(index, size); + return new DescendingListIterator(size, index); + } + + public E remove(int index) { + checkModifiable(); + int size = base.size(); + Objects.checkIndex(index, size); + return base.remove(size - index - 1); + } + + public boolean removeIf(Predicate filter) { + checkModifiable(); + return base.removeIf(filter); + } + + public void replaceAll(UnaryOperator operator) { + checkModifiable(); + base.replaceAll(operator); + } + + public void sort(Comparator c) { + checkModifiable(); + base.sort(Collections.reverseOrder(c)); + } + + public E set(int index, E element) { + checkModifiable(); + int size = base.size(); + Objects.checkIndex(index, size); + return base.set(size - index - 1, element); + } + + public List subList(int fromIndex, int toIndex) { + int size = base.size(); + Objects.checkFromToIndex(fromIndex, toIndex, size); + return new ReverseOrderListView<>(base.subList(size - toIndex, size - fromIndex), modifiable); + } + + static void checkClosedRange(int index, int size) { + if (index < 0 || index > size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + } +} diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java new file mode 100644 index 00000000000..404950e8fd5 --- /dev/null +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedMapView.java @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +/** + * Provides a reversed-ordered view of a SortedMap. Not serializable. + * + * TODO: copy in equals and hashCode from AbstractMap + */ +class ReverseOrderSortedMapView extends AbstractMap implements SortedMap { + final SortedMap base; + final Comparator cmp; + + private ReverseOrderSortedMapView(SortedMap map) { + base = map; + cmp = Collections.reverseOrder(map.comparator()); + } + + public static SortedMap of(SortedMap map) { + if (map instanceof ReverseOrderSortedMapView rosmv) { + return rosmv.base; + } else { + return new ReverseOrderSortedMapView<>(map); + } + } + + // ========== Object ========== + + // equals: inherited from AbstractMap + + // hashCode: inherited from AbstractMap + + public String toString() { + return toString(this, descendingEntryIterator(base)); + } + + // ========== Map ========== + + public void clear() { + base.clear(); + } + + public boolean containsKey(Object key) { + return base.containsKey(key); + } + + public boolean containsValue(Object value) { + return base.containsValue(value); + } + + public V get(Object key) { + return base.get(key); + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public V put(K key, V value) { + return base.put(key, value); + } + + public void putAll(Map m) { + base.putAll(m); + } + + public V remove(Object key) { + return base.remove(key); + } + + public int size() { + return base.size(); + } + + public Set keySet() { + return new AbstractSet<>() { + // inherit add(), which throws UOE + public Iterator iterator() { return descendingKeyIterator(base); } + public int size() { return base.size(); } + public void clear() { base.keySet().clear(); } + public boolean contains(Object o) { return base.keySet().contains(o); } + public boolean remove(Object o) { return base.keySet().remove(o); } + }; + } + + public Collection values() { + return new AbstractCollection<>() { + // inherit add(), which throws UOE + public Iterator iterator() { return descendingValueIterator(base); } + public int size() { return base.size(); } + public void clear() { base.values().clear(); } + public boolean contains(Object o) { return base.values().contains(o); } + public boolean remove(Object o) { return base.values().remove(o); } + }; + } + + public Set> entrySet() { + return new AbstractSet<>() { + // inherit add(), which throws UOE + public Iterator> iterator() { return descendingEntryIterator(base); } + public int size() { return base.size(); } + public void clear() { base.entrySet().clear(); } + public boolean contains(Object o) { return base.entrySet().contains(o); } + public boolean remove(Object o) { return base.entrySet().remove(o); } + }; + } + + // ========== SequencedMap ========== + + public SortedMap reversed() { + return base; + } + + public K firstKey() { + return base.lastKey(); + } + + public K lastKey() { + return base.firstKey(); + } + + public Map.Entry firstEntry() { + return base.lastEntry(); + } + + public Map.Entry lastEntry() { + return base.firstEntry(); + } + + public Map.Entry pollFirstEntry() { + return base.pollLastEntry(); + } + + public Map.Entry pollLastEntry() { + return base.pollFirstEntry(); + } + + public V putFirst(K k, V v) { + return base.putLast(k, v); + } + + public V putLast(K k, V v) { + return base.putFirst(k, v); + } + + // ========== SortedMap ========== + + public Comparator comparator() { + return cmp; + } + + public SortedMap subMap(K fromKey, K toKey) { + if (cmp.compare(fromKey, toKey) <= 0) { + return new Submap(fromKey, toKey); + } else { + throw new IllegalArgumentException(); + } + } + + public SortedMap headMap(K toKey) { + return new Submap(null, toKey); + } + + public SortedMap tailMap(K fromKey) { + return new Submap(fromKey, null); + } + + // ========== Infrastructure ========== + + static Iterator descendingKeyIterator(SortedMap map) { + return new Iterator<>() { + SortedMap root = map; + SortedMap view = map; + K prev = null; + + public boolean hasNext() { + return ! view.isEmpty(); + } + + public K next() { + if (view.isEmpty()) + throw new NoSuchElementException(); + K k = prev = view.lastKey(); + view = root.headMap(k); + return k; + } + + public void remove() { + if (prev == null) { + throw new IllegalStateException(); + } else { + root.remove(prev); + prev = null; + } + } + }; + } + + static Iterator descendingValueIterator(SortedMap map) { + return new Iterator<>() { + Iterator keyIterator = descendingKeyIterator(map); + + public boolean hasNext() { + return keyIterator.hasNext(); + } + + public V next() { + return map.get(keyIterator.next()); + } + + public void remove() { + keyIterator.remove(); + } + }; + } + + static Iterator> descendingEntryIterator(SortedMap map) { + return new Iterator<>() { + Iterator keyIterator = descendingKeyIterator(map); + + public boolean hasNext() { + return keyIterator.hasNext(); + } + + public Map.Entry next() { + K key = keyIterator.next(); + return new ViewEntry<>(map, key, map.get(key)); + } + + public void remove() { + keyIterator.remove(); + } + }; + } + + static class ViewEntry implements Map.Entry { + final Map map; + final K key; + final V value; + + ViewEntry(Map map, K key, V value) { + this.map = map; + this.key = key; + this.value = value; + } + + public K getKey() { return key; } + public V getValue() { return value; } + public V setValue(V newValue) { return map.put(key, newValue); } + + public boolean equals(Object o) { + return o instanceof Map.Entry e + && Objects.equals(key, e.getKey()) + && Objects.equals(value, e.getValue()); + } + + public int hashCode() { + return Objects.hashCode(key) ^ Objects.hashCode(value); + } + + public String toString() { + return key + "=" + value; + } + } + + // copied and modified from AbstractMap + static String toString(Map thisMap, Iterator> i) { + if (! i.hasNext()) + return "{}"; + + StringBuilder sb = new StringBuilder(); + sb.append('{'); + for (;;) { + Entry e = i.next(); + K key = e.getKey(); + V value = e.getValue(); + sb.append(key == thisMap ? "(this Map)" : key); + sb.append('='); + sb.append(value == thisMap ? "(this Map)" : value); + if (! i.hasNext()) + return sb.append('}').toString(); + sb.append(',').append(' '); + } + } + + /** + * Used for various submap views. We can't use the base SortedMap's subMap, + * because of the asymmetry between from-inclusive and to-exclusive. + */ + class Submap extends AbstractMap implements SortedMap { + final K head; // head key, or negative infinity if null + final K tail; // tail key, or positive infinity if null + + @SuppressWarnings("unchecked") + Submap(K head, K tail) { + this.head = head; + this.tail = tail; + } + + // returns whether e is above the head, inclusive + boolean aboveHead(K k) { + return head == null || cmp.compare(k, head) >= 0; + } + + // returns whether e is below the tail, exclusive + boolean belowTail(K k) { + return tail == null || cmp.compare(k, tail) < 0; + } + + Iterator> entryIterator() { + return new Iterator<>() { + Entry cache = null; + K prevKey = null; + boolean dead = false; + Iterator> it = descendingEntryIterator(base); + + public boolean hasNext() { + if (dead) + return false; + + if (cache != null) + return true; + + while (it.hasNext()) { + Entry e = it.next(); + + if (! aboveHead(e.getKey())) + continue; + + if (! belowTail(e.getKey())) { + dead = true; + return false; + } + + cache = e; + return true; + } + + return false; + } + + public Entry next() { + if (hasNext()) { + Entry e = cache; + cache = null; + prevKey = e.getKey(); + return e; + } else { + throw new NoSuchElementException(); + } + } + + public void remove() { + if (prevKey == null) { + throw new IllegalStateException(); + } else { + base.remove(prevKey); + } + } + }; + } + + // equals: inherited from AbstractMap + + // hashCode: inherited from AbstractMap + + public String toString() { + return ReverseOrderSortedMapView.toString(this, entryIterator()); + } + + public Set> entrySet() { + return new AbstractSet<>() { + public Iterator> iterator() { + return entryIterator(); + } + + public int size() { + int sz = 0; + for (var it = entryIterator(); it.hasNext();) { + it.next(); + sz++; + } + return sz; + } + }; + } + + public V put(K key, V value) { + if (aboveHead(key) && belowTail(key)) + return base.put(key, value); + else + throw new IllegalArgumentException(); + } + + public V remove(Object o) { + @SuppressWarnings("unchecked") + K key = (K) o; + if (aboveHead(key) && belowTail(key)) + return base.remove(o); + else + return null; + } + + public int size() { + return entrySet().size(); + } + + public Comparator comparator() { + return cmp; + } + + public K firstKey() { + return this.entryIterator().next().getKey(); + } + + public K lastKey() { + var it = this.entryIterator(); + if (! it.hasNext()) + throw new NoSuchElementException(); + var last = it.next(); + while (it.hasNext()) + last = it.next(); + return last.getKey(); + } + + public SortedMap subMap(K from, K to) { + if (aboveHead(from) && belowTail(from) && + aboveHead(to) && belowTail(to) && + cmp.compare(from, to) <= 0) { + return new Submap(from, to); + } else { + throw new IllegalArgumentException(); + } + } + + public SortedMap headMap(K to) { + if (aboveHead(to) && belowTail(to)) + return new Submap(head, to); + else + throw new IllegalArgumentException(); + } + + public SortedMap tailMap(K from) { + if (aboveHead(from) && belowTail(from)) + return new Submap(from, tail); + else + throw new IllegalArgumentException(); + } + } +} diff --git a/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java new file mode 100644 index 00000000000..678c82fc311 --- /dev/null +++ b/src/java.base/share/classes/java/util/ReverseOrderSortedSetView.java @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import jdk.internal.util.ArraysSupport; + +/** + * Provides a reversed-ordered view of a SortedSet. Not serializable. + */ +class ReverseOrderSortedSetView implements SortedSet { + final SortedSet base; + final Comparator comp; + + private ReverseOrderSortedSetView(SortedSet set) { + base = set; + comp = Collections.reverseOrder(set.comparator()); + } + + public static SortedSet of(SortedSet set) { + if (set instanceof ReverseOrderSortedSetView rossv) { + return rossv.base; + } else { + return new ReverseOrderSortedSetView<>(set); + } + } + + // ========== Object ========== + + // copied from AbstractSet + public boolean equals(Object o) { + if (o == this) + return true; + + if (!(o instanceof Set)) + return false; + Collection c = (Collection) o; + if (c.size() != size()) + return false; + try { + return containsAll(c); + } catch (ClassCastException | NullPointerException unused) { + return false; + } + } + + // copied from AbstractSet + public int hashCode() { + int h = 0; + Iterator i = iterator(); + while (i.hasNext()) { + E obj = i.next(); + if (obj != null) + h += obj.hashCode(); + } + return h; + } + + // copied from AbstractCollection + public String toString() { + Iterator it = iterator(); + if (! it.hasNext()) + return "[]"; + + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (;;) { + E e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (! it.hasNext()) + return sb.append(']').toString(); + sb.append(',').append(' '); + } + } + + // ========== Iterable ========== + + public void forEach(Consumer action) { + for (E e : this) + action.accept(e); + } + + public Iterator iterator() { + return descendingIterator(base); + } + + public Spliterator spliterator() { + return Spliterators.spliteratorUnknownSize(descendingIterator(base), 0); + } + + // ========== Collection ========== + + public boolean add(E e) { + base.add(e); + return true; + } + + public boolean addAll(Collection c) { + return base.addAll(c); + } + + public void clear() { + base.clear(); + } + + public boolean contains(Object o) { + return base.contains(o); + } + + public boolean containsAll(Collection c) { + return base.containsAll(c); + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + public boolean remove(Object o) { + return base.remove(o); + } + + public boolean removeAll(Collection c) { + return base.removeAll(c); + } + + // copied from AbstractCollection + public boolean retainAll(Collection c) { + return base.retainAll(c); + } + + public int size() { + return base.size(); + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + public Object[] toArray() { + return ArraysSupport.reverse(base.toArray()); + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + return ArraysSupport.toArrayReversed(base, a); + } + + public T[] toArray(IntFunction generator) { + return ArraysSupport.reverse(base.toArray(generator)); + } + + // ========== SortedSet ========== + + public Comparator comparator() { + return comp; + } + + public E first() { return base.last(); } + + public E last() { return base.first(); } + + public SortedSet headSet(E to) { + return new Subset(null, to); + } + + public SortedSet subSet(E from, E to) { + return new Subset(from, to); + } + + public SortedSet tailSet(E from) { + return new Subset(from, null); + } + + // ========== Infrastructure ========== + + static Iterator descendingIterator(SortedSet set) { + return new Iterator<>() { + SortedSet root = set; + SortedSet view = set; + T prev = null; + + public boolean hasNext() { + return ! view.isEmpty(); + } + + public T next() { + if (view.isEmpty()) + throw new NoSuchElementException(); + T t = prev = view.last(); + view = root.headSet(t); + return t; + } + + public void remove() { + if (prev == null) { + throw new IllegalStateException(); + } else { + root.remove(prev); + prev = null; + } + } + }; + } + + /** + * Used for various subset views. We can't use the base SortedSet's subset, + * because of the asymmetry between from-inclusive and to-exclusive. + */ + class Subset extends AbstractSet implements SortedSet { + final E head; // head element, or negative infinity if null + final E tail; // tail element, or positive infinity if null + final Comparator cmp; + + @SuppressWarnings("unchecked") + Subset(E head, E tail) { + this.head = head; + this.tail = tail; + Comparator c = (Comparator) ReverseOrderSortedSetView.this.comparator(); + if (c == null) + c = (Comparator) Comparator.naturalOrder(); + cmp = c; + } + + // returns whether e is above the head, inclusive + boolean aboveHead(E e) { + return head == null || cmp.compare(e, head) >= 0; + } + + // returns whether e is below the tail, exclusive + boolean belowTail(E e) { + return tail == null || cmp.compare(e, tail) < 0; + } + + public Iterator iterator() { + return new Iterator<>() { + E cache = null; + boolean dead = false; + Iterator it = descendingIterator(base); + + public boolean hasNext() { + if (dead) + return false; + + if (cache != null) + return true; + + while (it.hasNext()) { + E e = it.next(); + + if (! aboveHead(e)) + continue; + + if (! belowTail(e)) { + dead = true; + return false; + } + + cache = e; + return true; + } + + return false; + } + + public E next() { + if (hasNext()) { + E e = cache; + cache = null; + return e; + } else { + throw new NoSuchElementException(); + } + } + }; + } + + public boolean add(E e) { + if (aboveHead(e) && belowTail(e)) + return base.add(e); + else + throw new IllegalArgumentException(); + } + + public boolean remove(Object o) { + @SuppressWarnings("unchecked") + E e = (E) o; + if (aboveHead(e) && belowTail(e)) + return base.remove(o); + else + return false; + } + + public int size() { + int sz = 0; + for (E e : this) + sz++; + return sz; + } + + public Comparator comparator() { + return ReverseOrderSortedSetView.this.comparator(); + } + + public E first() { + return this.iterator().next(); + } + + public E last() { + var it = this.iterator(); + if (! it.hasNext()) + throw new NoSuchElementException(); + E last = it.next(); + while (it.hasNext()) + last = it.next(); + return last; + } + + public SortedSet subSet(E from, E to) { + if (aboveHead(from) && belowTail(from) && + aboveHead(to) && belowTail(to) && + cmp.compare(from, to) <= 0) { + return ReverseOrderSortedSetView.this.new Subset(from, to); + } else { + throw new IllegalArgumentException(); + } + } + + public SortedSet headSet(E to) { + if (aboveHead(to) && belowTail(to)) + return ReverseOrderSortedSetView.this.new Subset(head, to); + else + throw new IllegalArgumentException(); + } + + public SortedSet tailSet(E from) { + if (aboveHead(from) && belowTail(from)) + return ReverseOrderSortedSetView.this.new Subset(null, tail); + else + throw new IllegalArgumentException(); + } + + } +} diff --git a/src/java.base/share/classes/java/util/SequencedCollection.java b/src/java.base/share/classes/java/util/SequencedCollection.java new file mode 100644 index 00000000000..54237c7a3f7 --- /dev/null +++ b/src/java.base/share/classes/java/util/SequencedCollection.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +/** + * A collection that has a well-defined encounter order, that supports operations at both ends, + * and that is reversible. The elements of a sequenced collection have an + * encounter order, where conceptually the elements have a linear arrangement + * from the first element to the last element. Given any two elements, one element is + * either before (closer to the first element) or after (closer to the last element) + * the other element. + *

+ * (Note that this definition does not imply anything about physical positioning + * of elements, such as their locations in a computer's memory.) + *

+ * Several methods inherited from the {@link Collection} interface are required to operate + * on elements according to this collection's encounter order. For instance, the + * {@link Collection#iterator iterator} method provides elements starting from the first element, + * proceeding through successive elements, until the last element. Other methods that are + * required to operate on elements in encounter order include the following: + * {@link Iterable#forEach forEach}, {@link Collection#parallelStream parallelStream}, + * {@link Collection#spliterator spliterator}, {@link Collection#stream stream}, + * and all overloads of the {@link Collection#toArray toArray} method. + *

+ * This interface provides methods to add, retrieve, and remove elements at either end + * of the collection. + *

+ * This interface also defines the {@link #reversed reversed} method, which provides + * a reverse-ordered view of this collection. + * In the reverse-ordered view, the concepts of first and last are inverted, as are + * the concepts of successor and predecessor. The first element of this collection is + * the last element of the reverse-ordered view, and vice-versa. The successor of some + * element in this collection is its predecessor in the reversed view, and vice-versa. All + * methods that respect the encounter order of the collection operate as if the encounter order + * is inverted. For instance, the {@link #iterator} method of the reversed view reports the + * elements in order from the last element of this collection to the first. The availability of + * the {@code reversed} method, and its impact on the ordering semantics of all applicable + * methods, allow convenient iteration, searching, copying, and streaming of the elements of + * this collection in either forward order or reverse order. + *

+ * This class is a member of the + * + * Java Collections Framework. + * + * @apiNote + * This interface does not impose any requirements on the {@code equals} and {@code hashCode} + * methods, because requirements imposed by sub-interfaces {@link List} and {@link SequencedSet} + * (which inherits requirements from {@link Set}) would be in conflict. See the specifications for + * {@link Collection#equals Collection.equals} and {@link Collection#hashCode Collection.hashCode} + * for further information. + * + * @param the type of elements in this collection + * @since 21 + */ +public interface SequencedCollection extends Collection { + /** + * Returns a reverse-ordered view of this collection. + * The encounter order of elements in the returned view is the inverse of the encounter + * order of elements in this collection. The reverse ordering affects all order-sensitive + * operations, including those on the view collections of the returned view. If the collection + * implementation permits modifications to this view, the modifications "write through" to the + * underlying collection. Changes to the underlying collection might or might not be visible + * in this reversed view, depending upon the implementation. + * + * @return a reverse-ordered view of this collection + */ + SequencedCollection reversed(); + + /** + * Adds an element as the first element of this collection (optional operation). + * After this operation completes normally, the given element will be a member of + * this collection, and it will be the first element in encounter order. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @param e the element to be added + * @throws NullPointerException if the specified element is null and this + * collection does not permit null elements + * @throws UnsupportedOperationException if this collection implementation + * does not support this operation + */ + default void addFirst(E e) { + throw new UnsupportedOperationException(); + } + + /** + * Adds an element as the last element of this collection (optional operation). + * After this operation completes normally, the given element will be a member of + * this collection, and it will be the last element in encounter order. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @param e the element to be added. + * @throws NullPointerException if the specified element is null and this + * collection does not permit null elements + * @throws UnsupportedOperationException if this collection implementation + * does not support this operation + */ + default void addLast(E e) { + throw new UnsupportedOperationException(); + } + + /** + * Gets the first element of this collection. + * + * @implSpec + * The implementation in this interface obtains an iterator of this collection, and + * then it obtains an element by calling the iterator's {@code next} method. Any + * {@code NoSuchElementException} thrown is propagated. Otherwise, it returns + * the element. + * + * @return the retrieved element + * @throws NoSuchElementException if this collection is empty + */ + default E getFirst() { + return this.iterator().next(); + } + + /** + * Gets the last element of this collection. + * + * @implSpec + * The implementation in this interface obtains an iterator of the reversed view + * of this collection, and then it obtains an element by calling the iterator's + * {@code next} method. Any {@code NoSuchElementException} thrown is propagated. + * Otherwise, it returns the element. + * + * @return the retrieved element + * @throws NoSuchElementException if this collection is empty + */ + default E getLast() { + return this.reversed().iterator().next(); + } + + /** + * Removes and returns the first element of this collection (optional operation). + * + * @implSpec + * The implementation in this interface obtains an iterator of this collection, and then + * it obtains an element by calling the iterator's {@code next} method. Any + * {@code NoSuchElementException} thrown is propagated. It then calls the iterator's + * {@code remove} method. Any {@code UnsupportedOperationException} thrown is propagated. + * Then, it returns the element. + * + * @return the removed element + * @throws NoSuchElementException if this collection is empty + * @throws UnsupportedOperationException if this collection implementation + * does not support this operation + */ + default E removeFirst() { + var it = this.iterator(); + E e = it.next(); + it.remove(); + return e; + } + + /** + * Removes and returns the last element of this collection (optional operation). + * + * @implSpec + * The implementation in this interface obtains an iterator of the reversed view of this + * collection, and then it obtains an element by calling the iterator's {@code next} method. + * Any {@code NoSuchElementException} thrown is propagated. It then calls the iterator's + * {@code remove} method. Any {@code UnsupportedOperationException} thrown is propagated. + * Then, it returns the element. + * + * @return the removed element + * @throws NoSuchElementException if this collection is empty + * @throws UnsupportedOperationException if this collection implementation + * does not support this operation + */ + default E removeLast() { + var it = this.reversed().iterator(); + E e = it.next(); + it.remove(); + return e; + } +} diff --git a/src/java.base/share/classes/java/util/SequencedMap.java b/src/java.base/share/classes/java/util/SequencedMap.java new file mode 100644 index 00000000000..c8f88d004bc --- /dev/null +++ b/src/java.base/share/classes/java/util/SequencedMap.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +/** + * A Map that has a well-defined encounter order, that supports operations at both ends, and + * that is reversible. The encounter order + * of a {@code SequencedMap} is similar to that of the elements of a {@link SequencedCollection}, + * but the ordering applies to mappings instead of individual elements. + *

+ * The bulk operations on this map, including the {@link #forEach forEach} and the + * {@link #replaceAll replaceAll} methods, operate on this map's mappings in + * encounter order. + *

+ * The view collections provided by the + * {@link #keySet keySet}, + * {@link #values values}, + * {@link #entrySet entrySet}, + * {@link #sequencedKeySet sequencedKeySet}, + * {@link #sequencedValues sequencedValues}, + * and + * {@link #sequencedEntrySet sequencedEntrySet} methods all reflect the encounter order + * of this map. Even though the return values of the {@code keySet}, {@code values}, and + * {@code entrySet} methods are not sequenced types, the elements + * in those view collections do reflect the encounter order of this map. Thus, the + * iterators returned by the statements + * {@snippet : + * var it1 = sequencedMap.entrySet().iterator(); + * var it2 = sequencedMap.sequencedEntrySet().iterator(); + * } + * both provide the mappings of {@code sequencedMap} in that map's encounter order. + *

+ * This interface provides methods to add mappings, to retrieve mappings, and to remove + * mappings at either end of the map's encounter order. + *

+ * This interface also defines the {@link #reversed} method, which provides a + * reverse-ordered view of this map. + * In the reverse-ordered view, the concepts of first and last are inverted, as + * are the concepts of successor and predecessor. The first mapping of this map + * is the last mapping of the reverse-ordered view, and vice-versa. The successor of some + * mapping in this map is its predecessor in the reversed view, and vice-versa. All + * methods that respect the encounter order of the map operate as if the encounter order + * is inverted. For instance, the {@link #forEach forEach} method of the reversed view reports + * the mappings in order from the last mapping of this map to the first. In addition, all of + * the view collections of the reversed view also reflect the inverse of this map's + * encounter order. For example, + * {@snippet : + * var itr = sequencedMap.reversed().entrySet().iterator(); + * } + * provides the mappings of this map in the inverse of the encounter order, that is, from + * the last mapping to the first mapping. The availability of the {@code reversed} method, + * and its impact on the ordering semantics of all applicable methods and views, allow convenient + * iteration, searching, copying, and streaming of this map's mappings in either forward order or + * reverse order. + *

+ * A map's reverse-ordered view is generally not serializable, even if the original + * map is serializable. + *

+ * The {@link Map.Entry} instances obtained by iterating the {@link #entrySet} view, the + * {@link #sequencedEntrySet} view, and its reverse-ordered view, maintain a connection to the + * underlying map. This connection is guaranteed only during the iteration. It is unspecified + * whether the connection is maintained outside of the iteration. If the underlying map permits + * it, calling an Entry's {@link Map.Entry#setValue setValue} method will modify the value of the + * underlying mapping. It is, however, unspecified whether modifications to the value in the + * underlying mapping are visible in the {@code Entry} instance. + *

+ * The methods + * {@link #firstEntry}, + * {@link #lastEntry}, + * {@link #pollFirstEntry}, and + * {@link #pollLastEntry} + * return {@link Map.Entry} instances that represent snapshots of mappings as + * of the time of the call. They do not support mutation of the + * underlying map via the optional {@link Map.Entry#setValue setValue} method. + *

+ * Depending upon the implementation, the {@code Entry} instances returned by other + * means might or might not be connected to the underlying map. For example, consider + * an {@code Entry} obtained in the following manner: + * {@snippet : + * var entry = sequencedMap.sequencedEntrySet().getFirst(); + * } + * It is not specified by this interface whether the {@code setValue} method of the + * {@code Entry} thus obtained will update a mapping in the underlying map, or whether + * it will throw an exception, or whether changes to the underlying map are visible in + * that {@code Entry}. + *

+ * This interface has the same requirements on the {@code equals} and {@code hashCode} + * methods as defined by {@link Map#equals Map.equals} and {@link Map#hashCode Map.hashCode}. + * Thus, a {@code Map} and a {@code SequencedMap} will compare equals if and only + * if they have equal mappings, irrespective of ordering. + *

+ * This class is a member of the + * + * Java Collections Framework. + * + * @param the type of keys maintained by this map + * @param the type of mapped values + * @since 21 + */ +public interface SequencedMap extends Map { + /** + * Returns a reverse-ordered view of this map. + * The encounter order of mappings in the returned view is the inverse of the encounter + * order of mappings in this map. The reverse ordering affects all order-sensitive operations, + * including those on the view collections of the returned view. If the implementation permits + * modifications to this view, the modifications "write through" to the underlying map. + * Changes to the underlying map might or might not be visible in this reversed view, + * depending upon the implementation. + * + * @return a reverse-ordered view of this map + */ + SequencedMap reversed(); + + /** + * Returns the first key-value mapping in this map, + * or {@code null} if the map is empty. + * + * @implSpec + * The implementation in this interface obtains the iterator of this map's entrySet. + * If the iterator has an element, it returns an unmodifiable copy of that element. + * Otherwise, it returns null. + * + * @return the first key-value mapping, + * or {@code null} if this map is empty + */ + default Map.Entry firstEntry() { + var it = entrySet().iterator(); + return it.hasNext() ? Map.Entry.copyOf(it.next()) : null; + } + + /** + * Returns the last key-value mapping in this map, + * or {@code null} if the map is empty. + * + * @implSpec + * The implementation in this interface obtains the iterator of the entrySet of this map's + * reversed view. If the iterator has an element, it returns an unmodifiable copy of + * that element. Otherwise, it returns null. + * + * @return the last key-value mapping, + * or {@code null} if this map is empty + */ + default Map.Entry lastEntry() { + var it = reversed().entrySet().iterator(); + return it.hasNext() ? Map.Entry.copyOf(it.next()) : null; + } + + /** + * Removes and returns the first key-value mapping in this map, + * or {@code null} if the map is empty (optional operation). + * + * @implSpec + * The implementation in this interface obtains the iterator of this map's entrySet. + * If the iterator has an element, it calls {@code remove} on the iterator and + * then returns an unmodifiable copy of that element. Otherwise, it returns null. + * + * @return the removed first entry of this map, + * or {@code null} if this map is empty + * @throws UnsupportedOperationException if this collection implementation does not + * support this operation + */ + default Map.Entry pollFirstEntry() { + var it = entrySet().iterator(); + if (it.hasNext()) { + var entry = Map.Entry.copyOf(it.next()); + it.remove(); + return entry; + } else { + return null; + } + } + + /** + * Removes and returns the last key-value mapping in this map, + * or {@code null} if the map is empty (optional operation). + * + * @implSpec + * The implementation in this interface obtains the iterator of the entrySet of this map's + * reversed view. If the iterator has an element, it calls {@code remove} on the iterator + * and then returns an unmodifiable copy of that element. Otherwise, it returns null. + * + * @return the removed last entry of this map, + * or {@code null} if this map is empty + * @throws UnsupportedOperationException if this collection implementation does not + * support this operation + */ + default Map.Entry pollLastEntry() { + var it = reversed().entrySet().iterator(); + if (it.hasNext()) { + var entry = Map.Entry.copyOf(it.next()); + it.remove(); + return entry; + } else { + return null; + } + } + + /** + * Inserts the given mapping into the map if it is not already present, or replaces the + * value of a mapping if it is already present (optional operation). After this operation + * completes normally, the given mapping will be present in this map, and it will be the + * first mapping in this map's encounter order. + * + * @implSpec The implementation in this interface always throws + * {@code UnsupportedOperationException}. + * + * @param k the key + * @param v the value + * @return the value previously associated with k, or null if none + * @throws UnsupportedOperationException if this collection implementation does not + * support this operation + */ + default V putFirst(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * Inserts the given mapping into the map if it is not already present, or replaces the + * value of a mapping if it is already present (optional operation). After this operation + * completes normally, the given mapping will be present in this map, and it will be the + * last mapping in this map's encounter order. + * + * @implSpec The implementation in this interface always throws + * {@code UnsupportedOperationException}. + * + * @param k the key + * @param v the value + * @return the value previously associated with k, or null if none + * @throws UnsupportedOperationException if this collection implementation does not + * support this operation + */ + default V putLast(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * Returns a {@link SequencedSet} view of this map's keySet. + * + * @implSpec + * The implementation in this interface returns a {@code SequencedSet} + * implementation that delegates all operations either to this map or to this map's + * {@link #keySet}, except for its {@link SequencedSet#reversed reversed} method, + * which instead returns the result of calling {@code sequencedKeySet} on this map's + * reverse-ordered view. + * + * @return a SequencedSet view of this map's keySet + */ + default SequencedSet sequencedKeySet() { + class SeqKeySet extends AbstractMap.ViewCollection implements SequencedSet { + SeqKeySet() { + super(SequencedMap.this.keySet()); + } + public SequencedSet reversed() { + return SequencedMap.this.reversed().sequencedKeySet(); + } + } + return new SeqKeySet(); + } + + /** + * Returns a {@link SequencedCollection} view of this map's values collection. + * + * @implSpec + * The implementation in this interface returns a {@code SequencedCollection} + * implementation that delegates all operations either to this map or to this map's + * {@link #values} collection, except for its {@link SequencedCollection#reversed reversed} + * method, which instead returns the result of calling {@code sequencedValues} on this map's + * reverse-ordered view. + * + * @return a SequencedCollection view of this map's values collection + */ + default SequencedCollection sequencedValues() { + class SeqValues extends AbstractMap.ViewCollection implements SequencedCollection { + SeqValues() { + super(SequencedMap.this.values()); + } + public SequencedCollection reversed() { + return SequencedMap.this.reversed().sequencedValues(); + } + } + return new SeqValues(); + } + + /** + * Returns a {@link SequencedSet} view of this map's entrySet. + * + * @implSpec + * The implementation in this interface returns a {@code SequencedSet} + * implementation that delegates all operations either to this map or to this map's + * {@link #entrySet}, except for its {@link SequencedSet#reversed reversed} method, + * which instead returns the result of calling {@code sequencedEntrySet} on this map's + * reverse-ordered view. + * + * @return a SequencedSet view of this map's entrySet + */ + default SequencedSet> sequencedEntrySet() { + class SeqEntrySet extends AbstractMap.ViewCollection> + implements SequencedSet> { + SeqEntrySet() { + super(SequencedMap.this.entrySet()); + } + public SequencedSet> reversed() { + return SequencedMap.this.reversed().sequencedEntrySet(); + } + } + return new SeqEntrySet(); + } +} diff --git a/src/java.base/share/classes/java/util/SequencedSet.java b/src/java.base/share/classes/java/util/SequencedSet.java new file mode 100644 index 00000000000..c02bfc123ff --- /dev/null +++ b/src/java.base/share/classes/java/util/SequencedSet.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, 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. 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 java.util; + +/** + * A collection that is both a {@link SequencedCollection} and a {@link Set}. As such, + * it can be thought of either as a {@code Set} that also has a well-defined + * encounter order, or as a + * {@code SequencedCollection} that also has unique elements. + *

+ * This interface has the same requirements on the {@code equals} and {@code hashCode} + * methods as defined by {@link Set#equals Set.equals} and {@link Set#hashCode Set.hashCode}. + * Thus, a {@code Set} and a {@code SequencedSet} will compare equals if and only + * if they have equal elements, irrespective of ordering. + *

+ * {@code SequencedSet} defines the {@link #reversed} method, which provides a + * reverse-ordered view of this set. The only difference + * from the {@link SequencedCollection#reversed SequencedCollection.reversed} method is + * that the return type of {@code SequencedSet.reversed} is {@code SequencedSet}. + *

+ * This class is a member of the + * + * Java Collections Framework. + * + * @param the type of elements in this sequenced set + * @since 21 + */ +public interface SequencedSet extends SequencedCollection, Set { + /** + * {@inheritDoc} + * + * @return a reverse-ordered view of this collection, as a {@code SequencedSet} + */ + SequencedSet reversed(); +} diff --git a/src/java.base/share/classes/java/util/SortedMap.java b/src/java.base/share/classes/java/util/SortedMap.java index 77553bcc578..1af9d59e83e 100644 --- a/src/java.base/share/classes/java/util/SortedMap.java +++ b/src/java.base/share/classes/java/util/SortedMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -110,7 +110,7 @@ package java.util; * @since 1.2 */ -public interface SortedMap extends Map { +public interface SortedMap extends SequencedMap { /** * Returns the comparator used to order the keys in this map, or * {@code null} if this map uses the {@linkplain Comparable @@ -281,4 +281,48 @@ public interface SortedMap extends Map { * sorted in ascending key order */ Set> entrySet(); + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + default V putFirst(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + default V putLast(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns an instance of a reverse-ordered + * SortedMap that delegates its operations to this SortedMap. + * + * @return a reverse-ordered view of this map, as a {@code SortedMap} + * @since 21 + */ + default SortedMap reversed() { + return ReverseOrderSortedMapView.of(this); + } } diff --git a/src/java.base/share/classes/java/util/SortedSet.java b/src/java.base/share/classes/java/util/SortedSet.java index c3ef264a2af..48473a1fed5 100644 --- a/src/java.base/share/classes/java/util/SortedSet.java +++ b/src/java.base/share/classes/java/util/SortedSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -105,7 +105,7 @@ package java.util; * @since 1.2 */ -public interface SortedSet extends Set { +public interface SortedSet extends Set, SequencedSet { /** * Returns the comparator used to order the elements in this set, * or {@code null} if this set uses the {@linkplain Comparable @@ -261,4 +261,112 @@ public interface SortedSet extends Set { } }; } + + // ========== SequencedCollection ========== + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + default void addFirst(E e) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @implSpec + * The implementation in this interface always throws {@code UnsupportedOperationException}. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + default void addLast(E e) { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns the result of calling the {@code first} method. + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + default E getFirst() { + return this.first(); + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns the result of calling the {@code last} method. + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + default E getLast() { + return this.last(); + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface calls the {@code first} method to obtain the first + * element, then it calls {@code remove(element)} to remove the element, and then it returns + * the element. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeFirst() { + E e = this.first(); + this.remove(e); + return e; + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface calls the {@code last} method to obtain the last + * element, then it calls {@code remove(element)} to remove the element, and then it returns + * the element. + * + * @throws NoSuchElementException {@inheritDoc} + * @throws UnsupportedOperationException {@inheritDoc} + * @since 21 + */ + default E removeLast() { + E e = this.last(); + this.remove(e); + return e; + } + + /** + * {@inheritDoc} + * + * @implSpec + * The implementation in this interface returns an instance of a reverse-ordered + * SortedSet that delegates its operations to this SortedSet. + * + * @return a reverse-ordered view of this collection, as a {@code SortedSet} + * @since 21 + */ + default SortedSet reversed() { + return ReverseOrderSortedSetView.of(this); + } } diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index e33c95e44d2..a91a56a5900 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -99,6 +99,10 @@ import java.util.function.Function; * of the time of the call. They do not support mutation of the * underlying map via the optional {@link Map.Entry#setValue setValue} method. * + *

The {@link #putFirst putFirst} and {@link #putLast putLast} methods of this class + * throw {@code UnsupportedOperationException}. The encounter order of mappings is determined + * by the comparison method; therefore, explicit positioning is not supported. + * *

This class is a member of the * * Java Collections Framework. @@ -305,6 +309,30 @@ public class TreeMap return key(getLastEntry()); } + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public V putFirst(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public V putLast(K k, V v) { + throw new UnsupportedOperationException(); + } + /** * Copies all of the mappings from the specified map to this map. * These mappings replace any mappings that this map had for any diff --git a/src/java.base/share/classes/java/util/TreeSet.java b/src/java.base/share/classes/java/util/TreeSet.java index f189bb4a9f2..a68c157283e 100644 --- a/src/java.base/share/classes/java/util/TreeSet.java +++ b/src/java.base/share/classes/java/util/TreeSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -73,6 +73,10 @@ package java.util; * exception for its correctness: the fail-fast behavior of iterators * should be used only to detect bugs. * + *

The {@link #addFirst addFirst} and {@link #addLast addLast} methods of this class + * throw {@code UnsupportedOperationException}. The encounter order of elements is determined + * by the comparison method; therefore, explicit positioning is not supported. + * *

This class is a member of the * * Java Collections Framework. @@ -460,6 +464,30 @@ public class TreeSet extends AbstractSet return (e == null) ? null : e.getKey(); } + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public void addFirst(E e) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public void addLast(E e) { + throw new UnsupportedOperationException(); + } + /** * Returns a shallow copy of this {@code TreeSet} instance. (The elements * themselves are not cloned.) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 4c2add084ab..bccbccf5725 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -1870,6 +1870,30 @@ public class ConcurrentSkipListMap extends AbstractMap return n.key; } + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public V putFirst(K k, V v) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * map's comparison method determines the position of mappings, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public V putLast(K k, V v) { + throw new UnsupportedOperationException(); + } + /** * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if {@code fromKey} or {@code toKey} is null diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 4d79c421331..0db76e03e05 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -403,6 +403,30 @@ public class ConcurrentSkipListSet return m.lastKey(); } + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public void addFirst(E e) { + throw new UnsupportedOperationException(); + } + + /** + * Throws {@code UnsupportedOperationException}. The encounter order induced by this + * set's comparison method determines the position of elements, so explicit positioning + * is not supported. + * + * @throws UnsupportedOperationException always + * @since 21 + */ + public void addLast(E e) { + throw new UnsupportedOperationException(); + } + /** * @throws ClassCastException {@inheritDoc} * @throws NullPointerException if {@code fromElement} or diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index ee8e7b81728..909621bd5ba 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -39,6 +39,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.ConcurrentModificationException; import java.util.Iterator; @@ -50,9 +51,13 @@ import java.util.RandomAccess; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; +import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.ArraysSupport; /** * A thread-safe variant of {@link java.util.ArrayList} in which all mutative @@ -398,6 +403,34 @@ public class CopyOnWriteArrayList return elementAt(getArray(), index); } + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getFirst() { + Object[] es = getArray(); + if (es.length == 0) + throw new NoSuchElementException(); + else + return elementAt(es, 0); + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E getLast() { + Object[] es = getArray(); + if (es.length == 0) + throw new NoSuchElementException(); + else + return elementAt(es, es.length - 1); + } + /** * Replaces the element at the specified position in this list with the * specified element. @@ -464,6 +497,26 @@ public class CopyOnWriteArrayList } } + /** + * {@inheritDoc} + * + * @since 21 + */ + public void addFirst(E e) { + add(0, e); + } + + /** + * {@inheritDoc} + * + * @since 21 + */ + public void addLast(E e) { + synchronized (lock) { + add(getArray().length, e); + } + } + /** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their @@ -491,6 +544,37 @@ public class CopyOnWriteArrayList } } + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeFirst() { + synchronized (lock) { + if (getArray().length == 0) + throw new NoSuchElementException(); + else + return remove(0); + } + } + + /** + * {@inheritDoc} + * + * @throws NoSuchElementException {@inheritDoc} + * @since 21 + */ + public E removeLast() { + synchronized (lock) { + int size = getArray().length; + if (size == 0) + throw new NoSuchElementException(); + else + return remove(size - 1); + } + } + /** * Removes the first occurrence of the specified element from this list, * if it is present. If this list does not contain the element, it is @@ -1358,6 +1442,24 @@ public class CopyOnWriteArrayList } } + public E getFirst() { + synchronized (lock) { + if (size == 0) + throw new NoSuchElementException(); + else + return get(0); + } + } + + public E getLast() { + synchronized (lock) { + if (size == 0) + throw new NoSuchElementException(); + else + return get(size - 1); + } + } + public int size() { synchronized (lock) { checkForComodification(); @@ -1385,6 +1487,16 @@ public class CopyOnWriteArrayList } } + public void addFirst(E e) { + add(0, e); + } + + public void addLast(E e) { + synchronized (lock) { + add(size, e); + } + } + public boolean addAll(Collection c) { synchronized (lock) { final Object[] oldArray = getArrayChecked(); @@ -1426,6 +1538,24 @@ public class CopyOnWriteArrayList } } + public E removeFirst() { + synchronized (lock) { + if (size == 0) + throw new NoSuchElementException(); + else + return remove(0); + } + } + + public E removeLast() { + synchronized (lock) { + if (size == 0) + throw new NoSuchElementException(); + else + return remove(size - 1); + } + } + public boolean remove(Object o) { synchronized (lock) { checkForComodification(); @@ -1524,6 +1654,9 @@ public class CopyOnWriteArrayList } } + public List reversed() { + return new Reversed<>(this, lock); + } } private static class COWSubListIterator implements ListIterator { @@ -1589,6 +1722,365 @@ public class CopyOnWriteArrayList } } + /** + * {@inheritDoc} + *

+ * Modifications to the reversed view are permitted and will be propagated + * to this list. In addition, modifications to this list will be visible + * in the reversed view. Sublists and iterators of the reversed view have + * the same restrictions as those of this list. + * + * @since 21 + */ + public List reversed() { + return new Reversed<>(this, lock); + } + + /** + * Reversed view for CopyOnWriteArrayList and its sublists. + */ + private static class Reversed implements List, RandomAccess { + final List base; + final Object lock; + + Reversed(List base, Object lock) { + this.base = base; + this.lock = lock; + } + + class DescendingIterator implements Iterator { + final ListIterator it; + DescendingIterator() { + synchronized (lock) { + it = base.listIterator(base.size()); + } + } + public boolean hasNext() { return it.hasPrevious(); } + public E next() { return it.previous(); } + public void remove() { it.remove(); } + } + + class DescendingListIterator implements ListIterator { + final ListIterator it; + final int size; // iterator holds a snapshot of the array so this is constant + + DescendingListIterator(int pos) { + synchronized (lock) { + size = base.size(); + if (pos < 0 || pos > size) + throw new IndexOutOfBoundsException(); + it = base.listIterator(size - pos); + } + } + + public boolean hasNext() { + return it.hasPrevious(); + } + + public E next() { + return it.previous(); + } + + public boolean hasPrevious() { + return it.hasNext(); + } + + public E previous() { + return it.next(); + } + + public int nextIndex() { + return size - it.nextIndex(); + } + + public int previousIndex() { + return nextIndex() - 1; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public void set(E e) { + throw new UnsupportedOperationException(); + } + + public void add(E e) { + throw new UnsupportedOperationException(); + } + } + + // ========== Iterable ========== + + public void forEach(Consumer action) { + for (E e : this) + action.accept(e); + } + + public Iterator iterator() { + return new DescendingIterator(); + } + + public Spliterator spliterator() { + // TODO can probably improve this + return Spliterators.spliteratorUnknownSize(new DescendingIterator(), 0); + } + + // ========== Collection ========== + + public boolean add(E e) { + base.add(0, e); + return true; + } + + public boolean addAll(Collection c) { + @SuppressWarnings("unchecked") + E[] es = (E[]) c.toArray(); + if (es.length > 0) { + ArraysSupport.reverse(es); + base.addAll(0, Arrays.asList(es)); + return true; + } else { + return false; + } + } + + public void clear() { + base.clear(); + } + + public boolean contains(Object o) { + return base.contains(o); + } + + public boolean containsAll(Collection c) { + return base.containsAll(c); + } + + // copied from AbstractList + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof List)) + return false; + + ListIterator e1 = listIterator(); + ListIterator e2 = ((List) o).listIterator(); + while (e1.hasNext() && e2.hasNext()) { + E o1 = e1.next(); + Object o2 = e2.next(); + if (!(o1==null ? o2==null : o1.equals(o2))) + return false; + } + return !(e1.hasNext() || e2.hasNext()); + } + + // copied from AbstractList + public int hashCode() { + int hashCode = 1; + for (E e : this) + hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); + return hashCode; + } + + public boolean isEmpty() { + return base.isEmpty(); + } + + public Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + public boolean remove(Object o) { + synchronized (lock) { + int index = indexOf(o); + if (index == -1) + return false; + remove(index); + return true; + } + } + + public boolean removeAll(Collection c) { + return base.removeAll(c); + } + + public boolean retainAll(Collection c) { + return base.retainAll(c); + } + + public int size() { + return base.size(); + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + public Object[] toArray() { + return ArraysSupport.reverse(base.toArray()); + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + // TODO optimize this + return toArray(i -> (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), i)); + } + + public T[] toArray(IntFunction generator) { + return ArraysSupport.reverse(base.toArray(generator)); + } + + // copied from AbstractCollection + public String toString() { + Iterator it = iterator(); + if (! it.hasNext()) + return "[]"; + + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (;;) { + E e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (! it.hasNext()) + return sb.append(']').toString(); + sb.append(',').append(' '); + } + } + + // ========== List ========== + + public void add(int index, E element) { + synchronized (lock) { + base.add(base.size() - index, element); + } + } + + public void addFirst(E e) { + base.add(e); + } + + public void addLast(E e) { + base.add(0, e); + } + + public boolean addAll(int index, Collection c) { + @SuppressWarnings("unchecked") + E[] es = (E[]) c.toArray(); + if (es.length > 0) { + ArraysSupport.reverse(es); + synchronized (lock) { + base.addAll(base.size() - index, Arrays.asList(es)); + } + return true; + } else { + return false; + } + } + + public E get(int i) { + synchronized (lock) { + return base.get(base.size() - i - 1); + } + } + + public E getFirst() { + synchronized (lock) { + int size = base.size(); + if (size == 0) + throw new NoSuchElementException(); + else + return base.get(size - 1); + } + } + + public E getLast() { + synchronized (lock) { + if (base.size() == 0) + throw new NoSuchElementException(); + else + return base.get(0); + } + } + + public int indexOf(Object o) { + synchronized (lock) { + int i = base.lastIndexOf(o); + return i == -1 ? -1 : base.size() - i - 1; + } + } + + public int lastIndexOf(Object o) { + synchronized (lock) { + int i = base.indexOf(o); + return i == -1 ? -1 : base.size() - i - 1; + } + } + + public ListIterator listIterator() { + return new DescendingListIterator(0); + } + + public ListIterator listIterator(int index) { + return new DescendingListIterator(index); + } + + public E remove(int index) { + synchronized (lock) { + return base.remove(base.size() - index - 1); + } + } + + public E removeFirst() { + synchronized (lock) { + int size = base.size(); + if (size == 0) + throw new NoSuchElementException(); + else + return base.remove(size - 1); + } + } + + public E removeLast() { + synchronized (lock) { + if (base.size() == 0) + throw new NoSuchElementException(); + else + return base.remove(0); + } + } + + public boolean removeIf(Predicate filter) { + return base.removeIf(filter); + } + + public void replaceAll(UnaryOperator operator) { + base.replaceAll(operator); + } + + public void sort(Comparator c) { + base.sort(Collections.reverseOrder(c)); + } + + public E set(int index, E element) { + synchronized (lock) { + return base.set(base.size() - index - 1, element); + } + } + + public List subList(int fromIndex, int toIndex) { + synchronized (lock) { + int size = base.size(); + var sub = base.subList(size - toIndex, size - fromIndex); + return new Reversed<>(sub, lock); + } + } + + public List reversed() { + return base; + } + } + /** Initializes the lock; for use when deserializing or cloning. */ private void resetLock() { @SuppressWarnings("removal") diff --git a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java index b9d0e29e449..61be28519fc 100644 --- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java @@ -24,6 +24,8 @@ */ package jdk.internal.util; +import java.util.Arrays; +import java.util.Collection; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.Unsafe; @@ -755,4 +757,53 @@ public class ArraysSupport { return minLength; } } + + /** + * Reverses the elements of an array in-place. + * + * @param the array component type + * @param a the array to be reversed + * @return the reversed array, always the same array as the argument + */ + public static T[] reverse(T[] a) { + int limit = a.length / 2; + for (int i = 0, j = a.length - 1; i < limit; i++, j--) { + T t = a[i]; + a[i] = a[j]; + a[j] = t; + } + return a; + } + + /** + * Dump the contents of the given collection into the given array, in reverse order. + * This mirrors the semantics of Collection.toArray(T[]) in regard to reusing the given + * array, appending null if necessary, or allocating a new array of the same component type. + *

+ * A constraint is that this method should issue exactly one method call on the collection + * to obtain the elements and the size. Having a separate size() call or using an Iterator + * could result in errors if the collection changes size between calls. This implies that + * the elements need to be obtained via a single call to one of the toArray() methods. + * This further implies allocating memory proportional to the number of elements and + * making an extra copy, but this seems unavoidable. + *

+ * An obvious approach would be simply to call coll.toArray(array) and then reverse the + * order of the elements. This doesn't work, because if given array is sufficiently long, + * we cannot tell how many elements were copied into it and thus there is no way to reverse + * the right set of elements while leaving the remaining array elements undisturbed. + * + * @throws ArrayStoreException if coll contains elements that can't be stored in the array + */ + public static T[] toArrayReversed(Collection coll, T[] array) { + T[] newArray = reverse(coll.toArray(Arrays.copyOfRange(array, 0, 0))); + if (newArray.length > array.length) { + return newArray; + } else { + System.arraycopy(newArray, 0, array, 0, newArray.length); + if (array.length > newArray.length) { + array[newArray.length] = null; + } + return array; + } + } } diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index c4a9fe9dcd7..035f855a728 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -171,6 +171,7 @@ jdk_collections_core = \ java/util/Map \ java/util/NavigableMap \ java/util/PriorityQueue \ + java/util/SequencedCollection \ java/util/TimSort \ java/util/TreeMap \ java/util/Vector \ diff --git a/test/jdk/java/util/Collection/MOAT.java b/test/jdk/java/util/Collection/MOAT.java index ccaca2fc934..bbc332cc211 100644 --- a/test/jdk/java/util/Collection/MOAT.java +++ b/test/jdk/java/util/Collection/MOAT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,9 +137,13 @@ public class MOAT { testMap(Collections.synchronizedNavigableMap(new TreeMap())); // Unmodifiable wrappers - testImmutableSet(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3)))); + testImmutableSet(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3))), 99); testImmutableList(unmodifiableList(Arrays.asList(1,2,3))); testImmutableMap(unmodifiableMap(Collections.singletonMap(1,2))); + testImmutableSeqColl(unmodifiableSequencedCollection(Arrays.asList(1,2,3)), 99); + testImmutableSeqColl(unmodifiableSequencedSet(new LinkedHashSet<>(Arrays.asList(1,2,3))), 99); + var lhm = new LinkedHashMap(); lhm.put(1,2); lhm.put(3, 4); + testImmutableSeqMap(unmodifiableSequencedMap(lhm)); testCollMutatorsAlwaysThrow(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3)))); testCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet())); testEmptyCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet())); @@ -169,7 +173,7 @@ public class MOAT { testEmptySet(Collections.emptySet()); testEmptySet(Collections.emptySortedSet()); testEmptySet(Collections.emptyNavigableSet()); - testImmutableSet(emptySet); + testImmutableSet(emptySet, 99); List emptyList = emptyList(); testCollection(emptyList); @@ -194,7 +198,7 @@ public class MOAT { Set singletonSet = singleton(1); equal(singletonSet.size(), 1); testCollection(singletonSet); - testImmutableSet(singletonSet); + testImmutableSet(singletonSet, 99); List singletonList = singletonList(1); equal(singletonList.size(), 1); @@ -322,20 +326,20 @@ public class MOAT { Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), Set.of(integerArray))) { testCollection(set); - testImmutableSet(set); + testImmutableSet(set, 99); testCollMutatorsAlwaysThrow(set); } Set setCopy = Set.copyOf(Arrays.asList(1, 2, 3)); testCollection(setCopy); - testImmutableSet(setCopy); + testImmutableSet(setCopy, 99); testCollMutatorsAlwaysThrow(setCopy); Set setCollected = Stream.of(1, 1, 2, 3, 2, 3) .collect(Collectors.toUnmodifiableSet()); equal(setCollected, Set.of(1, 2, 3)); testCollection(setCollected); - testImmutableSet(setCollected); + testImmutableSet(setCollected, 99); testCollMutatorsAlwaysThrow(setCollected); // Immutable Map @@ -462,12 +466,12 @@ public class MOAT { testEmptyIterator(((NavigableSet)c).descendingIterator()); } - private static void testImmutableCollection(final Collection c) { + private static void testImmutableCollection(final Collection c, T t) { THROWS(UnsupportedOperationException.class, - () -> c.add(99), - () -> c.addAll(singleton(99))); + () -> c.add(t), + () -> c.addAll(singleton(t))); if (! c.isEmpty()) { - final Integer first = c.iterator().next(); + final T first = c.iterator().next(); THROWS(UnsupportedOperationException.class, () -> c.clear(), () -> c.remove(first), @@ -476,13 +480,36 @@ public class MOAT { } } - private static void testImmutableSet(final Set c) { - testImmutableCollection(c); + private static void testImmutableSeqColl(final SequencedCollection c, T t) { + SequencedCollection r = c.reversed(); + testImmutableCollection(c, t); + testImmutableCollection(r, t); + THROWS(UnsupportedOperationException.class, + () -> c.addFirst(t), + () -> c.addLast(t), + () -> r.addFirst(t), + () -> r.addLast(t)); + if (! c.isEmpty()) { + THROWS(UnsupportedOperationException.class, + () -> c.removeFirst(), + () -> c.removeLast(), + () -> r.removeFirst(), + () -> r.removeLast()); + } + } + + private static void testImmutableSet(final Set c, T t) { + testImmutableCollection(c, t); + } + + private static void testImmutableSeqSet(final SequencedSet c, T t) { + testImmutableSeqColl(c, t); } private static void testImmutableList(final List c) { testList(c); - testImmutableCollection(c); + testImmutableCollection(c, 42); + testImmutableSeqColl(c, 42); THROWS(UnsupportedOperationException.class, () -> c.set(0,42), () -> c.add(0,42), @@ -606,6 +633,15 @@ public class MOAT { check(! m.containsKey(1)); } + private static void testImmutableMapEntry(final Map.Entry me) { + Integer key = me.getKey(); + Integer val = me.getValue(); + THROWS(UnsupportedOperationException.class, + () -> me.setValue(3)); + equal(key, me.getKey()); + equal(val, me.getValue()); + } + private static void testImmutableMap(final Map m) { THROWS(UnsupportedOperationException.class, () -> m.put(1,1), @@ -615,18 +651,39 @@ public class MOAT { THROWS(UnsupportedOperationException.class, () -> m.remove(first), () -> m.clear()); - final Map.Entry me - = m.entrySet().iterator().next(); - Integer key = me.getKey(); - Integer val = me.getValue(); - THROWS(UnsupportedOperationException.class, - () -> me.setValue(3)); - equal(key, me.getKey()); - equal(val, me.getValue()); + testImmutableMapEntry(m.entrySet().iterator().next()); } - testImmutableSet(m.keySet()); - testImmutableCollection(m.values()); - //testImmutableSet(m.entrySet()); + testImmutableSet(m.keySet(), 99); + testImmutableCollection(m.values(), 99); + testImmutableSet(m.entrySet(), Map.entry(42, 43)); + } + + private static void testImmutableSeqMap(final SequencedMap m) { + SequencedMap r = m.reversed(); + testImmutableMap(m); + testImmutableMap(r); + THROWS(UnsupportedOperationException.class, + () -> m.putFirst(0, 0), + () -> m.putLast(0, 0), + () -> r.putFirst(0, 0), + () -> r.putLast(0, 0)); + if (! m.isEmpty()) { + THROWS(UnsupportedOperationException.class, + () -> m.pollFirstEntry(), + () -> m.pollLastEntry(), + () -> r.pollFirstEntry(), + () -> r.pollLastEntry()); + testImmutableMapEntry(m.sequencedEntrySet().getFirst()); + testImmutableMapEntry(r.sequencedEntrySet().getFirst()); + testImmutableMapEntry(m.sequencedEntrySet().reversed().getFirst()); + testImmutableMapEntry(r.sequencedEntrySet().reversed().getFirst()); + } + testImmutableSeqSet(m.sequencedKeySet(), 99); + testImmutableSeqColl(m.sequencedValues(), 99); + testImmutableSeqSet(m.sequencedEntrySet(), Map.entry(42, 43)); + testImmutableSeqSet(r.sequencedKeySet(), 99); + testImmutableSeqColl(r.sequencedValues(), 99); + testImmutableSeqSet(r.sequencedEntrySet(), Map.entry(42, 43)); } private static void clear(Map m) { diff --git a/test/jdk/java/util/Collections/Wrappers.java b/test/jdk/java/util/Collections/Wrappers.java index 3882a4efdd1..22a96b74623 100644 --- a/test/jdk/java/util/Collections/Wrappers.java +++ b/test/jdk/java/util/Collections/Wrappers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -33,14 +33,13 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Objects; import java.util.TreeMap; import java.util.TreeSet; import org.testng.annotations.Test; import org.testng.annotations.DataProvider; -import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; @Test(groups = "unit") public class Wrappers { @@ -66,9 +65,11 @@ public class Wrappers { } cases.add(new Object[] { Collections.unmodifiableCollection(seedList) }); + cases.add(new Object[] { Collections.unmodifiableSequencedCollection(seedList) }); cases.add(new Object[] { Collections.unmodifiableList(seedList) }); cases.add(new Object[] { Collections.unmodifiableList(seedRandomAccess) }); cases.add(new Object[] { Collections.unmodifiableSet(seedSet) }); + cases.add(new Object[] { Collections.unmodifiableSequencedSet(seedSet) }); cases.add(new Object[] { Collections.unmodifiableSortedSet(seedSet) }); cases.add(new Object[] { Collections.unmodifiableNavigableSet(seedSet) }); @@ -77,6 +78,24 @@ public class Wrappers { cases.add(new Object[] { Collections.unmodifiableMap(seedMap).entrySet() }); cases.add(new Object[] { Collections.unmodifiableMap(seedMap).keySet() }); cases.add(new Object[] { Collections.unmodifiableMap(seedMap).values() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).entrySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).keySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).values() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().entrySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().keySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().values() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedEntrySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedKeySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedValues() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedEntrySet().reversed() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedKeySet().reversed() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).sequencedValues().reversed() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedEntrySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedKeySet() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedValues() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedEntrySet().reversed() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedKeySet().reversed() }); + cases.add(new Object[] { Collections.unmodifiableSequencedMap(seedMap).reversed().sequencedValues().reversed() }); cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).entrySet() }); cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).keySet() }); cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).values() }); @@ -136,11 +155,14 @@ public class Wrappers { @Test(dataProvider = "collections") public static void testAllDefaultMethodsOverridden(Collection c) throws NoSuchMethodException { Class cls = c.getClass(); + var notOverridden = new ArrayList(); for (Method m: defaultMethods) { Method m2 = cls.getMethod(m.getName(), m.getParameterTypes()); - // default had been override - assertFalse(m2.isDefault(), cls.getCanonicalName()); + if (m2.isDefault()) { + notOverridden.add(m); + } } + assertTrue(notOverridden.isEmpty(), cls.getName() + " does not override " + notOverridden); } } diff --git a/test/jdk/java/util/SequencedCollection/Basic.java b/test/jdk/java/util/SequencedCollection/Basic.java new file mode 100644 index 00000000000..32a5d4e5c91 --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/Basic.java @@ -0,0 +1,857 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertThrows; +import static org.testng.Assert.assertTrue; + +/* + * @test + * @bug 8266571 + * @summary Basic tests for SequencedCollection + * @modules java.base/java.util:open + * @build SimpleDeque SimpleList SimpleSortedSet + * @run testng Basic + */ + +// TODO test that remove(obj) with duplicates removes the right element + +public class Basic { + + // ========== Data Providers ========== + + static final List ORIGINAL = List.of("a", "b", "c", "d", "e", "f", "g"); + + static List cklist(List contents) { + return Collections.checkedList(contents, String.class); + } + + static NavigableSet cknav(NavigableSet set) { + return Collections.checkedNavigableSet(set, String.class); + } + + static SortedSet cksorted(SortedSet set) { + return Collections.checkedSortedSet(set, String.class); + } + + static SequencedSet setFromMap(List contents) { + var lhm = new LinkedHashMap(); + var ss = Collections.newSequencedSetFromMap(lhm); + ss.addAll(contents); + return ss; + } + + static SequencedCollection ucoll(SequencedCollection coll) { + return Collections.unmodifiableSequencedCollection(coll); + } + + static SequencedCollection ulist(List list) { + return Collections.unmodifiableList(list); + } + + static NavigableSet unav(NavigableSet set) { + return Collections.unmodifiableNavigableSet(set); + } + + static SequencedSet uset(SequencedSet set) { + return Collections.unmodifiableSequencedSet(set); + } + + static SortedSet usorted(SortedSet set) { + return Collections.unmodifiableSortedSet(set); + } + + static List copyReversed(List list) { + var r = new ArrayList(list); + Collections.reverse(r); + return r; + } + + @DataProvider(name="all") + public Iterator all() { + var result = new ArrayList(); + populated().forEachRemaining(result::add); + empties().forEachRemaining(result::add); + return result.iterator(); + } + + @DataProvider(name="populated") + public Iterator populated() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "AsList", Arrays.asList(ORIGINAL.toArray()), ORIGINAL }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "ListOf", ORIGINAL, ORIGINAL }, + new Object[] { "SetFromMap", setFromMap(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleDeque", new SimpleDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", new SimpleList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedSet", new SimpleSortedSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "TreeSet", new TreeSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "UnmodColl", ucoll(new ArrayList<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodSet", uset(new LinkedHashSet<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="empties") + public Iterator empties() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(), List.of() }, + new Object[] { "ArrayList", new ArrayList<>(), List.of() }, + new Object[] { "AsList", Arrays.asList(new String[0]), List.of() }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(), List.of() }, + new Object[] { "EmptyList", Collections.emptyList(), List.of() }, + new Object[] { "EmptyNavigableSet", Collections.emptyNavigableSet(), List.of() }, + new Object[] { "EmptySortedSet", Collections.emptySortedSet(), List.of() }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(), List.of() }, + new Object[] { "LinkedList", new LinkedList<>(), List.of() }, + new Object[] { "ListOf", List.of(), List.of() }, + new Object[] { "SetFromMap", setFromMap(List.of()), List.of() }, + new Object[] { "SimpleDeque", new SimpleDeque<>(), List.of() }, + new Object[] { "SimpleList", new SimpleList<>(), List.of() }, + new Object[] { "SimpleSortedSet", new SimpleSortedSet<>(), List.of() }, + new Object[] { "TreeSet", new TreeSet<>(), List.of() }, + new Object[] { "UnmodColl", ucoll(new ArrayList<>()), List.of() }, + new Object[] { "UnmodSet", uset(new LinkedHashSet<>()), List.of() } + ).iterator(); + } + + @DataProvider(name="adds") + public Iterator adds() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SetFromMap", setFromMap(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleDeque", new SimpleDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", new SimpleList<>(ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="unpositionedAdd") + public Iterator unpositionedAdd() { + return Arrays.asList( + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="removes") + public Iterator removes() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SetFromMap", setFromMap(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleDeque", new SimpleDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", new SimpleList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedSet", new SimpleSortedSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "TreeSet", new TreeSet<>(ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="emptyRemoves") + public Iterator emptyRemoves() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(), List.of() }, + new Object[] { "ArrayList", new ArrayList<>(), List.of() }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(), List.of() }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(), List.of() }, + new Object[] { "LinkedList", new LinkedList<>(), List.of() }, + new Object[] { "SetFromMap", setFromMap(List.of()), List.of() }, + new Object[] { "SimpleDeque", new SimpleDeque<>(), List.of() }, + new Object[] { "SimpleList", new SimpleList<>(), List.of() }, + new Object[] { "SimpleSortedSet", new SimpleSortedSet<>(), List.of() }, + new Object[] { "TreeSet", new TreeSet<>(), List.of() } + ).iterator(); + } + + @DataProvider(name="serializable") + public Iterator serializable() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL), ORIGINAL }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "AsList", Arrays.asList(ORIGINAL.toArray()), ORIGINAL }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "ListOf", ORIGINAL, ORIGINAL }, + new Object[] { "SetFromMap", setFromMap(ORIGINAL), ORIGINAL }, + new Object[] { "TreeSet", new TreeSet<>(ORIGINAL), ORIGINAL }, + new Object[] { "UnmodColl", ucoll(new ArrayList<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodSet", uset(new LinkedHashSet<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="notSerializable") + public Iterator notSerializable() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL).reversed() }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL).reversed() }, + new Object[] { "AsList", Arrays.asList(ORIGINAL.toArray()).reversed() }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL).reversed() }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL).reversed() }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL).reversed() }, + new Object[] { "ListOf", ORIGINAL.reversed() }, + new Object[] { "SetFromMap", setFromMap(ORIGINAL).reversed() }, + new Object[] { "UnmodColl", ucoll(new ArrayList<>(ORIGINAL)).reversed() }, + new Object[] { "UnmodSet", uset(new LinkedHashSet<>(ORIGINAL)).reversed() } + ).iterator(); + } + + @DataProvider(name="doubleReverse") + public Iterator doubleReverse() { + return Arrays.asList( + new Object[] { "ArrayDeque", new ArrayDeque<>(ORIGINAL) }, + new Object[] { "ArrayList", new ArrayList<>(ORIGINAL) }, + new Object[] { "AsList", Arrays.asList(ORIGINAL.toArray()) }, + new Object[] { "COWAL", new CopyOnWriteArrayList<>(ORIGINAL) }, + new Object[] { "LinkedHashSet", new LinkedHashSet<>(ORIGINAL) }, + new Object[] { "LinkedList", new LinkedList<>(ORIGINAL) }, + new Object[] { "ListOf", ORIGINAL }, + new Object[] { "SimpleDeque", new SimpleDeque<>(ORIGINAL) }, + new Object[] { "SimpleList", new SimpleList<>(ORIGINAL) }, + new Object[] { "SimpleSortedSet", new SimpleSortedSet<>(ORIGINAL) } + ).iterator(); + } + + @DataProvider(name="unmodifiable") + public Iterator unmodifiable() { + return Arrays.asList( + new Object[] { "ListOf", ORIGINAL, ORIGINAL }, + new Object[] { "ListOfSub", ORIGINAL.subList(1, 3), ORIGINAL.subList(1, 3) }, + new Object[] { "SingleList", Collections.singletonList("a"), List.of("a") }, + new Object[] { "UnmodColl", ucoll(new ArrayList<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodList", ulist(new ArrayList<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodNav", unav(new TreeSet<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodSet", uset(new LinkedHashSet<>(ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodSorted", usorted(new TreeSet<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="checkedList") + public Iterator checkedList() { + return Arrays.asList( + new Object[] { "ChkList", cklist(new ArrayList<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="checkedNavSet") + public Iterator checkedNavSet() { + return Arrays.asList( + new Object[] { "ChkNav", cknav(new TreeSet<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="checkedSortedSet") + public Iterator checkedSortedSet() { + return Arrays.asList( + new Object[] { "ChkSorted", cksorted(new TreeSet<>(ORIGINAL)), ORIGINAL } + ).iterator(); + } + + // mode bit tests for subList testing + + boolean reverseList(int mode) { return (mode & 1) != 0; } + boolean reverseSub(int mode) { return (mode & 2) != 0; } + boolean isReversed(int mode) { return reverseList(mode) ^ reverseSub(mode); } + + List applyMode(int mode, List base) { + var list = reverseList(mode) ? base.reversed() : base; + var sub = list.subList(2, 5); + return reverseSub(mode) ? sub.reversed() : sub; + } + + /** + * Generate cases for testing subLists. For each different List implementation, generate 4 + * cases from the two bits of the testing mode int value: + * + * (bit 1) if true, the List is reversed + * (bit 2) if true, the subList is reversed + * + * @return the generated cases + */ + @DataProvider(name="subListMods") + public Iterator subListMods() { + var cases = new ArrayList(); + for (int mode = 0; mode < 4; mode++) { + cases.addAll(Arrays.asList( + new Object[] { "ArrayList", mode, new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "COWAL", mode, new CopyOnWriteArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", mode, new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", mode, new SimpleList<>(ORIGINAL), ORIGINAL } + )); + } + return cases.iterator(); + } + + @DataProvider(name="iteratorMods") + public Iterator iteratorMods() { + var cases = new ArrayList(); + for (boolean rev : List.of(false, true)) { + cases.addAll(Arrays.asList( + new Object[] { "ArrayList", rev, new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", rev, new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", rev, new SimpleList<>(ORIGINAL), ORIGINAL } + )); + } + return cases.iterator(); + } + + @DataProvider(name="subListIteratorMods") + public Iterator subListIteratorMods() { + var cases = new ArrayList(); + for (int mode = 0; mode < 4; mode++) { + cases.addAll(Arrays.asList( + new Object[] { "ArrayList", mode, new ArrayList<>(ORIGINAL), ORIGINAL }, + new Object[] { "LinkedList", mode, new LinkedList<>(ORIGINAL), ORIGINAL }, + new Object[] { "SimpleList", mode, new SimpleList<>(ORIGINAL), ORIGINAL } + )); + } + return cases.iterator(); + } + + // ========== Assertions ========== + + /** + * Basic checks over the contents of a SequencedCollection, + * compared to a reference List, in one direction. + * + * @param seq the SequencedCollection under test + * @param ref the reference List + */ + public void checkContents1(SequencedCollection seq, List ref) { + var list1 = new ArrayList(); + for (var s : seq) + list1.add(s); + assertEquals(list1, ref); + + var list2 = new ArrayList(); + seq.forEach(list2::add); + assertEquals(list2, ref); + + var list3 = Arrays.asList(seq.toArray()); + assertEquals(list3, ref); + + var list4 = Arrays.asList(seq.toArray(new String[0])); + assertEquals(list4, ref); + + var list5 = Arrays.asList(seq.toArray(String[]::new)); + assertEquals(list5, ref); + + var list6 = seq.stream().toList(); + assertEquals(list6, ref); + + var list7 = seq.parallelStream().toList(); + assertEquals(list7, ref); + + assertEquals(seq.size(), ref.size()); + assertEquals(seq.isEmpty(), ref.isEmpty()); + + for (var s : ref) { + assertTrue(seq.contains(s)); + } + } + + /** + * Check the contents of a SequencedCollection against a reference List, + * in both directions. + * + * @param seq the SequencedCollection under test + * @param ref the reference List + */ + public void checkContents(SequencedCollection seq, List ref) { + checkContents1(seq, ref); + + var rref = copyReversed(ref); + var rseq = seq.reversed(); + checkContents1(rseq, rref); + + var rrseq = rseq.reversed(); + checkContents1(rrseq, ref); + } + + /** + * Check that modification operations will throw UnsupportedOperationException, + * in one direction. + * + * @param seq the SequencedCollection under test + */ + public void checkUnmodifiable1(SequencedCollection seq) { + final var UOE = UnsupportedOperationException.class; + + assertThrows(UOE, () -> seq.add("x")); + assertThrows(UOE, () -> seq.clear()); + assertThrows(UOE, () -> { var it = seq.iterator(); it.next(); it.remove(); }); + assertThrows(UOE, () -> seq.removeIf(x -> true)); + + assertThrows(UOE, () -> seq.addFirst("x")); + assertThrows(UOE, () -> seq.addLast("x")); + assertThrows(UOE, () -> seq.removeFirst()); + assertThrows(UOE, () -> seq.removeLast()); + +// TODO these ops should throw unconditionally, but they don't in some implementations + // assertThrows(UOE, () -> seq.addAll(List.of())); + // assertThrows(UOE, () -> seq.remove("x")); + // assertThrows(UOE, () -> seq.removeAll(List.of())); + // assertThrows(UOE, () -> seq.removeIf(x -> false)); + // assertThrows(UOE, () -> seq.retainAll(seq)); + assertThrows(UOE, () -> seq.addAll(seq)); + assertThrows(UOE, () -> seq.remove(seq.iterator().next())); + assertThrows(UOE, () -> seq.removeAll(seq)); + assertThrows(UOE, () -> seq.retainAll(List.of())); + } + + /** + * Check that modification operations will throw UnsupportedOperationException, + * in both directions. + * + * @param seq the SequencedCollection under test + */ + public void checkUnmodifiable(SequencedCollection seq) { + checkUnmodifiable1(seq); + checkUnmodifiable1(seq.reversed()); + } + + static final Class CCE = ClassCastException.class; + + public void checkCheckedList(List list) { + List objList = (List)(List)list; + assertThrows(CCE, () -> { objList.addFirst(new Object()); }); + assertThrows(CCE, () -> { objList.addLast(new Object()); }); + assertThrows(CCE, () -> { objList.reversed().addFirst(new Object()); }); + assertThrows(CCE, () -> { objList.reversed().addLast(new Object()); }); + } + + public void checkCheckedNavSet(NavigableSet set) { + NavigableSet objSet = (NavigableSet)(NavigableSet)set; + assertThrows(CCE, () -> { objSet.add(new Object()); }); + assertThrows(CCE, () -> { objSet.reversed().add(new Object()); }); + } + + public void checkCheckedSortedSet(SortedSet set) { + SortedSet objSet = (SortedSet)(SortedSet)set; + assertThrows(CCE, () -> { objSet.add(new Object()); }); + assertThrows(CCE, () -> { objSet.reversed().add(new Object()); }); + } + + // ========== Tests ========== + + @Test(dataProvider="all") + public void testFundamentals(String label, SequencedCollection seq, List ref) { + checkContents(seq, ref); + } + + @Test(dataProvider="populated") + public void testGetFirst(String label, SequencedCollection seq, List ref) { + assertEquals(seq.getFirst(), ref.get(0)); + assertEquals(seq.reversed().getFirst(), ref.get(ref.size() - 1)); + checkContents(seq, ref); + } + + @Test(dataProvider="populated") + public void testGetLast(String label, SequencedCollection seq, List ref) { + assertEquals(seq.getLast(), ref.get(ref.size() - 1)); + assertEquals(seq.reversed().getLast(), ref.get(0)); + checkContents(seq, ref); + } + + @Test(dataProvider="empties") + public void testEmptyGetFirst(String label, SequencedCollection seq, List ref) { + assertThrows(NoSuchElementException.class, () -> seq.getFirst()); + assertThrows(NoSuchElementException.class, () -> seq.reversed().getFirst()); + checkContents(seq, ref); + } + + @Test(dataProvider="empties") + public void testEmptyGetLast(String label, SequencedCollection seq, List ref) { + assertThrows(NoSuchElementException.class, () -> seq.getLast()); + assertThrows(NoSuchElementException.class, () -> seq.reversed().getLast()); + checkContents(seq, ref); + } + + @Test(dataProvider="adds") + public void testAddFirst(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add(0, "x"); + seq.addFirst("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="adds") + public void testAddFirstRev(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add("x"); + seq.reversed().addFirst("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="adds") + public void testAddLast(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add("x"); + seq.addLast("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="adds") + public void testAddLastRev(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add(0, "x"); + seq.reversed().addLast("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="unpositionedAdd") + public void testUnpositionedAdd(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add("x"); + seq.add("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="unpositionedAdd") + public void testUnpositionedAddRev(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + ref.add("x"); + seq.reversed().add("x"); + checkContents(seq, ref); + } + + @Test(dataProvider="removes") + public void testRemoveFirst(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + var exp = ref.remove(0); + var act = seq.removeFirst(); + assertEquals(act, exp); + checkContents(seq, ref); + } + + @Test(dataProvider="removes") + public void testRemoveFirstRev(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + var exp = ref.remove(ref.size() - 1); + var act = seq.reversed().removeFirst(); + assertEquals(act, exp); + checkContents(seq, ref); + } + + @Test(dataProvider="removes") + public void testRemoveLast(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + var exp = ref.remove(ref.size() - 1); + var act = seq.removeLast(); + assertEquals(act, exp); + checkContents(seq, ref); + } + + @Test(dataProvider="removes") + public void testRemoveLastRev(String label, SequencedCollection seq, List baseref) { + var ref = new ArrayList<>(baseref); + var exp = ref.remove(0); + var act = seq.reversed().removeLast(); + assertEquals(act, exp); + checkContents(seq, ref); + } + + @Test(dataProvider="emptyRemoves") + public void testEmptyRemoveFirst(String label, SequencedCollection seq, List baseref) { + assertThrows(NoSuchElementException.class, () -> seq.removeFirst()); + assertThrows(NoSuchElementException.class, () -> seq.reversed().removeFirst()); + checkContents(seq, baseref); + } + + @Test(dataProvider="emptyRemoves") + public void testEmptyRemoveLast(String label, SequencedCollection seq, List baseref) { + assertThrows(NoSuchElementException.class, () -> seq.removeLast()); + assertThrows(NoSuchElementException.class, () -> seq.reversed().removeLast()); + checkContents(seq, baseref); + } + + @Test(dataProvider="serializable") + public void testSerializable(String label, SequencedCollection seq, List ref) + throws ClassNotFoundException, IOException + { + var baos = new ByteArrayOutputStream(); + try (var oos = new ObjectOutputStream(baos)) { + oos.writeObject(seq); + } + + try (var bais = new ByteArrayInputStream(baos.toByteArray()); + var ois = new ObjectInputStream(bais)) { + var seq2 = (SequencedCollection) ois.readObject(); + checkContents(seq2, ref); + } + } + + @Test(dataProvider="notSerializable") + public void testNotSerializable(String label, SequencedCollection seq) + throws ClassNotFoundException, IOException + { + var baos = new ByteArrayOutputStream(); + try (var oos = new ObjectOutputStream(baos)) { + assertThrows(ObjectStreamException.class, () -> oos.writeObject(seq)); + } + } + + @Test(dataProvider="doubleReverse") + public void testDoubleReverse(String label, SequencedCollection seq) { + var rrseq = seq.reversed().reversed(); + assertSame(rrseq, seq); + } + + @Test(dataProvider="unmodifiable") + public void testUnmodifiable(String label, SequencedCollection seq, List ref) { + checkUnmodifiable(seq); + checkContents(seq, ref); + } + + @Test(dataProvider="checkedList") + public void testCheckedList(String label, List list, List ref) { + checkCheckedList(list); + checkContents(list, ref); + } + + @Test(dataProvider="checkedNavSet") + public void testCheckedNavSet(String label, NavigableSet set, List ref) { + checkCheckedNavSet(set); + checkContents(set, ref); + } + + @Test(dataProvider="checkedSortedSet") + public void testCheckedSortedSet(String label, SortedSet set, List ref) { + checkCheckedSortedSet(set); + checkContents(set, ref); + } + + // Indexes for subList modification tests: + // 0 1 2 3 4 5 6 + // a, b, c, d, e, f, g + // c, d, e + + @Test(dataProvider="subListMods") + public void testSubListGet(String label, int mode, List list, List base) { + var sub = applyMode(mode, list); + assertEquals(sub.getFirst(), isReversed(mode) ? "e" : "c"); + assertEquals(sub.getLast(), isReversed(mode) ? "c" : "e"); + } + + @Test(dataProvider="subListMods") + public void testSubListAddFirst(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + refList.add(isReversed(mode) ? 5 : 2, "x"); + sub.addFirst("x"); + refSub.add(0, "x"); + + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListMods") + public void testSubListAddLast(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + refList.add(isReversed(mode) ? 2 : 5, "x"); + sub.addLast("x"); + refSub.add("x"); + + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListMods") + public void testSubListRemoveFirst(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + refList.remove(isReversed(mode) ? 4 : 2); + var act = sub.removeFirst(); + var exp = refSub.remove(0); + + assertEquals(act, exp); + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListMods") + public void testSubListRemoveLast(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + refList.remove(isReversed(mode) ? 2 : 4); + var act = sub.removeLast(); + var exp = refSub.remove(refSub.size() - 1); + + assertEquals(act, exp); + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListMods") + public void testSubListAddAllFirst(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + if (isReversed(mode)) + refList.addAll(5, List.of("y", "x")); + else + refList.addAll(2, List.of("x", "y")); + sub.addAll(0, List.of("x", "y")); + refSub.addAll(0, List.of("x", "y")); + + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListMods") + public void testSubListAddAllLast(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + if (isReversed(mode)) + refList.addAll(2, List.of("y", "x")); + else + refList.addAll(5, List.of("x", "y")); + sub.addAll(List.of("x", "y")); + refSub.addAll(List.of("x", "y")); + + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="iteratorMods") + public void testListIteratorAdd(String label, boolean rev, List list, List base) { + var ref = new ArrayList<>(base); + var it = (rev ? list.reversed() : list).listIterator(); + + ref.add(rev ? 5 : 2, "x"); + it.next(); + it.next(); + it.add("x"); + + assertEquals(it.next(), rev ? "e" : "c"); + checkContents(list, ref); + } + + @Test(dataProvider="iteratorMods") + public void testListIteratorSet(String label, boolean rev, List list, List base) { + var ref = new ArrayList<>(base); + var it = (rev ? list.reversed() : list).listIterator(); + + ref.set(rev ? 5 : 1, "x"); + it.next(); + it.next(); + it.set("x"); + + assertEquals(it.next(), rev ? "e" : "c"); + checkContents(list, ref); + } + + @Test(dataProvider="iteratorMods") + public void testListIteratorRemove(String label, boolean rev, List list, List base) { + var ref = new ArrayList<>(base); + var it = (rev ? list.reversed() : list).listIterator(); + + ref.remove(rev ? 5 : 1); + it.next(); + it.next(); + it.remove(); + + assertEquals(it.next(), rev ? "e" : "c"); + checkContents(list, ref); + } + + // SubList ListIterator modification tests. + + @Test(dataProvider="subListIteratorMods") + public void testSubListIteratorAdd(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + var it = sub.listIterator(); + it.next(); + it.add("x"); + refList.add(isReversed(mode) ? 4 : 3, "x"); + refSub.add(1, "x"); + + assertEquals(it.next(), "d"); + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListIteratorMods") + public void testSubListIteratorSet(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + var it = sub.listIterator(); + it.next(); + it.set("x"); + refList.set(isReversed(mode) ? 4 : 2, "x"); + refSub.set(0, "x"); + + assertEquals(it.next(), "d"); + checkContents(sub, refSub); + checkContents(list, refList); + } + + @Test(dataProvider="subListIteratorMods") + public void testSubListIteratorRemove(String label, int mode, List list, List base) { + var refList = new ArrayList<>(base); + var sub = applyMode(mode, list); + var refSub = new ArrayList<>(sub); + + var it = sub.listIterator(); + it.next(); + it.remove(); + refList.remove(isReversed(mode) ? 4 : 2); + refSub.remove(0); + + assertEquals(it.next(), "d"); + checkContents(sub, refSub); + checkContents(list, refList); + } +} diff --git a/test/jdk/java/util/SequencedCollection/BasicMap.java b/test/jdk/java/util/SequencedCollection/BasicMap.java new file mode 100644 index 00000000000..96a18cc88b7 --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/BasicMap.java @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.util.*; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertThrows; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; + +/* + * @test + * @bug 8266571 + * @summary Basic tests for SequencedMap + * @modules java.base/java.util:open + * @build SimpleSortedMap + * @run testng BasicMap + */ + +public class BasicMap { + + // ========== Data Providers ========== + + static final Class CCE = ClassCastException.class; + static final Class NSEE = NoSuchElementException.class; + static final Class UOE = UnsupportedOperationException.class; + + static final List> ORIGINAL = + List.of(Map.entry("a", 1), + Map.entry("b", 2), + Map.entry("c", 3), + Map.entry("d", 4), + Map.entry("e", 5)); + + static > + M load(M map, List> mappings) { + for (var e : mappings) + map.put(e.getKey(), e.getValue()); + return map; + } + + static NavigableMap cknav(NavigableMap map) { + return Collections.checkedNavigableMap(map, String.class, Integer.class); + } + + static SortedMap cksorted(SortedMap map) { + return Collections.checkedSortedMap(map, String.class, Integer.class); + } + + static SequencedMap umap(SequencedMap map) { + return Collections.unmodifiableSequencedMap(map); + } + + static SortedMap usorted(SortedMap map) { + return Collections.unmodifiableSortedMap(map); + } + + static NavigableMap unav(NavigableMap map) { + return Collections.unmodifiableNavigableMap(map); + } + + @DataProvider(name="all") + public Iterator all() { + var result = new ArrayList(); + populated().forEachRemaining(result::add); + empties().forEachRemaining(result::add); + return result.iterator(); + } + + @DataProvider(name="populated") + public Iterator populated() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedMap", load(new SimpleSortedMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", load(new TreeMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "UnmodMap", umap(load(new LinkedHashMap<>(), ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="empties") + public Iterator empties() { + return Arrays.asList( + new Object[] { "EmptyNavigableMap", Collections.emptyNavigableMap(), List.of() }, + new Object[] { "EmptySortedMap", Collections.emptySortedMap(), List.of() }, + new Object[] { "LinkedHashMap", new LinkedHashMap<>(), List.of() }, + new Object[] { "SimpleSortedMap", new SimpleSortedMap<>(), List.of() }, + new Object[] { "TreeMap", new TreeMap<>(), List.of() }, + new Object[] { "UnmodMap", umap(new LinkedHashMap<>()), List.of() } + ).iterator(); + } + + @DataProvider(name="polls") + public Iterator polls() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedMap", load(new SimpleSortedMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", load(new TreeMap<>(), ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="emptyPolls") + public Iterator emptyPolls() { + return Arrays.asList( + new Object[] { "LinkedHashMap", new LinkedHashMap<>(), List.of() }, + new Object[] { "SimpleSortedMap", new SimpleSortedMap<>(), List.of() }, + new Object[] { "TreeMap", new TreeMap<>(), List.of() } + ).iterator(); + } + + @DataProvider(name="puts") + public Iterator puts() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="putUnpositioned") + public Iterator putUnpositioned() { + return Arrays.asList( + new Object[] { "LinkedHashMap", false, load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "LinkedHashMap", true, load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="putThrows") + public Iterator putThrows() { + return Arrays.asList( + new Object[] { "SimpleSortedMap", load(new SimpleSortedMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", load(new TreeMap<>(), ORIGINAL), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="serializable") + public Iterator serializable() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", load(new TreeMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "UnmodMap", umap(load(new LinkedHashMap<>(), ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="notSerializable") + public Iterator notSerializable() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL).reversed() }, + new Object[] { "UnmodMap", umap(load(new LinkedHashMap<>(), ORIGINAL)).reversed() } + ).iterator(); + } + + @DataProvider(name="doubleReverse") + public Iterator doubleReverse() { + return Arrays.asList( + new Object[] { "LinkedHashMap", load(new LinkedHashMap<>(), ORIGINAL) } + ).iterator(); + } + + @DataProvider(name="unmodifiable") + public Iterator unmodifible() { + return Arrays.asList( + new Object[] { "UnmodMap", umap(load(new LinkedHashMap<>(), ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodNav", unav(load(new TreeMap<>(), ORIGINAL)), ORIGINAL }, + new Object[] { "UnmodSorted", usorted(load(new TreeMap<>(), ORIGINAL)), ORIGINAL } + ).iterator(); + } + + @DataProvider(name="checked") + public Iterator checked() { + return Arrays.asList( + new Object[] { "ChkNav", cknav(load(new TreeMap<>(), ORIGINAL)), ORIGINAL }, + new Object[] { "ChkSorted", cksorted(load(new TreeMap<>(), ORIGINAL)), ORIGINAL } + ).iterator(); + } + + // mode bit tests + + boolean reverseMap(int mode) { return (mode & 1) != 0; } + boolean reverseView(int mode) { return (mode & 2) != 0; } + boolean callLast(int mode) { return (mode & 4) != 0; } + + boolean refLast(int mode) { return reverseMap(mode) ^ reverseView(mode) ^ callLast(mode); } + + /** + * Generate cases for testing the removeFirst and removeLast methods of map views. For each + * different map implementation, generate 8 cases from the three bits of the testing mode + * int value: + * + * (bit 1) if true, the backing map is reversed + * (bit 2) if true, the view is reversed + * (bit 4) if true, the last element of the view is to be removed, otherwise the first + * + * The three bits XORed together (by refLast(), above) indicate (if true) the last + * or (if false) the first element of the reference entry list is to be removed. + * + * @return the generated cases + */ + @DataProvider(name="viewRemoves") + public Iterator viewRemoves() { + var cases = new ArrayList(); + for (int mode = 0; mode < 8; mode++) { + cases.addAll(Arrays.asList( + new Object[] { "LinkedHashMap", mode, load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedMap", mode, load(new SimpleSortedMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", mode, load(new TreeMap<>(), ORIGINAL), ORIGINAL } + )); + } + return cases.iterator(); + } + + @DataProvider(name="emptyViewRemoves") + public Iterator emptyViewRemoves() { + var cases = new ArrayList(); + for (int mode = 0; mode < 8; mode++) { + cases.addAll(Arrays.asList( + new Object[] { "LinkedHashMap", mode, new LinkedHashMap<>(), List.of() }, + new Object[] { "SimpleSortedMap", mode, new SimpleSortedMap<>(), List.of() }, + new Object[] { "TreeMap", mode, new TreeMap<>(), List.of() } + )); + } + return cases.iterator(); + } + + @DataProvider(name="viewAddThrows") + public Iterator viewAddThrows() { + var cases = new ArrayList(); + for (int mode = 0; mode < 8; mode++) { + cases.addAll(Arrays.asList( + new Object[] { "LinkedHashMap", mode, load(new LinkedHashMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "SimpleSortedMap", mode, load(new SimpleSortedMap<>(), ORIGINAL), ORIGINAL }, + new Object[] { "TreeMap", mode, load(new TreeMap<>(), ORIGINAL), ORIGINAL } + )); + } + return cases.iterator(); + } + + // ========== Assertions ========== + + /** + * Basic checks over the contents of a SequencedMap, compared to a reference List of entries, + * in one direction. + * + * @param map the SequencedMap under test + * @param ref the reference list of entries + */ + public void checkContents1(SequencedMap map, List> ref) { + var list1 = new ArrayList>(); + map.forEach((k, v) -> list1.add(Map.entry(k, v))); + assertEquals(list1, ref); + + assertEquals(map.size(), ref.size()); + assertEquals(map.isEmpty(), ref.isEmpty()); + + for (var e : ref) { + assertTrue(map.containsKey(e.getKey())); + assertTrue(map.containsValue(e.getValue())); + assertEquals(map.get(e.getKey()), e.getValue()); + } + } + + public void checkContents(SequencedMap map, List> ref) { + checkContents1(map, ref); + + var rref = new ArrayList<>(ref); + Collections.reverse(rref); + var rmap = map.reversed(); + checkContents1(rmap, rref); + + var rrmap = rmap.reversed(); + checkContents1(rrmap, ref); + } + + /** + * Check the entrySet, keySet, or values view of a SequencedMap in one direction. The view + * collection is ordered even though the collection type is not sequenced. + * + * @param the element type of the view + * @param mapView the actual map view + * @param expElements list of the expected elements + */ + public void checkView1(Collection mapView, List expElements) { + var list1 = new ArrayList(); + for (var k : mapView) + list1.add(k); + assertEquals(list1, expElements); + + var list2 = new ArrayList(); + mapView.forEach(list2::add); + assertEquals(list2, expElements); + + var list3 = Arrays.asList(mapView.toArray()); + assertEquals(list3, expElements); + + var list4 = Arrays.asList(mapView.toArray(new Object[0])); + assertEquals(list4, expElements); + + var list5 = Arrays.asList(mapView.toArray(Object[]::new)); + assertEquals(list5, expElements); + + var list6 = mapView.stream().toList(); + assertEquals(list6, expElements); + + var list7 = mapView.parallelStream().toList(); + assertEquals(list7, expElements); + + assertEquals(mapView.size(), expElements.size()); + assertEquals(mapView.isEmpty(), expElements.isEmpty()); + + for (var k : expElements) { + assertTrue(mapView.contains(k)); + } + + var it = mapView.iterator(); + if (expElements.isEmpty()) { + assertFalse(it.hasNext()); + } else { + assertTrue(it.hasNext()); + assertEquals(it.next(), expElements.get(0)); + } + } + + /** + * Check the sequenced entrySet, keySet, or values view of a SequencedMap in one direction. + * + * @param the element type of the view + * @param mapView the actual map view + * @param expElements list of the expected elements + */ + public void checkSeqView1(SequencedCollection mapView, List expElements) { + checkView1(mapView, expElements); + + if (expElements.isEmpty()) { + assertThrows(NoSuchElementException.class, () -> mapView.getFirst()); + assertThrows(NoSuchElementException.class, () -> mapView.getLast()); + } else { + assertEquals(mapView.getFirst(), expElements.get(0)); + assertEquals(mapView.getLast(), expElements.get(expElements.size() - 1)); + } + } + + /** + * Check the keySet and sequencedKeySet views of a map. It's possible to unify this with + * the corresponding checks for values and entrySet views, but doing this adds a bunch + * of generics and method references that tend to obscure more than they help. + * + * @param map the SequencedMap under test + * @param refEntries expected contents of the map + */ + public void checkKeySet(SequencedMap map, List> refEntries) { + List refKeys = refEntries.stream().map(Map.Entry::getKey).toList(); + List rrefKeys = new ArrayList<>(refKeys); + Collections.reverse(rrefKeys); + SequencedMap rmap = map.reversed(); + + checkView1(map.keySet(), refKeys); + checkSeqView1(map.sequencedKeySet(), refKeys); + checkSeqView1(map.sequencedKeySet().reversed(), rrefKeys); + + checkView1(rmap.keySet(), rrefKeys); + checkSeqView1(rmap.sequencedKeySet(), rrefKeys); + checkSeqView1(rmap.sequencedKeySet().reversed(), refKeys); + + checkView1(rmap.reversed().keySet(), refKeys); + checkSeqView1(rmap.reversed().sequencedKeySet(), refKeys); + checkSeqView1(rmap.reversed().sequencedKeySet().reversed(), rrefKeys); + } + + /** + * Check the values and sequencedValues views of a map. + * + * @param map the SequencedMap under test + * @param refEntries expected contents of the map + */ + public void checkValues(SequencedMap map, List> refEntries) { + List refValues = refEntries.stream().map(Map.Entry::getValue).toList(); + List rrefValues = new ArrayList<>(refValues); + Collections.reverse(rrefValues); + SequencedMap rmap = map.reversed(); + + checkView1(map.values(), refValues); + checkSeqView1(map.sequencedValues(), refValues); + checkSeqView1(map.sequencedValues().reversed(), rrefValues); + + checkView1(rmap.values(), rrefValues); + checkSeqView1(rmap.sequencedValues(), rrefValues); + checkSeqView1(rmap.sequencedValues().reversed(), refValues); + + checkView1(rmap.reversed().values(), refValues); + checkSeqView1(rmap.reversed().sequencedValues(), refValues); + checkSeqView1(rmap.reversed().sequencedValues().reversed(), rrefValues); + } + + /** + * Check the entrySet and sequencedEntrySet views of a map. + * + * @param map the SequencedMap under test + * @param refEntries expected contents of the map + */ + public void checkEntrySet(SequencedMap map, List> refEntries) { + List> rref = new ArrayList<>(refEntries); + Collections.reverse(rref); + SequencedMap rmap = map.reversed(); + + checkView1(map.entrySet(), refEntries); + checkSeqView1(map.sequencedEntrySet(), refEntries); + checkSeqView1(map.sequencedEntrySet().reversed(), rref); + + checkView1(rmap.entrySet(), rref); + checkSeqView1(rmap.sequencedEntrySet(), rref); + checkSeqView1(rmap.sequencedEntrySet().reversed(), refEntries); + + checkView1(rmap.reversed().entrySet(), refEntries); + checkSeqView1(rmap.reversed().sequencedEntrySet(), refEntries); + checkSeqView1(rmap.reversed().sequencedEntrySet().reversed(), rref); + } + + /** + * Test attempted modifications to unmodifiable map views. The only mutating operation + * map views can support is removal. + * + * @param element type of the map view + * @param view the map view + */ + public void checkUnmodifiableView(Collection view) { + assertThrows(UOE, () -> view.clear()); + assertThrows(UOE, () -> { var it = view.iterator(); it.next(); it.remove(); }); + assertThrows(UOE, () -> { var t = view.iterator().next(); view.remove(t); }); + +// TODO these ops should throw unconditionally, but they don't in some implementations + // assertThrows(UOE, () -> view.removeAll(List.of())); + // assertThrows(UOE, () -> view.removeIf(x -> false)); + // assertThrows(UOE, () -> view.retainAll(view)); + assertThrows(UOE, () -> view.removeAll(view)); + assertThrows(UOE, () -> view.removeIf(x -> true)); + assertThrows(UOE, () -> view.retainAll(List.of())); + } + + /** + * Test removal methods on unmodifiable sequenced map views. + * + * @param element type of the map view + * @param view the map view + */ + public void checkUnmodifiableSeqView(SequencedCollection view) { + checkUnmodifiableView(view); + assertThrows(UOE, () -> view.removeFirst()); + assertThrows(UOE, () -> view.removeLast()); + + var rview = view.reversed(); + checkUnmodifiableView(rview); + assertThrows(UOE, () -> rview.removeFirst()); + assertThrows(UOE, () -> rview.removeLast()); + } + + public void checkUnmodifiableEntry(SequencedMap map) { + assertThrows(UOE, () -> { map.firstEntry().setValue(99); }); + assertThrows(UOE, () -> { map.lastEntry().setValue(99); }); + assertThrows(UOE, () -> { map.sequencedEntrySet().getFirst().setValue(99); }); + assertThrows(UOE, () -> { map.sequencedEntrySet().getLast().setValue(99); }); + assertThrows(UOE, () -> { map.sequencedEntrySet().reversed().getFirst().setValue(99); }); + assertThrows(UOE, () -> { map.sequencedEntrySet().reversed().getLast().setValue(99); }); + } + + public void checkUnmodifiable1(SequencedMap map) { + assertThrows(UOE, () -> map.putFirst("x", 99)); + assertThrows(UOE, () -> map.putLast("x", 99)); + assertThrows(UOE, () -> { map.pollFirstEntry(); }); + assertThrows(UOE, () -> { map.pollLastEntry(); }); + + checkUnmodifiableEntry(map); + checkUnmodifiableView(map.keySet()); + checkUnmodifiableView(map.values()); + checkUnmodifiableView(map.entrySet()); + checkUnmodifiableSeqView(map.sequencedKeySet()); + checkUnmodifiableSeqView(map.sequencedValues()); + checkUnmodifiableSeqView(map.sequencedEntrySet()); + } + + public void checkUnmodifiable(SequencedMap map) { + checkUnmodifiable1(map); + checkUnmodifiable1(map.reversed()); + } + + // The putFirst/putLast operations aren't tested here, because the only instances of + // checked, sequenced maps are SortedMap and NavigableMap, which don't support them. + public void checkChecked(SequencedMap map) { + 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.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()); }); + } + + // ========== Tests ========== + + @Test(dataProvider="all") + public void testFundamentals(String label, SequencedMap map, List> ref) { + checkContents(map, ref); + checkEntrySet(map, ref); + checkKeySet(map, ref); + checkValues(map, ref); + } + + @Test(dataProvider="populated") + public void testFirstEntry(String label, SequencedMap map, List> ref) { + assertEquals(map.firstEntry(), ref.get(0)); + assertEquals(map.reversed().firstEntry(), ref.get(ref.size() - 1)); + assertThrows(UOE, () -> { map.firstEntry().setValue(99); }); + assertThrows(UOE, () -> { map.reversed().firstEntry().setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="populated") + public void testLastEntry(String label, SequencedMap map, List> ref) { + assertEquals(map.lastEntry(), ref.get(ref.size() - 1)); + assertEquals(map.reversed().lastEntry(), ref.get(0)); + assertThrows(UOE, () -> { map.lastEntry().setValue(99); }); + assertThrows(UOE, () -> { map.reversed().lastEntry().setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="empties") + public void testEmptyFirstEntry(String label, SequencedMap map, List> ref) { + assertNull(map.firstEntry()); + assertNull(map.reversed().firstEntry()); + checkContents(map, ref); + } + + @Test(dataProvider="empties") + public void testEmptyLastEntry(String label, SequencedMap map, List> ref) { + assertNull(map.lastEntry()); + assertNull(map.reversed().lastEntry()); + checkContents(map, ref); + } + + @Test(dataProvider="puts") + public void testPutFirst(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(0, Map.entry("x", 99)); + map.putFirst("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="puts") + public void testPutFirstRev(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + map.reversed().putFirst("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="puts") + public void testPutLast(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + map.putLast("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="puts") + public void testPutLastRev(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(0, Map.entry("x", 99)); + map.reversed().putLast("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposPut(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).put("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposPutAll(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).putAll(Map.of("x", 99)); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposPutIfAbsent(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).putIfAbsent("x", 99); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposCompute(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).compute("x", (k, v) -> 99); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposComputeIfAbsent(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).computeIfAbsent("x", k -> 99); + checkContents(map, ref); + } + + @Test(dataProvider="putUnpositioned") + public void testUnposMerge(String label, boolean rev, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + ref.add(Map.entry("x", 99)); + (rev ? map.reversed() : map).merge("x", 99, /*unused*/ (k, v) -> -1); + checkContents(map, ref); + } + + @Test(dataProvider="putThrows") + public void testPutThrows(String label, SequencedMap map, List> baseref) { + assertThrows(UOE, () -> map.putFirst("x", 99)); + assertThrows(UOE, () -> map.putLast("x", 99)); + assertThrows(UOE, () -> map.reversed().putFirst("x", 99)); + assertThrows(UOE, () -> map.reversed().putLast("x", 99)); + checkContents(map, baseref); + } + + @Test(dataProvider="polls") + public void testPollFirst(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + var act = map.pollFirstEntry(); + assertEquals(act, ref.remove(0)); + assertThrows(UOE, () -> { act.setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="polls") + public void testPollFirstRev(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + var act = map.reversed().pollFirstEntry(); + assertEquals(act, ref.remove(ref.size() - 1)); + assertThrows(UOE, () -> { act.setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="polls") + public void testPollLast(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + var act = map.pollLastEntry(); + assertEquals(act, ref.remove(ref.size() - 1)); + assertThrows(UOE, () -> { act.setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="polls") + public void testPollLastRev(String label, SequencedMap map, List> baseref) { + var ref = new ArrayList<>(baseref); + var act = map.reversed().pollLastEntry(); + assertEquals(act, ref.remove(0)); + assertThrows(UOE, () -> { act.setValue(99); }); + checkContents(map, ref); + } + + @Test(dataProvider="emptyPolls") + public void testEmptyPollFirst(String label, SequencedMap map, List> ref) { + assertNull(map.pollFirstEntry()); + assertNull(map.reversed().pollFirstEntry()); + checkContents(map, ref); + } + + @Test(dataProvider="emptyPolls") + public void testEmptyPollLast(String label, SequencedMap map, List> ref) { + assertNull(map.pollLastEntry()); + assertNull(map.reversed().pollLastEntry()); + checkContents(map, ref); + } + + @Test(dataProvider="serializable") + public void testSerializable(String label, SequencedMap map, List> ref) + throws ClassNotFoundException, IOException + { + var baos = new ByteArrayOutputStream(); + try (var oos = new ObjectOutputStream(baos)) { + oos.writeObject(map); + } + + try (var bais = new ByteArrayInputStream(baos.toByteArray()); + var ois = new ObjectInputStream(bais)) { + var map2 = (SequencedMap) ois.readObject(); + checkContents(map2, ref); + } + } + + @Test(dataProvider="notSerializable") + public void testNotSerializable(String label, SequencedMap map) + throws ClassNotFoundException, IOException + { + var baos = new ByteArrayOutputStream(); + try (var oos = new ObjectOutputStream(baos)) { + assertThrows(ObjectStreamException.class, () -> oos.writeObject(map)); + } + } + + @Test(dataProvider="doubleReverse") + public void testDoubleReverse(String label, SequencedMap map) { + var rrmap = map.reversed().reversed(); + assertSame(rrmap, map); + } + + @Test(dataProvider="unmodifiable") + public void testUnmodifiable(String label, SequencedMap map, List> ref) { + checkUnmodifiable(map); + checkContents(map, ref); + } + + @Test(dataProvider="checked") + public void testChecked(String label, SequencedMap map, List> ref) { + checkChecked(map); + checkContents(map, ref); + } + + /** + * Test that a removal from the sequenedKeySet view is properly reflected in the original + * backing map. The mode value indicates whether the backing map is reversed, whether the + * sequencedKeySet view is reversed, and whether the removeFirst or removeLast is called + * on the view. See the viewRemoves() dataProvider for details. + * + * @param label the implementation label + * @param mode reversed and first/last modes + * @param map the original map instance + * @param baseref reference contents of the original map + */ + @Test(dataProvider="viewRemoves") + public void testKeySetRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var ref = new ArrayList<>(baseref); + var exp = (refLast(mode) ? ref.remove(ref.size() - 1) : ref.remove(0)).getKey(); + var tempmap = reverseMap(mode) ? map.reversed() : map; + var keySet = reverseView(mode) ? tempmap.sequencedKeySet().reversed() : tempmap.sequencedKeySet(); + var act = callLast(mode) ? keySet.removeLast() : keySet.removeFirst(); + assertEquals(act, exp); + checkContents(map, ref); + } + + // As above, but for the sequencedValues view. + @Test(dataProvider="viewRemoves") + public void testValuesRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var ref = new ArrayList<>(baseref); + var exp = (refLast(mode) ? ref.remove(ref.size() - 1) : ref.remove(0)).getValue(); + var tempmap = reverseMap(mode) ? map.reversed() : map; + var values = reverseView(mode) ? tempmap.sequencedValues().reversed() : tempmap.sequencedValues(); + var act = callLast(mode) ? values.removeLast() : values.removeFirst(); + assertEquals(act, exp); + checkContents(map, ref); + } + + // As above, but for the sequencedEntrySet view. + @Test(dataProvider="viewRemoves") + public void testEntrySetRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var ref = new ArrayList<>(baseref); + var exp = refLast(mode) ? ref.remove(ref.size() - 1) : ref.remove(0); + var tempmap = reverseMap(mode) ? map.reversed() : map; + var entrySet = reverseView(mode) ? tempmap.sequencedEntrySet().reversed() : tempmap.sequencedEntrySet(); + var act = callLast(mode) ? entrySet.removeLast() : entrySet.removeFirst(); + assertEquals(act, exp); + checkContents(map, ref); + } + + // As above, but for the sequencedKeySet of an empty map. + @Test(dataProvider="emptyViewRemoves") + public void testEmptyKeySetRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var keySet = reverseView(mode) ? tempmap.sequencedKeySet().reversed() : tempmap.sequencedKeySet(); + if (callLast(mode)) + assertThrows(NSEE, () -> keySet.removeLast()); + else + assertThrows(NSEE, () -> keySet.removeFirst()); + checkContents(map, baseref); + + } + + // As above, but for the sequencedValues view. + @Test(dataProvider="emptyViewRemoves") + public void testEmptyValuesRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var values = reverseView(mode) ? tempmap.sequencedValues().reversed() : tempmap.sequencedValues(); + if (callLast(mode)) + assertThrows(NSEE, () -> values.removeLast()); + else + assertThrows(NSEE, () -> values.removeFirst()); + checkContents(map, baseref); + } + + // As above, but for the sequencedEntrySet view. + @Test(dataProvider="emptyViewRemoves") + public void testEmptyEntrySetRemoves(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var entrySet = reverseView(mode) ? tempmap.sequencedEntrySet().reversed() : tempmap.sequencedEntrySet(); + if (callLast(mode)) + assertThrows(NSEE, () -> entrySet.removeLast()); + else + assertThrows(NSEE, () -> entrySet.removeFirst()); + checkContents(map, baseref); + } + + // Test that addFirst/addLast on the sequencedKeySetView throw UnsupportedOperationException. + @Test(dataProvider="viewAddThrows") + public void testKeySetAddThrows(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var keySet = reverseView(mode) ? tempmap.sequencedKeySet().reversed() : tempmap.sequencedKeySet(); + if (callLast(mode)) + assertThrows(UOE, () -> keySet.addLast("x")); + else + assertThrows(UOE, () -> keySet.addFirst("x")); + checkContents(map, baseref); + } + + // As above, but for the sequencedValues view. + @Test(dataProvider="viewAddThrows") + public void testValuesAddThrows(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var values = reverseView(mode) ? tempmap.sequencedValues().reversed() : tempmap.sequencedValues(); + if (callLast(mode)) + assertThrows(UOE, () -> values.addLast(99)); + else + assertThrows(UOE, () -> values.addFirst(99)); + checkContents(map, baseref); + } + + // As above, but for the sequencedEntrySet view. + @Test(dataProvider="viewAddThrows") + public void testEntrySetAddThrows(String label, + int mode, + SequencedMap map, + List> baseref) { + var tempmap = reverseMap(mode) ? map.reversed() : map; + var entrySet = reverseView(mode) ? tempmap.sequencedEntrySet().reversed() : tempmap.sequencedEntrySet(); + if (callLast(mode)) + assertThrows(UOE, () -> entrySet.addLast(Map.entry("x", 99))); + else + assertThrows(UOE, () -> entrySet.addFirst(Map.entry("x", 99))); + checkContents(map, baseref); + } +} diff --git a/test/jdk/java/util/SequencedCollection/SimpleDeque.java b/test/jdk/java/util/SequencedCollection/SimpleDeque.java new file mode 100644 index 00000000000..c1ed07210fb --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/SimpleDeque.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; + +/** + * A complete Deque implementation that inherits the reversed() method + * from SequencedCollection. Useful for testing ReverseOrderDequeView. + * Underlying implementation provided by ArrayDeque. + */ +public class SimpleDeque implements Deque { + + final Deque deque; + + public SimpleDeque() { + deque = new ArrayDeque<>(); + } + + public SimpleDeque(Collection c) { + deque = new ArrayDeque<>(c); + } + + // ========== Object ========== + + public boolean equals(Object o) { + return deque.equals(o); + } + + public int hashCode() { + return deque.hashCode(); + } + + public String toString() { + return deque.toString(); + } + + // ========== Collection ========== + + public boolean add(E e) { + return deque.add(e); + } + + public boolean addAll(Collection c) { + return deque.addAll(c); + } + + public void clear() { + deque.clear(); + } + + public boolean contains(Object o) { + return deque.contains(o); + } + + public boolean containsAll(Collection c) { + return deque.containsAll(c); + } + + public boolean isEmpty() { + return deque.isEmpty(); + } + + public Iterator iterator() { + return deque.iterator(); + } + + public boolean remove(Object o) { + return deque.remove(o); + } + + public boolean removeAll(Collection c) { + return deque.removeAll(c); + } + + public boolean retainAll(Collection c) { + return deque.retainAll(c); + } + + public int size() { + return deque.size(); + } + + public Object[] toArray() { + return deque.toArray(); + } + + public T[] toArray(T[] a) { + return deque.toArray(a); + } + + // ========== Deque ========== + + public void addFirst(E e) { + deque.addFirst(e); + } + + public void addLast(E e) { + deque.addLast(e); + } + + public boolean offerFirst(E e) { + return deque.offerFirst(e); + } + + public boolean offerLast(E e) { + return deque.offerLast(e); + } + + public E removeFirst() { + return deque.removeFirst(); + } + + public E removeLast() { + return deque.removeLast(); + } + + public E pollFirst() { + return deque.pollFirst(); + } + + public E pollLast() { + return deque.pollLast(); + } + + public E getFirst() { + return deque.getFirst(); + } + + public E getLast() { + return deque.getLast(); + } + + public E peekFirst() { + return deque.peekFirst(); + } + + public E peekLast() { + return deque.peekLast(); + } + + public boolean removeFirstOccurrence(Object o) { + return deque.removeFirstOccurrence(o); + } + + public boolean removeLastOccurrence(Object o) { + return deque.removeLastOccurrence(o); + } + + public boolean offer(E e) { + return deque.offer(e); + } + + public E remove() { + return deque.remove(); + } + + public E poll() { + return deque.poll(); + } + + public E element() { + return deque.element(); + } + + public E peek() { + return deque.peek(); + } + + public void push(E e) { + deque.push(e); + } + + public E pop() { + return deque.pop(); + } + + public Iterator descendingIterator() { + return deque.descendingIterator(); + } +} diff --git a/test/jdk/java/util/SequencedCollection/SimpleList.java b/test/jdk/java/util/SequencedCollection/SimpleList.java new file mode 100644 index 00000000000..f717bf05b44 --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/SimpleList.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; + +/** + * A complete List implementation that inherits the reversed() method + * from List. Useful for testing ReverseOrderListView. + * Underlying implementation provided by ArrayList. + */ +public class SimpleList implements List { + + final List list; + + public SimpleList() { + list = new ArrayList<>(); + } + + public SimpleList(Collection c) { + list = new ArrayList<>(c); + } + + // ========== Object ========== + + public boolean equals(Object o) { + return list.equals(o); + } + + public int hashCode() { + return list.hashCode(); + } + + public String toString() { + return list.toString(); + } + + // ========== Collection ========== + + public boolean add(E e) { + return list.add(e); + } + + public boolean addAll(Collection c) { + return list.addAll(c); + } + + public void clear() { + list.clear(); + } + + public boolean contains(Object o) { + return list.contains(o); + } + + public boolean containsAll(Collection c) { + return list.containsAll(c); + } + + public boolean isEmpty() { + return list.isEmpty(); + } + + public Iterator iterator() { + return list.iterator(); + } + + public boolean remove(Object o) { + return list.remove(o); + } + + public boolean removeAll(Collection c) { + return list.removeAll(c); + } + + public boolean retainAll(Collection c) { + return list.retainAll(c); + } + + public int size() { + return list.size(); + } + + public Object[] toArray() { + return list.toArray(); + } + + public T[] toArray(T[] a) { + return list.toArray(a); + } + + // ========== List ========== + + public void add(int index, E element) { + list.add(index, element); + } + + public boolean addAll(int index, Collection c) { + return list.addAll(index, c); + } + + public E get(int index) { + return list.get(index); + } + + public int indexOf(Object o) { + return list.indexOf(o); + } + + public int lastIndexOf(Object o) { + return list.lastIndexOf(o); + } + + public ListIterator listIterator() { + return list.listIterator(); + } + + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + public E remove(int index) { + return list.remove(index); + } + + public E set(int index, E element) { + return list.set(index, element); + } + + public List subList(int fromIndex, int toIndex) { + return list.subList(fromIndex, toIndex); + } +} diff --git a/test/jdk/java/util/SequencedCollection/SimpleSortedMap.java b/test/jdk/java/util/SequencedCollection/SimpleSortedMap.java new file mode 100644 index 00000000000..4c439d51e28 --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/SimpleSortedMap.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; + +/** + * A SortedMap implementation that does not implement NavigableMap. Useful for + * testing ReverseOrderSortedMapView. Underlying implementation provided by TreeMap. + */ +public class SimpleSortedMap implements SortedMap { + final SortedMap map; + + public SimpleSortedMap() { + map = new TreeMap<>(); + } + + public SimpleSortedMap(Comparator comparator) { + map = new TreeMap<>(comparator); + } + + public SimpleSortedMap(Map m) { + map = new TreeMap<>(m); + } + + // ========== Object ========== + + public boolean equals(Object o) { + return map.equals(o); + } + + public int hashCode() { + return map.hashCode(); + } + + public String toString() { + return map.toString(); + } + + // ========== Map ========== + + public void clear() { + map.clear(); + } + + public boolean containsKey(Object key) { + return map.containsKey(key); + } + + public boolean containsValue(Object value) { + return map.containsValue(value); + } + + public Set> entrySet() { + return map.entrySet(); + } + + public V get(Object key) { + return map.get(key); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public Set keySet() { + return map.keySet(); + } + + public V put(K key, V value) { + return map.put(key, value); + } + + public void putAll(Map m) { + map.putAll(m); + } + + public V remove(Object key) { + return map.remove(key); + } + + public int size() { + return map.size(); + } + + public Collection values() { + return map.values(); + } + + // ========== SortedMap ========== + + public Comparator comparator() { + return map.comparator(); + } + + public K firstKey() { + return map.firstKey(); + } + + public SortedMap headMap(K toKey) { + return map.headMap(toKey); + } + + public K lastKey() { + return map.lastKey(); + } + + public SortedMap subMap(K fromKey, K toKey) { + return map.subMap(fromKey, toKey); + } + + public SortedMap tailMap(K fromKey) { + return map.tailMap(fromKey); + } +} diff --git a/test/jdk/java/util/SequencedCollection/SimpleSortedSet.java b/test/jdk/java/util/SequencedCollection/SimpleSortedSet.java new file mode 100644 index 00000000000..6ca2156a47d --- /dev/null +++ b/test/jdk/java/util/SequencedCollection/SimpleSortedSet.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; + +/** + * A SortedSet implementation that does not implement NavigableSet. Useful for + * testing ReverseOrderSortedSetView. Underlying implementation provided by TreeSet. + */ +public class SimpleSortedSet implements SortedSet { + + final SortedSet set; + + public SimpleSortedSet() { + set = new TreeSet(); + } + + public SimpleSortedSet(Collection c) { + set = new TreeSet<>(c); + } + + public SimpleSortedSet(Comparator comparator) { + set = new TreeSet<>(comparator); + } + + // ========== Object ========== + + public boolean equals(Object o) { + return set.equals(o); + } + + public int hashCode() { + return set.hashCode(); + } + + public String toString() { + return set.toString(); + } + + // ========== Collection ========== + + public boolean add(E e) { + return set.add(e); + } + + public boolean addAll(Collection c) { + return set.addAll(c); + } + + public void clear() { + set.clear(); + } + + public boolean contains(Object o) { + return set.contains(o); + } + + public boolean containsAll(Collection c) { + return set.containsAll(c); + } + + public boolean isEmpty() { + return set.isEmpty(); + } + + public Iterator iterator() { + return set.iterator(); + } + + public boolean remove(Object o) { + return set.remove(o); + } + + public boolean removeAll(Collection c) { + return set.removeAll(c); + } + + public boolean retainAll(Collection c) { + return set.retainAll(c); + } + + public int size() { + return set.size(); + } + + public Object[] toArray() { + return set.toArray(); + } + + public T[] toArray(T[] a) { + return set.toArray(a); + } + + // ========== SortedSet ========== + + public Comparator comparator() { + return set.comparator(); + } + + public E first() { + return set.first(); + } + + public SortedSet headSet(E toElement) { + return set.headSet(toElement); + } + + public E last() { + return set.last(); + } + + public SortedSet subSet(E fromElement, E toElement) { + return set.subSet(fromElement, toElement); + } + + public SortedSet tailSet(E fromElement) { + return set.tailSet(fromElement); + } +} diff --git a/test/jdk/jdk/internal/util/ArraysSupport/Reverse.java b/test/jdk/jdk/internal/util/ArraysSupport/Reverse.java new file mode 100644 index 00000000000..6e0ebd06257 --- /dev/null +++ b/test/jdk/jdk/internal/util/ArraysSupport/Reverse.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8266571 + * @modules java.base/jdk.internal.util + * @run testng Reverse + * @summary Tests for ArraysSupport.reverse + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; + +import java.util.Arrays; +import jdk.internal.util.ArraysSupport; + +public class Reverse { + @DataProvider(name = "data") + public Object[][] data() { + return new Object[][][] { + // pairs of actual, expected + { + { }, + { } + }, { + { "a" }, + { "a" } + }, { + { "a", "b" }, + { "b", "a" } + }, { + { "a", "b", "c" }, + { "c", "b", "a" } + }, { + { "a", "b", "c", "d" }, + { "d", "c", "b", "a" } + }, { + { "a", "b", "c", "d", "e" }, + { "e", "d", "c", "b", "a" } + } + }; + } + + @Test(dataProvider = "data") + public void testReverse(Object[] actual, Object[] expected) { + Object[] r = ArraysSupport.reverse(actual); + assertSame(r, actual); + assertEquals(actual.length, expected.length); + for (int i = 0; i < actual.length; i++) { + assertEquals(actual[i], expected[i], + "mismatch: actual=" + Arrays.asList(actual) + + " expected=" + Arrays.asList(expected) + " at index " + i); + } + } +} diff --git a/test/langtools/tools/javac/api/TestJavacTaskScanner.java b/test/langtools/tools/javac/api/TestJavacTaskScanner.java index e8110396dac..e302247bd68 100644 --- a/test/langtools/tools/javac/api/TestJavacTaskScanner.java +++ b/test/langtools/tools/javac/api/TestJavacTaskScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +102,7 @@ public class TestJavacTaskScanner extends ToolTester { System.out.println("#allMembers: " + numAllMembers); check(numTokens, "#Tokens", 1054); - check(numParseTypeElements, "#parseTypeElements", 158); + check(numParseTypeElements, "#parseTypeElements", 180); check(numAllMembers, "#allMembers", 52); } diff --git a/test/langtools/tools/javac/processing/model/type/BoundsTest.java b/test/langtools/tools/javac/processing/model/type/BoundsTest.java index b7e9121a956..f72fc6461b9 100644 --- a/test/langtools/tools/javac/processing/model/type/BoundsTest.java +++ b/test/langtools/tools/javac/processing/model/type/BoundsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -70,7 +70,7 @@ public class BoundsTest { }; private static final String[] Single_supers = { "java.lang.Object", - "java.util.Collection" + "java.util.SequencedCollection" }; private static final String NoBounds_name = "NoBoundsTest.java"; From 07ea445b43e0df682f305c8709495094e807b1f8 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Tue, 25 Apr 2023 15:29:28 +0000 Subject: [PATCH 125/288] 8306838: GetGraphicsTest needs to be headful Reviewed-by: jiefu, dcubed --- test/jdk/java/awt/Graphics/GetGraphicsTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/java/awt/Graphics/GetGraphicsTest.java b/test/jdk/java/awt/Graphics/GetGraphicsTest.java index 19285c7d803..7a80e1fd0df 100644 --- a/test/jdk/java/awt/Graphics/GetGraphicsTest.java +++ b/test/jdk/java/awt/Graphics/GetGraphicsTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 4746122 + * @key headful * @summary Checks getGraphics doesn't throw NullPointerExcepton for invalid colors and font. * @run main GetGraphicsTest */ From 98e8616a0c27ac73caf8f91cc83adc88b3490dcb Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Tue, 25 Apr 2023 15:48:12 +0000 Subject: [PATCH 126/288] 8301169: java/net/httpclient/ThrowingSubscribersAsInputStream.java,ThrowingSubscribersAsInputStreamAsync.java, and other httpclient tests failing on windows: Unable to establish loopback connection Reviewed-by: aefimov, djelinski --- .../AbstractThrowingPublishers.java | 36 +++++++++++++++++++ .../AbstractThrowingPushPromises.java | 36 +++++++++++++++++++ .../AbstractThrowingSubscribers.java | 36 +++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java index f2a47734e40..4079bd81e3e 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java @@ -388,6 +388,24 @@ public abstract class AbstractThrowingPublishers implements HttpServerAdapters { String body = response.join().body(); assertEquals(body, Stream.of(BODY.split("\\|")).collect(Collectors.joining())); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -470,6 +488,24 @@ public abstract class AbstractThrowingPublishers implements HttpServerAdapters { if (response != null) { finisher.finish(where, response, thrower); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java index a9d1906430d..b5230d48d10 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java @@ -340,6 +340,24 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters assertEquals(promisedBody, promised.uri().toASCIIString()); } assertEquals(3, pushPromises.size()); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -425,6 +443,24 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters if (response != null) { finisher.finish(where, req.uri(), response, thrower, promiseMap); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java index 893950608b1..d4100b7eb04 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java @@ -314,6 +314,24 @@ public abstract class AbstractThrowingSubscribers implements HttpServerAdapters HttpResponse response = client.send(req, handler); String body = response.body(); assertEquals(URI.create(body).getPath(), URI.create(uri2).getPath()); + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } @@ -461,6 +479,24 @@ public abstract class AbstractThrowingSubscribers implements HttpServerAdapters if (response != null) { finisher.finish(where, response, thrower); } + if (!sameClient) { + // Wait for the client to be garbage collected. + // we use the ReferenceTracker API rather than HttpClient::close here, + // because these tests inject faults by throwing inside callbacks, which + // is more likely to get HttpClient::close wedged until jtreg times out. + // By using the ReferenceTracker, we will get some diagnosis about what + // is keeping the client alive if it doesn't get GC'ed within the + // expected time frame. + var tracker = TRACKER.getTracker(client); + client = null; + System.gc(); + System.out.println(now() + "waiting for client to shutdown: " + tracker.getName()); + System.err.println(now() + "waiting for client to shutdown: " + tracker.getName()); + var error = TRACKER.check(tracker, 10000); + if (error != null) throw error; + System.out.println(now() + "client shutdown normally: " + tracker.getName()); + System.err.println(now() + "client shutdown normally: " + tracker.getName()); + } } } From e8f62de1cf791d0212805c7a5a97497b67e2a34a Mon Sep 17 00:00:00 2001 From: Quan Anh Mai Date: Tue, 25 Apr 2023 16:13:03 +0000 Subject: [PATCH 127/288] 8304676: [vectorapi] x86_32: Crash in Assembler::kmovql(Address, KRegister) Reviewed-by: shade, thartmann, jbhateja --- src/hotspot/cpu/x86/x86_32.ad | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 46e489f45e5..0b8bd0b2157 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1243,18 +1243,30 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo if (src_first_rc == rc_stack && dst_first_rc == rc_kreg) { assert((src_first & 1) == 0 && src_first + 1 == src_second, "invalid register pair"); assert((dst_first & 1) == 0 && dst_first + 1 == dst_second, "invalid register pair"); - MacroAssembler _masm(cbuf); int offset = ra_->reg2offset(src_first); - __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); + if (cbuf != nullptr) { + MacroAssembler _masm(cbuf); + __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); +#ifndef PRODUCT + } else { + st->print("KMOV %s, [ESP + %d]", Matcher::regName[dst_first], offset); +#endif + } return 0; } if (src_first_rc == rc_kreg && dst_first_rc == rc_stack) { assert((src_first & 1) == 0 && src_first + 1 == src_second, "invalid register pair"); assert((dst_first & 1) == 0 && dst_first + 1 == dst_second, "invalid register pair"); - MacroAssembler _masm(cbuf); int offset = ra_->reg2offset(dst_first); - __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); + if (cbuf != nullptr) { + MacroAssembler _masm(cbuf); + __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); +#ifndef PRODUCT + } else { + st->print("KMOV [ESP + %d], %s", offset, Matcher::regName[src_first]); +#endif + } return 0; } @@ -1271,8 +1283,14 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo if (src_first_rc == rc_kreg && dst_first_rc == rc_kreg) { assert((src_first & 1) == 0 && src_first + 1 == src_second, "invalid register pair"); assert((dst_first & 1) == 0 && dst_first + 1 == dst_second, "invalid register pair"); - MacroAssembler _masm(cbuf); - __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); + if (cbuf != nullptr) { + MacroAssembler _masm(cbuf); + __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); +#ifndef PRODUCT + } else { + st->print("KMOV %s, %s", Matcher::regName[dst_first], Matcher::regName[src_first]); +#endif + } return 0; } From 0ff3a2784e06873505956ba01f153bba82d6c07a Mon Sep 17 00:00:00 2001 From: Quan Anh Mai Date: Tue, 25 Apr 2023 16:13:45 +0000 Subject: [PATCH 128/288] 8306008: Several Vector API tests fail for client VM after JDK-8304450 Reviewed-by: psandoz --- .../jdk/incubator/vector/Double128Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Double256Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Double512Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Double64Vector.java | 26 ++++++++++++- .../jdk/incubator/vector/DoubleMaxVector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Long128Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Long256Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Long512Vector.java | 32 ++++++++++++---- .../jdk/incubator/vector/Long64Vector.java | 26 ++++++++++++- .../jdk/incubator/vector/LongMaxVector.java | 32 ++++++++++++---- .../vector/X-VectorBits.java.template | 37 +++++++++++++------ 11 files changed, 275 insertions(+), 70 deletions(-) diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java index efa18066482..93febadf3e3 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double128Vector.java @@ -805,13 +805,31 @@ final class Double128Vector extends DoubleVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java index 10677e59830..6b0b847f485 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double256Vector.java @@ -809,13 +809,31 @@ final class Double256Vector extends DoubleVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java index 80762d04019..addbc17c14f 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double512Vector.java @@ -817,13 +817,31 @@ final class Double512Vector extends DoubleVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java index aca9f2b65e8..c7e41bd382d 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Double64Vector.java @@ -803,7 +803,31 @@ final class Double64Vector extends DoubleVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - a[offset] = laneSource(0); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java index 54b593b8129..61dea4bcf8b 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleMaxVector.java @@ -802,13 +802,31 @@ final class DoubleMaxVector extends DoubleVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java index 9aa24fe471d..87d5bc36253 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long128Vector.java @@ -806,13 +806,31 @@ final class Long128Vector extends LongVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java index 498118027c8..4de92041ea8 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long256Vector.java @@ -810,13 +810,31 @@ final class Long256Vector extends LongVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java index bd3edf3a297..5bbe81f4c7c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long512Vector.java @@ -818,13 +818,31 @@ final class Long512Vector extends LongVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java index ce954591e4a..cf0246f670e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Long64Vector.java @@ -804,7 +804,31 @@ final class Long64Vector extends LongVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - a[offset] = laneSource(0); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java index 3bc9a8992fa..54a8cb6537c 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongMaxVector.java @@ -804,13 +804,31 @@ final class LongMaxVector extends LongVector { @Override @ForceInline public void intoArray(int[] a, int offset) { - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } } private static long[] prepare(int[] indices, int offset) { diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template index a22d526427d..8f0632a8b73 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-VectorBits.java.template @@ -1132,18 +1132,31 @@ final class $vectortype$ extends $abstractvectortype$ { toBitsVector().intoArray(a, offset); #end[intOrFloat] #if[longOrDouble] -#if[!1L] - VectorSpecies species = VectorSpecies.of( - int.class, - VectorShape.forBitSize(length() * Integer.SIZE)); - Vector v = toBitsVector(); - v.convertShape(VectorOperators.L2I, species, 0) - .reinterpretAsInts() - .intoArray(a, offset); -#end[!1L] -#if[1L] - a[offset] = laneSource(0); -#end[1L] + switch (length()) { + case 1 -> a[offset] = laneSource(0); + case 2 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_64, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 4 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_128, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 8 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_256, 0) + .reinterpretAsInts() + .intoArray(a, offset); + case 16 -> toBitsVector() + .convertShape(VectorOperators.L2I, IntVector.SPECIES_512, 0) + .reinterpretAsInts() + .intoArray(a, offset); + default -> { + VectorIntrinsics.checkFromIndexSize(offset, length(), a.length); + for (int i = 0; i < length(); i++) { + a[offset + i] = laneSource(i); + } + } + } #end[longOrDouble] } From c92883a3d540b8b6d28e31e1525d74b48161578c Mon Sep 17 00:00:00 2001 From: Eirik Bjorsnos Date: Tue, 25 Apr 2023 16:33:24 +0000 Subject: [PATCH 129/288] 8306772: Remove sun.security.x509.CertException, sun.security.x509.CertParseError Reviewed-by: mullan --- .../sun/security/x509/CertException.java | 175 ------------------ .../sun/security/x509/CertParseError.java | 45 ----- 2 files changed, 220 deletions(-) delete mode 100644 src/java.base/share/classes/sun/security/x509/CertException.java delete mode 100644 src/java.base/share/classes/sun/security/x509/CertParseError.java diff --git a/src/java.base/share/classes/sun/security/x509/CertException.java b/src/java.base/share/classes/sun/security/x509/CertException.java deleted file mode 100644 index a0ddc8130dc..00000000000 --- a/src/java.base/share/classes/sun/security/x509/CertException.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 1996, 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. 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.security.x509; - -/** - * CertException indicates one of a variety of certificate problems. - * - * @deprecated use one of Exceptions defined in the java.security.cert - * package. - * - * @see java.security.Certificate - * - * - * @author David Brownell - */ -@Deprecated -public class CertException extends SecurityException { - - @java.io.Serial - private static final long serialVersionUID = 6930793039696446142L; - - // Zero is reserved. - - /** Indicates that the signature in the certificate is not valid. */ - public static final int verf_INVALID_SIG = 1; - - /** Indicates that the certificate was revoked, and so is invalid. */ - public static final int verf_INVALID_REVOKED = 2; - - /** Indicates that the certificate is not yet valid. */ - public static final int verf_INVALID_NOTBEFORE = 3; - - /** Indicates that the certificate has expired and so is not valid. */ - public static final int verf_INVALID_EXPIRED = 4; - - /** Indicates that a certificate authority in the certification - * chain is not trusted. */ - public static final int verf_CA_UNTRUSTED = 5; - - /** Indicates that the certification chain is too long. */ - public static final int verf_CHAIN_LENGTH = 6; - - /** Indicates an error parsing the ASN.1/DER encoding of the certificate. */ - public static final int verf_PARSE_ERROR = 7; - - /** Indicates an error constructing a certificate or certificate chain. */ - public static final int err_CONSTRUCTION = 8; - - /** Indicates a problem with the public key */ - public static final int err_INVALID_PUBLIC_KEY = 9; - - /** Indicates a problem with the certificate version */ - public static final int err_INVALID_VERSION = 10; - - /** Indicates a problem with the certificate format */ - public static final int err_INVALID_FORMAT = 11; - - /** Indicates a problem with the certificate encoding */ - public static final int err_ENCODING = 12; - - // Private data members - private final int verfCode; - private final String moreData; - - - /** - * Constructs a certificate exception using an error code - * (verf_*) and a string describing the context - * of the error. - */ - public CertException(int code, String moredata) - { - verfCode = code; - moreData = moredata; - } - - /** - * Constructs a certificate exception using just an error code, - * without a string describing the context. - */ - public CertException(int code) - { - verfCode = code; - moreData = null;; - } - - /** - * Returns the error code with which the exception was created. - */ - public int getVerfCode() { return verfCode; } - - /** - * Returns a string describing the context in which the exception - * was reported. - */ - public String getMoreData() { return moreData; } - - /** - * Return a string corresponding to the error code used to create - * this exception. - */ - public String getVerfDescription() - { - switch (verfCode) { - case verf_INVALID_SIG: - return "The signature in the certificate is not valid."; - case verf_INVALID_REVOKED: - return "The certificate has been revoked."; - case verf_INVALID_NOTBEFORE: - return "The certificate is not yet valid."; - case verf_INVALID_EXPIRED: - return "The certificate has expired."; - case verf_CA_UNTRUSTED: - return "The Authority which issued the certificate is not trusted."; - case verf_CHAIN_LENGTH: - return "The certificate path to a trusted authority is too long."; - case verf_PARSE_ERROR: - return "The certificate could not be parsed."; - case err_CONSTRUCTION: - return "There was an error when constructing the certificate."; - case err_INVALID_PUBLIC_KEY: - return "The public key was not in the correct format."; - case err_INVALID_VERSION: - return "The certificate has an invalid version number."; - case err_INVALID_FORMAT: - return "The certificate has an invalid format."; - case err_ENCODING: - return "Problem encountered while encoding the data."; - - default: - return "Unknown code: " + verfCode; - } - } - - /** - * Returns a string describing the certificate exception. - */ - public String toString() - { - return "[Certificate Exception: " + getMessage() + ']'; - } - - /** - * Returns a string describing the certificate exception. - */ - public String getMessage() - { - return getVerfDescription() - + ( (moreData != null) - ? ( "\n (" + moreData + ')' ) : "" ); - } -} diff --git a/src/java.base/share/classes/sun/security/x509/CertParseError.java b/src/java.base/share/classes/sun/security/x509/CertParseError.java deleted file mode 100644 index 07d9fadb08f..00000000000 --- a/src/java.base/share/classes/sun/security/x509/CertParseError.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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.security.x509; - -/** - * CertException indicates one of a variety of certificate problems. - * @deprecated use one of the Exceptions defined in the - * java.security.cert package. - * - * @author David Brownell - */ -@Deprecated -class CertParseError extends CertException -{ - @java.io.Serial - private static final long serialVersionUID = -4559645519017017804L; - - CertParseError (String where) - { - super (CertException.verf_PARSE_ERROR, where); - } -} From 33d661415056107742e16d24efdd5a063a2eb81f Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Tue, 25 Apr 2023 17:48:42 +0000 Subject: [PATCH 130/288] 8304845: Update PCSC-Lite for Suse Linux to 1.9.9 and fix incomplete license wording Reviewed-by: manc, mullan --- src/java.smartcardio/unix/legal/pcsclite.md | 69 ++++++++++++++----- .../unix/native/libj2pcsc/MUSCLE/COPYING | 68 +----------------- .../unix/native/libj2pcsc/MUSCLE/pcsclite.h | 6 +- 3 files changed, 55 insertions(+), 88 deletions(-) diff --git a/src/java.smartcardio/unix/legal/pcsclite.md b/src/java.smartcardio/unix/legal/pcsclite.md index 4efc0817f8f..99a9936a477 100644 --- a/src/java.smartcardio/unix/legal/pcsclite.md +++ b/src/java.smartcardio/unix/legal/pcsclite.md @@ -1,24 +1,57 @@ -## PC/SC Lite v1.9.5 +## PC/SC Lite v1.9.9 + +### PC/SC Lite Notice +``` +MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ ) + +Only 3 header files are included in this distribution: winscard.h, wintypes.h, pcsclite.h + +Copyright for winscard.h: + * Copyright (C) 1999-2003 + * David Corcoran + * Copyright (C) 2002-2009 + * Ludovic Rousseau + +Copyright for wintypes.h: + * Copyright (C) 1999 + * David Corcoran + * Copyright (C) 2002-2011 + * Ludovic Rousseau + +Copyright for pcsclite.h: + * Copyright (C) 1999-2004 + * David Corcoran + * Copyright (C) 2002-2011 + * Ludovic Rousseau + * Copyright (C) 2005 + * Martin Paljak + +``` ### PC/SC Lite License -
+```
 
-The main parts of the code are using the BSD-like licence bellow:
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
 
-Copyright (c) 1999-2003 David Corcoran 
-Copyright (c) 2001-2011 Ludovic Rousseau 
-All rights reserved.
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
 
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
-
-Changes to this license can be made only by the copyright author with explicit written consent.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Some source code files are using other licences. See the [COPYING](https://salsa.debian.org/rousseau/PCSC/-/blob/master/COPYING) file for details.
-
-
+``` diff --git a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING index b3471ee09e4..63292279347 100644 --- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING +++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING @@ -26,70 +26,4 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Some files are under GNU GPL v3 or any later version -- doc/example/pcsc_demo.c -- the files in src/spy/ -- the files in UnitaryTests/ - - Copyright (C) 2003-2014 Ludovic Rousseau - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - -Files src/auth.c and src/auth.h are: - * Copyright (C) 2013 Red Hat - * - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * Author: Nikos Mavrogiannopoulos - - -Files src/simclist.c and src/simclist.h are: - * Copyright (c) 2007,2008,2009,2010,2011 Mij - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +Some source code files are using other licenses. However, they are not included here and thus this file is a truncated version of the [COPYING](https://salsa.debian.org/rousseau/PCSC/-/blob/master/COPYING) file. diff --git a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h index c7927d74361..e722b13a730 100644 --- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h +++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h @@ -58,7 +58,7 @@ typedef SCARDHANDLE *LPSCARDHANDLE; #define MAX_ATR_SIZE 33 /**< Maximum ATR size */ -/* Set structure elements aligment on bytes +/* Set structure elements alignment on bytes * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */ #ifdef __APPLE__ #pragma pack(1) @@ -279,7 +279,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci; #define INFINITE 0xFFFFFFFF /**< Infinite timeout */ #endif -#define PCSCLITE_VERSION_NUMBER "1.9.5" /**< Current version */ +#define PCSCLITE_VERSION_NUMBER "1.9.9" /**< Current version */ /** Maximum readers context (a slot is count as a reader) */ #define PCSCLITE_MAX_READERS_CONTEXTS 16 @@ -292,7 +292,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci; /* * The message and buffer sizes must be multiples of 16. * The max message size must be at least large enough - * to accomodate the transmit_struct + * to accommodate the transmit_struct */ #define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for short APDU */ #define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3 + 2) /**< enhanced (64K + APDU + Lc + Le + SW) Tx/Rx Buffer */ From 5f4965d422cf1d2b4bb372202e6cae96be863d30 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 25 Apr 2023 17:55:57 +0000 Subject: [PATCH 131/288] 8306687: Relax memory ordering constraints on metaspace atomic counters Reviewed-by: shade, minqi --- src/hotspot/share/memory/metaspace/counters.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/memory/metaspace/counters.hpp b/src/hotspot/share/memory/metaspace/counters.hpp index 33c19d1186a..c7c841df423 100644 --- a/src/hotspot/share/memory/metaspace/counters.hpp +++ b/src/hotspot/share/memory/metaspace/counters.hpp @@ -93,22 +93,22 @@ public: AbstractAtomicCounter() : _c(0) {} - T get() const { return _c; } + T get() const { return Atomic::load(&_c); } void increment() { - Atomic::inc(&_c); + Atomic::inc(&_c, memory_order_relaxed); } void decrement() { - Atomic::dec(&_c); + Atomic::dec(&_c, memory_order_relaxed); } void increment_by(T v) { - Atomic::add(&_c, v); + Atomic::add(&_c, v, memory_order_relaxed); } void decrement_by(T v) { - Atomic::sub(&_c, v); + Atomic::sub(&_c, v, memory_order_relaxed); } #ifdef ASSERT From 36d61c3106c69c019f2d4ded7dedd1649c1226b3 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 25 Apr 2023 18:10:52 +0000 Subject: [PATCH 132/288] 8306765: Some client related jtreg problem list entries are malformed Reviewed-by: iris --- test/jdk/ProblemList.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index b488180402c..34f3393440b 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -424,7 +424,7 @@ java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.j java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java 7107528 linux-all,macosx-all java/awt/Mouse/MouseDragEvent/MouseDraggedTest.java 8080676 linux-all java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersInKeyEvent.java 8157147 linux-all,windows-all,macosx-all -java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 +java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473 linux-all java/awt/Frame/DisposeParentGC/DisposeParentGC.java 8079786 macosx-all @@ -441,7 +441,7 @@ java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed. java/awt/PopupMenu/PopupMenuLocation.java 8238720 windows-all java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 windows-all java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720 windows-all -java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java +java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all # Several tests which fail sometimes on macos11 java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all From 9beae21864d18054ca3762ec989d51ff0660db84 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Tue, 25 Apr 2023 18:32:03 +0000 Subject: [PATCH 133/288] 8306718: Optimize and opensource some old AWT tests Reviewed-by: prr --- .../StoppingEdtOnPushPopTest.java | 118 ++++++++++++++++++ .../ExceptionAfterSetDirectory.java | 116 +++++++++++++++++ .../awt/FlowLayout/MinimumLayoutSize.java | 98 +++++++++++++++ .../awt/FlowLayout/PreferredLayoutSize.java | 78 ++++++++++++ 4 files changed, 410 insertions(+) create mode 100644 test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java create mode 100644 test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java create mode 100644 test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java create mode 100644 test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java diff --git a/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java b/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java new file mode 100644 index 00000000000..4186e690f0d --- /dev/null +++ b/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4848555 + @summary Popping an event queue could cause its thread to restart inadvertently + @run main StoppingEdtOnPushPopTest +*/ + +import java.awt.AWTEvent; +import java.awt.ActiveEvent; +import java.awt.EventQueue; +import java.awt.Toolkit; + +public class StoppingEdtOnPushPopTest implements Runnable { + public void start() { + int before = countEventQueues(); + try { + for (int i = 0; i < 10; i++) { + EventQueue.invokeAndWait(this); + } + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } catch (java.lang.reflect.InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException("InvocationTargetException occurred"); + } + pause(1000); + int after = countEventQueues(); + if (before < after && after > 1) { + throw new RuntimeException("Test failed (before=" + before + + "; after=" + after + ")"); + } + System.out.println("Test passed"); + } + + public void run() { + System.out.println("push/pop"); + MyEventQueue queue = new MyEventQueue(); + Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue); + Toolkit.getDefaultToolkit().getSystemEventQueue() + .postEvent(new EmptyEvent()); + queue.pop(); + } + + public int countEventQueues() { + int count = 0; + System.out.println("All threads currently running in the system"); + Thread threads[] = new Thread[Thread.activeCount()]; + Thread.enumerate(threads); + for (int i = 0; i < threads.length; ++i) { + Thread thread = threads[i]; + if (thread != null) { + System.out.println(thread.getName()); + if (thread.getName().startsWith("AWT-EventQueue")) { + count++; + } + } + } + return count; + } + + public void pause(long aMillis) { + try { + Thread.sleep(aMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } + } + + public static void main(String[] args) { + StoppingEdtOnPushPopTest test = new StoppingEdtOnPushPopTest(); + test.start(); + } +} + +class MyEventQueue extends EventQueue { + public MyEventQueue() { + super(); + } + + public void pop() { + super.pop(); + } +} + +class EmptyEvent extends AWTEvent implements ActiveEvent { + public EmptyEvent() { + super(new Object(), 0); + } + + public void dispatch() { + System.out.println("one more EmptyEvent"); + } +} diff --git a/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java b/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java new file mode 100644 index 00000000000..28d63ae6216 --- /dev/null +++ b/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6308332 + @summary FileDialog.setDirectory() throws exception on Linux & Solaris + @key headful + @run main ExceptionAfterSetDirectory +*/ + +import java.awt.AWTException; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class ExceptionAfterSetDirectory { + FileDialog fd = null; + Frame frame; + + public void start() throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ExceptionAfterSetDirectory"); + frame.setLayout(new FlowLayout()); + frame.setBounds(100, 100, 100, 100); + frame.setVisible(true); + fd = new FileDialog(frame, "file dialog", FileDialog.LOAD); + }); + + try { + test(); + } catch (Exception e) { + throw new RuntimeException("Test failed.", e); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + if (fd != null) { + EventQueue.invokeAndWait(fd::dispose);; + } + } + } + + private void test() throws InterruptedException, InvocationTargetException { + final Robot r; + + try { + r = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Can not initialize Robot.", e); + } + + r.setAutoDelay(200); + r.delay(500); + + EventQueue.invokeLater(() -> { + fd.setVisible(true); + }); + r.delay(2000); + r.waitForIdle(); + + if (System.getProperty("os.name").contains("OS X")) { + // Workaround for JDK-7186009 - try to close file dialog pressing escape + r.keyPress(KeyEvent.VK_ESCAPE); + r.keyRelease(KeyEvent.VK_ESCAPE); + r.delay(2000); + r.waitForIdle(); + } + + if (fd.isVisible()) { + EventQueue.invokeAndWait(() -> { + fd.setVisible(false); + }); + r.delay(2000); + r.waitForIdle(); + } + + // Changing directory on hidden file dialog should not cause an exception + EventQueue.invokeAndWait(() -> { + fd.setDirectory("/"); + }); + r.delay(2000); + r.waitForIdle(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ExceptionAfterSetDirectory test = new ExceptionAfterSetDirectory(); + test.start(); + } +} diff --git a/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java b/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java new file mode 100644 index 00000000000..7b79cc3317c --- /dev/null +++ b/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6257219 + @summary FlowLayout gives a wrong minimum size if the first component is hidden. + @key headful + @run main MinimumLayoutSize +*/ + + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.LayoutManager; +import java.awt.Panel; +import java.awt.Robot; +import java.lang.reflect.InvocationTargetException; + +public class MinimumLayoutSize { + Frame frame; + Button b1; + Button b2; + Panel panel; + + public void start() throws AWTException, + InterruptedException, InvocationTargetException { + try { + Robot robot = new Robot(); + LayoutManager layout = new FlowLayout(FlowLayout.LEFT, 100, 0); + final int[] widths = new int[2]; + EventQueue.invokeAndWait(() -> { + frame = new Frame("MinimumLayoutSize"); + b1 = new Button("B1"); + b2 = new Button("B2"); + panel = new Panel(); + panel.add(b2); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + //add hidden component b1 + EventQueue.invokeAndWait(() -> { + widths[0] = layout.minimumLayoutSize(panel).width; + b1.setVisible(false); + panel.add(b1, 0); + }); + robot.waitForIdle(); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + widths[1] = layout.minimumLayoutSize(panel).width; + frame.setVisible(false); + }); + System.out.println("TRACE: w1 = " + widths[0] + " w2 = " + widths[1]); + + if (widths[0] != widths[1]) { + throw new RuntimeException("Test FAILED. Minimum sizes are not equal." + + " w1 = " + widths[0] + " w2 = " + widths[1]); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + System.out.println("Test passed"); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + MinimumLayoutSize test = new MinimumLayoutSize(); + test.start(); + } +} diff --git a/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java b/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java new file mode 100644 index 00000000000..def1c044d24 --- /dev/null +++ b/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4284124 + @summary FlowLayout gives a wrong size if the first component is hidden. + @key headful + @run main PreferredLayoutSize +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class PreferredLayoutSize { + public void start() { + Frame f = new Frame("PreferredLayoutSize"); + int[] widths = new int[2]; + + try { + f.setLocationRelativeTo(null); + Button b1 = new Button("button 1"); + Button b2 = new Button("button 2"); + f.setLayout(new FlowLayout(FlowLayout.LEFT, 50, 5)); + f.add(b1); + f.add(b2); + f.pack(); + f.setVisible(true); + b1.setVisible(false); + b2.setVisible(true); + Dimension d1 = f.getPreferredSize(); + Dimension d2 = b2.getPreferredSize(); + widths[0] = d1.width - d2.width; + b1.setVisible(true); + b2.setVisible(false); + d1 = f.getPreferredSize(); + d2 = b1.getPreferredSize(); + widths[1] = d1.width - d2.width; + f.setVisible(false); + } finally { + f.dispose(); + } + + if (widths[0] != widths[1]) { + throw new RuntimeException("Test FAILED"); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PreferredLayoutSize test = new PreferredLayoutSize(); + EventQueue.invokeAndWait(test::start); + } +} From 28829f308fe6314388c9a47b91273bcf81eb806c Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 25 Apr 2023 18:46:55 +0000 Subject: [PATCH 134/288] 8306734: Shenandoah: Missing barriers on deoptimization path Reviewed-by: eosterlund, rkennke --- src/hotspot/share/runtime/stackValue.cpp | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/runtime/stackValue.cpp b/src/hotspot/share/runtime/stackValue.cpp index 9934cb060f6..b08c527dd01 100644 --- a/src/hotspot/share/runtime/stackValue.cpp +++ b/src/hotspot/share/runtime/stackValue.cpp @@ -80,7 +80,19 @@ static oop oop_from_oop_location(stackChunkOop chunk, void* addr) { } // Load oop from stack - return *(oop*)addr; + oop val = *(oop*)addr; + +#if INCLUDE_SHENANDOAHGC + if (UseShenandoahGC) { + // Pass the value through the barrier to avoid capturing bad oops as + // stack values. Note: do not heal the location, to avoid accidentally + // corrupting the stack. Stack watermark barriers are supposed to handle + // the healing. + val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val); + } +#endif + + return val; } static oop oop_from_narrowOop_location(stackChunkOop chunk, void* addr, bool is_register) { @@ -105,7 +117,19 @@ static oop oop_from_narrowOop_location(stackChunkOop chunk, void* addr, bool is_ } // Load oop from stack - return CompressedOops::decode(*narrow_addr); + oop val = CompressedOops::decode(*narrow_addr); + +#if INCLUDE_SHENANDOAHGC + if (UseShenandoahGC) { + // Pass the value through the barrier to avoid capturing bad oops as + // stack values. Note: do not heal the location, to avoid accidentally + // corrupting the stack. Stack watermark barriers are supposed to handle + // the healing. + val = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(val); + } +#endif + + return val; } StackValue* StackValue::create_stack_value_from_oop_location(stackChunkOop chunk, void* addr) { From d819debaa5f0155e5e3990fa4f919ab420610c97 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 25 Apr 2023 19:33:22 +0000 Subject: [PATCH 135/288] 8304423: Refactor FdLibm.java Reviewed-by: bpb --- .../share/classes/java/lang/FdLibm.java | 157 +++++++++--------- 1 file changed, 82 insertions(+), 75 deletions(-) diff --git a/src/java.base/share/classes/java/lang/FdLibm.java b/src/java.base/share/classes/java/lang/FdLibm.java index f712f3efc97..5410a0a1ad6 100644 --- a/src/java.base/share/classes/java/lang/FdLibm.java +++ b/src/java.base/share/classes/java/lang/FdLibm.java @@ -64,6 +64,16 @@ class FdLibm { private static final double TWO54 = 0x1.0p54; // 1.80143985094819840000e+16 private static final double HUGE = 1.0e+300; + /* + * Constants for bit-wise manipulation of IEEE 754 double + * values. These constants are for the high-order 32-bits of a + * 64-bit double value: 1 sign bit as the most significant bit, + * followed by 11 exponent bits, and then the remaining bits as + * the significand. + */ + private static final int SIGN_BIT = 0x8000_0000; + private static final int EXP_BITS = 0x7ff0_0000; + private static final int EXP_SIGNIF_BITS = 0x7fff_ffff; private FdLibm() { throw new UnsupportedOperationException("No FdLibm instances for you."); @@ -156,10 +166,10 @@ class FdLibm { ix = __HI(x); // |x| ~< pi/4 - ix &= 0x7fff_ffff; + ix &= EXP_SIGNIF_BITS; if (ix <= 0x3fe9_21fb) { return __kernel_sin(x, z, 0); - } else if (ix>=0x7ff0_0000) { // sin(Inf or NaN) is NaN + } else if (ix >= EXP_BITS) { // sin(Inf or NaN) is NaN return x - x; } else { // argument reduction needed n = RemPio2.__ieee754_rem_pio2(x, y); @@ -211,7 +221,7 @@ class FdLibm { static double __kernel_sin(double x, double y, int iy) { double z, r, v; int ix; - ix = __HI(x) & 0x7fff_ffff; // high word of x + ix = __HI(x) & EXP_SIGNIF_BITS; // high word of x if (ix < 0x3e40_0000) { // |x| < 2**-27 if ((int)x == 0) // generate inexact return x; @@ -269,11 +279,11 @@ class FdLibm { ix = __HI(x); // |x| ~< pi/4 - ix &= 0x7fff_ffff; + ix &= EXP_SIGNIF_BITS; if (ix <= 0x3fe9_21fb) { return __kernel_cos(x, z); - } else if (ix >= 0x7ff0_0000) { // cos(Inf or NaN) is NaN - return x-x; + } else if (ix >= EXP_BITS) { // cos(Inf or NaN) is NaN + return x - x; } else { // argument reduction needed n = RemPio2.__ieee754_rem_pio2(x,y); switch (n & 3) { @@ -331,7 +341,7 @@ class FdLibm { static double __kernel_cos(double x, double y) { double a, hz, z, r, qx = 0.0; int ix; - ix = __HI(x) & 0x7fff_ffff; // ix = |x|'s high word + ix = __HI(x) & EXP_SIGNIF_BITS; // ix = |x|'s high word if (ix < 0x3e40_0000) { // if x < 2**27 if (((int)x) == 0) { // generate inexact return 1.0; @@ -395,11 +405,11 @@ class FdLibm { ix = __HI(x); // |x| ~< pi/4 - ix &= 0x7fff_ffff; + ix &= EXP_SIGNIF_BITS; if (ix <= 0x3fe9_21fb) { return __kernel_tan(x, z, 1); - } else if (ix >= 0x7ff0_0000) { // tan(Inf or NaN) is NaN - return x-x; // NaN + } else if (ix >= EXP_BITS) { // tan(Inf or NaN) is NaN + return x - x; // NaN } else { // argument reduction needed n = RemPio2.__ieee754_rem_pio2(x, y); return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); // 1 -- n even; -1 -- n odd @@ -462,7 +472,7 @@ class FdLibm { double z, r, v, w, s; int ix, hx; hx = __HI(x); // high word of x - ix = hx&0x7fff_ffff; // high word of |x| + ix = hx & EXP_SIGNIF_BITS; // high word of |x| if (ix < 0x3e30_0000) { // x < 2**-28 if ((int)x == 0) { // generate inexact if (((ix | __LO(x)) | (iy + 1)) == 0) { @@ -584,7 +594,7 @@ class FdLibm { int e0, i, j, nx, n, ix, hx; hx = __HI(x); // high word of x - ix = hx & 0x7fff_ffff; + ix = hx & EXP_SIGNIF_BITS; if (ix <= 0x3fe9_21fb) { // |x| ~<= pi/4 , no need for reduction y[0] = x; y[1] = 0; @@ -655,13 +665,13 @@ class FdLibm { /* * all other (large) arguments */ - if (ix >= 0x7ff0_0000) { // x is inf or NaN + if (ix >= EXP_BITS) { // x is inf or NaN y[0] = y[1] = x - x; return 0; } - // set z = scalbn(|x|,ilogb(x)-23) + // set z = scalbn(|x|, ilogb(x)-23) z = __LO(z, __LO(x)); - e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ + e0 = (ix >> 20) - 1046; // e0 = ilogb(z) - 23; z = __HI(z, ix - (e0 << 20)); for (i=0; i < 2; i++) { tx[i] = (double)((int)(z)); @@ -859,7 +869,7 @@ class FdLibm { // compute n z = Math.scalb(z, q0); // actual value of z - z -= 8.0*Math.floor(z*0.125); // trim off integer >= 8 + z -= 8.0*Math.floor(z*0.125); // trim off integer >= 8 n = (int) z; z -= (double)n; ih = 0; @@ -1071,7 +1081,7 @@ class FdLibm { double t = 0, w, p, q, c, r, s; int hx, ix; hx = __HI(x); - ix = hx & 0x7fff_ffff; + ix = hx & EXP_SIGNIF_BITS; if (ix >= 0x3ff0_0000) { // |x| >= 1 if(((ix - 0x3ff0_0000) | __LO(x)) == 0) { // asin(1) = +-pi/2 with inexact @@ -1157,7 +1167,7 @@ class FdLibm { double z, p, q, r, w, s, c, df; int hx, ix; hx = __HI(x); - ix = hx & 0x7fff_ffff; + ix = hx & EXP_SIGNIF_BITS; if (ix >= 0x3ff0_0000) { // |x| >= 1 if (((ix - 0x3ff0_0000) | __LO(x)) == 0) { // |x| == 1 if (hx > 0) {// acos(1) = 0 @@ -1166,7 +1176,7 @@ class FdLibm { return Math.PI + 2.0*pio2_lo; } } - return (x-x)/(x-x); // acos(|x| > 1) is NaN + return (x - x)/(x - x); // acos(|x| > 1) is NaN } if (ix < 0x3fe0_0000) { // |x| < 0.5 if (ix <= 0x3c60_0000) { // if |x| < 2**-57 @@ -1255,10 +1265,10 @@ class FdLibm { int ix, hx, id; hx = __HI(x); - ix = hx & 0x7fff_ffff; + ix = hx & EXP_SIGNIF_BITS; if (ix >= 0x4410_0000) { // if |x| >= 2^66 - if (ix > 0x7ff0_0000 || - (ix == 0x7ff0_0000 && (__LO(x) != 0))) { + if (ix > EXP_BITS || + (ix == EXP_BITS && (__LO(x) != 0))) { return x+x; // NaN } if (hx > 0) { @@ -1352,10 +1362,10 @@ class FdLibm { /*unsigned*/ int lx, ly; hx = __HI(x); - ix = hx & 0x7fff_ffff; + ix = hx & EXP_SIGNIF_BITS; lx = __LO(x); hy = __HI(y); - iy = hy&0x7fff_ffff; + iy = hy & EXP_SIGNIF_BITS; ly = __LO(y); if (Double.isNaN(x) || Double.isNaN(y)) return x + y; @@ -1378,8 +1388,8 @@ class FdLibm { } // when x is INF - if (ix == 0x7ff0_0000) { - if (iy == 0x7ff0_0000) { + if (ix == EXP_BITS) { + if (iy == EXP_BITS) { switch(m) { case 0: return pi_o_4 + tiny; // atan(+INF, +INF) case 1: return -pi_o_4 - tiny; // atan(-INF, +INF) @@ -1396,7 +1406,7 @@ class FdLibm { } } // when y is INF - if (iy == 0x7ff0_0000) { + if (iy == EXP_BITS) { return (hy < 0)? -pi_o_2 - tiny : pi_o_2 + tiny; } @@ -1494,7 +1504,7 @@ class FdLibm { static double compute(double x) { double z = 0.0; - int sign = 0x8000_0000; + int sign = SIGN_BIT; /*unsigned*/ int r, t1, s1, ix1, q1; int ix0, s0, q, m, t, i; @@ -1502,7 +1512,7 @@ class FdLibm { ix1 = __LO(x); // low word of x // take care of Inf and NaN - if ((ix0 & 0x7ff0_0000) == 0x7ff0_0000) { + if ((ix0 & EXP_BITS) == EXP_BITS) { return x*x + x; // sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN } // take care of zero @@ -1510,7 +1520,7 @@ class FdLibm { if (((ix0 & (~sign)) | ix1) == 0) return x; // sqrt(+-0) = +-0 else if (ix0 < 0) - return (x-x)/(x-x); // sqrt(-ve) = sNaN + return (x - x)/(x - x); // sqrt(-ve) = sNaN } // normalize x m = (ix0 >> 20); @@ -2136,7 +2146,7 @@ class FdLibm { } final int hx = __HI(x); - int ix = hx & 0x7fffffff; + int ix = hx & EXP_SIGNIF_BITS; /* * When x < 0, determine if y is an odd integer: @@ -2176,7 +2186,7 @@ class FdLibm { // (x < 0)**(non-int) is NaN if ((n | y_is_int) == 0) - return (x-x)/(x-x); + return (x - x)/(x - x); s = 1.0; // s (sign of result -ve**odd) = -1 else = 1 if ( (n | (y_is_int - 1)) == 0) @@ -2299,7 +2309,7 @@ class FdLibm { if (p_l + OVT > z - p_h) return s * INFINITY; // Overflow } - } else if ((j & 0x7fffffff) >= 0x4090cc00 ) { // z <= -1075 + } else if ((j & EXP_SIGNIF_BITS) >= 0x4090cc00 ) { // z <= -1075 if (((j - 0xc090cc00) | i)!=0) // z < -1075 return s * 0.0; // Underflow else { @@ -2319,12 +2329,12 @@ class FdLibm { final double LG2 = 0x1.62e4_2fef_a39efp-1; // 6.93147180559945286227e-01 final double LG2_H = 0x1.62e43p-1; // 6.93147182464599609375e-01 final double LG2_L = -0x1.05c6_10ca_86c39p-29; // -1.90465429995776804525e-09 - i = j & 0x7fffffff; + i = j & EXP_SIGNIF_BITS; k = (i >> 20) - 0x3ff; n = 0; if (i > 0x3fe00000) { // if |z| > 0.5, set n = [z + 0.5] n = j + (0x00100000 >> (k + 1)); - k = ((n & 0x7fffffff) >> 20) - 0x3ff; // new k for n + k = ((n & EXP_SIGNIF_BITS) >> 20) - 0x3ff; // new k for n t = 0.0; t = __HI(t, (n & ~(0x000fffff >> k)) ); n = ((n & 0x000fffff) | 0x00100000) >> (20 - k); @@ -2449,7 +2459,7 @@ class FdLibm { hx = __HI(x); /* high word of x */ xsb = (hx >> 31) & 1; /* sign bit of x */ - hx &= 0x7fffffff; /* high word of |x| */ + hx &= EXP_SIGNIF_BITS; /* high word of |x| */ /* filter out non-finite argument */ if (hx >= 0x40862E42) { /* if |x| >= 709.78... */ @@ -2568,8 +2578,6 @@ class FdLibm { Lg6 = 0x1.39a09d078c69fp-3, // 1.531383769920937332e-01 Lg7 = 0x1.2f112df3e5244p-3; // 1.479819860511658591e-01 - private static final double zero = 0.0; - static double compute(double x) { double hfsq, f, s, z, R, w, t1, t2, dk; int k, hx, i, j; @@ -2580,17 +2588,17 @@ class FdLibm { k=0; if (hx < 0x0010_0000) { // x < 2**-1022 - if (((hx & 0x7fff_ffff) | lx) == 0) { // log(+-0) = -inf - return -TWO54/zero; + if (((hx & EXP_SIGNIF_BITS) | lx) == 0) { // log(+-0) = -inf + return -TWO54/0.0; } if (hx < 0) { // log(-#) = NaN - return (x - x)/zero; + return (x - x)/0.0; } k -= 54; x *= TWO54; // subnormal number, scale up x hx = __HI(x); // high word of x } - if (hx >= 0x7ff0_0000) { + if (hx >= EXP_BITS) { return x + x; } k += (hx >> 20) - 1023; @@ -2600,9 +2608,9 @@ class FdLibm { k += (i >> 20); f = x - 1.0; if ((0x000f_ffff & (2 + hx)) < 3) {// |f| < 2**-20 - if (f == zero) { + if (f == 0.0) { if (k == 0) { - return zero; + return 0.0; } else { dk = (double)k; return dk*ln2_hi + dk*ln2_lo; @@ -2694,7 +2702,7 @@ class FdLibm { k=0; if (hx < 0x0010_0000) { /* x < 2**-1022 */ - if (((hx & 0x7fff_ffff) | lx) == 0) { + if (((hx & EXP_SIGNIF_BITS) | lx) == 0) { return -TWO54/0.0; /* log(+-0)=-inf */ } if (hx < 0) { @@ -2705,12 +2713,12 @@ class FdLibm { hx = __HI(x); } - if (hx >= 0x7ff0_0000) { + if (hx >= EXP_BITS) { return x + x; } k += (hx >> 20) - 1023; - i = (k & 0x8000_0000) >>> 31; // unsigned shift + i = (k & SIGN_BIT) >>> 31; // unsigned shift hx = (hx & 0x000f_ffff) | ((0x3ff - i) << 20); y = (double)(k + i); x = __HI(x, hx); // replace high word of x with hx @@ -2800,7 +2808,7 @@ class FdLibm { int k, hx, hu=0, ax; hx = __HI(x); /* high word of x */ - ax = hx & 0x7fff_ffff; + ax = hx & EXP_SIGNIF_BITS; k = 1; if (hx < 0x3FDA_827A) { /* x < 0.41422 */ @@ -2826,7 +2834,7 @@ class FdLibm { } } - if (hx >= 0x7ff0_0000) { + if (hx >= EXP_BITS) { return x + x; } @@ -2977,7 +2985,6 @@ class FdLibm { * to produce the hexadecimal values shown. */ static class Expm1 { - private static final double one = 1.0; private static final double huge = 1.0e+300; private static final double tiny = 1.0e-300; private static final double o_threshold = 0x1.62e42fefa39efp9; // 7.09782712893383973096e+02 @@ -2997,9 +3004,9 @@ class FdLibm { /*unsigned*/ int hx; hx = __HI(x); // high word of x - xsb = hx & 0x8000_0000; // sign bit of x + xsb = hx & SIGN_BIT; // sign bit of x y = Math.abs(x); - hx &= 0x7fff_ffff; // high word of |x| + hx &= EXP_SIGNIF_BITS; // high word of |x| // filter out huge and non-finite argument if (hx >= 0x4043_687A) { // if |x| >= 56*ln2 @@ -3017,7 +3024,7 @@ class FdLibm { } if (xsb != 0) { // x < -56*ln2, return -1.0 with inexact if (x + tiny < 0.0) { // raise inexact - return tiny - one; // return -1 + return tiny - 1.0; // return -1 } } } @@ -3052,7 +3059,7 @@ class FdLibm { // x is now in primary range hfx = 0.5*x; hxs = x*hfx; - r1 = one + hxs*(Q1 + hxs*(Q2 + hxs*(Q3 + hxs*(Q4 + hxs*Q5)))); + r1 = 1.0 + hxs*(Q1 + hxs*(Q2 + hxs*(Q3 + hxs*(Q4 + hxs*Q5)))); t = 3.0 - r1*hfx; e = hxs *((r1 - t)/(6.0 - x*t)); if (k == 0) { @@ -3067,15 +3074,15 @@ class FdLibm { if (x < -0.25) { return -2.0*(e - (x + 0.5)); } else { - return one + 2.0*(x - e); + return 1.0 + 2.0*(x - e); } } if (k <= -2 || k > 56) { // suffice to return exp(x) - 1 - y = one - (e - x); + y = 1.0 - (e - x); y = __HI(y, __HI(y) + (k << 20)); // add k to y's exponent - return y - one; + return y - 1.0; } - t = one; + t = 1.0; if (k < 20) { t = __HI(t, 0x3ff0_0000 - (0x2_00000 >> k)); // t = 1-2^-k y = t - ( e - x); @@ -3083,7 +3090,7 @@ class FdLibm { } else { t = __HI(t, ((0x3ff - k) << 20)); // 2^-k y = x - (e + t); - y += one; + y += 1.0; y = __HI(y, __HI(y) + (k << 20)); // add k to y's exponent } } @@ -3120,10 +3127,10 @@ class FdLibm { // High word of |x| jx = __HI(x); - ix = jx & 0x7fff_ffff; + ix = jx & EXP_SIGNIF_BITS; // x is INF or NaN - if (ix >= 0x7ff0_0000) { + if (ix >= EXP_BITS) { return x + x; } @@ -3196,10 +3203,10 @@ class FdLibm { // High word of |x| ix = __HI(x); - ix &= 0x7fff_ffff; + ix &= EXP_SIGNIF_BITS; // x is INF or NaN - if (ix >= 0x7ff0_0000) { + if (ix >= EXP_BITS) { return x*x; } @@ -3273,10 +3280,10 @@ class FdLibm { // High word of |x|. jx = __HI(x); - ix = jx & 0x7fff_ffff; + ix = jx & EXP_SIGNIF_BITS; // x is INF or NaN - if (ix >= 0x7ff0_0000) { + if (ix >= EXP_BITS) { if (jx >= 0) { // tanh(+-inf)=+-1 return 1.0/x + 1.0; } else { // tanh(NaN) = NaN @@ -3314,17 +3321,17 @@ class FdLibm { lx = __LO(x); // low word of x hp = __HI(p); // high word of p lp = __LO(p); // low word of p - sx = hx & 0x8000_0000; - hp &= 0x7fff_ffff; - hx &= 0x7fff_ffff; + sx = hx & SIGN_BIT; + hp &= EXP_SIGNIF_BITS; + hx &= EXP_SIGNIF_BITS; // purge off exception values if ((hp | lp) == 0) {// p = 0 return (x*p)/(x*p); } - if ((hx >= 0x7ff0_0000) || // not finite - ((hp >= 0x7ff0_0000) && // p is NaN - (((hp - 0x7ff0_0000) | lp) != 0))) + if ((hx >= EXP_BITS) || // not finite + ((hp >= EXP_BITS) && // p is NaN + (((hp - EXP_BITS) | lp) != 0))) return (x*p)/(x*p); if (hp <= 0x7fdf_ffff) { // now x < 2p @@ -3362,13 +3369,13 @@ class FdLibm { lx = __LO(x); // low word of x hy = __HI(y); // high word of y ly = __LO(y); // low word of y - sx = hx & 0x8000_0000; // sign of x + sx = hx & SIGN_BIT; // sign of x hx ^= sx; // |x| - hy &= 0x7fff_ffff; // |y| + hy &= EXP_SIGNIF_BITS; // |y| // purge off exception values - if ((hy | ly) == 0 || (hx >= 0x7ff0_0000)|| // y = 0, or x not finite - ((hy | ((ly | -ly) >>> 31)) > 0x7ff0_0000)) // or y is NaN, unsigned shift + if ((hy | ly) == 0 || (hx >= EXP_BITS)|| // y = 0, or x not finite + ((hy | ((ly | -ly) >>> 31)) > EXP_BITS)) // or y is NaN, unsigned shift return (x*y)/(x*y); if (hx <= hy) { if ((hx < hy) || (Integer.compareUnsigned(lx, ly) < 0)) { // |x| < |y| return x From e3ccaa6541e98aaa57b31a05cb998d48a0f7ee87 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Tue, 25 Apr 2023 20:18:19 +0000 Subject: [PATCH 136/288] 8306623: (bf) CharBuffer::allocate throws unexpected exception type with some CharSequences Reviewed-by: alanb, lancea --- .../classes/java/nio/X-Buffer.java.template | 11 ++++++- .../jdk/java/nio/Buffer/Basic-X.java.template | 32 ++++++++++++++++++- test/jdk/java/nio/Buffer/Basic.java | 4 +-- test/jdk/java/nio/Buffer/BasicChar.java | 32 ++++++++++++++++++- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/nio/X-Buffer.java.template b/src/java.base/share/classes/java/nio/X-Buffer.java.template index 6c496667d25..1261e325515 100644 --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -2045,8 +2045,17 @@ public abstract sealed class $Type$Buffer */ public $Type$Buffer append(CharSequence csq, int start, int end) { if (csq instanceof CharBuffer cb) { - int pos = position(); + // + // the append method throws BufferOverflowException when + // there is insufficient space in the buffer + // int length = end - start; + int pos = position(); + int lim = limit(); + int rem = (pos <= lim) ? lim - pos : 0; + if (length > rem) + throw new BufferOverflowException(); + put(pos, cb, start, length); position(pos + length); return this; diff --git a/test/jdk/java/nio/Buffer/Basic-X.java.template b/test/jdk/java/nio/Buffer/Basic-X.java.template index 0c328c89baf..25ba1e2e26d 100644 --- a/test/jdk/java/nio/Buffer/Basic-X.java.template +++ b/test/jdk/java/nio/Buffer/Basic-X.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -627,6 +627,36 @@ public class Basic$Type$ absBulkGet(b); #if[char] + // 8306623 + String str = "in violet night walking beneath a reign of uncouth stars"; + char[] chars = str.toCharArray(); + int cslen = chars.length; + CharSequence[] csqs = new CharSequence[] { + str, + new StringBuffer(str), + new StringBuilder(str), + CharBuffer.wrap(chars), + ByteBuffer.allocateDirect(2*chars.length).asCharBuffer() + }; + + int[][] bounds = new int[][] { + {-1, cslen}, // negative start + {0, -1}, // negative end + {1, 0}, // start > end + {cslen/2, cslen + 1} // end > cslen + }; + + for (CharSequence csq : csqs) { + // append() should throw BufferOverflowException + tryCatch(b, BufferOverflowException.class, () -> + CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2)); + + // append() should throw IndexOutOfBoundsException + for (int[] bds : bounds) + tryCatch(b, IndexOutOfBoundsException.class, () -> + CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1])); + } + // end 8306623 bulkPutString(b); relGet(b); diff --git a/test/jdk/java/nio/Buffer/Basic.java b/test/jdk/java/nio/Buffer/Basic.java index 90d5ec943ab..6bdf901012b 100644 --- a/test/jdk/java/nio/Buffer/Basic.java +++ b/test/jdk/java/nio/Buffer/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,7 +26,7 @@ * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431 * 5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219 - * 7199551 8065556 8149469 8230665 8237514 + * 7199551 8065556 8149469 8230665 8237514 8306623 * @modules java.base/java.nio:open * java.base/jdk.internal.misc * @author Mark Reinhold diff --git a/test/jdk/java/nio/Buffer/BasicChar.java b/test/jdk/java/nio/Buffer/BasicChar.java index 08c247841ef..58cbd0799ec 100644 --- a/test/jdk/java/nio/Buffer/BasicChar.java +++ b/test/jdk/java/nio/Buffer/BasicChar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -627,6 +627,36 @@ public class BasicChar absBulkGet(b); + // 8306623 + String str = "in violet night walking beneath a reign of uncouth stars"; + char[] chars = str.toCharArray(); + int cslen = chars.length; + CharSequence[] csqs = new CharSequence[] { + str, + new StringBuffer(str), + new StringBuilder(str), + CharBuffer.wrap(chars), + ByteBuffer.allocateDirect(2*chars.length).asCharBuffer() + }; + + int[][] bounds = new int[][] { + {-1, cslen}, // negative start + {0, -1}, // negative end + {1, 0}, // start > end + {cslen/2, cslen + 1} // end > cslen + }; + + for (CharSequence csq : csqs) { + // append() should throw BufferOverflowException + tryCatch(b, BufferOverflowException.class, () -> + CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2)); + + // append() should throw IndexOutOfBoundsException + for (int[] bds : bounds) + tryCatch(b, IndexOutOfBoundsException.class, () -> + CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1])); + } + // end 8306623 bulkPutString(b); relGet(b); From b372f28ad4b7c1f46e0070a930911542d4d1a032 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Tue, 25 Apr 2023 20:25:16 +0000 Subject: [PATCH 137/288] 8306753: Open source several container AWT tests Reviewed-by: prr --- .../awt/Container/FindComponentAtTest.java | 86 +++ .../java/awt/Container/FindComponentTest.java | 90 ++++ .../FocusTraversalPolicyProviderTest.java | 509 ++++++++++++++++++ .../awt/Container/PropertyEventsTest.java | 129 +++++ 4 files changed, 814 insertions(+) create mode 100644 test/jdk/java/awt/Container/FindComponentAtTest.java create mode 100644 test/jdk/java/awt/Container/FindComponentTest.java create mode 100644 test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java create mode 100644 test/jdk/java/awt/Container/PropertyEventsTest.java diff --git a/test/jdk/java/awt/Container/FindComponentAtTest.java b/test/jdk/java/awt/Container/FindComponentAtTest.java new file mode 100644 index 00000000000..f9c9f1bed0c --- /dev/null +++ b/test/jdk/java/awt/Container/FindComponentAtTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4311614 + @summary findComponentAt() should check for isShowing() instead of isVisible() + @key headful +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; + +public class FindComponentAtTest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + Panel aContainer; + Panel bContainer; + Panel cContainer; + Button button = new Button("button4"); + Frame frame = new Frame("FindComponentAtTest"); + + try { + aContainer = new Panel(); + bContainer = new Panel(); + cContainer = new Panel(); + aContainer.setName("ACONT"); + bContainer.setName("BCONT"); + + frame.add(aContainer); + + aContainer.add(bContainer); + bContainer.add(cContainer); + cContainer.add(button); + + bContainer.setVisible(false); + + frame.setSize(200, 200); + frame.setVisible(true); + frame.validate(); + + System.out.println("Test set for FindComponentAt() method."); + System.out.println("aContainer - visible"); + System.out.println("bContainer - child of aContainer - is invisible"); + System.out.println("cContainer - child of bContainer - is visible"); + System.out.println("button4 - child of cContainer - is visible"); + Component comp = cContainer.findComponentAt( + cContainer.getWidth() / 2, + cContainer.getHeight() / 2); + + if (comp != null) { + throw new RuntimeException( + "cContainer: Visible component inserted into " + + "invisible container have found " + + "by findComponentAt(x, y) method"); + } + } finally { + frame.dispose(); + } + System.out.println("FindComponentAt Test Succeeded."); + }); + } +} diff --git a/test/jdk/java/awt/Container/FindComponentTest.java b/test/jdk/java/awt/Container/FindComponentTest.java new file mode 100644 index 00000000000..5721c6d29b5 --- /dev/null +++ b/test/jdk/java/awt/Container/FindComponentTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4196100 + @summary Make sure findComponentAt() only returns visible components. + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import javax.swing.JFrame; +import javax.swing.JTabbedPane; +import javax.swing.JPanel; + +public class FindComponentTest { + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + FindComponentFrame findComponentAtTest = new FindComponentFrame(); + + try { + if (!findComponentAtTest.didItWork()) { + throw new RuntimeException( + "findComponentAt() returned non-visible component"); + } + } finally { + findComponentAtTest.dispose(); + } + }); + } +} + + +class FindComponentFrame extends JFrame { + public FindComponentFrame() { + super("FindComponentFrame"); + } + + public boolean didItWork() { + setTitle("FindComponentTest"); + setSize(new Dimension(200, 200)); + + JTabbedPane tabbedpane = new JTabbedPane(); + setContentPane(tabbedpane); + + JPanel panel1 = new JPanel(); + panel1.setName("Panel 1"); + panel1.setLayout(new BorderLayout()); + tabbedpane.add(panel1); + JPanel subPanel = new JPanel(); + subPanel.setName("Sub-Panel"); + subPanel.setBackground(Color.green); + panel1.add(subPanel); // add sub panel to 1st tab + + JPanel panel2 = new JPanel(); + panel2.setName("Panel 2"); + tabbedpane.add(panel2); + + tabbedpane.setSelectedIndex(1); // display 2nd tab + setVisible(true); + + boolean success = tabbedpane.findComponentAt(50,50) + .getName().equals("Panel 2"); + return success; + } +} diff --git a/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java b/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java new file mode 100644 index 00000000000..1bc55aad2b2 --- /dev/null +++ b/test/jdk/java/awt/Container/FocusTraversalPolicyProviderTest.java @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for ability of FocusTraversalPolicyProvider + @key headful +*/ + +import java.awt.Button; +import java.awt.Component; +import java.awt.Container; +import java.awt.ContainerOrderFocusTraversalPolicy; +import java.awt.DefaultFocusTraversalPolicy; +import java.awt.EventQueue; +import java.awt.FocusTraversalPolicy; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.Window; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.LayoutFocusTraversalPolicy; + +public class FocusTraversalPolicyProviderTest { + final String errorOrderMessage = "Test Failed. Traversal Order not correct."; + final String successStage = "Test stage completed.Passed."; + + final int n_buttons = 4; + final int jumps = 3 * n_buttons; + Container[] cycle_roots = new Container[3]; + Panel[] a_conts = new Panel[cycle_roots.length]; + Panel[] b_conts = new Panel[cycle_roots.length]; + Component[][] a_buttons = new Component[cycle_roots.length][n_buttons]; + Component[][] b_buttons = new Component[cycle_roots.length][n_buttons]; + + static volatile Frame mainFrame = null; + static volatile Frame frame = null; + static volatile JFrame jframe = null; + + static Robot robot; + + public static void main(String[] args) throws Exception { + FocusTraversalPolicyProviderTest test + = new FocusTraversalPolicyProviderTest(); + try { + robot = new Robot(); + EventQueue.invokeAndWait(test::init); + robot.delay(1000); + EventQueue.invokeAndWait(test::testStages); + + EventQueue.invokeAndWait(test::initSwingContInFrame); + robot.delay(1000); + EventQueue.invokeAndWait(test::testSwingContInFrame); + // test for Swing container in java.awt.Frame + System.out.println("Test passed."); + } finally { + EventQueue.invokeAndWait(() -> { + if (mainFrame != null) mainFrame.dispose(); + if (frame != null) frame.dispose(); + if (jframe != null) jframe.dispose(); + }); + } + } + + public void init() { + mainFrame = new Frame("FocusTraversalPolicyProviderTest - main"); + mainFrame.setSize(400, 400); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + + for (int i = 0; i < cycle_roots.length; i++) { + cycle_roots[i] = new Panel(); + cycle_roots[i].setFocusable(false); + cycle_roots[i].setName("root" + i); + cycle_roots[i].setFocusCycleRoot(true); + cycle_roots[i].setLayout (new GridLayout(1, 2)); + mainFrame.add(cycle_roots[i]); + + a_conts[i] = new Panel(); + a_conts[i].setName("ac" + i); + a_conts[i].setFocusable(false); + cycle_roots[i].add(a_conts[i]); + + b_conts[i] = new Panel(); + b_conts[i].setName("bc" + i); + b_conts[i].setFocusable(false); + cycle_roots[i].add(b_conts[i]); + + for (int j = 0; j < n_buttons; j++){ + String name = "a" + i + "x" + j; + a_buttons[i][j] = new Button(name); + a_buttons[i][j].setName(name); + a_conts[i].add(a_buttons[i][j]); + } + + for (int j = 0; j < n_buttons; j++){ + String name = "b" + i + "x" + j; + b_buttons[i][j] = new Button(name); + b_buttons[i][j].setName(name); + b_conts[i].add(b_buttons[i][j]); + } + } + + cycle_roots[0].setFocusTraversalPolicy(new DefaultFocusTraversalPolicy()); + cycle_roots[1].setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); + cycle_roots[2].setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); + } + + public void testStages() { + for (int i = 0; i < cycle_roots.length; i++) { + testStage(cycle_roots[i], a_conts[i], b_conts[i], + a_buttons[i], b_buttons[i]); + } + } + + void testStage(Container aFCR, Container aCont, Container bCont, + Component[] a_comps, Component[] b_comps) { + System.out.println("focus cycle root = " + aFCR.getName()); + System.out.println("policy = " + aFCR.getFocusTraversalPolicy()); + System.out.println("aContainer = " + aCont.getName()); + System.out.println("bContainer = " + bCont.getName()); + System.out.println("Both containers are not Providers."); + + Component[] a_comps_backward = revertArray(a_comps); + Component[] b_comps_backward = revertArray(b_comps); + + testForwardStage(aFCR, aCont, bCont, + false, a_comps, false, b_comps); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + false, b_comps_backward); + + System.out.println("Both containers are Providers."); + testForwardStage(aFCR, aCont, bCont, + true, a_comps, true, b_comps); + testForwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps), + true, shakeArray(b_comps)); + + testBackwardStage(aFCR, aCont, bCont, + true, a_comps_backward, + true, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps_backward), + true, shakeArray(b_comps_backward)); + + System.out.println("aContainer.isProvider = true. " + + "bContainer.isProvider = false."); + testForwardStage(aFCR, aCont, bCont, + true, a_comps, false, b_comps); + testForwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps), + false, b_comps); + testBackwardStage(aFCR, aCont, bCont, + true, a_comps_backward, + false, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + true, shakeArray(a_comps_backward), + false, b_comps_backward); + + System.out.println("aContainer.isProvider = false. " + + "bContainer.isProvider = true."); + testForwardStage(aFCR, aCont, bCont, + false, a_comps, + true, b_comps); + testForwardStage(aFCR, aCont, bCont, + false, a_comps, + true, shakeArray(b_comps)); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + true, b_comps_backward); + testBackwardStage(aFCR, aCont, bCont, + false, a_comps_backward, + true, shakeArray(b_comps_backward)); + + System.out.println("Stage completed."); + } + + public void printGoldOrder(Component[] comps) { + String goldOrderStr = ""; + for (int i =0;i < jumps; i++){ + goldOrderStr += " " + comps[i].getName(); + } + System.out.println("GoldOrder: " + goldOrderStr); + } + + public void testForwardStage(Container focusCycleRoot, + Container aContainer, + Container bContainer, + boolean aProvider, Component[] aComps, + boolean bProvider, Component[] bComps) { + System.out.println("test forward traversal"); + System.out.println("\taProvider = " + aProvider); + System.out.println("\tbProvider = " + bProvider); + Component[] goldOrder = new Component[2*aComps.length + bComps.length]; + System.arraycopy(aComps, 0, goldOrder, 0, aComps.length); + System.arraycopy(bComps, 0, goldOrder, + aComps.length, bComps.length); + System.arraycopy(aComps, 0, goldOrder, + aComps.length + bComps.length, + aComps.length); + printGoldOrder(goldOrder); + + String jumpStr = ""; + aContainer.setFocusTraversalPolicyProvider(aProvider); + aContainer.setFocusTraversalPolicy( + new ArrayOrderFocusTraversalPolicy(aContainer, aComps)); + bContainer.setFocusTraversalPolicyProvider(bProvider); + bContainer.setFocusTraversalPolicy( + new ArrayOrderFocusTraversalPolicy(bContainer, bComps)); + FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy(); + System.out.println("policy=" + policy); + Component current = policy.getFirstComponent(focusCycleRoot); + + for (int i = 0;i= 0) { + return comps[current_index]; + } + + if (focusCycleRoot.isFocusCycleRoot()) { + return getLastComponent(focusCycleRoot); + } else { + return null; + } + } + + public Component getFirstComponent(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + return comps[0]; + } + + public Component getLastComponent(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + return comps[comps.length - 1]; + } + + public Component getDefaultComponent(Container focusCycleRoot) { + return getFirstComponent(focusCycleRoot); + } + + public Component getInitialComponent(Window window) { + throw new UnsupportedOperationException("getInitialComponent() is not supported."); + } + + public Component[] getCycle(Container focusCycleRoot) { + checkContainer(focusCycleRoot); + Component[] temp = new Component[comps.length]; + System.arraycopy(comps, 0, temp, 0, comps.length); + return temp; + } +} diff --git a/test/jdk/java/awt/Container/PropertyEventsTest.java b/test/jdk/java/awt/Container/PropertyEventsTest.java new file mode 100644 index 00000000000..162228251fe --- /dev/null +++ b/test/jdk/java/awt/Container/PropertyEventsTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for ability of FocusTraversalPolicyProvider +*/ + +import java.awt.Container; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class PropertyEventsTest implements PropertyChangeListener { + final String PROPERTY = "focusTraversalPolicyProvider"; + + + public static void main(String[] args) throws Exception { + new PropertyEventsTest().start(); + } + + public void start () { + Container c1 = new Container(); + c1.addPropertyChangeListener(PROPERTY, this); + + assertEquals("Container shouldn't be a provider by default", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(false, true); + c1.setFocusTraversalPolicyProvider(true); + assertEventOccured(); + assertEquals("Policy provider property was not set.", + true, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(true, false); + c1.setFocusTraversalPolicyProvider(false); + assertEventOccured(); + assertEquals("Policy provider property was not reset.", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(false, true); + c1.setFocusCycleRoot(true); + assertEventMissed(); + assertEquals("Cycle root shouldn't be a policy provider.", + false, c1.isFocusTraversalPolicyProvider()); + + prepareForEvent(true, false); + c1.setFocusCycleRoot(false); + assertEventMissed(); + assertEquals("setFocusCycleRoot(false) should reset " + + "policy provider property.", + false, c1.isFocusTraversalPolicyProvider()); + + System.out.println("Test passed."); + }// start() + + void assertEquals(String msg, boolean expected, boolean actual) { + if (expected != actual) { + Assert(msg + "(expected=" + expected + ", actual=" + actual + ")"); + } + } + + void assertEquals(String msg, Object expected, Object actual) { + if ((expected != null && !expected.equals(actual)) + || (actual != null && !actual.equals(expected))) + { + Assert(msg + "(expected=" + expected + ", actual=" + actual + ")"); + } + } + + void Assert(String msg) { + throw new RuntimeException(msg); + } + + void prepareForEvent(boolean old_val, boolean new_val) { + property_change_fired = false; + expected_new_value = Boolean.valueOf(new_val); + expected_old_value = Boolean.valueOf(old_val); + } + + void assertEventOccured() { + if (!property_change_fired) { + Assert("Property Change Event missed."); + } + } + + void assertEventMissed() { + if (property_change_fired) { + Assert("Unexpected property change event."); + } + } + + boolean property_change_fired; + Boolean expected_new_value; + Boolean expected_old_value; + + public void propertyChange(PropertyChangeEvent e) { + System.out.println("PropertyChangeEvent[property=" + e.getPropertyName() + + ", new=" + e.getNewValue() + + ", old=" + e.getOldValue() + "]"); + + assertEquals("Wrong proeprty name.", + PROPERTY, e.getPropertyName()); + assertEquals("Wrong new value.", + expected_new_value, e.getNewValue()); + assertEquals("Wrong old value.", + expected_old_value, e.getOldValue()); + property_change_fired = true; + } +} From 1c2dadc31e8b732d43df5494437720bfbc3f5c8b Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Tue, 25 Apr 2023 20:26:45 +0000 Subject: [PATCH 138/288] 8306683: Open source several clipboard and color AWT tests Reviewed-by: prr --- .../java/awt/Clipboard/DelayedQueryTest.java | 252 ++++++++++++++++++ .../java/awt/Clipboard/NullContentsTest.java | 58 ++++ .../Clipboard/SerializeLocalFlavorTest.java | 198 ++++++++++++++ .../ColorClass/ColorSerializationTest.java | 62 +++++ 4 files changed, 570 insertions(+) create mode 100644 test/jdk/java/awt/Clipboard/DelayedQueryTest.java create mode 100644 test/jdk/java/awt/Clipboard/NullContentsTest.java create mode 100644 test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java create mode 100644 test/jdk/java/awt/ColorClass/ColorSerializationTest.java diff --git a/test/jdk/java/awt/Clipboard/DelayedQueryTest.java b/test/jdk/java/awt/Clipboard/DelayedQueryTest.java new file mode 100644 index 00000000000..857a6f79707 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/DelayedQueryTest.java @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4085183 8000630 + @summary tests that clipboard contents is retrieved even if the app didn't + receive native events for a long time. + @requires (os.family != "mac") + @key headful + @run main DelayedQueryTest +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.InputEvent; +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; + +public class DelayedQueryTest implements ClipboardOwner, Runnable { + int returnCode = Child.CHILD_RETURN_CODE_NOT_READY; + + Process childProcess = null; + Frame frame; + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + String osName = System.getProperty("os.name"); + if (osName.toLowerCase().contains("os x")) { + System.out.println("This test is not for MacOS, considered passed."); + return; + } + DelayedQueryTest delayedQueryTest = new DelayedQueryTest(); + EventQueue.invokeAndWait(delayedQueryTest::initAndShowGui); + try { + delayedQueryTest.start(); + } finally { + EventQueue.invokeAndWait(() -> delayedQueryTest.frame.dispose()); + } + } + + public void initAndShowGui(){ + frame = new Frame("DelayedQueryTest"); + frame.add(new Panel()); + frame.setBounds(200,200, 200, 200); + frame.setVisible(true); + } + + public void start() { + try { + Robot robot = new Robot(); + // Some mouse activity to update the Xt time stamp at + // the parent process. + robot.delay(1000); + robot.waitForIdle(); + + Point p = frame.getLocationOnScreen(); + robot.mouseMove(p.x + 100, p.y + 100); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } catch (AWTException e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + Child.sysClipboard.setContents(Child.transferable, this); + + String javaPath = System.getProperty("java.home", ""); + String[] command = { + javaPath + File.separator + "bin" + File.separator + "java", + "-cp", System.getProperty("test.classes", "."), + "Child" + }; + + try { + Process process = Runtime.getRuntime().exec(command); + childProcess = process; + returnCode = process.waitFor(); + childProcess = null; + + InputStream errorStream = process.getErrorStream(); + int count = errorStream.available(); + if (count > 0) { + byte[] b = new byte[count]; + errorStream.read(b); + System.err.println("========= Child VM System.err ========"); + System.err.print(new String(b)); + System.err.println("======================================"); + } + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException("The test failed."); + } + if (returnCode != Child.CHILD_RETURN_CODE_OK) { + System.err.println("Child VM: returned " + returnCode); + throw new RuntimeException("The test failed."); + } + } // start() + + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + // At this moment the child process has definitely started. + // So we can try to retrieve the clipboard contents set + // by the child process. + new Thread(this).start(); + } + + public void run() { + // We are going to check if it is possible to retrieve the data + // after the child process has set the clipboard contents twice, + // since after the first setting the retrieval is always successful. + // So we wait to let the child process set the clipboard contents + // twice. + try { + Thread.sleep(Child.CHILD_SELECTION_CHANGE_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + String s = (String)Child.sysClipboard + .getContents(null) + .getTransferData(DataFlavor.stringFlavor); + if (!"String".equals(s)) { + System.err.println("Data retrieved: " + s); + throw new RuntimeException("Retrieved data is incorrect."); + } + } catch (Exception e) { + e.printStackTrace(); + if (childProcess != null) { + childProcess.destroy(); + childProcess = null; + } + throw new RuntimeException("Failed to retrieve the data."); + } + Child.sysClipboard.setContents(Child.transferable, null); + } +} + +class Child { + static final Clipboard sysClipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + static final Transferable transferable = new StringSelection("String"); + + /* + * Timeouts. + */ + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int PARENT_TIME_STAMP_TIMEOUT = 1000; + static final int CHILD_SELECTION_CHANGE_TIMEOUT = + FRAME_ACTIVATION_TIMEOUT + PARENT_TIME_STAMP_TIMEOUT + 5000; + static final int PARENT_RETRIEVE_DATA_TIMEOUT = 10000; + + /* + * Child process return codes. + */ + static final int CHILD_RETURN_CODE_NOT_READY = -1; + static final int CHILD_RETURN_CODE_OK = 0; + static final int CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION = 1; + static final int CHILD_RETURN_CODE_OTHER_FAILURE = 2; + static Button button; + + static void initAndShowGui() { + final Frame frame = new Frame(); + button = new Button("button"); + frame.add(button); + frame.pack(); + frame.setLocation(100, 100); + frame.setVisible(true); + } + + public static void main(String[] args) { + sysClipboard.setContents( + new StringSelection("First String"), null); + + // Some mouse activity to update the Xt time stamp at + // the child process. + try { + EventQueue.invokeAndWait(Child::initAndShowGui); + try { + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + + Robot robot = new Robot(); + robot.waitForIdle(); + + Point p = button.getLocationOnScreen(); + robot.mouseMove(p.x + 10, p.y + 10); + // Wait to let the Xt time stamp become out-of-date. + try { + Thread.sleep(PARENT_TIME_STAMP_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } catch (Exception e) { + e.printStackTrace(); + System.exit(CHILD_RETURN_CODE_UNEXPECTED_EXCEPTION); + } + + sysClipboard.setContents(transferable, new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + System.exit(CHILD_RETURN_CODE_OK); + } + }); + // Wait to let the parent process retrieve the data. + try { + Thread.sleep(PARENT_RETRIEVE_DATA_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // Parent failed to set clipboard contents, so we signal test failure + System.exit(CHILD_RETURN_CODE_OTHER_FAILURE); + } +} diff --git a/test/jdk/java/awt/Clipboard/NullContentsTest.java b/test/jdk/java/awt/Clipboard/NullContentsTest.java new file mode 100644 index 00000000000..6d4031b49eb --- /dev/null +++ b/test/jdk/java/awt/Clipboard/NullContentsTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4378007 4250859 + @summary Verifies that setting the contents of the system Clipboard to null + throws a NullPointerException + @key headful + @run main NullContentsTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +public class NullContentsTest { + + public static void main(String[] args) { + // Clipboard.setContents(null, foo) should throw an NPE, but + // Clipboard.setContents(bar, foo), where bar.getTransferData(baz) + // returns null, should not. + Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); + try { + clip.setContents(null, null); + } catch (NullPointerException e) { + StringSelection ss = new StringSelection(null); + try { + clip.setContents(ss, null); + } catch (NullPointerException ee) { + throw new RuntimeException("test failed: null transfer data"); + } + System.err.println("test passed"); + return; + } + throw new RuntimeException("test failed: null Transferable"); + } +} diff --git a/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java b/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java new file mode 100644 index 00000000000..90b9f0cd305 --- /dev/null +++ b/test/jdk/java/awt/Clipboard/SerializeLocalFlavorTest.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4696186 + @summary tests that NotSerializableException is not printed in the console if + non-serializable object with DataFlavor.javaJVMLocalObjectMimeType + is set into the clipboard + @key headful + @run main SerializeLocalFlavorTest +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.InputStream; +import java.io.Serializable; + + +public class SerializeLocalFlavorTest { + private boolean failed = false; + + public static void main(String[] args) { + new SerializeLocalFlavorTest().start(); + } + + public void start () { + try { + String[] command = { + System.getProperty("java.home", "") + + File.separator + "bin" + File.separator + + "java", + "-cp", + System.getProperty("test.classes", "."), + "Child" + }; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + if (pres.stderr.indexOf("java.io.NotSerializableException") >= 0) { + failed = true; + } + + } catch (Exception e) { + e.printStackTrace(); + } + + if (failed) { + throw new RuntimeException( + "The test failed: java.io.NotSerializableException printed!"); + } else { + System.err.println("The test passed!"); + } + } +} + +class Child { + public static void main (String [] args) throws Exception { + NotSerializableLocalTransferable t = + new NotSerializableLocalTransferable(new NotSer()); + Toolkit.getDefaultToolkit() + .getSystemClipboard().setContents(t, null); + } +} + +class NotSerializableLocalTransferable implements Transferable { + public final DataFlavor flavor; + + private final DataFlavor[] flavors; + + private final Object data; + + + public NotSerializableLocalTransferable(Object data) throws Exception { + this.data = data; + flavor = new DataFlavor( + DataFlavor.javaJVMLocalObjectMimeType + + ";class=" + "\"" + data.getClass().getName() + "\""); + this.flavors = new DataFlavor[] { flavor }; + } + + public DataFlavor[] getTransferDataFlavors() { + return flavors.clone(); + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return this.flavor.equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException + { + if (this.flavor.equals(flavor)) { + return (Object)data; + } + throw new UnsupportedFlavorException(flavor); + } + +} + +class NotSer implements Serializable { + private Object field = new Object(); // not serializable field +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff --git a/test/jdk/java/awt/ColorClass/ColorSerializationTest.java b/test/jdk/java/awt/ColorClass/ColorSerializationTest.java new file mode 100644 index 00000000000..b0e661b3cfb --- /dev/null +++ b/test/jdk/java/awt/ColorClass/ColorSerializationTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 4330102 + @summary Tests that Color object is serializable + @run main ColorSerializationTest +*/ + +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.IndexColorModel; +import java.io.ObjectOutputStream; +import java.io.ByteArrayOutputStream; + +public class ColorSerializationTest { + + public static void main(String[] args) { + java.awt.Color cobj = new java.awt.Color(255, 255, 255); + try { + cobj.createContext( + new IndexColorModel( + 8, 1, + new byte[]{0}, new byte[]{0}, new byte[]{0}), + new Rectangle(1, 1, 2, 3), + new Rectangle(3, 3), + new AffineTransform(), + new RenderingHints(null)); + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + ObjectOutputStream objos = new ObjectOutputStream(ostream); + objos.writeObject(cobj); + objos.close(); + System.out.println("Test PASSED"); + } catch (java.io.IOException e) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED: Color is not serializable: " + e.getMessage()); + } + + } +} From 88d9ebf8e80eeead3e4a1494ba537530c16b75e1 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Tue, 25 Apr 2023 20:27:34 +0000 Subject: [PATCH 139/288] 8306752: Open source several container and component AWT tests Reviewed-by: prr --- .../java/awt/Component/GetListenersTest.java | 376 ++++++++++++++++++ .../Container/OpenedPopupFrameDisposal.java | 127 ++++++ .../Container/RemoveByIndexExceptionTest.java | 56 +++ .../Container/ShowingChangedEventTest.java | 105 +++++ 4 files changed, 664 insertions(+) create mode 100644 test/jdk/java/awt/Component/GetListenersTest.java create mode 100644 test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java create mode 100644 test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java create mode 100644 test/jdk/java/awt/Container/ShowingChangedEventTest.java diff --git a/test/jdk/java/awt/Component/GetListenersTest.java b/test/jdk/java/awt/Component/GetListenersTest.java new file mode 100644 index 00000000000..f10a1c3a849 --- /dev/null +++ b/test/jdk/java/awt/Component/GetListenersTest.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4240721 + @summary Test Component.getListeners API added in 1.3 + @key headful + @run main GetListenersTest + */ + +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentListener; +import java.awt.event.ContainerAdapter; +import java.awt.event.ContainerListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusListener; +import java.awt.event.HierarchyBoundsAdapter; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.InputMethodEvent; +import java.awt.event.InputMethodListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.event.WindowListener; +import java.awt.event.WindowStateListener; +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Method; +import java.util.EventListener; + +public class GetListenersTest { + + public static void main(String args[]) throws Exception { + EventQueue.invokeAndWait(()-> { + // Create frame with a bunch of components + // and test that each component returns + // the right type of listeners from Component.getListeners + GLTFrame gltFrame = new GLTFrame(); + try { + gltFrame.initAndShowGui(); + gltFrame.test(); + } catch (Exception e) { + throw new RuntimeException("Test failed", e); + } finally { + gltFrame.dispose(); + } + }); + } + + /* + * Checks an object has a listener for every support listener type + */ + static void checkForListenersOfEveryType(Object object) throws Exception { + Class type = object.getClass(); + + BeanInfo info = Introspector.getBeanInfo(type); + EventSetDescriptor esets[] = info.getEventSetDescriptors(); + + // ensure there are listeners for every type + for (int nset = 0; nset < esets.length; nset++) { + Class listenerType = esets[nset].getListenerType(); + EventListener listener[] = getListeners(object, listenerType); + // Skip PropertyChangeListener for now + if (listener.length == 0 && validListenerToTest(listenerType)) { + throw new RuntimeException("getListeners didn't return type " + + listenerType); + } + } + + System.out.println("************"); + System.out.println("PASSED: getListeners on " + + object + " has all the right listeners."); + System.out.println("************"); + } + + /* + * Calls getListeners on the object + */ + static EventListener[] getListeners(Object object, Class type) + throws Exception { + Method methods[] = object.getClass().getMethods(); + Method method = null; + + for (int nmethod = 0; nmethod < methods.length; nmethod++) { + if (methods[nmethod].getName().equals("getListeners")) { + method = methods[nmethod]; + break; + } + } + if (method == null) { + throw new RuntimeException("Object " + + object + " has no getListeners method"); + } + Class params[] = {type}; + EventListener listeners[] = null; + listeners = (EventListener[]) method.invoke(object, params); + System.out.println("Listeners of type: " + type + " on " + object); + GetListenersTest.printArray(listeners); + return listeners; + } + + /* + * Adds a listener of every type to the object + */ + static void addDummyListenersOfEveryType(Object object) throws Exception { + Class type = object.getClass(); + + BeanInfo info = Introspector.getBeanInfo(type); + EventSetDescriptor esets[] = info.getEventSetDescriptors(); + + // add every kind of listener + for (int nset = 0; nset < esets.length; nset++) { + Class listenerType = esets[nset].getListenerType(); + EventListener listener = makeListener(listenerType); + Method addListenerMethod = esets[nset].getAddListenerMethod(); + Object params[] = {listener}; + addListenerMethod.invoke(object, params); + } + } + + /* + * Determines what listeners to exclude from the test for now + */ + static boolean validListenerToTest(Class listenerType) { + /* Don't have any provision for PropertyChangeListeners... */ + if ( listenerType == PropertyChangeListener.class ) { + return false; + } + + return true; + } + + static void testGetListeners(Object object) throws Exception { + GetListenersTest.addDummyListenersOfEveryType(object); + GetListenersTest.checkForListenersOfEveryType(object); + } + + static void printArray(Object objects[]) { + System.out.println("{"); + for(int n = 0; n < objects.length; n++) { + System.out.println("\t"+objects[n]+","); + } + System.out.println("}"); + } + + /* + * Makes a dummy listener implementation for the given listener type + */ + static EventListener makeListener(Class listenerType) throws Exception { + Object map[][] = { + {ActionListener.class, MyActionAdapter.class}, + {AdjustmentListener.class, MyAdjustmentAdapter.class}, + {ComponentListener.class, MyComponentAdapter.class}, + {ContainerListener.class, MyContainerAdapter.class}, + {FocusListener.class, MyFocusAdapter.class}, + {HierarchyBoundsListener.class, MyHierarchyBoundsAdapter.class}, + {HierarchyListener.class, MyHierarchyAdapter.class}, + {InputMethodListener.class, MyInputMethodAdapter.class}, + {ItemListener.class, MyItemAdapter.class}, + {KeyListener.class, MyKeyAdapter.class}, + {MouseListener.class, MyMouseAdapter.class}, + {MouseMotionListener.class, MyMouseMotionAdapter.class}, + {MouseWheelListener.class, MyMouseWheelAdapter.class}, + {TextListener.class, MyTextAdapter.class}, + {WindowListener.class, MyWindowAdapter.class}, + {WindowFocusListener.class, MyWindowFocusAdapter.class}, + {WindowStateListener.class, MyWindowStateAdapter.class}, + {PropertyChangeListener.class, MyPropertyChangeAdapter.class}, + }; + + for (int n = 0; n < map.length; n++) { + if (map[n][0] == listenerType) { + Class adapterClass = (Class) map[n][1]; + EventListener listener = + (EventListener) adapterClass.newInstance(); + return listener; + } + } + + throw new RuntimeException("No adapter found for listener type " + + listenerType); + } +} + +class GLTFrame extends Frame { + MenuItem mitem; + CheckboxMenuItem cmitem; + + GLTFrame() { + super("Component.getListeners API Test"); + } + + public void initAndShowGui() { + setLayout(new FlowLayout()); + + add(new Label("Label")); + add(new Button("Button")); + add(new Checkbox("Checkbox")); + Choice c = new Choice(); + c.add("choice"); + java.awt.List l = new java.awt.List(); + l.add("list"); + add(new Scrollbar()); + add(new TextField("TextField")); + add(new TextArea("TextArea")); + add(new Panel()); + add(new Canvas()); + + MenuBar menuBar = new MenuBar(); + Menu menu = new Menu("Menu"); + mitem = new MenuItem("Item 1"); + cmitem = new CheckboxMenuItem("Item 2"); + menu.add(mitem); + menu.add(cmitem); + menuBar.add(menu); + setMenuBar(menuBar); + + pack(); + setVisible(true); + } + + public void test() throws Exception { + // test Frame.getListeners + GetListenersTest.testGetListeners(this); + + // + // test getListeners on menu items + // + GetListenersTest.testGetListeners(mitem); + GetListenersTest.testGetListeners(cmitem); + + // + // test getListeners on all AWT Components + // + Component components[] = getComponents(); + for (int nc = 0; nc < components.length; nc++) { + GetListenersTest.testGetListeners(components[nc]); + } + } +} + +/************************************************ + * Dummy listener implementations we add to our components/models/objects + */ + +class MyPropertyChangeAdapter implements PropertyChangeListener { + public void propertyChange(PropertyChangeEvent evt) {} +} + +class MyActionAdapter implements ActionListener { + public void actionPerformed(ActionEvent ev) { + } +} + +class MyAdjustmentAdapter implements AdjustmentListener { + public void adjustmentValueChanged(AdjustmentEvent e) { + } +} + +class MyHierarchyAdapter implements HierarchyListener { + public void hierarchyChanged(HierarchyEvent e) { + } +} + +class MyInputMethodAdapter implements InputMethodListener { + public void inputMethodTextChanged(InputMethodEvent event) { + } + + public void caretPositionChanged(InputMethodEvent event) { + } +} + +class MyItemAdapter implements ItemListener { + public void itemStateChanged(ItemEvent e) { + } +} + +class MyTextAdapter implements TextListener { + public void textValueChanged(TextEvent e) { + } +} + +class MyComponentAdapter extends ComponentAdapter { +} + +class MyContainerAdapter extends ContainerAdapter { +} + +class MyFocusAdapter extends FocusAdapter { +} + +class MyHierarchyBoundsAdapter extends HierarchyBoundsAdapter { +} + +class MyKeyAdapter extends KeyAdapter { +} + +class MyMouseAdapter extends MouseAdapter { +} + +class MyMouseMotionAdapter extends MouseMotionAdapter { +} + +class MyMouseWheelAdapter implements MouseWheelListener { + public void mouseWheelMoved(MouseWheelEvent e) {} +} + +class MyWindowAdapter extends WindowAdapter { +} + +class MyWindowFocusAdapter implements WindowFocusListener { + public void windowGainedFocus(WindowEvent t) {} + public void windowLostFocus(WindowEvent t) {} +} + +class MyWindowStateAdapter extends WindowAdapter { +} diff --git a/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java b/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java new file mode 100644 index 00000000000..9b97ece4ebe --- /dev/null +++ b/test/jdk/java/awt/Container/OpenedPopupFrameDisposal.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4852790 + @summary Frame disposal must remove opened popup without exception + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JMenuBar; +import javax.swing.JPanel; + + +public class OpenedPopupFrameDisposal { + public static final int SIZE = 300; + + volatile JFrame jf = null; + volatile JComboBox jcb = null; + + public void start() { + jf = new JFrame("OpenedPopupFrameDisposal - Frame to dispose"); + // Note that original bug cannot be reproduced without JMenuBar present. + jf.setJMenuBar(new JMenuBar()); + jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + jf.setLocationRelativeTo(null); + jf.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent evt) { + jf.setVisible(false); + jf.dispose(); + } + }); + + + JPanel panel = new JPanel(new FlowLayout()); + jcb = new JComboBox<>(); + jcb.addItem("one"); + jcb.addItem("two"); + jcb.addItem("Three"); + panel.add(jcb); + + jf.getContentPane().add(panel, BorderLayout.CENTER); + jf.pack(); + jf.setSize(new Dimension(SIZE, SIZE)); + + jf.setVisible(true); + + } + + public void test() throws Exception { + Robot robot = new Robot(); + robot.delay(1000); // wait for jf visible + Point pt = jf.getLocationOnScreen(); + + int x, y; + + x = pt.x + SIZE / 2; + y = pt.y + SIZE / 2; + + robot.mouseMove(x, y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + + pt = jcb.getLocationOnScreen(); + x = pt.x + jcb.getWidth() / 2; + y = pt.y + jcb.getHeight() / 2; + + robot.mouseMove(x, y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + + // Here on disposal we had a NullPointerException + EventQueue.invokeAndWait(() -> { + if (jf != null) { + jf.setVisible(false); + jf.dispose(); + } + }); + } + + public static void main(String[] args) throws Exception { + OpenedPopupFrameDisposal imt = new OpenedPopupFrameDisposal(); + try { + EventQueue.invokeAndWait(imt::start); + imt.test(); + } finally { + EventQueue.invokeAndWait(() -> { + if (imt.jf != null) { + imt.jf.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java b/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java new file mode 100644 index 00000000000..79480d22508 --- /dev/null +++ b/test/jdk/java/awt/Container/RemoveByIndexExceptionTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4546535 + @summary java.awt.Container.remove(int) throws unexpected NPE +*/ + +import java.awt.Canvas; +import java.awt.Panel; + +public class RemoveByIndexExceptionTest { + + public static void main(String[] args) throws Exception { + Panel p = new Panel(); + p.add(new Canvas()); + p.remove(0); + + int[] bad = {-1, 0, 1}; + for (int i = 0; i < bad.length; i++) { + try { + System.out.println("Removing " + bad[i]); + p.remove(bad[i]); + System.out.println("No exception"); + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + System.out.println("This is correct exception - " + e); + } catch (NullPointerException e) { + e.printStackTrace(); + throw new RuntimeException("Test Failed: NPE was thrown."); + } + } + System.out.println("Test Passed."); + } +} diff --git a/test/jdk/java/awt/Container/ShowingChangedEventTest.java b/test/jdk/java/awt/Container/ShowingChangedEventTest.java new file mode 100644 index 00000000000..020615f9616 --- /dev/null +++ b/test/jdk/java/awt/Container/ShowingChangedEventTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4924516 + @summary Verifies that SHOWING_CHANGED event is propagated to \ + HierarchyListeners then toolkit enabled + @key headful +*/ + + +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class ShowingChangedEventTest + implements AWTEventListener, HierarchyListener{ + private boolean eventRegisteredOnButton = false; + + private final JFrame frame = new JFrame("ShowingChangedEventTest"); + private final JPanel panel = new JPanel(); + private final JButton button = new JButton(); + + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + ShowingChangedEventTest showingChangedEventTest + = new ShowingChangedEventTest(); + + try { + showingChangedEventTest.start(); + } finally { + showingChangedEventTest.frame.dispose(); + } + }); + } + + public void start () { + frame.getContentPane().add(panel); + panel.add(button); + + frame.pack(); + frame.setVisible(true); + + Toolkit.getDefaultToolkit() + .addAWTEventListener(this, AWTEvent.HIERARCHY_EVENT_MASK); + + button.addHierarchyListener(this); + panel.setVisible(false); + + if (!eventRegisteredOnButton){ + throw new RuntimeException("Event wasn't registered on Button."); + } + } + + @Override + public void eventDispatched(AWTEvent awtevt) { + if (awtevt instanceof HierarchyEvent) { + HierarchyEvent hevt = (HierarchyEvent) awtevt; + if (hevt != null && (hevt.getChangeFlags() + & HierarchyEvent.SHOWING_CHANGED) != 0) { + System.out.println("Hierarchy event was received on Toolkit. " + + "SHOWING_CHANGED for " + + hevt.getChanged().getClass().getName()); + } + } + } + + @Override + public void hierarchyChanged(HierarchyEvent e) { + if ((HierarchyEvent.SHOWING_CHANGED & e.getChangeFlags()) != 0) { + System.out.println("Hierarchy event was received on Button. " + + "SHOWING_CHANGED for " + + e.getChanged().getClass().getName()); + } + eventRegisteredOnButton = true; + } +} From 00b1eacad6ae2d5ea5afb1de506768e9ab960743 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Tue, 25 Apr 2023 20:32:24 +0000 Subject: [PATCH 140/288] 8306031: Update IANA Language Subtag Registry to Version 2023-04-13 Reviewed-by: naoto --- .../EquivMapsGenerator.java | 45 +++++++++++++------ .../data/lsrdata/language-subtag-registry.txt | 4 +- .../Locale/LanguageSubtagRegistryTest.java | 6 +-- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java index d196230bfbe..79597f4d8b2 100644 --- a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java +++ b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -39,7 +39,7 @@ import java.util.Locale; import java.util.Map; import java.util.TimeZone; import java.util.TreeMap; -import java.util.stream.Collectors; +import java.util.regex.Pattern; /** * This tool reads the IANA Language Subtag Registry data file downloaded from @@ -136,10 +136,29 @@ public class EquivMapsGenerator { } } else { // language, extlang, legacy, and redundant if (!initialLanguageMap.containsKey(preferred)) { - sb = new StringBuilder(preferred); - sb.append(','); - sb.append(tag); - initialLanguageMap.put(preferred, sb); + // IANA update 4/13 introduced case where a preferred value + // can have a preferred value itself. + // eg: ar-ajp has pref ajp which has pref apc + boolean foundInOther = false; + Pattern pattern = Pattern.compile(","+preferred+"(,|$)"); + // Check if current pref exists inside a value for another pref + List doublePrefs = initialLanguageMap + .values() + .stream() + .filter(e -> pattern.matcher(e.toString()).find()) + .toList(); + for (StringBuilder otherPrefVal : doublePrefs) { + otherPrefVal.append(","); + otherPrefVal.append(tag); + foundInOther = true; + } + if (!foundInOther) { + // does not exist in any other pref's values, so add as new entry + sb = new StringBuilder(preferred); + sb.append(','); + sb.append(tag); + initialLanguageMap.put(preferred, sb); + } } else { sb = initialLanguageMap.get(preferred); sb.append(','); @@ -156,7 +175,7 @@ public class EquivMapsGenerator { // "yue" is defined both as extlang and redundant. Remove the dup. subtags = Arrays.stream(initialLanguageMap.get(preferred).toString().split(",")) .distinct() - .collect(Collectors.toList()) + .toList() .toArray(new String[0]); if (subtags.length == 2) { @@ -241,7 +260,7 @@ public class EquivMapsGenerator { + " static final Map multiEquivsMap;\n" + " static final Map regionVariantEquivMap;\n\n" + " static {\n" - + " singleEquivMap = new HashMap<>("; + + " singleEquivMap = HashMap.newHashMap("; private static final String footerText = " }\n\n" @@ -263,11 +282,11 @@ public class EquivMapsGenerator { Paths.get(fileName))) { writer.write(getOpenJDKCopyright()); writer.write(headerText - + (int)(sortedLanguageMap1.size() / 0.75f + 1) + ");\n" - + " multiEquivsMap = new HashMap<>(" - + (int)(sortedLanguageMap2.size() / 0.75f + 1) + ");\n" - + " regionVariantEquivMap = new HashMap<>(" - + (int)(sortedRegionVariantMap.size() / 0.75f + 1) + ");\n\n" + + sortedLanguageMap1.size() + ");\n" + + " multiEquivsMap = HashMap.newHashMap(" + + sortedLanguageMap2.size() + ");\n" + + " regionVariantEquivMap = HashMap.newHashMap(" + + sortedRegionVariantMap.size() + ");\n\n" + " // This is an auto-generated file and should not be manually edited.\n" + " // LSR Revision: " + LSRrevisionDate); writer.newLine(); 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 1a29e6f0450..4fbc0c16806 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: 2023-03-22 +File-Date: 2023-04-13 %% Type: language Subtag: aa @@ -42986,7 +42986,7 @@ Subtag: ajp Description: South Levantine Arabic Added: 2009-07-29 Deprecated: 2023-03-17 -Preferred-Value: apc +Preferred-Value: ajp Prefix: ar Macrolanguage: ar %% diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index 50fc824beb8..9722823430f 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -24,9 +24,9 @@ /* * @test * @bug 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 - * 8258795 8267038 8287180 8302512 8304761 + * 8258795 8267038 8287180 8302512 8304761 8306031 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2023-03-22) with Locale and Locale.LanguageRange + * (LSR Revision: 2023-04-13) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ @@ -44,7 +44,7 @@ public class LanguageSubtagRegistryTest { static boolean err = false; private static final String ACCEPT_LANGUAGE = - "Accept-Language: aam, adp, aeb, ajs, aog, apc, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, ema," + "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, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, lvi, mtm," + " ngv, nns, ola, oyb, pat, phr, plu, pnd, pub, rib, rnb, rsn, scv, snz, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx," + " umi, uss, uth, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; From adf62febe6ccfd0b433588fe93fb6903848effbb Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Tue, 25 Apr 2023 23:24:08 +0000 Subject: [PATCH 141/288] 8304918: Remove unused decl field from AnnotatedType implementations Reviewed-by: stsypanov, darcy --- .../annotation/AnnotatedTypeFactory.java | 70 +++++++------------ .../annotation/TypeAnnotationParser.java | 9 +-- 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java index c2362da9fdb..69169c8d35a 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java @@ -46,14 +46,11 @@ public final class AnnotatedTypeFactory { * @param actualTypeAnnos the type annotations this AnnotatedType has * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget * as the AnnotatedType being built - * @param decl the declaration having the type use this AnnotatedType - * corresponds to */ public static AnnotatedType buildAnnotatedType(Type type, LocationInfo currentLoc, TypeAnnotation[] actualTypeAnnos, - TypeAnnotation[] allOnSameTarget, - AnnotatedElement decl) { + TypeAnnotation[] allOnSameTarget) { if (type == null) { return EMPTY_ANNOTATED_TYPE; } @@ -61,32 +58,27 @@ public final class AnnotatedTypeFactory { return new AnnotatedArrayTypeImpl(type, currentLoc, actualTypeAnnos, - allOnSameTarget, - decl); + allOnSameTarget); if (type instanceof Class) { return new AnnotatedTypeBaseImpl(type, currentLoc, actualTypeAnnos, - allOnSameTarget, - decl); + allOnSameTarget); } else if (type instanceof TypeVariable typeVariable) { return new AnnotatedTypeVariableImpl(typeVariable, currentLoc, actualTypeAnnos, - allOnSameTarget, - decl); + allOnSameTarget); } else if (type instanceof ParameterizedType paramType) { return new AnnotatedParameterizedTypeImpl(paramType, currentLoc, actualTypeAnnos, - allOnSameTarget, - decl); + allOnSameTarget); } else if (type instanceof WildcardType wildType) { return new AnnotatedWildcardTypeImpl(wildType, currentLoc, actualTypeAnnos, - allOnSameTarget, - decl); + allOnSameTarget); } throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen."); } @@ -123,7 +115,7 @@ public final class AnnotatedTypeFactory { static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0]; static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION, - EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY, null); + EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY); static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0]; /* @@ -134,16 +126,13 @@ public final class AnnotatedTypeFactory { private static class AnnotatedTypeBaseImpl implements AnnotatedType { private final Type type; - private final AnnotatedElement decl; private final LocationInfo location; private final TypeAnnotation[] allOnSameTargetTypeAnnotations; private final Map, Annotation> annotations; AnnotatedTypeBaseImpl(Type type, LocationInfo location, - TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, - AnnotatedElement decl) { + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations) { this.type = type; - this.decl = decl; this.location = location; this.allOnSameTargetTypeAnnotations = allOnSameTargetTypeAnnotations; this.annotations = TypeAnnotationParser.mapTypeAnnotations(location.filter(actualTypeAnnotations)); @@ -202,7 +191,7 @@ public final class AnnotatedTypeFactory { LocationInfo outerLoc = getLocation().popLocation((byte)1); if (outerLoc == null) { return buildAnnotatedType(owner, LocationInfo.BASE_LOCATION, - EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY, getDecl()); + EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY); } TypeAnnotation[]all = getTypeAnnotations(); List l = new ArrayList<>(all.length); @@ -211,7 +200,7 @@ public final class AnnotatedTypeFactory { if (t.getLocationInfo().isSameLocationInfo(outerLoc)) l.add(t); - return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl()); + return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all); } @@ -285,16 +274,12 @@ public final class AnnotatedTypeFactory { final TypeAnnotation[] getTypeAnnotations() { return allOnSameTargetTypeAnnotations; } - final AnnotatedElement getDecl() { - return decl; - } } private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType { AnnotatedArrayTypeImpl(Type type, LocationInfo location, - TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, - AnnotatedElement decl) { - super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations); } @Override @@ -303,8 +288,7 @@ public final class AnnotatedTypeFactory { return AnnotatedTypeFactory.buildAnnotatedType(t, nestingForType(t, getLocation().pushArray()), getTypeAnnotations(), - getTypeAnnotations(), - getDecl()); + getTypeAnnotations()); } @Override @@ -367,9 +351,8 @@ public final class AnnotatedTypeFactory { private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable { AnnotatedTypeVariableImpl(TypeVariable type, LocationInfo location, - TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, - AnnotatedElement decl) { - super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations); } @Override @@ -406,9 +389,8 @@ public final class AnnotatedTypeFactory { private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedParameterizedType { AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location, - TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, - AnnotatedElement decl) { - super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations); } @Override @@ -426,8 +408,7 @@ public final class AnnotatedTypeFactory { res[i] = buildAnnotatedType(arguments[i], newLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), - getTypeAnnotations(), - getDecl()); + getTypeAnnotations()); } return res; } @@ -441,7 +422,7 @@ public final class AnnotatedTypeFactory { LocationInfo outerLoc = getLocation().popLocation((byte)1); if (outerLoc == null) { return buildAnnotatedType(owner, LocationInfo.BASE_LOCATION, - EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY, getDecl()); + EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY); } TypeAnnotation[]all = getTypeAnnotations(); List l = new ArrayList<>(all.length); @@ -450,7 +431,7 @@ public final class AnnotatedTypeFactory { if (t.getLocationInfo().isSameLocationInfo(outerLoc)) l.add(t); - return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl()); + return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all); } private ParameterizedType getParameterizedType() { @@ -494,9 +475,8 @@ public final class AnnotatedTypeFactory { private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType { private final boolean hasUpperBounds; AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location, - TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, - AnnotatedElement decl) { - super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations); hasUpperBounds = (type.getLowerBounds().length == 0); } @@ -506,8 +486,7 @@ public final class AnnotatedTypeFactory { return new AnnotatedType[] { buildAnnotatedType(Object.class, LocationInfo.BASE_LOCATION, EMPTY_TYPE_ANNOTATION_ARRAY, - EMPTY_TYPE_ANNOTATION_ARRAY, - null) + EMPTY_TYPE_ANNOTATION_ARRAY) }; } return getAnnotatedBounds(getWildcardType().getUpperBounds()); @@ -538,8 +517,7 @@ public final class AnnotatedTypeFactory { res[i] = buildAnnotatedType(bounds[i], newLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), - getTypeAnnotations(), - getDecl()); + getTypeAnnotations()); } return res; } diff --git a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 4265d26fcf2..30f9434d6b7 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -78,8 +78,7 @@ public final class TypeAnnotationParser { return AnnotatedTypeFactory.buildAnnotatedType(type, AnnotatedTypeFactory.nestingForType(type, LocationInfo.BASE_LOCATION), typeAnnotations, - typeAnnotations, - decl); + typeAnnotations); } /** @@ -156,8 +155,7 @@ public final class TypeAnnotationParser { result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], AnnotatedTypeFactory.nestingForType(types[i], LocationInfo.BASE_LOCATION), typeAnnotations, - typeAnnotations, - decl); + typeAnnotations); } return result; @@ -303,8 +301,7 @@ public final class TypeAnnotationParser { res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], AnnotatedTypeFactory.nestingForType(bounds[i], loc), typeAnnotations, - typeAnnotations, - decl); + typeAnnotations); } return res; } From 1c1a73f715b291faabbc77d09d0f7b0ae65ebea7 Mon Sep 17 00:00:00 2001 From: Dingli Zhang Date: Wed, 26 Apr 2023 02:24:49 +0000 Subject: [PATCH 142/288] 8302908: RISC-V: Support masked vector arithmetic instructions for Vector API Co-authored-by: zifeihan Reviewed-by: fyang, fjiang, yzhu --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 24 + .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 67 +- .../cpu/riscv/c2_MacroAssembler_riscv.hpp | 46 +- .../cpu/riscv/macroAssembler_riscv.hpp | 41 +- src/hotspot/cpu/riscv/matcher_riscv.hpp | 2 +- src/hotspot/cpu/riscv/riscv.ad | 139 ++- src/hotspot/cpu/riscv/riscv_v.ad | 812 +++++++++++++++--- 7 files changed, 993 insertions(+), 138 deletions(-) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 35f36a1f1c0..d1669cd3737 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -1488,6 +1488,16 @@ enum VectorMask { #undef INSN +#define INSN(NAME, op, funct3, vm, funct6) \ + void NAME(VectorRegister Vd, VectorRegister Vs2, Register Rs1) { \ + patch_VArith(op, Vd, funct3, Rs1->raw_encoding(), Vs2, vm, funct6); \ + } + + // Vector Integer Merge Instructions + INSN(vmerge_vxm, 0b1010111, 0b100, 0b0, 0b010111); + +#undef INSN + #define INSN(NAME, op, funct3, funct6) \ void NAME(VectorRegister Vd, VectorRegister Vs2, FloatRegister Rs1, VectorMask vm = unmasked) { \ patch_VArith(op, Vd, funct3, Rs1->raw_encoding(), Vs2, vm, funct6); \ @@ -1542,6 +1552,17 @@ enum VectorMask { #undef INSN +#define INSN(NAME, op, funct3, vm, funct6) \ + void NAME(VectorRegister Vd, VectorRegister Vs2, int32_t imm) { \ + guarantee(is_simm5(imm), "imm is invalid"); \ + patch_VArith(op, Vd, funct3, (uint32_t)(imm & 0x1f), Vs2, vm, funct6); \ + } + + // Vector Integer Merge Instructions + INSN(vmerge_vim, 0b1010111, 0b011, 0b0, 0b010111); + +#undef INSN + #define INSN(NAME, op, funct3, vm, funct6) \ void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1) { \ patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \ @@ -1560,6 +1581,9 @@ enum VectorMask { INSN(vmnand_mm, 0b1010111, 0b010, 0b1, 0b011101); INSN(vmand_mm, 0b1010111, 0b010, 0b1, 0b011001); + // Vector Integer Merge Instructions + INSN(vmerge_vvm, 0b1010111, 0b000, 0b0, 0b010111); + #undef INSN #define INSN(NAME, op, funct3, Vs2, vm, funct6) \ diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index ba8f221e291..01d99db782c 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1304,7 +1304,7 @@ void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Regis } // Set dst to NaN if any NaN input. -void C2_MacroAssembler::minmax_FD(FloatRegister dst, FloatRegister src1, FloatRegister src2, +void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2, bool is_double, bool is_min) { assert_different_registers(dst, src1, src2); @@ -1616,7 +1616,7 @@ void C2_MacroAssembler::string_indexof_char_v(Register str1, Register cnt1, } // Set dst to NaN if any NaN input. -void C2_MacroAssembler::minmax_FD_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, +void C2_MacroAssembler::minmax_fp_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, bool is_double, bool is_min, int length_in_bytes) { assert_different_registers(dst, src1, src2); @@ -1632,7 +1632,7 @@ void C2_MacroAssembler::minmax_FD_v(VectorRegister dst, VectorRegister src1, Vec } // Set dst to NaN if any NaN input. -void C2_MacroAssembler::reduce_minmax_FD_v(FloatRegister dst, +void C2_MacroAssembler::reduce_minmax_fp_v(FloatRegister dst, FloatRegister src1, VectorRegister src2, VectorRegister tmp1, VectorRegister tmp2, bool is_double, bool is_min, int length_in_bytes) { @@ -1722,3 +1722,64 @@ void C2_MacroAssembler::rvv_vsetvli(BasicType bt, int length_in_bytes, Register } } } + +void C2_MacroAssembler::compare_integral_v(VectorRegister vd, BasicType bt, int length_in_bytes, + VectorRegister src1, VectorRegister src2, int cond, VectorMask vm) { + assert(is_integral_type(bt), "unsupported element type"); + assert(vm == Assembler::v0_t ? vd != v0 : true, "should be different registers"); + rvv_vsetvli(bt, length_in_bytes); + vmclr_m(vd); + switch (cond) { + case BoolTest::eq: vmseq_vv(vd, src1, src2, vm); break; + case BoolTest::ne: vmsne_vv(vd, src1, src2, vm); break; + case BoolTest::le: vmsle_vv(vd, src1, src2, vm); break; + case BoolTest::ge: vmsge_vv(vd, src1, src2, vm); break; + case BoolTest::lt: vmslt_vv(vd, src1, src2, vm); break; + case BoolTest::gt: vmsgt_vv(vd, src1, src2, vm); break; + default: + assert(false, "unsupported compare condition"); + ShouldNotReachHere(); + } +} + +void C2_MacroAssembler::compare_floating_point_v(VectorRegister vd, BasicType bt, int length_in_bytes, + VectorRegister src1, VectorRegister src2, + VectorRegister tmp1, VectorRegister tmp2, + VectorRegister vmask, int cond, VectorMask vm) { + assert(is_floating_point_type(bt), "unsupported element type"); + assert(vd != v0, "should be different registers"); + assert(vm == Assembler::v0_t ? vmask != v0 : true, "vmask should not be v0"); + rvv_vsetvli(bt, length_in_bytes); + // Check vector elements of src1 and src2 for quiet or signaling NaN. + vfclass_v(tmp1, src1); + vfclass_v(tmp2, src2); + vsrl_vi(tmp1, tmp1, 8); + vsrl_vi(tmp2, tmp2, 8); + vmseq_vx(tmp1, tmp1, zr); + vmseq_vx(tmp2, tmp2, zr); + if (vm == Assembler::v0_t) { + vmand_mm(tmp2, tmp1, tmp2); + if (cond == BoolTest::ne) { + vmandn_mm(tmp1, vmask, tmp2); + } + vmand_mm(v0, vmask, tmp2); + } else { + vmand_mm(v0, tmp1, tmp2); + if (cond == BoolTest::ne) { + vmnot_m(tmp1, v0); + } + } + vmclr_m(vd); + switch (cond) { + case BoolTest::eq: vmfeq_vv(vd, src1, src2, Assembler::v0_t); break; + case BoolTest::ne: vmfne_vv(vd, src1, src2, Assembler::v0_t); + vmor_mm(vd, vd, tmp1); break; + case BoolTest::le: vmfle_vv(vd, src1, src2, Assembler::v0_t); break; + case BoolTest::ge: vmfge_vv(vd, src1, src2, Assembler::v0_t); break; + case BoolTest::lt: vmflt_vv(vd, src1, src2, Assembler::v0_t); break; + case BoolTest::gt: vmfgt_vv(vd, src1, src2, Assembler::v0_t); break; + default: + assert(false, "unsupported compare condition"); + ShouldNotReachHere(); + } +} \ No newline at end of file diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 94a5068fd9a..30aac05f40b 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -137,13 +137,15 @@ vl1re8_v(v, t0); } - void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, int vec_reg_size_in_bytes) { - assert(vec_reg_size_in_bytes % 16 == 0, "unexpected vector reg size"); - unspill(v0, src_offset); - spill(v0, dst_offset); + void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, int vector_length_in_bytes) { + assert(vector_length_in_bytes % 16 == 0, "unexpected vector reg size"); + for (int i = 0; i < vector_length_in_bytes / 8; i++) { + unspill(t0, true, src_offset + (i * 8)); + spill(t0, true, dst_offset + (i * 8)); + } } - void minmax_FD(FloatRegister dst, + void minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2, bool is_double, bool is_min); @@ -183,11 +185,11 @@ Register tmp1, Register tmp2, bool isL); - void minmax_FD_v(VectorRegister dst, + void minmax_fp_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, bool is_double, bool is_min, int length_in_bytes); - void reduce_minmax_FD_v(FloatRegister dst, + void reduce_minmax_fp_v(FloatRegister dst, FloatRegister src1, VectorRegister src2, VectorRegister tmp1, VectorRegister tmp2, bool is_double, bool is_min, int length_in_bytes); @@ -198,4 +200,34 @@ void rvv_vsetvli(BasicType bt, int length_in_bytes, Register tmp = t0); + void compare_integral_v(VectorRegister dst, BasicType bt, int length_in_bytes, + VectorRegister src1, VectorRegister src2, int cond, VectorMask vm = Assembler::unmasked); + + void compare_floating_point_v(VectorRegister dst, BasicType bt, int length_in_bytes, + VectorRegister src1, VectorRegister src2, VectorRegister tmp1, VectorRegister tmp2, + VectorRegister vmask, int cond, VectorMask vm = Assembler::unmasked); + + // In Matcher::scalable_predicate_reg_slots, + // we assume each predicate register is one-eighth of the size of + // scalable vector register, one mask bit per vector byte. + void spill_vmask(VectorRegister v, int offset){ + rvv_vsetvli(T_BYTE, MaxVectorSize >> 3); + add(t0, sp, offset); + vse8_v(v, t0); + } + + void unspill_vmask(VectorRegister v, int offset){ + rvv_vsetvli(T_BYTE, MaxVectorSize >> 3); + add(t0, sp, offset); + vle8_v(v, t0); + } + + void spill_copy_vmask_stack_to_stack(int src_offset, int dst_offset, int vector_length_in_bytes) { + assert(vector_length_in_bytes % 4 == 0, "unexpected vector mask reg size"); + for (int i = 0; i < vector_length_in_bytes / 4; i++) { + unspill(t0, false, src_offset + (i * 4)); + spill(t0, false, dst_offset + (i * 4)); + } + } + #endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 18a03eff7ee..c60d1a5ad66 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1264,7 +1264,7 @@ public: vmnand_mm(vd, vs, vs); } - inline void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm) { + inline void vncvt_x_x_w(VectorRegister vd, VectorRegister vs, VectorMask vm = unmasked) { vnsrl_wx(vd, vs, x0, vm); } @@ -1276,6 +1276,45 @@ public: vfsgnjn_vv(vd, vs, vs); } + inline void vmsgt_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmslt_vv(vd, vs1, vs2, vm); + } + + inline void vmsgtu_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmsltu_vv(vd, vs1, vs2, vm); + } + + inline void vmsge_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmsle_vv(vd, vs1, vs2, vm); + } + + inline void vmsgeu_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmsleu_vv(vd, vs1, vs2, vm); + } + + inline void vmfgt_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmflt_vv(vd, vs1, vs2, vm); + } + + inline void vmfge_vv(VectorRegister vd, VectorRegister vs2, VectorRegister vs1, VectorMask vm = unmasked) { + vmfle_vv(vd, vs1, vs2, vm); + } + + // Copy mask register + inline void vmmv_m(VectorRegister vd, VectorRegister vs) { + vmand_mm(vd, vs, vs); + } + + // Clear mask register + inline void vmclr_m(VectorRegister vd) { + vmxor_mm(vd, vd, vd); + } + + // Set mask register + inline void vmset_m(VectorRegister vd) { + vmxnor_mm(vd, vd, vd); + } + static const int zero_words_block_size; void cast_primitive_type(BasicType type, Register Rt) { diff --git a/src/hotspot/cpu/riscv/matcher_riscv.hpp b/src/hotspot/cpu/riscv/matcher_riscv.hpp index eeee72f3910..a2b38ee4a48 100644 --- a/src/hotspot/cpu/riscv/matcher_riscv.hpp +++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp @@ -149,7 +149,7 @@ // Some microarchitectures have mask registers used on vectors static const bool has_predicated_vectors(void) { - return false; + return UseRVV; } // true means we have fast l2f conversion diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 708defd68e7..88dd95a1b8a 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -830,7 +830,8 @@ reg_class double_reg( F31, F31_H ); -// Class for all RVV vector registers +// Class for RVV vector registers +// Note: v0, v30 and v31 are used as mask registers. reg_class vectora_reg( V1, V1_H, V1_J, V1_K, V2, V2_H, V2_J, V2_K, @@ -860,9 +861,7 @@ reg_class vectora_reg( V26, V26_H, V26_J, V26_K, V27, V27_H, V27_J, V27_K, V28, V28_H, V28_J, V28_K, - V29, V29_H, V29_J, V29_K, - V30, V30_H, V30_J, V30_K, - V31, V31_H, V31_J, V31_K + V29, V29_H, V29_J, V29_K ); // Class for 64 bit register f0 @@ -912,6 +911,23 @@ reg_class v5_reg( // class for condition codes reg_class reg_flags(RFLAGS); + +// Class for RVV v0 mask register +// https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#53-vector-masking +// The mask value used to control execution of a masked vector +// instruction is always supplied by vector register v0. +reg_class vmask_reg_v0 ( + V0 +); + +// Class for RVV mask registers +// We need two more vmask registers to do the vector mask logical ops, +// so define v30, v31 as mask register too. +reg_class vmask_reg ( + V0, + V30, + V31 +); %} //----------DEFINITION BLOCK--------------------------------------------------- @@ -1522,7 +1538,7 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); - if (src_hi != OptoReg::Bad) { + if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) { assert((src_lo & 1) == 0 && src_lo + 1 == src_hi && (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi, "expected aligned-adjacent pairs"); @@ -1558,6 +1574,25 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo } else { ShouldNotReachHere(); } + } else if (bottom_type()->isa_vectmask() && cbuf) { + C2_MacroAssembler _masm(cbuf); + int vmask_size_in_bytes = Matcher::scalable_predicate_reg_slots() * 32 / 8; + if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { + // stack to stack + __ spill_copy_vmask_stack_to_stack(src_offset, dst_offset, + vmask_size_in_bytes); + } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) { + // vmask to stack + __ spill_vmask(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo)); + } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) { + // stack to vmask + __ unspill_vmask(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo)); + } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) { + // vmask to vmask + __ vmv1r_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo])); + } else { + ShouldNotReachHere(); + } } } else if (cbuf != NULL) { C2_MacroAssembler _masm(cbuf); @@ -1642,7 +1677,7 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo } else { st->print("%s", Matcher::regName[dst_lo]); } - if (bottom_type()->isa_vect() != NULL) { + if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { int vsize = 0; if (ideal_reg() == Op_VecA) { vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; @@ -1650,6 +1685,10 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo ShouldNotReachHere(); } st->print("\t# vector spill size = %d", vsize); + } else if (ideal_reg() == Op_RegVectMask) { + assert(Matcher::supports_scalable_vector(), "bad register type for spill"); + int vsize = Matcher::scalable_predicate_reg_slots() * 32; + st->print("\t# vmask spill size = %d", vsize); } else { st->print("\t# spill size = %d", is64 ? 64 : 32); } @@ -1863,7 +1902,59 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType } const bool Matcher::match_rule_supported_vector_masked(int opcode, int vlen, BasicType bt) { - return false; + if (!UseRVV) { + return false; + } + switch (opcode) { + case Op_AddVB: + case Op_AddVS: + case Op_AddVI: + case Op_AddVL: + case Op_AddVF: + case Op_AddVD: + case Op_SubVB: + case Op_SubVS: + case Op_SubVI: + case Op_SubVL: + case Op_SubVF: + case Op_SubVD: + case Op_MulVB: + case Op_MulVS: + case Op_MulVI: + case Op_MulVL: + case Op_MulVF: + case Op_MulVD: + case Op_DivVF: + case Op_DivVD: + case Op_VectorLoadMask: + case Op_VectorMaskCmp: + case Op_AndVMask: + case Op_XorVMask: + case Op_OrVMask: + case Op_RShiftVB: + case Op_RShiftVS: + case Op_RShiftVI: + case Op_RShiftVL: + case Op_LShiftVB: + case Op_LShiftVS: + case Op_LShiftVI: + case Op_LShiftVL: + case Op_URShiftVB: + case Op_URShiftVS: + case Op_URShiftVI: + case Op_URShiftVL: + case Op_VectorBlend: + break; + case Op_LoadVector: + opcode = Op_LoadVectorMasked; + break; + case Op_StoreVector: + opcode = Op_StoreVectorMasked; + break; + default: + return false; + } + return match_rule_supported_vector(opcode, vlen, bt); } const bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) { @@ -1875,11 +1966,11 @@ const bool Matcher::vector_needs_load_shuffle(BasicType elem_bt, int vlen) { } const RegMask* Matcher::predicate_reg_mask(void) { - return NULL; + return &_VMASK_REG_mask; } const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { - return NULL; + return new TypeVectMask(elemTy, length); } // Vector calling convention not yet implemented. @@ -3556,6 +3647,28 @@ operand vReg_V5() interface(REG_INTER); %} +operand vRegMask() +%{ + constraint(ALLOC_IN_RC(vmask_reg)); + match(RegVectMask); + match(vRegMask_V0); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + +// The mask value used to control execution of a masked +// vector instruction is always supplied by vector register v0. +operand vRegMask_V0() +%{ + constraint(ALLOC_IN_RC(vmask_reg_v0)); + match(RegVectMask); + match(vRegMask); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + // Java Thread Register operand javaThread_RegP(iRegP reg) %{ @@ -7271,7 +7384,7 @@ instruct maxF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ format %{ "maxF $dst, $src1, $src2" %} ins_encode %{ - __ minmax_FD(as_FloatRegister($dst$$reg), + __ minmax_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), false /* is_double */, false /* is_min */); %} @@ -7287,7 +7400,7 @@ instruct minF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ format %{ "minF $dst, $src1, $src2" %} ins_encode %{ - __ minmax_FD(as_FloatRegister($dst$$reg), + __ minmax_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), false /* is_double */, true /* is_min */); %} @@ -7303,7 +7416,7 @@ instruct maxD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ format %{ "maxD $dst, $src1, $src2" %} ins_encode %{ - __ minmax_FD(as_FloatRegister($dst$$reg), + __ minmax_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), true /* is_double */, false /* is_min */); %} @@ -7319,7 +7432,7 @@ instruct minD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ format %{ "minD $dst, $src1, $src2" %} ins_encode %{ - __ minmax_FD(as_FloatRegister($dst$$reg), + __ minmax_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), true /* is_double */, true /* is_min */); %} diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 700cb18eafb..240baa1b577 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -35,14 +35,18 @@ source_hpp %{ source %{ static void loadStore(C2_MacroAssembler masm, bool is_store, - VectorRegister reg, BasicType bt, Register base, int length_in_bytes) { + VectorRegister reg, BasicType bt, Register base, + int length_in_bytes, Assembler::VectorMask vm = Assembler::unmasked) { Assembler::SEW sew = Assembler::elemtype_to_sew(bt); masm.rvv_vsetvli(bt, length_in_bytes); if (is_store) { - masm.vsex_v(reg, base, sew); + masm.vsex_v(reg, base, sew, vm); } else { - masm.vlex_v(reg, base, sew); + if (vm == Assembler::v0_t) { + masm.vxor_vv(reg, reg, reg); + } + masm.vlex_v(reg, base, sew, vm); } } @@ -66,7 +70,6 @@ source %{ // Vector API specific case Op_LoadVectorGather: case Op_StoreVectorScatter: - case Op_VectorBlend: case Op_VectorCast: case Op_VectorCastB2X: case Op_VectorCastD2X: @@ -75,12 +78,9 @@ source %{ case Op_VectorCastL2X: case Op_VectorCastS2X: case Op_VectorInsert: - case Op_VectorLoadMask: case Op_VectorLoadShuffle: - case Op_VectorMaskCmp: case Op_VectorRearrange: case Op_VectorReinterpret: - case Op_VectorStoreMask: case Op_VectorTest: case Op_PopCountVI: case Op_PopCountVL: @@ -123,6 +123,112 @@ instruct storeV(vReg src, vmemA mem) %{ ins_pipe(pipe_slow); %} +// vector load mask + +instruct vloadmask(vRegMask dst, vReg src) %{ + match(Set dst (VectorLoadMask src)); + format %{ "vloadmask $dst, $src" %} + ins_encode %{ + __ rvv_vsetvli(T_BOOLEAN, Matcher::vector_length(this)); + __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), zr); + %} + ins_pipe(pipe_slow); +%} + +instruct vloadmask_masked(vRegMask dst, vReg src, vRegMask_V0 v0) %{ + match(Set dst (VectorLoadMask src v0)); + format %{ "vloadmask_masked $dst, $src, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_BOOLEAN, Matcher::vector_length(this)); + __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), zr, Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +// vector store mask + +instruct vstoremask(vReg dst, vRegMask_V0 v0, immI size) %{ + match(Set dst (VectorStoreMask v0 size)); + format %{ "vstoremask $dst, V0" %} + ins_encode %{ + __ rvv_vsetvli(T_BOOLEAN, Matcher::vector_length(this)); + __ vmv_v_x(as_VectorRegister($dst$$reg), zr); + __ vmerge_vim(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), 1); + %} + ins_pipe(pipe_slow); +%} + +// vector mask compare + +instruct vmaskcmp(vRegMask dst, vReg src1, vReg src2, immI cond) %{ + predicate(Matcher::vector_element_basic_type(n) == T_BYTE || + Matcher::vector_element_basic_type(n) == T_SHORT || + Matcher::vector_element_basic_type(n) == T_INT || + Matcher::vector_element_basic_type(n) == T_LONG); + match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); + format %{ "vmaskcmp $dst, $src1, $src2, $cond" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + __ compare_integral_v(as_VectorRegister($dst$$reg), bt, length_in_bytes, as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg), (int)($cond$$constant)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskcmp_masked(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask_V0 v0) %{ + predicate(Matcher::vector_element_basic_type(n) == T_BYTE || + Matcher::vector_element_basic_type(n) == T_SHORT || + Matcher::vector_element_basic_type(n) == T_INT || + Matcher::vector_element_basic_type(n) == T_LONG); + match(Set dst (VectorMaskCmp (Binary src1 src2) (Binary cond v0))); + effect(TEMP_DEF dst); + format %{ "vmaskcmp_masked $dst, $src1, $src2, $cond, $v0" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + __ compare_integral_v(as_VectorRegister($dst$$reg), bt, length_in_bytes, as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg), (int)($cond$$constant), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +// vector mask float compare + +instruct vmaskcmp_fp(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask_V0 v0, vReg tmp1, vReg tmp2) %{ + predicate(Matcher::vector_element_basic_type(n) == T_FLOAT || + Matcher::vector_element_basic_type(n) == T_DOUBLE); + match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP v0); + format %{ "vmaskcmp_fp $dst, $src1, $src2, $cond\t# KILL $tmp1, $tmp2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + __ compare_floating_point_v(as_VectorRegister($dst$$reg), bt, length_in_bytes, + as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + as_VectorRegister($v0$$reg), (int)($cond$$constant)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskcmp_fp_masked(vRegMask dst, vReg src1, vReg src2, immI cond, vRegMask vmask, vReg tmp1, vReg tmp2, vRegMask_V0 v0) %{ + predicate(Matcher::vector_element_basic_type(n) == T_FLOAT || + Matcher::vector_element_basic_type(n) == T_DOUBLE); + match(Set dst (VectorMaskCmp (Binary src1 src2) (Binary cond vmask))); + effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP v0); + format %{ "vmaskcmp_fp_masked $dst, $src1, $src2, $cond, $vmask\t# KILL $tmp1, $tmp2, $v0" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + __ compare_floating_point_v(as_VectorRegister($dst$$reg), bt, length_in_bytes, + as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), + as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), + as_VectorRegister($vmask$$reg), (int)($cond$$constant), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // vector abs instruct vabsB(vReg dst, vReg src, vReg tmp) %{ @@ -283,6 +389,40 @@ instruct vaddD(vReg dst, vReg src1, vReg src2) %{ ins_pipe(pipe_slow); %} +// vector add - predicated + +instruct vadd_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (AddVB (Binary dst_src1 src2) v0)); + match(Set dst_src1 (AddVS (Binary dst_src1 src2) v0)); + match(Set dst_src1 (AddVI (Binary dst_src1 src2) v0)); + match(Set dst_src1 (AddVL (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vadd.vv $dst_src1, $src2, $v0\t#@vadd_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vadd_vv(as_VectorRegister($dst_src1$$reg), + as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vadd_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (AddVF (Binary dst_src1 src2) v0)); + match(Set dst_src1 (AddVD (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vfadd.vv $dst_src1, $src2, $v0\t#@vadd_fp_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vfadd_vv(as_VectorRegister($dst_src1$$reg), + as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // vector and instruct vand(vReg dst, vReg src1, vReg src2) %{ @@ -290,7 +430,8 @@ instruct vand(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vand.vv $dst, $src1, $src2\t#@vand" %} ins_encode %{ - __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); __ vand_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg)); @@ -305,7 +446,8 @@ instruct vor(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vor.vv $dst, $src1, $src2\t#@vor" %} ins_encode %{ - __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); __ vor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg)); @@ -320,7 +462,8 @@ instruct vxor(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vxor.vv $dst, $src1, $src2\t#@vxor" %} ins_encode %{ - __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg)); @@ -356,6 +499,23 @@ instruct vdivD(vReg dst, vReg src1, vReg src2) %{ ins_pipe(pipe_slow); %} +// vector float div - predicated + +instruct vdiv_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (DivVF (Binary dst_src1 src2) v0)); + match(Set dst_src1 (DivVD (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vfdiv.vv $dst_src1, $src2, $v0\t#@vdiv_fp_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vfdiv_vv(as_VectorRegister($dst_src1$$reg), + as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // vector integer max/min instruct vmax(vReg dst, vReg src1, vReg src2) %{ @@ -397,7 +557,7 @@ instruct vmaxF(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vmaxF $dst, $src1, $src2\t#@vmaxF" %} ins_encode %{ - __ minmax_FD_v(as_VectorRegister($dst$$reg), + __ minmax_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), false /* is_double */, false /* is_min */, Matcher::vector_length_in_bytes(this)); %} @@ -411,7 +571,7 @@ instruct vmaxD(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vmaxD $dst, $src1, $src2\t#@vmaxD" %} ins_encode %{ - __ minmax_FD_v(as_VectorRegister($dst$$reg), + __ minmax_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), true /* is_double */, false /* is_min */, Matcher::vector_length_in_bytes(this)); %} @@ -425,7 +585,7 @@ instruct vminF(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vminF $dst, $src1, $src2\t#@vminF" %} ins_encode %{ - __ minmax_FD_v(as_VectorRegister($dst$$reg), + __ minmax_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), false /* is_double */, true /* is_min */, Matcher::vector_length_in_bytes(this)); %} @@ -439,7 +599,7 @@ instruct vminD(vReg dst, vReg src1, vReg src2) %{ ins_cost(VEC_COST); format %{ "vminD $dst, $src1, $src2\t#@vminD" %} ins_encode %{ - __ minmax_FD_v(as_VectorRegister($dst$$reg), + __ minmax_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), as_VectorRegister($src2$$reg), true /* is_double */, true /* is_min */, Matcher::vector_length_in_bytes(this)); %} @@ -756,6 +916,38 @@ instruct vmulD(vReg dst, vReg src1, vReg src2) %{ ins_pipe(pipe_slow); %} +// vector mul - predicated + +instruct vmul_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (MulVB (Binary dst_src1 src2) v0)); + match(Set dst_src1 (MulVS (Binary dst_src1 src2) v0)); + match(Set dst_src1 (MulVI (Binary dst_src1 src2) v0)); + match(Set dst_src1 (MulVL (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vmul.vv $dst_src1, $src2, $v0\t#@vmul_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmul_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vmul_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (MulVF (Binary dst_src1 src2) v0)); + match(Set dst_src1 (MulVD (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vmul.vv $dst_src1, $src2, $v0\t#@vmul_fp_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vfmul_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + // vector neg instruct vnegI(vReg dst, vReg src) %{ @@ -1000,7 +1192,7 @@ instruct vreduce_maxI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ match(Set dst (MaxReductionV src1 src2)); ins_cost(VEC_COST); effect(TEMP tmp); - format %{ "vreduce_maxI $dst, $src1, $src2, $tmp" %} + format %{ "vreduce_maxI $dst, $src1, $src2\t# KILL $tmp" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg), @@ -1015,7 +1207,7 @@ instruct vreduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{ match(Set dst (MaxReductionV src1 src2)); ins_cost(VEC_COST); effect(TEMP tmp); - format %{ "vreduce_maxL $dst, $src1, $src2, $tmp" %} + format %{ "vreduce_maxL $dst, $src1, $src2\t# KILL $tmp" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg), @@ -1034,7 +1226,7 @@ instruct vreduce_minI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vReg tmp) %{ match(Set dst (MinReductionV src1 src2)); ins_cost(VEC_COST); effect(TEMP tmp); - format %{ "vreduce_minI $dst, $src1, $src2, $tmp" %} + format %{ "vreduce_minI $dst, $src1, $src2\t# KILL $tmp" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg), @@ -1049,7 +1241,7 @@ instruct vreduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vReg tmp) %{ match(Set dst (MinReductionV src1 src2)); ins_cost(VEC_COST); effect(TEMP tmp); - format %{ "vreduce_minL $dst, $src1, $src2, $tmp" %} + format %{ "vreduce_minL $dst, $src1, $src2\t# KILL $tmp" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ rvv_reduce_integral($dst$$Register, as_VectorRegister($tmp$$reg), @@ -1068,7 +1260,7 @@ instruct vreduce_maxF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); format %{ "reduce_maxF $dst, $src1, $src2, $tmp1, $tmp2" %} ins_encode %{ - __ reduce_minmax_FD_v($dst$$FloatRegister, + __ reduce_minmax_fp_v($dst$$FloatRegister, $src1$$FloatRegister, as_VectorRegister($src2$$reg), as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), false /* is_double */, false /* is_min */, Matcher::vector_length_in_bytes(this, $src2)); @@ -1083,7 +1275,7 @@ instruct vreduce_maxD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); format %{ "reduce_maxD $dst, $src1, $src2, $tmp1, $tmp2" %} ins_encode %{ - __ reduce_minmax_FD_v($dst$$FloatRegister, + __ reduce_minmax_fp_v($dst$$FloatRegister, $src1$$FloatRegister, as_VectorRegister($src2$$reg), as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), true /* is_double */, false /* is_min */, Matcher::vector_length_in_bytes(this, $src2)); @@ -1100,7 +1292,7 @@ instruct vreduce_minF(fRegF dst, fRegF src1, vReg src2, vReg tmp1, vReg tmp2) %{ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); format %{ "reduce_minF $dst, $src1, $src2, $tmp1, $tmp2" %} ins_encode %{ - __ reduce_minmax_FD_v($dst$$FloatRegister, + __ reduce_minmax_fp_v($dst$$FloatRegister, $src1$$FloatRegister, as_VectorRegister($src2$$reg), as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), false /* is_double */, true /* is_min */, Matcher::vector_length_in_bytes(this, $src2)); @@ -1115,7 +1307,7 @@ instruct vreduce_minD(fRegD dst, fRegD src1, vReg src2, vReg tmp1, vReg tmp2) %{ effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2); format %{ "reduce_minD $dst, $src1, $src2, $tmp1, $tmp2" %} ins_encode %{ - __ reduce_minmax_FD_v($dst$$FloatRegister, + __ reduce_minmax_fp_v($dst$$FloatRegister, $src1$$FloatRegister, as_VectorRegister($src2$$reg), as_VectorRegister($tmp1$$reg), as_VectorRegister($tmp2$$reg), true /* is_double */, true /* is_min */, Matcher::vector_length_in_bytes(this, $src2)); @@ -1265,44 +1457,38 @@ instruct replicateD(vReg dst, fRegD src) %{ // vector shift -instruct vasrB(vReg dst, vReg src, vReg shift) %{ +instruct vasrB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ match(Set dst (RShiftVB src shift)); ins_cost(VEC_COST); - effect(TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift 7\t#@vasrB\n\t" - "vsra.vi $dst, $src, 7, Assembler::v0_t\n\t" - "vmnot.m v0, v0\n\t" - "vsra.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst, TEMP v0); + format %{ "vasrB $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), BitsPerByte - 1, Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} ins_pipe(pipe_slow); %} -instruct vasrS(vReg dst, vReg src, vReg shift) %{ +instruct vasrS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ match(Set dst (RShiftVS src shift)); ins_cost(VEC_COST); - effect(TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift, 15\t#@vasrS\n\t" - "vsra.vi $dst, $src, 15, Assembler::v0_t\n\t" - "vmnot.m v0, v0\n\t" - "vsra.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst, TEMP v0); + format %{ "vasrS $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); __ vsra_vi(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), BitsPerShort - 1, Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} @@ -1312,7 +1498,7 @@ instruct vasrS(vReg dst, vReg src, vReg shift) %{ instruct vasrI(vReg dst, vReg src, vReg shift) %{ match(Set dst (RShiftVI src shift)); ins_cost(VEC_COST); - format %{ "vsra.vv $dst, $src, $shift\t#@vasrI" %} + format %{ "vasrI $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), @@ -1324,53 +1510,109 @@ instruct vasrI(vReg dst, vReg src, vReg shift) %{ instruct vasrL(vReg dst, vReg src, vReg shift) %{ match(Set dst (RShiftVL src shift)); ins_cost(VEC_COST); - format %{ "vsra.vv $dst, $src, $shift\t#@vasrL" %} + format %{ "vasrL $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); __ vsra_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), - as_VectorRegister($shift$$reg)); + as_VectorRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} -instruct vlslB(vReg dst, vReg src, vReg shift) %{ +instruct vasrB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (RShiftVB (Binary dst_src shift) vmask)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vasrB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); + // if shift > BitsPerByte - 1, clear the low BitsPerByte - 1 bits + __ vmerge_vim(as_VectorRegister($shift$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); + // otherwise, shift + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vasrS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (RShiftVS (Binary dst_src shift) vmask)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vasrS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); + // if shift > BitsPerShort - 1, clear the low BitsPerShort - 1 bits + __ vmerge_vim(as_VectorRegister($shift$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); + // otherwise, shift + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vasrI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (RShiftVI (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vasrI_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); + __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vasrL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (RShiftVL (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vasrL_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + __ vsra_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlslB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ match(Set dst (LShiftVB src shift)); ins_cost(VEC_COST); - effect( TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift, 7\t#@vlslB\n\t" - "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" - "vmnot.m v0, v0\n\t" - "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst, TEMP v0); + format %{ "vlslB $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerByte - 1, clear the element - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg), Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} ins_pipe(pipe_slow); %} -instruct vlslS(vReg dst, vReg src, vReg shift) %{ +instruct vlslS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ match(Set dst (LShiftVS src shift)); ins_cost(VEC_COST); - effect(TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift, 15\t#@vlslS\n\t" - "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" - "vmnot.m v0, v0\n\t" - "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst, TEMP v0); + format %{ "vlslS $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerShort - 1, clear the element - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg), Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} @@ -1380,7 +1622,7 @@ instruct vlslS(vReg dst, vReg src, vReg shift) %{ instruct vlslI(vReg dst, vReg src, vReg shift) %{ match(Set dst (LShiftVI src shift)); ins_cost(VEC_COST); - format %{ "vsll.vv $dst, $src, $shift\t#@vlslI" %} + format %{ "vlslI $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), @@ -1392,7 +1634,7 @@ instruct vlslI(vReg dst, vReg src, vReg shift) %{ instruct vlslL(vReg dst, vReg src, vReg shift) %{ match(Set dst (LShiftVL src shift)); ins_cost(VEC_COST); - format %{ "vsll.vv $dst, $src, $shift\t# vector (D)" %} + format %{ "vlslL $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); __ vsll_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), @@ -1401,55 +1643,116 @@ instruct vlslL(vReg dst, vReg src, vReg shift) %{ ins_pipe(pipe_slow); %} -instruct vlsrB(vReg dst, vReg src, vReg shift) %{ - match(Set dst (URShiftVB src shift)); +instruct vlslB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (LShiftVB (Binary dst_src shift) vmask)); ins_cost(VEC_COST); - effect(TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift, 7\t#@vlsrB\n\t" - "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" - "vmnot.m v0, v0, v0\n\t" - "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vlslB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} ins_encode %{ __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerByte - 1, clear the element - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerByte - 1); - __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), - as_VectorRegister($src$$reg), Assembler::v0_t); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); + __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), + as_VectorRegister($vmask$$reg)); + __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($dst_src$$reg), Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); - __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} ins_pipe(pipe_slow); %} -instruct vlsrS(vReg dst, vReg src, vReg shift) %{ - match(Set dst (URShiftVS src shift)); +instruct vlslS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (LShiftVS (Binary dst_src shift) vmask)); ins_cost(VEC_COST); - effect(TEMP_DEF dst); - format %{ "vmsgtu.vi v0, $shift, 15\t#@vlsrS\n\t" - "vxor.vv $dst, $src, $src, Assembler::v0_t\n\t" - "vmnot.m v0, v0\n\t" - "vsll.vv $dst, $src, $shift, Assembler::v0_t" %} + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vlslS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} ins_encode %{ __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); // if shift > BitsPerShort - 1, clear the element - __ vmsgtu_vi(v0, as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), + as_VectorRegister($vmask$$reg)); + __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($dst_src$$reg), Assembler::v0_t); + // otherwise, shift + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlslI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (LShiftVI (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vlslI_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); + __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlslL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (LShiftVL (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vlslL_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + __ vsll_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlsrB(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst (URShiftVB src shift)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst, TEMP v0); + format %{ "vlsrB $dst, $src, $shift" %} + ins_encode %{ + __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); + // if shift > BitsPerByte - 1, clear the element + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($src$$reg), Assembler::v0_t); // otherwise, shift - __ vmnot_m(v0, v0); + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), as_VectorRegister($shift$$reg), Assembler::v0_t); %} ins_pipe(pipe_slow); %} +instruct vlsrS(vReg dst, vReg src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst (URShiftVS src shift)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst, TEMP v0); + format %{ "vlsrS $dst, $src, $shift" %} + ins_encode %{ + __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); + // if shift > BitsPerShort - 1, clear the element + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), + as_VectorRegister($src$$reg), Assembler::v0_t); + // otherwise, shift + __ vmnot_m(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg)); + __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} instruct vlsrI(vReg dst, vReg src, vReg shift) %{ match(Set dst (URShiftVI src shift)); ins_cost(VEC_COST); - format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrI" %} + format %{ "vlsrI $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), @@ -1458,11 +1761,10 @@ instruct vlsrI(vReg dst, vReg src, vReg shift) %{ ins_pipe(pipe_slow); %} - instruct vlsrL(vReg dst, vReg src, vReg shift) %{ match(Set dst (URShiftVL src shift)); ins_cost(VEC_COST); - format %{ "vsrl.vv $dst, $src, $shift\t#@vlsrL" %} + format %{ "vlsrL $dst, $src, $shift" %} ins_encode %{ __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); __ vsrl_vv(as_VectorRegister($dst$$reg), as_VectorRegister($src$$reg), @@ -1471,6 +1773,74 @@ instruct vlsrL(vReg dst, vReg src, vReg shift) %{ ins_pipe(pipe_slow); %} +instruct vlsrB_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (URShiftVB (Binary dst_src shift) vmask)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vlsrB_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_BYTE, Matcher::vector_length_in_bytes(this)); + // if shift > BitsPerByte - 1, clear the element + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerByte - 1); + __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), + as_VectorRegister($vmask$$reg)); + __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($dst_src$$reg), Assembler::v0_t); + // otherwise, shift + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlsrS_masked(vReg dst_src, vReg shift, vRegMask vmask, vRegMask_V0 v0) %{ + match(Set dst_src (URShiftVS (Binary dst_src shift) vmask)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src, TEMP v0); + format %{ "vlsrS_masked $dst_src, $dst_src, $shift, $vmask\t# KILL $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_SHORT, Matcher::vector_length_in_bytes(this)); + // if shift > BitsPerShort - 1, clear the element + __ vmsgtu_vi(as_VectorRegister($v0$$reg), as_VectorRegister($shift$$reg), BitsPerShort - 1); + __ vmand_mm(as_VectorRegister($v0$$reg), as_VectorRegister($v0$$reg), + as_VectorRegister($vmask$$reg)); + __ vxor_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($dst_src$$reg), Assembler::v0_t); + // otherwise, shift + __ vmv1r_v(as_VectorRegister($v0$$reg), as_VectorRegister($vmask$$reg)); + __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlsrI_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (URShiftVI (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vlsrI_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_INT, Matcher::vector_length_in_bytes(this)); + __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vlsrL_masked(vReg dst_src, vReg shift, vRegMask_V0 v0) %{ + match(Set dst_src (URShiftVL (Binary dst_src shift) v0)); + ins_cost(VEC_COST); + effect(TEMP_DEF dst_src); + format %{ "vlsrL_masked $dst_src, $dst_src, $shift, $v0" %} + ins_encode %{ + __ rvv_vsetvli(T_LONG, Matcher::vector_length_in_bytes(this)); + __ vsrl_vv(as_VectorRegister($dst_src$$reg), as_VectorRegister($dst_src$$reg), + as_VectorRegister($shift$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + instruct vasrB_imm(vReg dst, vReg src, immI shift) %{ match(Set dst (RShiftVB src (RShiftCntV shift))); ins_cost(VEC_COST); @@ -1827,13 +2197,45 @@ instruct vsubD(vReg dst, vReg src1, vReg src2) %{ ins_pipe(pipe_slow); %} +// vector sub - predicated + +instruct vsub_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (SubVB (Binary dst_src1 src2) v0)); + match(Set dst_src1 (SubVS (Binary dst_src1 src2) v0)); + match(Set dst_src1 (SubVI (Binary dst_src1 src2) v0)); + match(Set dst_src1 (SubVL (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vsub.vv $dst_src1, $src2, $v0\t#@vsub_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct vsub_fp_masked(vReg dst_src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst_src1 (SubVF (Binary dst_src1 src2) v0)); + match(Set dst_src1 (SubVD (Binary dst_src1 src2) v0)); + ins_cost(VEC_COST); + format %{ "vfsub.vv $dst_src1, $src2, $v0\t#@vsub_fp_masked" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vfsub_vv(as_VectorRegister($dst_src1$$reg), as_VectorRegister($dst_src1$$reg), + as_VectorRegister($src2$$reg), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, iRegI_R10 result, vReg_V1 v1, - vReg_V2 v2, vReg_V3 v3, rFlagsReg cr) + vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, rFlagsReg cr) %{ predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrEquals (Binary str1 str2) cnt)); - effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr); + effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, TEMP v0, KILL cr); format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %} ins_encode %{ @@ -1846,11 +2248,11 @@ instruct vstring_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, instruct vstring_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, iRegI_R10 result, vReg_V1 v1, - vReg_V2 v2, vReg_V3 v3, rFlagsReg cr) + vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, rFlagsReg cr) %{ predicate(UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrEquals (Binary str1 str2) cnt)); - effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, KILL cr); + effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP v1, TEMP v2, TEMP v3, TEMP v0, KILL cr); format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %} ins_encode %{ @@ -1862,11 +2264,11 @@ instruct vstring_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, %} instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegP_R28 tmp, rFlagsReg cr) %{ predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); - effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr); + effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, TEMP v0, KILL cr); format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp" %} ins_encode %{ @@ -1877,11 +2279,11 @@ instruct varray_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, %} instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegP_R28 tmp, rFlagsReg cr) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegP_R28 tmp, rFlagsReg cr) %{ predicate(UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); - effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, KILL cr); + effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP v1, TEMP v2, TEMP v3, TEMP v0, KILL cr); format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp" %} ins_encode %{ @@ -1893,12 +2295,12 @@ instruct varray_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, - iRegP_R28 tmp1, iRegL_R29 tmp2) + vRegMask_V0 v0, iRegP_R28 tmp1, iRegL_R29 tmp2) %{ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU); match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); + TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5, TEMP v0); format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %} ins_encode %{ @@ -1912,12 +2314,12 @@ instruct vstring_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_ %} instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, - iRegP_R28 tmp1, iRegL_R29 tmp2) + vRegMask_V0 v0, iRegP_R28 tmp1, iRegL_R29 tmp2) %{ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL); match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); + TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5, TEMP v0); format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %} ins_encode %{ @@ -1931,12 +2333,12 @@ instruct vstring_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_ instruct vstring_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, - iRegP_R28 tmp1, iRegL_R29 tmp2) + vRegMask_V0 v0, iRegP_R28 tmp1, iRegL_R29 tmp2) %{ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL); match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); + TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5, TEMP v0); format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %} ins_encode %{ @@ -1949,12 +2351,12 @@ instruct vstring_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI %} instruct vstring_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, iRegI_R10 result, vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vReg_V4 v4, vReg_V5 v5, - iRegP_R28 tmp1, iRegL_R29 tmp2) + vRegMask_V0 v0, iRegP_R28 tmp1, iRegL_R29 tmp2) %{ predicate(UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU); match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2))); effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5); + TEMP v1, TEMP v2, TEMP v3, TEMP v4, TEMP v5, TEMP v0); format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %} ins_encode %{ @@ -1968,11 +2370,11 @@ instruct vstring_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI // fast byte[] to char[] inflation instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 len, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) %{ predicate(UseRVV); match(Set dummy (StrInflatedCopy src (Binary dst len))); - effect(TEMP v1, TEMP v2, TEMP v3, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len); + effect(TEMP v1, TEMP v2, TEMP v3, TEMP v0, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len); format %{ "String Inflate $src,$dst" %} ins_encode %{ @@ -1983,12 +2385,12 @@ instruct vstring_inflate(Universe dummy, iRegP_R10 src, iRegP_R11 dst, iRegI_R12 // encode char[] to byte[] in ISO_8859_1 instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) %{ predicate(UseRVV); match(Set result (EncodeISOArray src (Binary dst len))); effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, - TEMP v1, TEMP v2, TEMP v3, TEMP tmp); + TEMP v1, TEMP v2, TEMP v3, TEMP tmp, TEMP v0); format %{ "Encode array $src,$dst,$len -> $result" %} ins_encode %{ @@ -2000,12 +2402,12 @@ instruct vencode_iso_array(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R1 // fast char[] to byte[] compression instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 result, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) %{ predicate(UseRVV); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP_DEF result, USE_KILL src, USE_KILL dst, USE_KILL len, - TEMP v1, TEMP v2, TEMP v3, TEMP tmp); + TEMP v1, TEMP v2, TEMP v3, TEMP tmp, TEMP v0); format %{ "String Compress $src,$dst -> $result // KILL R11, R12, R13" %} ins_encode %{ @@ -2016,11 +2418,11 @@ instruct vstring_compress(iRegP_R12 src, iRegP_R11 dst, iRegI_R13 len, iRegI_R10 %} instruct vcount_positives(iRegP_R11 ary, iRegI_R12 len, iRegI_R10 result, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, iRegLNoSp tmp) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0, iRegLNoSp tmp) %{ predicate(UseRVV); match(Set result (CountPositives ary len)); - effect(TEMP_DEF result, USE_KILL ary, USE_KILL len, TEMP v1, TEMP v2, TEMP v3, TEMP tmp); + effect(TEMP_DEF result, USE_KILL ary, USE_KILL len, TEMP v1, TEMP v2, TEMP v3, TEMP tmp, TEMP v0); format %{ "count positives byte[] $ary, $len -> $result" %} ins_encode %{ @@ -2032,12 +2434,12 @@ instruct vcount_positives(iRegP_R11 ary, iRegI_R12 len, iRegI_R10 result, instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0) %{ predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, - TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3); + TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3, TEMP v0); format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %} @@ -2052,12 +2454,12 @@ instruct vstringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, - vReg_V1 v1, vReg_V2 v2, vReg_V3 v3) + vReg_V1 v1, vReg_V2 v2, vReg_V3 v3, vRegMask_V0 v0) %{ predicate(UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); effect(TEMP_DEF result, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, - TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3); + TEMP tmp1, TEMP tmp2, TEMP v1, TEMP v2, TEMP v3, TEMP v0); format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %} @@ -2072,11 +2474,11 @@ instruct vstringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, // clearing of an array instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy, - vReg_V1 vReg1, vReg_V2 vReg2, vReg_V3 vReg3) + vReg_V1 vReg1, vReg_V2 vReg2, vReg_V3 vReg3, vRegMask_V0 v0) %{ predicate(!UseBlockZeroing && UseRVV); match(Set dummy (ClearArray cnt base)); - effect(USE_KILL cnt, USE_KILL base, TEMP vReg1, TEMP vReg2, TEMP vReg3); + effect(USE_KILL cnt, USE_KILL base, TEMP vReg1, TEMP vReg2, TEMP vReg3, TEMP v0); format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %} @@ -2101,4 +2503,188 @@ instruct vloadcon(vReg dst, immI0 src) %{ } %} ins_pipe(pipe_slow); +%} + +instruct vmask_gen_I(vRegMask dst, iRegI src) %{ + match(Set dst (VectorMaskGen (ConvI2L src))); + format %{ "vmask_gen_I $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + Assembler::SEW sew = Assembler::elemtype_to_sew(bt); + __ vsetvli(t0, $src$$Register, sew); + __ vmset_m(as_VectorRegister($dst$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_gen_L(vRegMask dst, iRegL src) %{ + match(Set dst (VectorMaskGen src)); + format %{ "vmask_gen_L $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + Assembler::SEW sew = Assembler::elemtype_to_sew(bt); + __ vsetvli(t0, $src$$Register, sew); + __ vmset_m(as_VectorRegister($dst$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_gen_imm(vRegMask dst, immL con) %{ + match(Set dst (VectorMaskGen con)); + format %{ "vmask_gen_imm $dst, $con" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, (uint)($con$$constant)); + __ vmset_m(as_VectorRegister($dst$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskAll_immI(vRegMask dst, immI src) %{ + match(Set dst (MaskAll src)); + format %{ "vmaskAll_immI $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + int con = (int)$src$$constant; + if (con == 0) { + __ vmclr_m(as_VectorRegister($dst$$reg)); + } else { + assert(con == -1, "invalid constant value for mask"); + __ vmset_m(as_VectorRegister($dst$$reg)); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskAllI(vRegMask dst, iRegI src) %{ + match(Set dst (MaskAll src)); + format %{ "vmaskAllI $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); + __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), zr); + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskAll_immL(vRegMask dst, immL src) %{ + match(Set dst (MaskAll src)); + format %{ "vmaskAll_immL $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + long con = (long)$src$$constant; + if (con == 0) { + __ vmclr_m(as_VectorRegister($dst$$reg)); + } else { + assert(con == -1, "invalid constant value for mask"); + __ vmset_m(as_VectorRegister($dst$$reg)); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskAllL(vRegMask dst, iRegL src) %{ + match(Set dst (MaskAll src)); + format %{ "vmaskAllL $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmv_v_x(as_VectorRegister($dst$$reg), as_Register($src$$reg)); + __ vmsne_vx(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), zr); + %} + ins_pipe(pipe_slow); +%} + +// ------------------------------ Vector mask basic OPs ------------------------ + +// vector mask logical ops: and/or/xor + +instruct vmask_and(vRegMask dst, vRegMask src1, vRegMask src2) %{ + match(Set dst (AndVMask src1 src2)); + format %{ "vmask_and $dst, $src1, $src2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmand_mm(as_VectorRegister($dst$$reg), + as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_or(vRegMask dst, vRegMask src1, vRegMask src2) %{ + match(Set dst (OrVMask src1 src2)); + format %{ "vmask_or $dst, $src1, $src2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmor_mm(as_VectorRegister($dst$$reg), + as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmask_xor(vRegMask dst, vRegMask src1, vRegMask src2) %{ + match(Set dst (XorVMask src1 src2)); + format %{ "vmask_xor $dst, $src1, $src2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmxor_mm(as_VectorRegister($dst$$reg), + as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vmaskcast(vRegMask dst_src) %{ + match(Set dst_src (VectorMaskCast dst_src)); + ins_cost(0); + format %{ "vmaskcast $dst_src\t# do nothing" %} + ins_encode(/* empty encoding */); + ins_pipe(pipe_class_empty); +%} + +// vector load/store - predicated + +instruct loadV_masked(vReg dst, vmemA mem, vRegMask_V0 v0) %{ + match(Set dst (LoadVectorMasked mem v0)); + format %{ "loadV_masked $dst, $mem, $v0" %} + ins_encode %{ + VectorRegister dst_reg = as_VectorRegister($dst$$reg); + loadStore(C2_MacroAssembler(&cbuf), false, dst_reg, + Matcher::vector_element_basic_type(this), as_Register($mem$$base), + Matcher::vector_length_in_bytes(this), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +instruct storeV_masked(vReg src, vmemA mem, vRegMask_V0 v0) %{ + match(Set mem (StoreVectorMasked mem (Binary src v0))); + format %{ "storeV_masked $mem, $src, $v0" %} + ins_encode %{ + VectorRegister src_reg = as_VectorRegister($src$$reg); + loadStore(C2_MacroAssembler(&cbuf), true, src_reg, + Matcher::vector_element_basic_type(this, $src), as_Register($mem$$base), + Matcher::vector_length_in_bytes(this, $src), Assembler::v0_t); + %} + ins_pipe(pipe_slow); +%} + +// ------------------------------ Vector blend --------------------------------- + +instruct vblend(vReg dst, vReg src1, vReg src2, vRegMask_V0 v0) %{ + match(Set dst (VectorBlend (Binary src1 src2) v0)); + format %{ "vmerge_vvm $dst, $src1, $src2, v0\t#@vector blend" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ rvv_vsetvli(bt, Matcher::vector_length_in_bytes(this)); + __ vmerge_vvm(as_VectorRegister($dst$$reg), as_VectorRegister($src1$$reg), + as_VectorRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); %} \ No newline at end of file From f3e8bd1d1161772539f42405fc4fcb02259f5b66 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 26 Apr 2023 03:13:56 +0000 Subject: [PATCH 143/288] 8306755: Open source few Swing JComponent and AbstractButton tests Reviewed-by: prr --- .../swing/AbstractButton/bug4143867.java | 143 ++++++++++++++++++ .../swing/AbstractButton/bug4147740.java | 109 +++++++++++++ .../swing/AbstractButton/bug4246045.java | 120 +++++++++++++++ .../javax/swing/JComponent/bug4419219.java | 112 ++++++++++++++ .../javax/swing/JComponent/bug4962718.java | 92 +++++++++++ 5 files changed, 576 insertions(+) create mode 100644 test/jdk/javax/swing/AbstractButton/bug4143867.java create mode 100644 test/jdk/javax/swing/AbstractButton/bug4147740.java create mode 100644 test/jdk/javax/swing/AbstractButton/bug4246045.java create mode 100644 test/jdk/javax/swing/JComponent/bug4419219.java create mode 100644 test/jdk/javax/swing/JComponent/bug4962718.java diff --git a/test/jdk/javax/swing/AbstractButton/bug4143867.java b/test/jdk/javax/swing/AbstractButton/bug4143867.java new file mode 100644 index 00000000000..588f168255d --- /dev/null +++ b/test/jdk/javax/swing/AbstractButton/bug4143867.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4143867 4237390 4383709 + @summary Tests set/getAction(.) and some constructors with Action argument + @key headful + @run main bug4143867 +*/ + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.DefaultButtonModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JFrame; +import javax.swing.JToggleButton; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JRadioButton; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.SwingUtilities; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; + +public class bug4143867 { + static final int TEST_MNEMONIC = KeyEvent.VK_1; + static JFrame fr; + + public static void main(String[] argv) throws Exception { + bug4143867 b = new bug4143867(); + SwingUtilities.invokeAndWait(() -> { + try { + b.doInitAndTest(); + } finally { + if (fr != null) { + fr.dispose(); + } + } + }); + } + + public void doInitAndTest() { + fr = new JFrame("bug4143867"); + JMenuBar mb = new JMenuBar(); + JMenu m = mb.add(new JMenu("Menu1")); + fr.setJMenuBar(mb); + JMenuItem it1 = m.add(new JMenuItem("Item1")); + fr.getContentPane().setLayout(new FlowLayout()); + JButton bt1 = new JButton("Button1"); + fr.getContentPane().add(bt1); + + final AbstractAction al = new AbstractAction() { + public void actionPerformed(ActionEvent e) { + System.out.println("Pressed..."); + } + }; + al.putValue(Action.NAME, "Action"); + al.putValue(Action.MNEMONIC_KEY, new Integer(TEST_MNEMONIC)); + m.add(al); + m.getItem(0).setAction(al); + bt1.setAction(al); + JButton bt2 = new JButton(al); + fr.getContentPane().add(bt2); + if (it1.getAction() != al || m.getItem(1).getAction() != al || + bt1.getAction() != al || bt2.getAction() != al) { + throw new RuntimeException("Action was not set correctly."); + } + + if (bt1.getMnemonic() != TEST_MNEMONIC) { + throw new RuntimeException("Failed 4383709: JButton doesn't get mnemonic from Action"); + } + + class TestProtectedOfAbstractButton extends AbstractButton { + public void test() { + PropertyChangeListener pcl = createActionPropertyChangeListener(null); + setModel(new DefaultButtonModel()); + configurePropertiesFromAction(al); + } + } + TestProtectedOfAbstractButton tpAB = new TestProtectedOfAbstractButton(); + tpAB.test(); + + // Constructors presence test + JRadioButton ct1 = new JRadioButton(al); + JCheckBox ct2 = new JCheckBox(al); + JRadioButton ct3 = new JRadioButton(al); + JToggleButton ct4 = new JToggleButton(al); + JMenuItem ct5 = new JMenuItem(al); + JMenu ct6 = new JMenu(al); + JCheckBoxMenuItem ct7 = new JCheckBoxMenuItem(al); + JRadioButtonMenuItem ct8 = new JRadioButtonMenuItem(al); + if (ct1.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButton..."); + } + if (ct2.getAction() != al) { + throw new RuntimeException("Constructor error in JCheckBox..."); + } + if (ct3.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButton..."); + } + if (ct4.getAction() != al) { + throw new RuntimeException("Constructor error in JToggleButton..."); + } + if (ct5.getAction() != al) { + throw new RuntimeException("Constructor error in JMenuItem..."); + } + if (ct6.getAction() != al) { + throw new RuntimeException("Constructor error in JMenu..."); + } + if (ct7.getAction() != al) { + throw new RuntimeException("Constructor error in JCheckBoxMenuItem..."); + } + if (ct8.getAction() != al) { + throw new RuntimeException("Constructor error in JRadioButtonMenuItem..."); + } + } +} diff --git a/test/jdk/javax/swing/AbstractButton/bug4147740.java b/test/jdk/javax/swing/AbstractButton/bug4147740.java new file mode 100644 index 00000000000..0011a03278c --- /dev/null +++ b/test/jdk/javax/swing/AbstractButton/bug4147740.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4147740 + @summary Tests that AbstractButton does not update images it doesn't use + @key headful + @run main bug4147740 +*/ + +import java.awt.Image; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.ImageIcon; +import java.awt.Robot; +import javax.swing.SwingUtilities; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; + +public class bug4147740 { + + static JButton b; + static JFrame frame; + static volatile boolean imageUpdated = false; + static volatile boolean shouldUpdate = true; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4147740"); + b = new AnimatedButton(); + frame.getContentPane().add(b); + b.addHierarchyListener(new Listener()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + static class Listener implements HierarchyListener { + public void hierarchyChanged(HierarchyEvent ev) { + if ((ev.getChangeFlags() | HierarchyEvent.SHOWING_CHANGED) != 0 && + frame.isShowing()) { + + frame.repaint(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + synchronized(b) { + b.setEnabled(false); + shouldUpdate = false; + } + } + }); + } + } + } + + static class AnimatedButton extends JButton { + boolean shouldNotUpdate = false; + + AnimatedButton() { + super(); + setIcon(new ImageIcon("animated.gif")); + setDisabledIcon(new ImageIcon("static.gif")); + } + + public boolean imageUpdate(Image img, int infoflags, + int x, int y, int w, int h) { + boolean updated; + synchronized(b) { + updated = super.imageUpdate(img, infoflags, x, y, w, h); + if (!shouldUpdate && updated) { + throw new RuntimeException("Failed: unused image is being updated"); + } + } + return updated; + } + } +} diff --git a/test/jdk/javax/swing/AbstractButton/bug4246045.java b/test/jdk/javax/swing/AbstractButton/bug4246045.java new file mode 100644 index 00000000000..8e6e018c724 --- /dev/null +++ b/test/jdk/javax/swing/AbstractButton/bug4246045.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4246045 + @summary AbstractButton fires accessible PropertyChangeEvent incorrectly + @key headful + @run main bug4246045 +*/ + +import java.awt.Container; +import java.awt.Robot; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.SwingUtilities; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleState; + +public class bug4246045 { + + class Listener implements PropertyChangeListener { + boolean state = false; // focused or not + + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals( + AccessibleContext.ACCESSIBLE_STATE_PROPERTY)) { + + boolean reported = false; + if (e.getNewValue() == null) { + reported = false; + } else if (e.getNewValue().equals(AccessibleState.FOCUSED)) { + reported = true; + } else { + throw new RuntimeException("Unknown value of ACCESSIBLE_STATE_PROPERTY"); + } + + if (!state == reported) { + state = reported; + } else { + throw new RuntimeException("Bad value of ACCESSIBLE_STATE_PROPERTY"); + } + } + } + } + + static JFrame frame; + static JButton btn; + static JToggleButton tb; + static JTextField dummy; + + public void init() { + btn = new JButton("JButton"); + tb = new JToggleButton("JToggleButton"); + dummy = new JTextField(); + Container pane = frame.getContentPane(); + pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); + pane.add(btn); + pane.add(tb); + pane.add(dummy); + + Listener bl = new Listener(); + btn.getAccessibleContext().addPropertyChangeListener(bl); + Listener tbl = new Listener(); + tb.getAccessibleContext().addPropertyChangeListener(tbl); + } + + public void start() { + btn.requestFocus(); + btn.transferFocus(); + tb.transferFocus(); + } + + public static void main(String[] argv) throws Exception { + Robot robot = new Robot(); + bug4246045 bug = new bug4246045(); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("4246045 Test"); + bug.init(); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + bug.start(); + }); + robot.waitForIdle(); + robot.delay(1000); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/javax/swing/JComponent/bug4419219.java b/test/jdk/javax/swing/JComponent/bug4419219.java new file mode 100644 index 00000000000..df3c39c8064 --- /dev/null +++ b/test/jdk/javax/swing/JComponent/bug4419219.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 4419219 + @summary Tests that registerKeyboardAction(null, ...) doen't throw NPE. + @key headful + @run main bug4419219 +*/ + +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.KeyStroke; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JTable; +import javax.swing.SwingUtilities; + +public class bug4419219 { + static volatile boolean passed = true; + static JFrame frame; + static Robot robo; + + public static void main(String[] args) throws Exception { + robo = new Robot(); + robo.setAutoWaitForIdle(true); + robo.setAutoDelay(100); + SwingUtilities.invokeAndWait(() -> { + try { + frame = new JFrame("bug4419219 Table"); + + final String[] names = {"col"}; + final Object[][] data = {{"A"}, {"B"}, {"C"}, {"D"}, {"E"}}; + + JTable tableView = (JTable)new TestTable(data, names); + // unregister ctrl-A + tableView.registerKeyboardAction(null, + KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK), + JComponent.WHEN_FOCUSED); + + frame.getContentPane().add(tableView); + frame.setSize(250,250); + frame.setLocationRelativeTo(null); + frame.addWindowListener(new TestStateListener()); + frame.setVisible(true); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + if (!passed) { + throw new RuntimeException("Test failed."); + } + } + + static class TestStateListener extends WindowAdapter { + public void windowOpened(WindowEvent ev) { + robo.delay(1000); + robo.mouseMove(100,100); + robo.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robo.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robo.keyPress(KeyEvent.VK_CONTROL); + robo.keyPress(KeyEvent.VK_A); + robo.keyRelease(KeyEvent.VK_A); + robo.keyRelease(KeyEvent.VK_CONTROL); + } + } + + static class TestTable extends JTable { + + public TestTable(Object[][] data, String[] names) { + super(data, names); + } + + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) { + try { + return super.processKeyBinding(ks, e, condition, pressed); + } catch (NullPointerException ex) { + passed = false; + } + return false; + } + } +} diff --git a/test/jdk/javax/swing/JComponent/bug4962718.java b/test/jdk/javax/swing/JComponent/bug4962718.java new file mode 100644 index 00000000000..5a7a1557f9d --- /dev/null +++ b/test/jdk/javax/swing/JComponent/bug4962718.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4962718 + * @summary Propertychange Listener not fired by inheritPopupMenu and Popupmenu properties + * @key headful + * @run main bug4962718 +*/ + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class bug4962718 { + static volatile boolean popupWasSet = false; + static volatile boolean inheritWasSet = false; + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4962718"); + JButton button = new JButton("For test"); + JPopupMenu popup = new JPopupMenu(); + + button.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("inheritsPopupMenu")) { + inheritWasSet = true; + } else if( evt.getPropertyName(). + equals("componentPopupMenu")) { + popupWasSet = true; + } + } + }); + + frame.add(button); + button.setInheritsPopupMenu(true); + button.setInheritsPopupMenu(false); + button.setComponentPopupMenu(popup); + button.setComponentPopupMenu(null); + frame.pack(); + frame.setVisible(true); + }); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + + if (!inheritWasSet) { + throw new RuntimeException("Test failed, inheritsPopupMenu " + + " property change listener was not called"); + } + if (!popupWasSet) { + throw new RuntimeException("Test failed, componentPopupMenu " + + " property change listener was not called"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} + From ed1ebd242a4bb82a7074564ea96dc3d26b78f9e1 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 26 Apr 2023 05:17:48 +0000 Subject: [PATCH 144/288] 8306652: Open source AWT MenuItem related tests Reviewed-by: prr, psadhukhan --- test/jdk/java/awt/MenuItem/EnableTest.java | 74 ++++++++++++ .../java/awt/MenuItem/MenuSetLabelTest.java | 112 ++++++++++++++++++ .../MenuItem/SetLabelWithPeerCreatedTest.java | 70 +++++++++++ test/jdk/java/awt/MenuItem/SetStateTest.java | 70 +++++++++++ 4 files changed, 326 insertions(+) create mode 100644 test/jdk/java/awt/MenuItem/EnableTest.java create mode 100644 test/jdk/java/awt/MenuItem/MenuSetLabelTest.java create mode 100644 test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java create mode 100644 test/jdk/java/awt/MenuItem/SetStateTest.java diff --git a/test/jdk/java/awt/MenuItem/EnableTest.java b/test/jdk/java/awt/MenuItem/EnableTest.java new file mode 100644 index 00000000000..4090a717221 --- /dev/null +++ b/test/jdk/java/awt/MenuItem/EnableTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4257944 + @summary PopupMenu.setEnabled fails on Win32 + @key headful + @run main EnableTest +*/ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +public class EnableTest { + PopupMenu popup = null; + Frame frame; + + public static void main(String[] args) throws Exception { + EnableTest test = new EnableTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("EnableTest"); + popup = new PopupMenu("Popup Menu Title"); + MenuItem mi1 = new MenuItem("Menu Item"); + MenuItem mi2 = new MenuItem("Menu Item"); + popup.add(mi1); + popup.addSeparator(); + popup.add(mi2); + popup.setEnabled(false); + popup.setLabel("New Label"); + mi2.setEnabled(false); + frame.add(popup); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff --git a/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java b/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java new file mode 100644 index 00000000000..083edf2c0f2 --- /dev/null +++ b/test/jdk/java/awt/MenuItem/MenuSetLabelTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4261935 + @summary Menu display problem when changing the text of the menu(window 98) + @key headful + @run main MenuSetLabelTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Robot; + +public class MenuSetLabelTest { + Menu1 f; + + public static void main(String[] args) throws Exception { + MenuSetLabelTest test = new MenuSetLabelTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + f = new Menu1(); + f.setTitle("MenuSetLabelTest"); + f.setSize(300, 200); + f.setLocationRelativeTo(null); + f.setVisible(true); + }); + Robot robot = new Robot(); + robot.delay(1000); + robot.waitForIdle(); + EventQueue.invokeAndWait(() -> { + f.changeMenuLabel(); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } + +} + +class Menu1 extends Frame { + + String s1 = new String("short"); + String s2 = new String("This is a long string"); + String s3 = new String("Menu Item string"); + + MenuBar mb1 = new MenuBar(); + Menu f = new Menu(s1); + Menu m = new Menu(s1); + boolean flag = true; + + public Menu1() + { + for (int i = 0; i < 5; i++) { + m.add(new MenuItem(s3)); + } + for (int i = 0; i < 10; i++) { + f.add(new MenuItem(s3)); + } + mb1.add(f); + mb1.add(m); + setMenuBar(mb1); + } + + public void changeMenuLabel() { + MenuBar mb = getMenuBar(); + Menu m0 = mb.getMenu(0); + Menu m1 = mb.getMenu(1); + + if (flag) { + m0.setLabel(s2); + m1.setLabel(s2); + } else { + m0.setLabel(s1); + m1.setLabel(s1); + } + flag = !flag; + } +} diff --git a/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java b/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java new file mode 100644 index 00000000000..697168ef6dc --- /dev/null +++ b/test/jdk/java/awt/MenuItem/SetLabelWithPeerCreatedTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4234266 + @summary MenuItem throws NullPointer exception when setting the label with created peer. + @key headful + @run main SetLabelWithPeerCreatedTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; + +public class SetLabelWithPeerCreatedTest { + Frame frame; + public static void main(String[] args) throws Exception { + SetLabelWithPeerCreatedTest test = new SetLabelWithPeerCreatedTest(); + test.start(); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("SetLabel with Peer Created Test"); + Menu menu = new Menu("Menu"); + MenuItem mi = new MenuItem("Item"); + MenuBar mb = new MenuBar(); + menu.add(mi); + mb.add(menu); + frame.setMenuBar(mb); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + mi.setLabel("new label"); + frame.setVisible(true); + System.out.println("Test PASSED!"); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + } diff --git a/test/jdk/java/awt/MenuItem/SetStateTest.java b/test/jdk/java/awt/MenuItem/SetStateTest.java new file mode 100644 index 00000000000..bc3ea099330 --- /dev/null +++ b/test/jdk/java/awt/MenuItem/SetStateTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 5106833 + @summary NullPointerException in XMenuPeer.repaintMenuItem + @key headful + @run main SetStateTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.CheckboxMenuItem; + +public class SetStateTest { + Frame frame; + public static void main(String[] args) throws Exception { + SetStateTest test = new SetStateTest(); + test.start(); + } + + public void start () throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("SetStateTest"); + MenuBar bar = new MenuBar(); + Menu menu = new Menu("Menu"); + CheckboxMenuItem checkboxMenuItem = new CheckboxMenuItem("Item"); + bar.add(menu); + frame.setMenuBar(bar); + menu.add(checkboxMenuItem); + checkboxMenuItem.setState(true); + frame.setSize(300, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + System.out.println("Test PASSED!"); + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From cc894d849aa5f730d5a806acfc7a237cf5170af1 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Wed, 26 Apr 2023 05:42:26 +0000 Subject: [PATCH 145/288] 8303466: C2: failed: malformed control flow. Limit type made precise with MaxL/MinL Reviewed-by: roland, kvn, chagedorn, thartmann --- src/hotspot/share/opto/addnode.cpp | 132 ++++++++++++++++++ src/hotspot/share/opto/addnode.hpp | 26 ++-- src/hotspot/share/opto/convertnode.cpp | 14 ++ src/hotspot/share/opto/convertnode.hpp | 1 + src/hotspot/share/opto/loopTransform.cpp | 119 +++++----------- src/hotspot/share/opto/macro.cpp | 14 ++ .../compiler/lib/ir_framework/IRNode.java | 10 ++ .../TestLoopLimitSubtractionsCollapse.java | 69 +++++++++ .../loopopts/TestUnrollLimitPreciseType.java | 92 ++++++++++++ 9 files changed, 386 insertions(+), 91 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestLoopLimitSubtractionsCollapse.java create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index f4931085fa4..3c56f5bd770 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -1258,6 +1258,138 @@ const Type *MinINode::add_ring( const Type *t0, const Type *t1 ) const { return TypeInt::make( MIN2(r0->_lo,r1->_lo), MIN2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) ); } +// Collapse the "addition with overflow-protection" pattern, and the symmetrical +// "subtraction with underflow-protection" pattern. These are created during the +// unrolling, when we have to adjust the limit by subtracting the stride, but want +// to protect against underflow: MaxL(SubL(limit, stride), min_jint). +// If we have more than one of those in a sequence: +// +// x con2 +// | | +// AddL clamp2 +// | | +// Max/MinL con1 +// | | +// AddL clamp1 +// | | +// Max/MinL (n) +// +// We want to collapse it to: +// +// x con1 con2 +// | | | +// | AddLNode (new_con) +// | | +// AddLNode clamp1 +// | | +// Max/MinL (n) +// +// Note: we assume that SubL was already replaced by an AddL, and that the stride +// has its sign flipped: SubL(limit, stride) -> AddL(limit, -stride). +Node* fold_subI_no_underflow_pattern(Node* n, PhaseGVN* phase) { + assert(n->Opcode() == Op_MaxL || n->Opcode() == Op_MinL, "sanity"); + // Check that the two clamps have the correct values. + jlong clamp = (n->Opcode() == Op_MaxL) ? min_jint : max_jint; + auto is_clamp = [&](Node* c) { + const TypeLong* t = phase->type(c)->isa_long(); + return t != nullptr && t->is_con() && + t->get_con() == clamp; + }; + // Check that the constants are negative if MaxL, and positive if MinL. + auto is_sub_con = [&](Node* c) { + const TypeLong* t = phase->type(c)->isa_long(); + return t != nullptr && t->is_con() && + t->get_con() < max_jint && t->get_con() > min_jint && + (t->get_con() < 0) == (n->Opcode() == Op_MaxL); + }; + // Verify the graph level by level: + Node* add1 = n->in(1); + Node* clamp1 = n->in(2); + if (add1->Opcode() == Op_AddL && is_clamp(clamp1)) { + Node* max2 = add1->in(1); + Node* con1 = add1->in(2); + if (max2->Opcode() == n->Opcode() && is_sub_con(con1)) { + Node* add2 = max2->in(1); + Node* clamp2 = max2->in(2); + if (add2->Opcode() == Op_AddL && is_clamp(clamp2)) { + Node* x = add2->in(1); + Node* con2 = add2->in(2); + if (is_sub_con(con2)) { + Node* new_con = phase->transform(new AddLNode(con1, con2)); + Node* new_sub = phase->transform(new AddLNode(x, new_con)); + n->set_req_X(1, new_sub, phase); + return n; + } + } + } + } + return nullptr; +} + +const Type* MaxLNode::add_ring(const Type* t0, const Type* t1) const { + const TypeLong* r0 = t0->is_long(); + const TypeLong* r1 = t1->is_long(); + + return TypeLong::make(MAX2(r0->_lo, r1->_lo), MAX2(r0->_hi, r1->_hi), MAX2(r0->_widen, r1->_widen)); +} + +Node* MaxLNode::Identity(PhaseGVN* phase) { + const TypeLong* t1 = phase->type(in(1))->is_long(); + const TypeLong* t2 = phase->type(in(2))->is_long(); + + // Can we determine maximum statically? + if (t1->_lo >= t2->_hi) { + return in(1); + } else if (t2->_lo >= t1->_hi) { + return in(2); + } + + return MaxNode::Identity(phase); +} + +Node* MaxLNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* n = AddNode::Ideal(phase, can_reshape); + if (n != nullptr) { + return n; + } + if (can_reshape) { + return fold_subI_no_underflow_pattern(this, phase); + } + return nullptr; +} + +const Type* MinLNode::add_ring(const Type* t0, const Type* t1) const { + const TypeLong* r0 = t0->is_long(); + const TypeLong* r1 = t1->is_long(); + + return TypeLong::make(MIN2(r0->_lo, r1->_lo), MIN2(r0->_hi, r1->_hi), MIN2(r0->_widen, r1->_widen)); +} + +Node* MinLNode::Identity(PhaseGVN* phase) { + const TypeLong* t1 = phase->type(in(1))->is_long(); + const TypeLong* t2 = phase->type(in(2))->is_long(); + + // Can we determine minimum statically? + if (t1->_lo >= t2->_hi) { + return in(2); + } else if (t2->_lo >= t1->_hi) { + return in(1); + } + + return MaxNode::Identity(phase); +} + +Node* MinLNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* n = AddNode::Ideal(phase, can_reshape); + if (n != nullptr) { + return n; + } + if (can_reshape) { + return fold_subI_no_underflow_pattern(this, phase); + } + return nullptr; +} + //------------------------------add_ring--------------------------------------- const Type *MinFNode::add_ring( const Type *t0, const Type *t1 ) const { const TypeF *r0 = t0->is_float_constant(); diff --git a/src/hotspot/share/opto/addnode.hpp b/src/hotspot/share/opto/addnode.hpp index c6a6138adb7..fb47972e8b3 100644 --- a/src/hotspot/share/opto/addnode.hpp +++ b/src/hotspot/share/opto/addnode.hpp @@ -322,28 +322,38 @@ public: // MAXimum of 2 longs. class MaxLNode : public MaxNode { public: - MaxLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {} + MaxLNode(Compile* C, Node* in1, Node* in2) : MaxNode(in1, in2) { + init_flags(Flag_is_macro); + C->add_macro_node(this); + } virtual int Opcode() const; - virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; } - virtual const Type *add_id() const { return TypeLong::make(min_jlong); } - virtual const Type *bottom_type() const { return TypeLong::LONG; } + virtual const Type* add_ring(const Type* t0, const Type* t1) const; + virtual const Type* add_id() const { return TypeLong::make(min_jlong); } + virtual const Type* bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } int max_opcode() const { return Op_MaxL; } int min_opcode() const { return Op_MinL; } + virtual Node* Identity(PhaseGVN* phase); + virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); }; //------------------------------MinLNode--------------------------------------- // MINimum of 2 longs. class MinLNode : public MaxNode { public: - MinLNode(Node *in1, Node *in2) : MaxNode(in1, in2) {} + MinLNode(Compile* C, Node* in1, Node* in2) : MaxNode(in1, in2) { + init_flags(Flag_is_macro); + C->add_macro_node(this); + } virtual int Opcode() const; - virtual const Type *add_ring(const Type*, const Type*) const { return TypeLong::LONG; } - virtual const Type *add_id() const { return TypeLong::make(max_jlong); } - virtual const Type *bottom_type() const { return TypeLong::LONG; } + virtual const Type* add_ring(const Type* t0, const Type* t1) const; + virtual const Type* add_id() const { return TypeLong::make(max_jlong); } + virtual const Type* bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } int max_opcode() const { return Op_MaxL; } int min_opcode() const { return Op_MinL; } + virtual Node* Identity(PhaseGVN* phase); + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); }; //------------------------------MaxFNode--------------------------------------- diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index b276a4d1611..ab2e839424a 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp @@ -322,6 +322,20 @@ const Type* ConvI2LNode::Value(PhaseGVN* phase) const { return this_type; } +Node* ConvI2LNode::Identity(PhaseGVN* phase) { + // If type is in "int" sub-range, we can + // convert I2L(L2I(x)) => x + // since the conversions have no effect. + if (in(1)->Opcode() == Op_ConvL2I) { + Node* x = in(1)->in(1); + const TypeLong* t = phase->type(x)->isa_long(); + if (t != nullptr && t->_lo >= min_jint && t->_hi <= max_jint) { + return x; + } + } + return this; +} + #ifdef ASSERT static inline bool long_ranges_overlap(jlong lo1, jlong hi1, jlong lo2, jlong hi2) { diff --git a/src/hotspot/share/opto/convertnode.hpp b/src/hotspot/share/opto/convertnode.hpp index e58213fbc09..dbebf337db2 100644 --- a/src/hotspot/share/opto/convertnode.hpp +++ b/src/hotspot/share/opto/convertnode.hpp @@ -190,6 +190,7 @@ class ConvI2LNode : public TypeNode { virtual int Opcode() const; virtual const Type* Value(PhaseGVN* phase) const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + virtual Node* Identity(PhaseGVN* phase); virtual uint ideal_reg() const { return Op_RegL; } }; diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index cb704b076a4..9070a1080f4 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -2288,74 +2288,32 @@ void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adj new_limit = _igvn.intcon(limit->get_int() - stride_con); set_ctrl(new_limit, C->root()); } else { - // Limit is not constant. - assert(loop_head->unrolled_count() != 1 || has_ctrl(opaq), "should have opaque for first unroll"); - if ((stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo)) || - (stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi))) { - // No underflow. - new_limit = new SubINode(limit, stride); + // Limit is not constant. Int subtraction could lead to underflow. + // (1) Convert to long. + Node* limit_l = new ConvI2LNode(limit); + register_new_node(limit_l, get_ctrl(limit)); + Node* stride_l = _igvn.longcon(stride_con); + set_ctrl(stride_l, C->root()); + + // (2) Subtract: compute in long, to prevent underflow. + Node* new_limit_l = new SubLNode(limit_l, stride_l); + register_new_node(new_limit_l, ctrl); + + // (3) Clamp to int range, in case we had subtraction underflow. + Node* underflow_clamp_l = _igvn.longcon((stride_con > 0) ? min_jint : max_jint); + set_ctrl(underflow_clamp_l, C->root()); + Node* new_limit_no_underflow_l = nullptr; + if (stride_con > 0) { + // limit = MaxL(limit - stride, min_jint) + new_limit_no_underflow_l = new MaxLNode(C, new_limit_l, underflow_clamp_l); } else { - // (limit - stride) may underflow. - // Clamp the adjustment value with MININT or MAXINT: - // - // new_limit = limit-stride - // if (stride > 0) - // new_limit = (limit < new_limit) ? MININT : new_limit; - // else - // new_limit = (limit > new_limit) ? MAXINT : new_limit; - // - BoolTest::mask bt = loop_end->test_trip(); - assert(bt == BoolTest::lt || bt == BoolTest::gt, "canonical test is expected"); - Node* underflow_clamp = _igvn.intcon((stride_con > 0) ? min_jint : max_jint); - set_ctrl(underflow_clamp, C->root()); - Node* limit_before_underflow = nullptr; - Node* prev_limit = nullptr; - Node* bol = limit->is_CMove() ? limit->in(CMoveNode::Condition) : nullptr; - if (loop_head->unrolled_count() > 1 && - limit->is_CMove() && limit->Opcode() == Op_CMoveI && - limit->in(CMoveNode::IfTrue) == underflow_clamp && - bol->as_Bool()->_test._test == bt && - bol->in(1)->Opcode() == Op_CmpI && - bol->in(1)->in(2) == limit->in(CMoveNode::IfFalse)) { - // Loop was unrolled before, and had an unrolling protection CMoveI. - // Use inputs to previous CMoveI for the new one: - prev_limit = limit->in(CMoveNode::IfFalse); // unpack previous limit with underflow - limit_before_underflow = bol->in(1)->in(1); // CMoveI -> Bool -> CmpI -> limit_before_underflow - } else { - // Loop was not unrolled before, or the limit did not underflow in a previous unrolling. - prev_limit = limit; - limit_before_underflow = limit; - } - // prev_limit stride - // | | - // limit_before_underflow new_limit_with_underflow (SubI) - // | | | - // underflow_cmp | - // | | - // underflow_bool [lt/gt] | - // | | - // +----+ +------------+ - // | | - // | | underflow_clamp (min_jint/max_jint) - // | | | - // CMoveINode ([min_jint..hi] / [lo..max_jing]) - // - assert(limit_before_underflow != nullptr && prev_limit != nullptr, "must find them"); - Node* new_limit_with_underflow = new SubINode(prev_limit, stride); - register_new_node(new_limit_with_underflow, ctrl); - // We must compare with limit_before_underflow, prev_limit may already have underflowed. - Node* underflow_cmp = new CmpINode(limit_before_underflow, new_limit_with_underflow); - register_new_node(underflow_cmp, ctrl); - Node* underflow_bool = new BoolNode(underflow_cmp, bt); - register_new_node(underflow_bool, ctrl); - // Prevent type from becoming too pessimistic due to type underflow. The new limit - // may be arbitrarily decreased by unrolling, but still in [min_jint..hi] / [lo..max_jint] - const TypeInt* limit_before_underflow_t = _igvn.type(limit_before_underflow)->is_int(); - const TypeInt* no_underflow_t = TypeInt::make(stride_con > 0 ? min_jint : limit_before_underflow_t->_lo, - stride_con > 0 ? limit_before_underflow_t->_hi : max_jint, - Type::WidenMax); - new_limit = new CMoveINode(underflow_bool, new_limit_with_underflow, underflow_clamp, no_underflow_t); + // limit = MinL(limit - stride, max_jint) + new_limit_no_underflow_l = new MinLNode(C, new_limit_l, underflow_clamp_l); } + register_new_node(new_limit_no_underflow_l, ctrl); + + // (4) Convert back to int. + new_limit = new ConvL2INode(new_limit_no_underflow_l); register_new_node(new_limit, ctrl); } @@ -2564,6 +2522,9 @@ void PhaseIdealLoop::mark_reductions(IdealLoopTree *loop) { //------------------------------adjust_limit----------------------------------- // Helper function that computes new loop limit as (rc_limit-offset)/scale Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round) { + Node* old_limit_long = new ConvI2LNode(old_limit); + register_new_node(old_limit_long, pre_ctrl); + Node* sub = new SubLNode(rc_limit, offset); register_new_node(sub, pre_ctrl); Node* limit = new DivLNode(nullptr, sub, scale); @@ -2589,27 +2550,19 @@ Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* o // - integer underflow of limit: MAXL chooses old_limit (>= MIN_INT > limit) // INT() is finally converting the limit back to an integer value. - // We use CMove nodes to implement long versions of min/max (MINL/MAXL). - // We use helper methods for inner MINL/MAXL which return CMoveL nodes to keep a long value for the outer MINL/MAXL comparison: - Node* inner_result_long; + Node* inner_result_long = nullptr; + Node* outer_result_long = nullptr; if (is_positive_stride) { - inner_result_long = MaxNode::signed_max(limit, _igvn.longcon(min_jint), TypeLong::LONG, _igvn); + inner_result_long = new MaxLNode(C, limit, _igvn.longcon(min_jint)); + outer_result_long = new MinLNode(C, inner_result_long, old_limit_long); } else { - inner_result_long = MaxNode::signed_min(limit, _igvn.longcon(max_jint), TypeLong::LONG, _igvn); + inner_result_long = new MinLNode(C, limit, _igvn.longcon(max_jint)); + outer_result_long = new MaxLNode(C, inner_result_long, old_limit_long); } - set_subtree_ctrl(inner_result_long, false); + register_new_node(inner_result_long, pre_ctrl); + register_new_node(outer_result_long, pre_ctrl); - // Outer MINL/MAXL: - // The comparison is done with long values but the result is the converted back to int by using CmovI. - Node* old_limit_long = new ConvI2LNode(old_limit); - register_new_node(old_limit_long, pre_ctrl); - Node* cmp = new CmpLNode(old_limit_long, limit); - register_new_node(cmp, pre_ctrl); - Node* bol = new BoolNode(cmp, is_positive_stride ? BoolTest::gt : BoolTest::lt); - register_new_node(bol, pre_ctrl); - Node* inner_result_int = new ConvL2INode(inner_result_long); // Could under-/overflow but that's fine as comparison was done with CmpL - register_new_node(inner_result_int, pre_ctrl); - limit = new CMoveINode(bol, old_limit, inner_result_int, TypeInt::INT); + limit = new ConvL2INode(outer_result_long); register_new_node(limit, pre_ctrl); return limit; } diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index f2cfe06c75c..e9132f83274 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2373,6 +2373,8 @@ void PhaseMacroExpand::eliminate_macro_nodes() { assert(n->Opcode() == Op_LoopLimit || n->Opcode() == Op_Opaque3 || n->Opcode() == Op_Opaque4 || + n->Opcode() == Op_MaxL || + n->Opcode() == Op_MinL || BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(n), "unknown node type in macro list"); } @@ -2457,6 +2459,18 @@ bool PhaseMacroExpand::expand_macro_nodes() { n->as_OuterStripMinedLoop()->adjust_strip_mined_loop(&_igvn); C->remove_macro_node(n); success = true; + } else if (n->Opcode() == Op_MaxL) { + // Since MaxL and MinL are not implemented in the backend, we expand them to + // a CMoveL construct now. At least until here, the type could be computed + // precisely. CMoveL is not so smart, but we can give it at least the best + // type we know abouot n now. + Node* repl = MaxNode::signed_max(n->in(1), n->in(2), _igvn.type(n), _igvn); + _igvn.replace_node(n, repl); + success = true; + } else if (n->Opcode() == Op_MinL) { + Node* repl = MaxNode::signed_min(n->in(1), n->in(2), _igvn.type(n), _igvn); + _igvn.replace_node(n, repl); + success = true; } assert(!success || (C->macro_count() == (old_macro_count - 1)), "elimination must have deleted one node from macro list"); progress = progress || success; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index bdbdf006779..8c1dbaef277 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -654,6 +654,11 @@ public class IRNode { beforeMatchingNameRegex(MAX_I, "MaxI"); } + public static final String MAX_L = PREFIX + "MAX_L" + POSTFIX; + static { + beforeMatchingNameRegex(MAX_L, "MaxL"); + } + public static final String MAX_V = PREFIX + "MAX_V" + POSTFIX; static { beforeMatchingNameRegex(MAX_V, "MaxV"); @@ -679,6 +684,11 @@ public class IRNode { beforeMatchingNameRegex(MIN_I, "MinI"); } + public static final String MIN_L = PREFIX + "MIN_L" + POSTFIX; + static { + beforeMatchingNameRegex(MIN_L, "MinL"); + } + public static final String MIN_V = PREFIX + "MIN_V" + POSTFIX; static { beforeMatchingNameRegex(MIN_V, "MinV"); diff --git a/test/hotspot/jtreg/compiler/loopopts/TestLoopLimitSubtractionsCollapse.java b/test/hotspot/jtreg/compiler/loopopts/TestLoopLimitSubtractionsCollapse.java new file mode 100644 index 00000000000..129916cf6f7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestLoopLimitSubtractionsCollapse.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8303466 + * @summary Verify that AddL->MaxL->AddL->MaxL chains of unroll limit adjustments collapse. + * If it did not collapse, we would have about 10 MaxL/MinL. With the collapse, it + * is now one or two. + * @library /test/lib / + * @requires vm.compiler2.enabled + * @run driver compiler.loopopts.TestLoopLimitSubtractionsCollapse + */ + +package compiler.loopopts; +import compiler.lib.ir_framework.*; + +public class TestLoopLimitSubtractionsCollapse { + static int START = 0; + static int FINISH = 512; + static int RANGE = 512; + + static byte[] data1 = new byte[RANGE]; + static byte[] data2 = new byte[RANGE]; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @Warmup(0) + @IR(counts = {IRNode.MAX_L, "> 0", IRNode.MAX_L, "<= 2"}, + phase = CompilePhase.PHASEIDEALLOOP_ITERATIONS) + public static void test1() { + for (int j = START; j < FINISH; j++) { + data1[j] = (byte)(data1[j] * 11); + } + } + + @Test + @Warmup(0) + @IR(counts = {IRNode.MIN_L, "> 0", IRNode.MIN_L, "<= 2"}, + phase = CompilePhase.PHASEIDEALLOOP_ITERATIONS) + public static void test2() { + for (int j = FINISH-1; j >= START; j--) { + data2[j] = (byte)(data2[j] * 11); + } + } +} diff --git a/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java b/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java new file mode 100644 index 00000000000..18a58aa7ae5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestUnrollLimitPreciseType.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test id=test1 + * @bug 8298935 + * @summary CMoveI for underflow protection of the limit did not compute a type that was precise enough. + * This lead to dead data but zero-trip-guard control did not die -> "malformed control flow". + * @requires vm.compiler2.enabled + * @run main/othervm + * -XX:CompileCommand=compileonly,compiler.loopopts.TestUnrollLimitPreciseType::test1 + * -XX:CompileCommand=dontinline,compiler.loopopts.TestUnrollLimitPreciseType::* + * -XX:MaxVectorSize=64 + * -Xcomp + * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=0 -XX:PerMethodTrapLimit=0 + * compiler.loopopts.TestUnrollLimitPreciseType test1 + */ + +/* + * @test id=test2 + * @bug 8298935 + * @summary CMoveI for underflow protection of the limit did not compute a type that was precise enough. + * This lead to dead data but zero-trip-guard control did not die -> "malformed control flow". + * @requires vm.compiler2.enabled + * @run main/othervm + * -XX:CompileCommand=compileonly,compiler.loopopts.TestUnrollLimitPreciseType::* + * -Xcomp + * compiler.loopopts.TestUnrollLimitPreciseType test2 + */ + + +package compiler.loopopts; + +public class TestUnrollLimitPreciseType { + static final int RANGE = 512; + + public static void main(String args[]) { + if (args.length != 1) { + throw new RuntimeException("Need exactly one argument."); + } + if (args[0].equals("test1")) { + byte[] data = new byte[RANGE]; + test1(data); + } else if (args[0].equals("test2")) { + test2(); + } else { + throw new RuntimeException("Do not have: " + args[0]); + } + } + + public static void test1(byte[] data) { + // Did not fully analyze this. But it is also unrolled, SuperWorded, + // and further unrolled with vectorlized post loop. + // Only seems to reproduce with avx512, and not with avx2. + for (int j = 192; j < RANGE; j++) { + data[j - 192] = (byte)(data[j] * 11); + } + } + + static void test2() { + // Loop is SuperWord'ed. + // We unroll more afterwards, and so add vectorized post loop. + // But it turns out that the vectorized post loop is never entered. + // This lead to assert, because the zero-trip-guard did not collaspse, + // but the CastII with the trip count did die. + // Only seems to reproduce with avx512, and not with avx2. + double dArr[][] = new double[100][100]; + for (int i = 2, j = 2; j < 68; j++) { + dArr[i][j] = 8; + } + } +} From 44d9f55d0b3c469988be6f1c47f0cfbc433c4490 Mon Sep 17 00:00:00 2001 From: Tejesh R Date: Wed, 26 Apr 2023 05:44:13 +0000 Subject: [PATCH 146/288] 8306072: Open source several AWT MouseInfo related tests Reviewed-by: serb, psadhukhan --- .../jdk/java/awt/MouseInfo/ButtonsNumber.java | 41 +++++ .../MouseInfo/ContainerMousePositionTest.java | 172 ++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 test/jdk/java/awt/MouseInfo/ButtonsNumber.java create mode 100644 test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java diff --git a/test/jdk/java/awt/MouseInfo/ButtonsNumber.java b/test/jdk/java/awt/MouseInfo/ButtonsNumber.java new file mode 100644 index 00000000000..9da0756333c --- /dev/null +++ b/test/jdk/java/awt/MouseInfo/ButtonsNumber.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4908137 + @summary tests that non-zero number of mouse buttons is returned + @key headful +*/ + +import java.awt.MouseInfo; + +public class ButtonsNumber { + + public static void main(String[] args) { + + if (MouseInfo.getNumberOfButtons() == 0) { + throw new RuntimeException("Zero returned by getNumberOfButtons(). Test failed."); + } + } +} diff --git a/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java b/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java new file mode 100644 index 00000000000..18f1e975c31 --- /dev/null +++ b/test/jdk/java/awt/MouseInfo/ContainerMousePositionTest.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @summary unit test for a new method in Container class: getMousePosition(boolean) + @bug 4009555 + @key headful +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; + +public class ContainerMousePositionTest { + private Button button; + private Frame frame; + private Panel panel; + private static Dimension BUTTON_DIMENSION = new Dimension(100, 100); + private static Dimension FRAME_DIMENSION = new Dimension(200, 200); + private static Point POINT_WITHOUT_COMPONENTS = new Point(10, 10); + private static Point FIRST_BUTTON_LOCATION = new Point(20, 20); + private static int DELAY = 1000; + Robot robot; + volatile int xPos = 0; + volatile int yPos = 0; + Point pMousePosition; + + public static void main(String[] args) throws Exception { + ContainerMousePositionTest containerObj = new ContainerMousePositionTest(); + containerObj.init(); + containerObj.start(); + } + + public void init() throws Exception { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + button = new Button("Button"); + frame = new Frame("Testing Component.getMousePosition()"); + panel = new Panel(); + + button.setSize(BUTTON_DIMENSION); + button.setLocation(FIRST_BUTTON_LOCATION); + + panel.setLayout(null); + + panel.add(button); + frame.add(panel); + frame.setSize(FRAME_DIMENSION); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + robot.delay(DELAY); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + Point p = button.getLocationOnScreen(); + xPos = p.x + button.getWidth() / 2; + yPos = p.y + button.getHeight() / 2; + }); + robot.mouseMove(xPos,yPos); + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = frame.getMousePosition(false); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Container is " + + "overlapped by " + " child and it should be taken " + + "into account"); + } + System.out.println("Test stage completed: Container is " + + "overlapped by " + " child and it was taken into " + + "account"); + + pMousePosition = frame.getMousePosition(true); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Container is " + + "overlapped by " + " child and it should not be " + + "taken into account"); + } + System.out.println("Test stage completed: Container is " + + "overlapped by " + " child and it should not be " + + "taken into account"); + xPos = panel.getLocationOnScreen().x + POINT_WITHOUT_COMPONENTS.x; + yPos = panel.getLocationOnScreen().y + POINT_WITHOUT_COMPONENTS.y; + }); + + robot.mouseMove(xPos, yPos); + + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = panel.getMousePosition(true); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Pointer was " + + "outside of " + "the component so getMousePosition()" + + " should not return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the component and getMousePosition() has not returned null"); + + pMousePosition = panel.getMousePosition(false); + if (pMousePosition == null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the component so getMousePosition() should not return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the component and getMousePosition() has not returned null"); + xPos = frame.getLocationOnScreen().x + frame.getWidth() + POINT_WITHOUT_COMPONENTS.x; + yPos = frame.getLocationOnScreen().y + frame.getHeight() + POINT_WITHOUT_COMPONENTS.y; + }); + robot.mouseMove(xPos, yPos); + + robot.delay(DELAY); + + EventQueue.invokeAndWait(() -> { + pMousePosition = frame.getMousePosition(true); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the Frame widow and getMousePosition() should return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the Frame widow and getMousePosition() returned null"); + + pMousePosition = frame.getMousePosition(false); + if (pMousePosition != null) { + throw new RuntimeException("Test failed: Pointer was outside of " + + "the Frame widow and getMousePosition() should return null"); + } + System.out.println("Test stage completed: Pointer was outside of " + + "the Frame widow and getMousePosition() returned null"); + }); + robot.delay(DELAY); + + System.out.println("ComponentMousePositionTest PASSED."); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} From 8d899925dc281c5dabbef14d85a6df807f8d300e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Wed, 26 Apr 2023 08:25:11 +0000 Subject: [PATCH 147/288] 8298189: Regression in SPECjvm2008-MonteCarlo for pre-Cascade Lake Intel processors Co-authored-by: Quan Anh Mai Reviewed-by: shade, thartmann, kvn --- src/hotspot/cpu/x86/vm_version_x86.cpp | 7 +++++-- src/hotspot/cpu/x86/vm_version_x86.hpp | 2 ++ src/hotspot/cpu/x86/x86_64.ad | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index b194f42e195..b4e9e721b5a 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -2079,11 +2079,14 @@ bool VM_Version::is_default_intel_cascade_lake() { return FLAG_IS_DEFAULT(UseAVX) && FLAG_IS_DEFAULT(MaxVectorSize) && UseAVX > 2 && - is_intel_skylake() && - _stepping >= 5; + is_intel_cascade_lake(); } #endif +bool VM_Version::is_intel_cascade_lake() { + return is_intel_skylake() && _stepping >= 5; +} + // avx3_threshold() sets the threshold at which 64-byte instructions are used // for implementing the array copy and clear operations. // The Intel platforms that supports the serialize instruction diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index 65f8c5b3cba..3074621229a 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -716,6 +716,8 @@ public: static bool is_default_intel_cascade_lake(); #endif + static bool is_intel_cascade_lake(); + static int avx3_threshold(); static bool is_intel_tsc_synched_at_init(); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 7c1eb99bf58..fd64a684674 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -13732,6 +13732,13 @@ instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) ins_pipe(ialu_reg_reg); %} +// These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, +// sal}) with lea instructions. The {add, sal} rules are beneficial in +// processors with at least partial ALU support for lea +// (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally +// beneficial for processors with full ALU support +// (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. + peephole %{ peeppredicate(VM_Version::supports_fast_2op_lea()); @@ -13750,7 +13757,8 @@ peephole peephole %{ - peeppredicate(VM_Version::supports_fast_2op_lea()); + peeppredicate(VM_Version::supports_fast_3op_lea() || + VM_Version::is_intel_cascade_lake()); peepmatch (incI_rReg); peepprocedure (lea_coalesce_imm); peepreplace (leaI_rReg_immI_peep()); @@ -13758,7 +13766,8 @@ peephole peephole %{ - peeppredicate(VM_Version::supports_fast_2op_lea()); + peeppredicate(VM_Version::supports_fast_3op_lea() || + VM_Version::is_intel_cascade_lake()); peepmatch (decI_rReg); peepprocedure (lea_coalesce_imm); peepreplace (leaI_rReg_immI_peep()); @@ -13790,7 +13799,8 @@ peephole peephole %{ - peeppredicate(VM_Version::supports_fast_2op_lea()); + peeppredicate(VM_Version::supports_fast_3op_lea() || + VM_Version::is_intel_cascade_lake()); peepmatch (incL_rReg); peepprocedure (lea_coalesce_imm); peepreplace (leaL_rReg_immL32_peep()); @@ -13798,7 +13808,8 @@ peephole peephole %{ - peeppredicate(VM_Version::supports_fast_2op_lea()); + peeppredicate(VM_Version::supports_fast_3op_lea() || + VM_Version::is_intel_cascade_lake()); peepmatch (decL_rReg); peepprocedure (lea_coalesce_imm); peepreplace (leaL_rReg_immL32_peep()); From d74769826ddb5e68df76407fb94c7560475249a0 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Wed, 26 Apr 2023 08:29:06 +0000 Subject: [PATCH 148/288] 8306823: Native memory leak in SharedRuntime::notify_jvmti_unmount/mount. Reviewed-by: pchilanomate, sspitsyn --- src/hotspot/share/runtime/sharedRuntime.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index ddb9dc6988f..91cba5dd3ea 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -64,7 +64,7 @@ #include "runtime/interfaceSupport.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" -#include "runtime/jniHandles.hpp" +#include "runtime/jniHandles.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stackWatermarkSet.hpp" #include "runtime/stubRoutines.hpp" @@ -644,6 +644,8 @@ JRT_ENTRY(void, SharedRuntime::notify_jvmti_mount(oopDesc* vt, jboolean hide, jb } else { JvmtiVTMSTransitionDisabler::VTMS_mount_end(vthread, first_mount); } + + JNIHandles::destroy_local(vthread); JRT_END JRT_ENTRY(void, SharedRuntime::notify_jvmti_unmount(oopDesc* vt, jboolean hide, jboolean last_unmount, JavaThread* current)) @@ -654,6 +656,8 @@ JRT_ENTRY(void, SharedRuntime::notify_jvmti_unmount(oopDesc* vt, jboolean hide, } else { JvmtiVTMSTransitionDisabler::VTMS_unmount_end(vthread, last_unmount); } + + JNIHandles::destroy_local(vthread); JRT_END #endif // INCLUDE_JVMTI From 86f41a4c42268d364175263804eb4d1ce82fa943 Mon Sep 17 00:00:00 2001 From: Ivan Walulya Date: Wed, 26 Apr 2023 10:09:56 +0000 Subject: [PATCH 149/288] 8306735: G1: G1FullGCScope remove unnecessary member _explicit_gc Reviewed-by: ayang, tschatzl --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 17 ++++++----------- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 7 ++----- src/hotspot/share/gc/g1/g1FullCollector.cpp | 5 ++--- src/hotspot/share/gc/g1/g1FullCollector.hpp | 1 - src/hotspot/share/gc/g1/g1FullGCScope.cpp | 6 ------ src/hotspot/share/gc/g1/g1FullGCScope.hpp | 3 --- src/hotspot/share/gc/g1/g1VMOperations.cpp | 3 +-- 7 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 7fa45347647..22528a0fe2c 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -841,8 +841,7 @@ void G1CollectedHeap::prepare_heap_for_full_collection() { _hrm.remove_all_free_regions(); } -void G1CollectedHeap::verify_before_full_collection(bool explicit_gc) { - assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant"); +void G1CollectedHeap::verify_before_full_collection() { assert_used_and_recalculate_used_equal(this); if (!VerifyBeforeGC) { return; @@ -913,8 +912,7 @@ void G1CollectedHeap::verify_after_full_collection() { _ref_processor_cm->verify_no_references_recorded(); } -bool G1CollectedHeap::do_full_collection(bool explicit_gc, - bool clear_all_soft_refs, +bool G1CollectedHeap::do_full_collection(bool clear_all_soft_refs, bool do_maximal_compaction) { assert_at_safepoint_on_vm_thread(); @@ -928,7 +926,7 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc, G1FullGCMark gc_mark; GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true); - G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs, do_maximal_compaction, gc_mark.tracer()); + G1FullCollector collector(this, do_clear_all_soft_refs, do_maximal_compaction, gc_mark.tracer()); collector.prepare_collection(); collector.collect(); @@ -943,16 +941,14 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { // the caller that the collection did not succeed (e.g., because it was locked // out by the GC locker). So, right now, we'll ignore the return value. - do_full_collection(false, /* explicit_gc */ - clear_all_soft_refs, + do_full_collection(clear_all_soft_refs, false /* do_maximal_compaction */); } bool G1CollectedHeap::upgrade_to_full_collection() { GCCauseSetter compaction(this, GCCause::_g1_compaction_pause); log_info(gc, ergo)("Attempting full compaction clearing soft references"); - bool success = do_full_collection(false /* explicit gc */, - true /* clear_all_soft_refs */, + bool success = do_full_collection(true /* clear_all_soft_refs */, false /* do_maximal_compaction */); // do_full_collection only fails if blocked by GC locker and that can't // be the case here since we only call this when already completed one gc. @@ -1008,8 +1004,7 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size, } else { log_info(gc, ergo)("Attempting full compaction"); } - *gc_succeeded = do_full_collection(false, /* explicit_gc */ - maximal_compaction /* clear_all_soft_refs */ , + *gc_succeeded = do_full_collection(maximal_compaction /* clear_all_soft_refs */ , maximal_compaction /* do_maximal_compaction */); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 59d9f69ed2e..b3b282f3712 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -479,16 +479,13 @@ private: void retire_gc_alloc_region(HeapRegion* alloc_region, size_t allocated_bytes, G1HeapRegionAttr dest); - // - if explicit_gc is true, the GC is for a System.gc() etc, - // otherwise it's for a failed allocation. // - if clear_all_soft_refs is true, all soft references should be // cleared during the GC. // - if do_maximal_compaction is true, full gc will do a maximally // compacting collection, leaving no dead wood. // - it returns false if it is unable to do the collection due to the // GC locker being active, true otherwise. - bool do_full_collection(bool explicit_gc, - bool clear_all_soft_refs, + bool do_full_collection(bool clear_all_soft_refs, bool do_maximal_compaction); // Callback from VM_G1CollectFull operation, or collect_as_vm_thread. @@ -505,7 +502,7 @@ private: // Internal helpers used during full GC to split it up to // increase readability. bool abort_concurrent_cycle(); - void verify_before_full_collection(bool explicit_gc); + void verify_before_full_collection(); void prepare_heap_for_full_collection(); void prepare_for_mutator_after_full_collection(); void abort_refinement(); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 64b9a69defb..14f9c9f2279 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -111,12 +111,11 @@ uint G1FullCollector::calc_active_workers() { } G1FullCollector::G1FullCollector(G1CollectedHeap* heap, - bool explicit_gc, bool clear_soft_refs, bool do_maximal_compaction, G1FullGCTracer* tracer) : _heap(heap), - _scope(heap->monitoring_support(), explicit_gc, clear_soft_refs, do_maximal_compaction, tracer), + _scope(heap->monitoring_support(), clear_soft_refs, do_maximal_compaction, tracer), _num_workers(calc_active_workers()), _has_compaction_targets(false), _has_humongous(false), @@ -183,7 +182,7 @@ void G1FullCollector::prepare_collection() { // Verification needs the bitmap, so we should clear the bitmap only later. bool in_concurrent_cycle = _heap->abort_concurrent_cycle(); - _heap->verify_before_full_collection(scope()->is_explicit_gc()); + _heap->verify_before_full_collection(); if (in_concurrent_cycle) { GCTraceTime(Debug, gc) debug("Clear Bitmap"); _heap->concurrent_mark()->clear_bitmap(_heap->workers()); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index e20cef20ab5..0f274d5252f 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -100,7 +100,6 @@ class G1FullCollector : StackObj { public: G1FullCollector(G1CollectedHeap* heap, - bool explicit_gc, bool clear_soft_refs, bool do_maximal_compaction, G1FullGCTracer* tracer); diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index 25abb4b05ea..5bbc5c4e2d4 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -37,12 +37,10 @@ G1FullGCJFRTracerMark::~G1FullGCJFRTracerMark() { } G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support, - bool explicit_gc, bool clear_soft, bool do_maximal_compaction, G1FullGCTracer* tracer) : _rm(), - _explicit_gc(explicit_gc), _do_maximal_compaction(do_maximal_compaction), _g1h(G1CollectedHeap::heap()), _svc_marker(SvcGCMarker::FULL), @@ -57,10 +55,6 @@ G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support, HeapRegion::GrainWords : (1 - MarkSweepDeadRatio / 100.0) * HeapRegion::GrainWords) { } -bool G1FullGCScope::is_explicit_gc() { - return _explicit_gc; -} - bool G1FullGCScope::should_clear_soft_refs() { return _soft_refs.should_clear(); } diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.hpp b/src/hotspot/share/gc/g1/g1FullGCScope.hpp index 398b7ba386c..f3d89c7646f 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp @@ -47,7 +47,6 @@ public: // Class used to group scoped objects used in the Full GC together. class G1FullGCScope : public StackObj { ResourceMark _rm; - bool _explicit_gc; bool _do_maximal_compaction; G1CollectedHeap* _g1h; SvcGCMarker _svc_marker; @@ -62,12 +61,10 @@ class G1FullGCScope : public StackObj { public: G1FullGCScope(G1MonitoringSupport* monitoring_support, - bool explicit_gc, bool clear_soft, bool do_maximal_compaction, G1FullGCTracer* tracer); - bool is_explicit_gc(); bool should_clear_soft_refs(); bool do_maximal_compaction() { return _do_maximal_compaction; } diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 8ccd7f2c9fb..e149301e277 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -51,8 +51,7 @@ bool VM_G1CollectFull::skip_operation() const { void VM_G1CollectFull::doit() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); GCCauseSetter x(g1h, _gc_cause); - _gc_succeeded = g1h->do_full_collection(true /* explicit_gc */, - false /* clear_all_soft_refs */, + _gc_succeeded = g1h->do_full_collection(false /* clear_all_soft_refs */, false /* do_maximal_compaction */); } From c5910fa065ec9b95fcc63047a76f9f4c5cf64dd6 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 26 Apr 2023 10:58:50 +0000 Subject: [PATCH 150/288] 8306749: Make CardTable::invalidate non-virtual Reviewed-by: tschatzl --- src/hotspot/share/gc/shared/cardTable.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp index c2c4011ca24..c9b4ba164ee 100644 --- a/src/hotspot/share/gc/shared/cardTable.hpp +++ b/src/hotspot/share/gc/shared/cardTable.hpp @@ -133,7 +133,7 @@ public: return byte_for(p) + 1; } - virtual void invalidate(MemRegion mr); + void invalidate(MemRegion mr); // Provide read-only access to the card table array. const CardValue* byte_for_const(const void* p) const { From 9ad6dc881d285cc26c136f0ef19af5bac0a75022 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 26 Apr 2023 11:11:54 +0000 Subject: [PATCH 151/288] 8306774: Make runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java more reliable Reviewed-by: stuefe, dcubed --- test/hotspot/jtreg/ProblemList.txt | 4 -- .../GuaranteedAsyncDeflationIntervalTest.java | 41 ++++++++++++++----- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 6d4ce15ce62..289102d7633 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -101,10 +101,6 @@ runtime/CompressedOops/CompressedClassPointers.java 8305765 generic-all runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/Thread/TestAlwaysPreTouchStacks.java 8305416 generic-all runtime/ErrorHandling/TestDwarf.java 8305489 linux-all -runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#allDisabled 8306774 generic-all -runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#guaranteedNoADI 8306774 generic-all -runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#allEnabled 8306774 generic-all -runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java#guaranteedNoMUDT 8306774 generic-all applications/jcstress/copy.java 8229852 linux-all diff --git a/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java b/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java index 59957005789..0bda25aebf3 100644 --- a/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java +++ b/test/hotspot/jtreg/runtime/Monitor/GuaranteedAsyncDeflationIntervalTest.java @@ -58,21 +58,40 @@ public class GuaranteedAsyncDeflationIntervalTest { public static class Test { // Inflate a lot of monitors, so that threshold heuristics definitely fires - public static final int MONITORS = 10_000; + private static final int MONITORS = 10_000; - public static Object[] monitors; + // Use a handful of threads to inflate the monitors, to eat the cost of + // wait(1) calls. This can be larger than available parallelism, since threads + // would be time-waiting. + private static final int THREADS = 16; + + private static Thread[] threads; + private static Object[] monitors; public static void main(String... args) throws Exception { monitors = new Object[MONITORS]; - for (int i = 0; i < MONITORS; i++) { - Object o = new Object(); - synchronized (o) { - try { - o.wait(1); // Inflate! - } catch (InterruptedException ie) { + threads = new Thread[THREADS]; + + for (int t = 0; t < THREADS; t++) { + int monStart = t * MONITORS / THREADS; + int monEnd = (t + 1) * MONITORS / THREADS; + threads[t] = new Thread(() -> { + for (int m = monStart; m < monEnd; m++) { + Object o = new Object(); + synchronized (o) { + try { + o.wait(1); + } catch (InterruptedException e) { + } + } + monitors[m] = o; } - } - monitors[i] = o; + }); + threads[t].start(); + } + + for (Thread t : threads) { + t.join(); } try { @@ -170,7 +189,7 @@ public class GuaranteedAsyncDeflationIntervalTest { "-Xmx100M", "-XX:+UnlockDiagnosticVMOptions", "-XX:GuaranteedAsyncDeflationInterval=5000", - "-XX:MonitorUsedDeflationThreshold=10", + "-XX:MonitorUsedDeflationThreshold=1", "-Xlog:monitorinflation=info", "GuaranteedAsyncDeflationIntervalTest$Test"); From 35e7bc21d3c1b38e2268924b20ae4b149b4f8cd8 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 26 Apr 2023 11:12:42 +0000 Subject: [PATCH 152/288] 8306855: [s390x] fix difference in abi sizes Reviewed-by: mdoerr, lucy --- src/hotspot/cpu/s390/c1_FrameMap_s390.hpp | 6 +- src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 4 +- src/hotspot/cpu/s390/c1_Runtime1_s390.cpp | 6 +- src/hotspot/cpu/s390/frame_s390.cpp | 6 +- src/hotspot/cpu/s390/frame_s390.hpp | 59 ++++++++++--------- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 2 +- .../cpu/s390/macroAssembler_s390.inline.hpp | 8 +-- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 6 +- .../templateInterpreterGenerator_s390.cpp | 2 +- 9 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/hotspot/cpu/s390/c1_FrameMap_s390.hpp b/src/hotspot/cpu/s390/c1_FrameMap_s390.hpp index ef20d0399c1..66ccc8de876 100644 --- a/src/hotspot/cpu/s390/c1_FrameMap_s390.hpp +++ b/src/hotspot/cpu/s390/c1_FrameMap_s390.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023, 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. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ enum { nof_reg_args = 5, // Registers Z_ARG1 - Z_ARG5 are available for parameter passing. - first_available_sp_in_frame = frame::z_abi_16_size, + first_available_sp_in_frame = frame::z_common_abi_size, frame_pad_in_bytes = 0 }; diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index 2f945837dfc..a32667f65df 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -238,7 +238,7 @@ int LIR_Assembler::emit_unwind_handler() { // Remove the activation and dispatch to the unwind handler. __ pop_frame(); - __ z_lg(Z_EXC_PC, _z_abi16(return_pc), Z_SP); + __ z_lg(Z_EXC_PC, _z_common_abi(return_pc), Z_SP); // Z_EXC_OOP: exception oop // Z_EXC_PC: exception pc diff --git a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp index 1a3ce714e32..28acb398c1f 100644 --- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp +++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -807,7 +807,7 @@ OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { // Load issuing PC (the return address for this stub). const int frame_size_in_bytes = sasm->frame_size() * VMRegImpl::slots_per_word * VMRegImpl::stack_slot_size; - __ z_lg(Z_EXC_PC, Address(Z_SP, frame_size_in_bytes + _z_abi16(return_pc))); + __ z_lg(Z_EXC_PC, Address(Z_SP, frame_size_in_bytes + _z_common_abi(return_pc))); DEBUG_ONLY(__ z_lay(reg_fp, Address(Z_SP, frame_size_in_bytes));) // Make sure that the vm_results are cleared (may be unnecessary). @@ -850,7 +850,7 @@ OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { #ifdef ASSERT { NearLabel ok; - __ z_cg(Z_EXC_PC, Address(reg_fp, _z_abi16(return_pc))); + __ z_cg(Z_EXC_PC, Address(reg_fp, _z_common_abi(return_pc))); __ branch_optimized(Assembler::bcondEqual, ok); __ stop("use throwing pc as return address (has bci & oop map)"); __ bind(ok); diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index 37683bdac8e..23547fa6617 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2022 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -117,7 +117,7 @@ bool frame::safe_for_sender(JavaThread *thread) { return false; } - z_abi_16* sender_abi = (z_abi_16*)fp; + z_common_abi* sender_abi = (z_common_abi*)fp; intptr_t* sender_sp = (intptr_t*) fp; address sender_pc = (address) sender_abi->return_pc; @@ -278,7 +278,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const { if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { return false; } - int min_frame_slots = (z_abi_16_size + z_ijava_state_size) / sizeof(intptr_t); + int min_frame_slots = (z_common_abi_size + z_ijava_state_size) / sizeof(intptr_t); if (fp() - min_frame_slots < sp()) { return false; } diff --git a/src/hotspot/cpu/s390/frame_s390.hpp b/src/hotspot/cpu/s390/frame_s390.hpp index a7c53f23c70..2c2aee26270 100644 --- a/src/hotspot/cpu/s390/frame_s390.hpp +++ b/src/hotspot/cpu/s390/frame_s390.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023, 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. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ // 0 [ABI_160] // // ABI_160: - // 0 [ABI_16] + // 0 [Z_COMMON_ABI] // 16 CARG_1: spill slot for outgoing arg 1. used by next callee. // 24 CARG_2: spill slot for outgoing arg 2. used by next callee. // 32 CARG_3: spill slot for outgoing arg 3. used by next callee. @@ -61,7 +61,7 @@ // 152 CFARG_4: spill slot for outgoing fp arg 4. used by next callee. // 160 [REMAINING CARGS] // - // ABI_16: + // Z_COMMON_ABI: // 0 callers_sp // 8 return_pc @@ -76,17 +76,23 @@ log_2_of_alignment_in_bits = 6 } frame_constants; - struct z_abi_16 { + // Common ABI. On top of all frames, C and Java + struct z_common_abi { uint64_t callers_sp; uint64_t return_pc; }; enum { - z_abi_16_size = sizeof(z_abi_16) + z_common_abi_size = sizeof(z_common_abi) }; - #define _z_abi16(_component) \ - (offset_of(frame::z_abi_16, _component)) + #define _z_common_abi(_component) \ + (offset_of(frame::z_common_abi, _component)) + + // Z_NATIVE_ABI for native C frames. + struct z_native_abi: z_common_abi { + // Nothing to add here! + }; // ABI_160: @@ -98,9 +104,7 @@ // long as we do not provide extra infrastructure, one should use // either z_abi_160_size, or _z_abi(remaining_cargs) instead of // sizeof(...). - struct z_abi_160 { - uint64_t callers_sp; - uint64_t return_pc; + struct z_abi_160 : z_native_abi { uint64_t carg_1; uint64_t carg_2; uint64_t carg_3; @@ -123,6 +127,7 @@ }; enum { + z_native_abi_size = sizeof(z_native_abi), z_abi_160_size = 160 }; @@ -158,6 +163,10 @@ // Frame layout for the Java template interpreter on z/Architecture. // + // We differentiate between TOP and PARENT frames. + // TOP frames allow for calling native C code. + // A TOP frame is trimmed to a PARENT frame when calling a Java method. + // // In these figures the stack grows upwards, while memory grows // downwards. Square brackets denote regions possibly larger than // single 64 bit slots. @@ -250,13 +259,14 @@ public: - // PARENT_IJAVA_FRAME_ABI + // ABI for every Java frame, compiled and interpreted - struct z_parent_ijava_frame_abi : z_abi_16 { + struct z_java_abi : z_common_abi { + // Nothing to add here! }; - enum { - z_parent_ijava_frame_abi_size = sizeof(z_parent_ijava_frame_abi) + struct z_parent_ijava_frame_abi : z_java_abi { + // Nothing to add here! }; #define _z_parent_ijava_frame_abi(_component) \ @@ -268,6 +278,8 @@ }; enum { + z_java_abi_size = sizeof(z_java_abi), + z_parent_ijava_frame_abi_size = sizeof(z_parent_ijava_frame_abi), z_top_ijava_frame_abi_size = sizeof(z_top_ijava_frame_abi) }; @@ -357,17 +369,8 @@ // [monitor] (optional) // [in_preserve] added / removed by prolog / epilog - public: - - struct z_top_jit_abi_32 { - uint64_t callers_sp; - uint64_t return_pc; - uint64_t toc; - uint64_t tmp; - }; - - #define _z_top_jit_abi(_component) \ - (offset_of(frame::z_top_jit_abi_32, _component)) + // For JIT frames we don't differentiate between TOP and PARENT frames. + // Runtime calls go through stubs which push a new frame. struct jit_monitor { uint64_t monitor[1]; @@ -378,7 +381,7 @@ // nothing to add here! }; - struct jit_out_preserve : z_top_jit_abi_32 { + struct jit_out_preserve : z_java_abi { // Nothing to add here! }; @@ -473,7 +476,7 @@ inline intptr_t sp_at( int index) const { return *sp_addr_at(index); } // Access ABIs. - inline z_abi_16* own_abi() const { return (z_abi_16*) sp(); } + inline z_common_abi* own_abi() const { return (z_common_abi*) sp(); } inline z_abi_160* callers_abi() const { return (z_abi_160*) fp(); } private: diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 50a4f1bc438..dcd98b3866d 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -2125,7 +2125,7 @@ void MacroAssembler::pop_frame() { // Pop current C frame and restore return PC register (Z_R14). void MacroAssembler::pop_frame_restore_retPC(int frame_size_in_bytes) { BLOCK_COMMENT("pop_frame_restore_retPC:"); - int retPC_offset = _z_abi16(return_pc) + frame_size_in_bytes; + int retPC_offset = _z_common_abi(return_pc) + frame_size_in_bytes; // If possible, pop frame by add instead of load (a penny saved is a penny got :-). if (Displacement::is_validDisp(retPC_offset)) { z_lg(Z_R14, retPC_offset, Z_SP); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp index 08c81e908f4..d81562d9e9a 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023, 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. * * This code is free software; you can redistribute it and/or modify it @@ -250,11 +250,11 @@ inline bool MacroAssembler::is_load_addr_pcrel(address a) { // Save the return pc in the register that should be stored as the return pc // in the current frame (default is R14). inline void MacroAssembler::save_return_pc(Register pc) { - z_stg(pc, _z_abi16(return_pc), Z_SP); + z_stg(pc, _z_common_abi(return_pc), Z_SP); } inline void MacroAssembler::restore_return_pc() { - z_lg(Z_R14, _z_abi16(return_pc), Z_SP); + z_lg(Z_R14, _z_common_abi(return_pc), Z_SP); } // Call a function with given entry. diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index a1c0a6b1811..8b7a5b1bc56 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -329,7 +329,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, RegisterSet reg // We have to restore return_pc right away. // Nobody else will. Furthermore, return_pc isn't necessarily the default (Z_R14). // Nobody else knows which register we saved. - __ z_lg(return_pc, _z_abi16(return_pc) + frame_size_in_bytes, Z_SP); + __ z_lg(return_pc, _z_common_abi(return_pc) + frame_size_in_bytes, Z_SP); // Register save area in new frame starts above z_abi_160 area. int offset = register_save_offset; @@ -2921,7 +2921,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t if (!cause_return) { Label no_adjust; // If our stashed return pc was modified by the runtime we avoid touching it - const int offset_of_return_pc = _z_abi16(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers); + const int offset_of_return_pc = _z_common_abi(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers); __ z_cg(Z_R6, offset_of_return_pc, Z_SP); __ z_brne(no_adjust); diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index bea48e51544..627f0bc44c9 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1087,7 +1087,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { } // asm_assert* is a nop in product builds - NOT_PRODUCT(__ z_cg(Z_R14, _z_abi16(return_pc), Z_SP)); + NOT_PRODUCT(__ z_cg(Z_R14, _z_common_abi(return_pc), Z_SP)); NOT_PRODUCT(__ asm_assert_eq("killed Z_R14", 0)); __ resize_frame_absolute(sp_after_resize, fp, true); __ save_return_pc(Z_R14); From 2e340e855b760e381793107f2a4d74095bd40199 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Wed, 26 Apr 2023 14:53:33 +0000 Subject: [PATCH 153/288] 8233725: ProcessTools.startProcess() has output issues when using an OutputAnalyzer at the same time Reviewed-by: cjplummer, sspitsyn --- test/jdk/sun/tools/jstatd/JstatdTest.java | 7 +- .../process/ProcessToolsStartProcessTest.java | 122 ++++++++++++++++++ .../jdk/test/lib/process/ProcessTools.java | 92 +++++++++++-- 3 files changed, 209 insertions(+), 12 deletions(-) create mode 100644 test/lib-test/jdk/test/lib/process/ProcessToolsStartProcessTest.java diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java index 81180b6a993..a3183c64c16 100644 --- a/test/jdk/sun/tools/jstatd/JstatdTest.java +++ b/test/jdk/sun/tools/jstatd/JstatdTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -350,7 +350,10 @@ public final class JstatdTest { // Verify output from jstatd OutputAnalyzer output = jstatdThread.getOutput(); - output.shouldBeEmptyIgnoreVMWarnings(); + List stdout = output.asLinesWithoutVMWarnings(); + output.reportDiagnosticSummary(); + assertEquals(stdout.size(), 1, "Output should contain one line"); + assertTrue(stdout.get(0).startsWith("jstatd started"), "List should start with 'jstatd started'"); assertNotEquals(output.getExitValue(), 0, "jstatd process exited with unexpected exit code"); } diff --git a/test/lib-test/jdk/test/lib/process/ProcessToolsStartProcessTest.java b/test/lib-test/jdk/test/lib/process/ProcessToolsStartProcessTest.java new file mode 100644 index 00000000000..7ba339918c5 --- /dev/null +++ b/test/lib-test/jdk/test/lib/process/ProcessToolsStartProcessTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Unit test for ProcessTools.startProcess() + * @library /test/lib + * @compile ProcessToolsStartProcessTest.java + * @run main ProcessToolsStartProcessTest + */ + +import java.util.function.Consumer; +import java.io.File; + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class ProcessToolsStartProcessTest { + static final int NUM_LINES = 50; + static String output = ""; + + private static Consumer outputConsumer = s -> { + output += s + "\n"; + }; + + static boolean testStartProcess(boolean withConsumer) throws Exception { + boolean success = true; + Process p; + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java"); + launcher.addToolArg("-cp"); + launcher.addToolArg(Utils.TEST_CLASSES); + launcher.addToolArg("ProcessToolsStartProcessTest"); + launcher.addToolArg("test"); // This one argument triggers producing the output + ProcessBuilder pb = new ProcessBuilder(); + pb.command(launcher.getCommand()); + + System.out.println("DEBUG: Test with withConsumer=" + withConsumer); + System.out.println("DEBUG: about to start process."); + if (withConsumer) { + p = ProcessTools.startProcess("java", pb, outputConsumer); + } else { + p = ProcessTools.startProcess("java", pb); + } + OutputAnalyzer out = new OutputAnalyzer(p); + + System.out.println("DEBUG: process started."); + p.waitFor(); + if (p.exitValue() != 0) { + throw new RuntimeException("Bad exit value: " + p.exitValue()); + } + + if (withConsumer) { + int numLines = output.split("\n").length; + if (numLines != NUM_LINES ) { + System.out.print("FAILED: wrong number of lines in Consumer output\n"); + success = false; + } + System.out.println("DEBUG: Consumer output: got " + numLines + " lines , expected " + + NUM_LINES + ". Output follow:"); + System.out.print(output); + System.out.println("DEBUG: done with Consumer output."); + } + + int numLinesOut = out.getStdout().split("\n").length; + if (numLinesOut != NUM_LINES) { + System.out.print("FAILED: wrong number of lines in OutputAnalyzer output\n"); + success = false; + } + System.out.println("DEBUG: OutputAnalyzer output: got " + numLinesOut + " lines, expected " + + NUM_LINES + ". Output follows:"); + System.out.print(out.getStdout()); + System.out.println("DEBUG: done with OutputAnalyzer stdout."); + + return success; + } + + public static void main(String[] args) { + if (args.length > 0) { + for (int i = 0; i < NUM_LINES; i++) { + System.out.println("A line on stdout " + i); + } + } else { + try { + boolean test1Result = testStartProcess(false); + boolean test2Result = testStartProcess(true); + if (!test1Result || !test2Result) { + throw new RuntimeException("One or more tests failed. See output for details."); + } + } catch (RuntimeException re) { + re.printStackTrace(); + System.out.println("Test ERROR"); + throw re; + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("Test ERROR"); + throw new RuntimeException(ex); + } + } + } +} diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index aa0957725fc..2e3d670a8f8 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -27,6 +27,7 @@ import jdk.test.lib.JDKToolFinder; import jdk.test.lib.Platform; import jdk.test.lib.Utils; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -71,14 +72,17 @@ public final class ProcessTools { ps.println("[" + prefix + "] " + line); } } - private ProcessTools() { } /** *

Starts a process from its builder.

* The default redirects of STDOUT and STDERR are started - * + *

+ * Same as + * {@linkplain #startProcess(String, ProcessBuilder, Consumer, Predicate, long, TimeUnit) startProcess} + * {@code (name, processBuilder, null, null, -1, TimeUnit.NANOSECONDS)} + *

* @param name The process name * @param processBuilder The process builder * @return Returns the initialized process @@ -93,11 +97,15 @@ public final class ProcessTools { /** *

Starts a process from its builder.

* The default redirects of STDOUT and STDERR are started - *

It is possible to monitor the in-streams via the provided {@code consumer} + *

+ * Same as + * {@linkplain #startProcess(String, ProcessBuilder, Consumer, Predicate, long, TimeUnit) startProcess} + * {@code (name, processBuilder, consumer, null, -1, TimeUnit.NANOSECONDS)} + *

* * @param name The process name - * @param consumer {@linkplain Consumer} instance to process the in-streams * @param processBuilder The process builder + * @param consumer {@linkplain Consumer} instance to process the in-streams * @return Returns the initialized process * @throws IOException */ @@ -118,8 +126,9 @@ public final class ProcessTools { *

Starts a process from its builder.

* The default redirects of STDOUT and STDERR are started *

- * It is possible to wait for the process to get to a warmed-up state - * via {@linkplain Predicate} condition on the STDOUT/STDERR + * Same as + * {@linkplain #startProcess(String, ProcessBuilder, Consumer, Predicate, long, TimeUnit) startProcess} + * {@code (name, processBuilder, null, linePredicate, timeout, unit)} *

* * @param name The process name @@ -144,6 +153,58 @@ public final class ProcessTools { return startProcess(name, processBuilder, null, linePredicate, timeout, unit); } + + /* + BufferOutputStream and BufferInputStream allow to re-use p.getInputStream() amd p.getOutputStream() of + processes started with ProcessTools.startProcess(...). + Implementation cashes ALL process output and allow to read it through InputStream. + */ + private static class BufferOutputStream extends ByteArrayOutputStream { + private int current = 0; + final private Process p; + + public BufferOutputStream(Process p) { + this.p = p; + } + + synchronized int readNext() { + if (current > count) { + throw new RuntimeException("Shouldn't ever happen. start: " + + current + " count: " + count + " buffer: " + this); + } + while (current == count) { + if (!p.isAlive()) { + return -1; + } + try { + wait(1); + } catch (InterruptedException ie) { + return -1; + } + } + return this.buf[current++]; + } + } + + private static class BufferInputStream extends InputStream { + + private final BufferOutputStream buffer; + + public BufferInputStream(Process p) { + buffer = new BufferOutputStream(p); + } + + OutputStream getOutputStream() { + return buffer; + } + + @Override + public int read() throws IOException { + return buffer.readNext(); + } + } + + /** *

Starts a process from its builder.

* The default redirects of STDOUT and STDERR are started @@ -181,6 +242,12 @@ public final class ProcessTools { stdout.addPump(new LineForwarder(name, System.out)); stderr.addPump(new LineForwarder(name, System.err)); + BufferInputStream stdOut = new BufferInputStream(p); + BufferInputStream stdErr = new BufferInputStream(p); + + stdout.addOutputStream(stdOut.getOutputStream()); + stderr.addOutputStream(stdErr.getOutputStream()); + if (lineConsumer != null) { StreamPumper.LinePump pump = new StreamPumper.LinePump() { @Override @@ -250,7 +317,7 @@ public final class ProcessTools { throw e; } - return new ProcessImpl(p, stdoutTask, stderrTask); + return new ProcessImpl(p, stdoutTask, stderrTask, stdOut, stdErr); } /** @@ -701,14 +768,19 @@ public final class ProcessTools { private static class ProcessImpl extends Process { + private final InputStream stdOut; + private final InputStream stdErr; private final Process p; private final Future stdoutTask; private final Future stderrTask; - public ProcessImpl(Process p, Future stdoutTask, Future stderrTask) { + public ProcessImpl(Process p, Future stdoutTask, Future stderrTask, + InputStream stdOut, InputStream etdErr) { this.p = p; this.stdoutTask = stdoutTask; this.stderrTask = stderrTask; + this.stdOut = stdOut; + this.stdErr = etdErr; } @Override @@ -718,12 +790,12 @@ public final class ProcessTools { @Override public InputStream getInputStream() { - return p.getInputStream(); + return stdOut; } @Override public InputStream getErrorStream() { - return p.getErrorStream(); + return stdErr; } @Override From 35e802374c18123687ccb5d74a9c2eac0f1b4c52 Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Wed, 26 Apr 2023 16:02:53 +0000 Subject: [PATCH 154/288] 8306872: Rename Node_Array::Size() Reviewed-by: kvn, thartmann, shade --- src/hotspot/share/opto/loopnode.cpp | 6 +++--- src/hotspot/share/opto/matcher.cpp | 2 +- src/hotspot/share/opto/node.hpp | 2 +- src/hotspot/share/opto/output.cpp | 2 +- src/hotspot/share/opto/phaseX.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index f62f9dac876..035c19419e3 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -4468,7 +4468,7 @@ void PhaseIdealLoop::build_and_optimize() { AutoNodeBudget node_budget(this); if (lpt->_head->as_CountedLoop()->is_normal_loop() && lpt->policy_maximally_unroll(this)) { - memset( worklist.adr(), 0, worklist.Size()*sizeof(Node*) ); + memset( worklist.adr(), 0, worklist.max()*sizeof(Node*) ); do_maximally_unroll(lpt, worklist); } } @@ -4543,7 +4543,7 @@ void PhaseIdealLoop::build_and_optimize() { // If split-if's didn't hack the graph too bad (no CFG changes) // then do loop opts. if (C->has_loops() && !C->major_progress()) { - memset( worklist.adr(), 0, worklist.Size()*sizeof(Node*) ); + memset( worklist.adr(), 0, worklist.max()*sizeof(Node*) ); _ltree_root->_child->iteration_split( this, worklist ); // No verify after peeling! GCM has hoisted code out of the loop. // After peeling, the hoisted code could sink inside the peeled area. @@ -6356,7 +6356,7 @@ void PhaseIdealLoop::dump(IdealLoopTree* loop, uint idx, Node_List &rpo_list) co } } // Dump nodes it controls - for (uint k = 0; k < _nodes.Size(); k++) { + for (uint k = 0; k < _nodes.max(); k++) { // (k < C->unique() && get_ctrl(find(k)) == n) if (k < C->unique() && _nodes[k] == (Node*)((intptr_t)n + 1)) { Node* m = C->root()->find(k); diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index c9ea54bde1f..15cea8a2555 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -1735,7 +1735,7 @@ MachNode* Matcher::find_shared_node(Node* leaf, uint rule) { if (!leaf->is_Con() && !leaf->is_DecodeNarrowPtr()) return nullptr; // See if this Con has already been reduced using this rule. - if (_shared_nodes.Size() <= leaf->_idx) return nullptr; + if (_shared_nodes.max() <= leaf->_idx) return nullptr; MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx); if (last != nullptr && rule == last->rule()) { // Don't expect control change for DecodeN diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 107654752bf..e3c10822429 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -1548,7 +1548,7 @@ public: Copy::zero_to_bytes(_nodes, _max * sizeof(Node*)); } - uint Size() const { return _max; } + uint max() const { return _max; } void dump() const; }; diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 5539eb5724c..524e38fcf72 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -3072,7 +3072,7 @@ void Scheduling::garbage_collect_pinch_nodes() { if (_cfg->C->trace_opto_output()) tty->print("Reclaimed pinch nodes:"); #endif int trace_cnt = 0; - for (uint k = 0; k < _reg_node.Size(); k++) { + for (uint k = 0; k < _reg_node.max(); k++) { Node* pinch = _reg_node[k]; if ((pinch != nullptr) && pinch->Opcode() == Op_Node && // no predecence input edges diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index b00d5e2d29b..1f7d8130382 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -664,7 +664,7 @@ void PhaseTransform::dump_old2new_map() const { } void PhaseTransform::dump_new( uint nidx ) const { - for( uint i=0; i<_nodes.Size(); i++ ) + for( uint i=0; i<_nodes.max(); i++ ) if( _nodes[i] && _nodes[i]->_idx == nidx ) { _nodes[i]->dump(); tty->cr(); From 9bc6a212f70eede108a8d3bc1ba1f780722b6e33 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 26 Apr 2023 16:04:48 +0000 Subject: [PATCH 155/288] 8306033: Resolve multiple definition of 'throwIOException' and friends when statically linking with JDK native libraries Reviewed-by: alanb --- .../share/native/libmanagement/management.c | 9 +-- .../share/native/libmanagement/management.h | 3 +- .../share/native/libj2gss/GSSLibStub.c | 4 +- .../share/native/libj2gss/NativeUtil.c | 20 ++--- .../share/native/libj2gss/NativeUtil.h | 4 +- .../share/native/libj2pcsc/pcsc.c | 4 +- .../unix/native/libj2pcsc/pcsc_md.c | 8 +- .../share/native/libj2pkcs11/p11_convert.c | 54 ++++++------- .../share/native/libj2pkcs11/p11_digest.c | 6 +- .../share/native/libj2pkcs11/p11_dual.c | 10 +-- .../share/native/libj2pkcs11/p11_general.c | 6 +- .../share/native/libj2pkcs11/p11_keymgmt.c | 8 +- .../share/native/libj2pkcs11/p11_mutex.c | 6 +- .../share/native/libj2pkcs11/p11_objmgmt.c | 8 +- .../share/native/libj2pkcs11/p11_sessmgmt.c | 8 +- .../share/native/libj2pkcs11/p11_sign.c | 18 ++--- .../share/native/libj2pkcs11/p11_util.c | 81 +++++++++---------- .../share/native/libj2pkcs11/pkcs11wrapper.h | 11 ++- .../unix/native/libj2pkcs11/j2secmod_md.c | 6 +- .../unix/native/libj2pkcs11/p11_md.c | 18 ++--- .../windows/native/libj2pkcs11/j2secmod_md.c | 10 +-- .../windows/native/libj2pkcs11/p11_md.c | 14 ++-- .../native/libmanagement_ext/management_ext.c | 9 +-- .../native/libmanagement_ext/management_ext.h | 3 +- .../libmanagement_ext/OperatingSystemImpl.c | 9 ++- 25 files changed, 160 insertions(+), 177 deletions(-) diff --git a/src/java.management/share/native/libmanagement/management.c b/src/java.management/share/native/libmanagement/management.c index 1ef7f78b040..bd0cad0c316 100644 --- a/src/java.management/share/native/libmanagement/management.c +++ b/src/java.management/share/native/libmanagement/management.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -53,10 +53,3 @@ JNIEXPORT jint JNICALL jmm_version = jmm_interface->GetVersion(env); return (*env)->GetVersion(env); } - -void throw_internal_error(JNIEnv* env, const char* msg) { - char errmsg[128]; - - snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg); - JNU_ThrowInternalError(env, errmsg); -} diff --git a/src/java.management/share/native/libmanagement/management.h b/src/java.management/share/native/libmanagement/management.h index eeb29560fcd..e7cf9209df1 100644 --- a/src/java.management/share/native/libmanagement/management.h +++ b/src/java.management/share/native/libmanagement/management.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -33,6 +33,5 @@ extern const JmmInterface* jmm_interface; extern jint jmm_version; -extern void throw_internal_error(JNIEnv* env, const char* msg); #endif diff --git a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c index 308879f3a8d..b801edddfc5 100644 --- a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c +++ b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -198,7 +198,7 @@ gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) { cb = malloc(sizeof(struct gss_channel_bindings_struct)); if (cb == NULL) { - throwOutOfMemoryError(env,NULL); + gssThrowOutOfMemoryError(env, NULL); return NULL; } diff --git a/src/java.security.jgss/share/native/libj2gss/NativeUtil.c b/src/java.security.jgss/share/native/libj2gss/NativeUtil.c index 29559d386ae..a1801347898 100644 --- a/src/java.security.jgss/share/native/libj2gss/NativeUtil.c +++ b/src/java.security.jgss/share/native/libj2gss/NativeUtil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -451,20 +451,14 @@ jint getJavaErrorCode(int cNonCallingErr) { return GSS_S_COMPLETE; } - -/* Throws a Java Exception by name */ -void throwByName(JNIEnv *env, const char *name, const char *msg) { - jclass cls = (*env)->FindClass(env, name); +void gssThrowOutOfMemoryError(JNIEnv *env, const char *message) { + jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); if (cls != NULL) { - (*env)->ThrowNew(env, cls, msg); + (*env)->ThrowNew(env, cls, message); } } -void throwOutOfMemoryError(JNIEnv *env, const char *message) { - throwByName(env, "java/lang/OutOfMemoryError", message); -} - /* * Utility routine for creating a java.lang.String object * using the specified gss_buffer_t structure. The specified @@ -602,7 +596,7 @@ void initGSSBuffer(JNIEnv *env, jbyteArray jbytes, len = (*env)->GetArrayLength(env, jbytes); value = malloc(len); if (value == NULL) { - throwOutOfMemoryError(env, NULL); + gssThrowOutOfMemoryError(env, NULL); return; } else { (*env)->GetByteArrayRegion(env, jbytes, 0, len, value); @@ -677,13 +671,13 @@ gss_OID newGSSOID(JNIEnv *env, jobject jOid) { } cOid = malloc(sizeof(struct gss_OID_desc_struct)); if (cOid == NULL) { - throwOutOfMemoryError(env,NULL); + gssThrowOutOfMemoryError(env,NULL); return GSS_C_NO_OID; } cOid->length = (*env)->GetArrayLength(env, jbytes) - 2; cOid->elements = malloc(cOid->length); if (cOid->elements == NULL) { - throwOutOfMemoryError(env,NULL); + gssThrowOutOfMemoryError(env,NULL); goto cleanup; } (*env)->GetByteArrayRegion(env, jbytes, 2, cOid->length, diff --git a/src/java.security.jgss/share/native/libj2gss/NativeUtil.h b/src/java.security.jgss/share/native/libj2gss/NativeUtil.h index 26c0189ab42..81873252900 100644 --- a/src/java.security.jgss/share/native/libj2gss/NativeUtil.h +++ b/src/java.security.jgss/share/native/libj2gss/NativeUtil.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ extern "C" { extern OM_uint32 getGSSTime(jint); extern void checkStatus(JNIEnv *, jobject, OM_uint32, OM_uint32, char*); extern jint checkTime(OM_uint32); - extern void throwOutOfMemoryError(JNIEnv *, const char*); + extern void gssThrowOutOfMemoryError(JNIEnv *, const char*); extern void initGSSBuffer(JNIEnv *, jbyteArray, gss_buffer_t); extern void resetGSSBuffer(gss_buffer_t); diff --git a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c index a55b0e7fddc..733c28a159a 100644 --- a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c +++ b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ #define J2PCSC_EXCEPTION_NAME "sun/security/smartcardio/PCSCException" -void throwOutOfMemoryError(JNIEnv *env, const char *msg) { +static void throwOutOfMemoryError(JNIEnv *env, const char *msg) { jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); if (cls != NULL) /* Otherwise an exception has already been thrown */ diff --git a/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.c b/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.c index f344f4a00d9..f4c80679be5 100644 --- a/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.c +++ b/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ FPTR_SCardControl scardControl; /* * Throws a Java Exception by name */ -void throwByName(JNIEnv *env, const char *name, const char *msg) +static void throwByName(JNIEnv *env, const char *name, const char *msg) { jclass cls = (*env)->FindClass(env, name); @@ -62,7 +62,7 @@ void throwByName(JNIEnv *env, const char *name, const char *msg) /* * Throws java.lang.NullPointerException */ -void throwNullPointerException(JNIEnv *env, const char *msg) +static void throwNullPointerException(JNIEnv *env, const char *msg) { throwByName(env, "java/lang/NullPointerException", msg); } @@ -70,7 +70,7 @@ void throwNullPointerException(JNIEnv *env, const char *msg) /* * Throws java.io.IOException */ -void throwIOException(JNIEnv *env, const char *msg) +static void throwIOException(JNIEnv *env, const char *msg) { throwByName(env, "java/io/IOException", msg); } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c index d941b574cc7..5765662e611 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -271,7 +271,7 @@ jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion) // allocate memory for CK_VERSION pointer ckpVersion = (CK_VERSION_PTR) calloc(1, sizeof(CK_VERSION)); if (ckpVersion == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -320,7 +320,7 @@ CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate) // allocate memory for CK_DATE pointer ckpDate = (CK_DATE *) calloc(1, sizeof(CK_DATE)); if (ckpDate == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -334,7 +334,7 @@ CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate) ckLength = (*env)->GetArrayLength(env, jYear); jTempChars = (jchar*) calloc(ckLength, sizeof(jchar)); if (jTempChars == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } (*env)->GetCharArrayRegion(env, jYear, 0, ckLength, jTempChars); @@ -355,7 +355,7 @@ CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate) ckLength = (*env)->GetArrayLength(env, jMonth); jTempChars = (jchar*) calloc(ckLength, sizeof(jchar)); if (jTempChars == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } (*env)->GetCharArrayRegion(env, jMonth, 0, ckLength, jTempChars); @@ -376,7 +376,7 @@ CK_DATE * jDateObjectToCKDatePtr(JNIEnv *env, jobject jDate) ckLength = (*env)->GetArrayLength(env, jDay); jTempChars = (jchar*) calloc(ckLength, sizeof(jchar)); if (jTempChars == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } (*env)->GetCharArrayRegion(env, jDay, 0, ckLength, jTempChars); @@ -525,7 +525,7 @@ jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(JNIEnv *env, // allocate memory for CK_SSL3_MASTER_KEY_DERIVE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -585,7 +585,7 @@ jTls12MasterKeyDeriveParamToCKTls12MasterKeyDeriveParamPtr(JNIEnv *env, // allocate memory for CK_TLS12_MASTER_KEY_DERIVE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -644,7 +644,7 @@ jTlsPrfParamsToCKTlsPrfParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_TLS_PRF_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_TLS_PRF_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -716,7 +716,7 @@ jTlsMacParamsToCKTlsMacParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_TLS_MAC_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_TLS_MAC_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -810,7 +810,7 @@ void keyMatParamToCKKeyMatParam(JNIEnv *env, jobject jParam, *cKKeyMatParamPReturnedKeyMaterial = (CK_SSL3_KEY_MAT_OUT_PTR) calloc(1, sizeof(CK_SSL3_KEY_MAT_OUT)); if (*cKKeyMatParamPReturnedKeyMaterial == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } @@ -867,7 +867,7 @@ jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pL // allocate memory for CK_SSL3_KEY_MAT_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_SSL3_KEY_MAT_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -927,7 +927,7 @@ CK_TLS12_KEY_MAT_PARAMS_PTR jTls12KeyMatParamToCKTls12KeyMatParamPtr(JNIEnv *env // allocate memory for CK_TLS12_KEY_MAT_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_TLS12_KEY_MAT_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -989,7 +989,7 @@ jAesCtrParamsToCKAesCtrParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_AES_CTR_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_AES_CTR_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1056,7 +1056,7 @@ jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_GCM_PARAMS_NO_IVBITS pointer ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1128,7 +1128,7 @@ jCCMParamsToCKCCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_CCM_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_CCM_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1198,7 +1198,7 @@ jSalsaChaChaPolyParamsToCKSalsaChaChaPolyParamPtr( // allocate memory for CK_SALSA20_CHACHA20_POLY1305_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1243,7 +1243,7 @@ CK_MECHANISM_PTR jMechanismToCKMechanismPtr(JNIEnv *env, jobject jMech) /* allocate memory for CK_MECHANISM_PTR */ ckpMech = (CK_MECHANISM_PTR) calloc(1, sizeof(CK_MECHANISM)); if (ckpMech == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p\n", ckpMech); @@ -1553,7 +1553,7 @@ CK_VOID_PTR jMechParamToCKMechParamPtrSlow(JNIEnv *env, jobject jParam, case CKM_SKIPJACK_PRIVATE_WRAP: // CK_SKIPJACK_PRIVATE_WRAP_PARAMS case CKM_SKIPJACK_RELAYX: // CK_SKIPJACK_RELAYX_PARAMS case CKM_KEY_WRAP_SET_OAEP: // CK_KEY_WRAP_SET_OAEP_PARAMS - throwPKCS11RuntimeException(env, "No parameter support for this mechanism"); + p11ThrowPKCS11RuntimeException(env, "No parameter support for this mechanism"); break; default: /* if everything failed up to here */ @@ -1612,7 +1612,7 @@ jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(JNIEnv *env, jobject jParam, CK_ULONG * // allocate memory for CK_RSA_PKCS_OAEP_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_RSA_PKCS_OAEP_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1674,7 +1674,7 @@ jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // allocate memory for CK_PBE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_PBE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1811,7 +1811,7 @@ jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pL // allocate memory for CK_PKCS5_PBKD2_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_PKCS5_PBKD2_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1879,7 +1879,7 @@ jRsaPkcsPssParamToCKRsaPkcsPssParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pL // allocate memory for CK_RSA_PKCS_PSS_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_RSA_PKCS_PSS_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -1936,7 +1936,7 @@ jEcdh1DeriveParamToCKEcdh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG * // allocate memory for CK_ECDH1_DERIVE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_ECDH1_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -2007,7 +2007,7 @@ jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG * // allocate memory for CK_ECDH2_DERIVE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_ECDH2_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -2081,7 +2081,7 @@ jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULO // allocate memory for CK_X9_42_DH1_DERIVE_PARAMS pointer ckParamPtr = calloc(1, sizeof(CK_X9_42_DH1_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -2156,7 +2156,7 @@ jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULO // allocate memory for CK_DATE pointer ckParamPtr = calloc(1, sizeof(CK_X9_42_DH2_DERIVE_PARAMS)); if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c index 77b9eb11cfe..fc221e14134 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -125,7 +125,7 @@ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle /* always use single part op, even for large data */ bufP = (CK_BYTE_PTR) malloc((size_t)jInLen); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } } @@ -187,7 +187,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestUpdate bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c index 891b3854a2c..8b37f9a62f8 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -92,7 +92,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestEn ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE)); if (ckpEncryptedPart == NULL) { free(ckpPart); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -144,7 +144,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptD ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE)); if (ckpPart == NULL) { free(ckpEncryptedPart); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -196,7 +196,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignEncr ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE)); if (ckpEncryptedPart == NULL) { free(ckpPart); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -248,7 +248,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptV ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE)); if (ckpPart == NULL) { free(ckpEncryptedPart); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c index 397397ccde5..7cad5c39fa0 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -385,7 +385,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID)); if (ckpSlotList == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -686,7 +686,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList ckpMechanismList = (CK_MECHANISM_TYPE_PTR) malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE)); if (ckpMechanismList == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c index fe9e0751af9..08257d05b1b 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -200,7 +200,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_getNativeKeyInfo ckpAttributes = (CK_ATTRIBUTE_PTR) calloc( CK_ATTRIBUTES_TEMPLATE_LENGTH, sizeof(CK_ATTRIBUTE)); if (ckpAttributes == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } memcpy(ckpAttributes, ckpAttributesTemplate, @@ -599,7 +599,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Generate ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) calloc(2, sizeof(CK_OBJECT_HANDLE)); if (ckpKeyHandles == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } ckpPublicKeyHandle = ckpKeyHandles; /* first element of array is Public Key */ @@ -699,7 +699,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey ckpWrappedKey = (CK_BYTE_PTR) calloc(ckWrappedKeyLength, sizeof(CK_BYTE)); if (ckpWrappedKey == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c index 8c94060cc63..787347993e7 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -92,7 +92,7 @@ CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs) /* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */ ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS)); if (ckpInitArgs == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL_PTR; } ckpInitArgs->flags = (CK_FLAGS)0; @@ -155,7 +155,7 @@ CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs) ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS)); if (ckpGlobalInitArgs == NULL) { free(ckpInitArgs); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL_PTR; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c index 55537bf8f83..f0a106efc95 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -252,7 +252,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeVa if (rv == CKR_ATTRIBUTE_SENSITIVE || rv == CKR_ATTRIBUTE_TYPE_INVALID) { msg = malloc(80); // should be more than sufficient if (msg == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); free(ckpAttributes); return; } @@ -282,7 +282,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeVa ckpAttributes[i].pValue = (void *) malloc(ckBufferLength); if (ckpAttributes[i].pValue == NULL) { freeCKAttributeArray(ckpAttributes, i); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } ckpAttributes[i].ulValueLen = ckBufferLength; @@ -415,7 +415,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObje ckMaxObjectLength = jLongToCKULong(jMaxObjectCount); ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength); if (ckpObjectHandleArray == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c index 5154fde8885..90f51a957af 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -98,7 +98,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession if (jNotify != NULL) { notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation)); if (notifyEncapsulation == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return 0L; } notifyEncapsulation->jApplicationData = (jApplication != NULL) @@ -328,7 +328,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOpera ckpState = (CK_BYTE_PTR) malloc(ckStateLength); if (ckpState == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } @@ -517,7 +517,7 @@ void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode)); if (newNode == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } newNode->hSession = hSession; diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c index f6984093096..c8685df9927 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -147,7 +147,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign if (rv == CKR_BUFFER_TOO_SMALL) { bufP = (CK_BYTE_PTR) malloc(ckSignatureLength); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, @@ -205,7 +205,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } } @@ -264,7 +264,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFina if (rv == CKR_BUFFER_TOO_SMALL) { bufP = (CK_BYTE_PTR) malloc(ckSignatureLength); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength); @@ -355,7 +355,7 @@ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover } else { inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen); if (inBufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return 0; } ckSignatureLength = jInLen; @@ -371,7 +371,7 @@ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) { outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength); if (outBufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength); @@ -516,7 +516,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); if (bufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } } @@ -653,7 +653,7 @@ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover } else { inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen); if (inBufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return 0; } ckDataLength = jInLen; @@ -670,7 +670,7 @@ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) { outBufP = (CK_BYTE_PTR) malloc(ckDataLength); if (outBufP == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength); diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c index 1b57abffdc9..68368717e46 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -58,6 +58,16 @@ ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation); int isModulePresent(JNIEnv *env, jobject pkcs11Implementation); void removeAllModuleEntries(JNIEnv *env); +/* + * This function simply throws a PKCS#11RuntimeException. The message says that + * the object is not connected to the module. + * + * @param env Used to call JNI functions and to get the Exception class. + */ +static void throwDisconnectedRuntimeException(JNIEnv *env) +{ + p11ThrowPKCS11RuntimeException(env, "This object is not connected to a module."); +} /* ************************************************************************** */ /* Functions for keeping track of currently active and loaded modules */ @@ -237,7 +247,7 @@ jlong ckAssertReturnValueOK2(JNIEnv *env, CK_RV returnValue, const char* msg) { /* * Throws a Java Exception by name */ -void throwByName(JNIEnv *env, const char *name, const char *msg) +static void throwByName(JNIEnv *env, const char *name, const char *msg) { jclass cls = (*env)->FindClass(env, name); @@ -248,7 +258,7 @@ void throwByName(JNIEnv *env, const char *name, const char *msg) /* * Throws java.lang.OutOfMemoryError */ -void throwOutOfMemoryError(JNIEnv *env, const char *msg) +void p11ThrowOutOfMemoryError(JNIEnv *env, const char *msg) { throwByName(env, "java/lang/OutOfMemoryError", msg); } @@ -256,7 +266,7 @@ void throwOutOfMemoryError(JNIEnv *env, const char *msg) /* * Throws java.lang.NullPointerException */ -void throwNullPointerException(JNIEnv *env, const char *msg) +void p11ThrowNullPointerException(JNIEnv *env, const char *msg) { throwByName(env, "java/lang/NullPointerException", msg); } @@ -264,7 +274,7 @@ void throwNullPointerException(JNIEnv *env, const char *msg) /* * Throws java.io.IOException */ -void throwIOException(JNIEnv *env, const char *msg) +void p11ThrowIOException(JNIEnv *env, const char *msg) { throwByName(env, "java/io/IOException", msg); } @@ -276,22 +286,11 @@ void throwIOException(JNIEnv *env, const char *msg) * @param env Used to call JNI functions and to get the Exception class. * @param jmessage The message string of the Exception object. */ -void throwPKCS11RuntimeException(JNIEnv *env, const char *message) +void p11ThrowPKCS11RuntimeException(JNIEnv *env, const char *message) { throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message); } -/* - * This function simply throws a PKCS#11RuntimeException. The message says that - * the object is not connected to the module. - * - * @param env Used to call JNI functions and to get the Exception class. - */ -void throwDisconnectedRuntimeException(JNIEnv *env) -{ - throwPKCS11RuntimeException(env, "This object is not connected to a module."); -} - /* This function frees the specified CK_ATTRIBUTE array. * * @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array. @@ -448,7 +447,7 @@ CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) { (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) { pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS)); if (pGcmParams2 == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter; @@ -524,7 +523,7 @@ void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBO *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean)); if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp); @@ -536,7 +535,7 @@ void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBO *ckpArray = (CK_BBOOL*) calloc (*ckpLength, sizeof(CK_BBOOL)); if (*ckpArray == NULL) { free(jpTemp); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } for (i=0; i<(*ckpLength); i++) { @@ -566,7 +565,7 @@ void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR * *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte)); if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp); @@ -582,7 +581,7 @@ void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR * *ckpArray = (CK_BYTE_PTR) calloc (*ckpLength, sizeof(CK_BYTE)); if (*ckpArray == NULL) { free(jpTemp); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } for (i=0; i<(*ckpLength); i++) { @@ -613,7 +612,7 @@ void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpLength = (*env)->GetArrayLength(env, jArray); jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong)); if (jTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp); @@ -625,7 +624,7 @@ void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray = (CK_ULONG_PTR) calloc(*ckpLength, sizeof(CK_ULONG)); if (*ckpArray == NULL) { free(jTemp); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } for (i=0; i<(*ckpLength); i++) { @@ -655,7 +654,7 @@ void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR * *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp); @@ -667,7 +666,7 @@ void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR * *ckpArray = (CK_CHAR_PTR) calloc (*ckpLength, sizeof(CK_CHAR)); if (*ckpArray == NULL) { free(jpTemp); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } for (i=0; i<(*ckpLength); i++) { @@ -697,7 +696,7 @@ void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CH *ckpLength = (*env)->GetArrayLength(env, jArray); jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); if (jTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp); @@ -709,7 +708,7 @@ void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CH *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength, sizeof(CK_UTF8CHAR)); if (*ckpArray == NULL) { free(jTemp); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } for (i=0; i<(*ckpLength); i++) { @@ -744,7 +743,7 @@ void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength + 1, sizeof(CK_UTF8CHAR)); if (*ckpArray == NULL) { (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } strcpy((char*)*ckpArray, pCharArray); @@ -777,7 +776,7 @@ void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTR *ckpLength = jLongToCKULong(jLength); *ckpArray = (CK_ATTRIBUTE_PTR) calloc(*ckpLength, sizeof(CK_ATTRIBUTE)); if (*ckpArray == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return; } TRACE1(", converting %lld attributes", (long long int) jLength); @@ -818,7 +817,7 @@ jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_U } else { jpTemp = (jbyte*) calloc(ckLength, sizeof(jbyte)); if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } for (i=0; iCallBooleanMethod(env, jObject, jValueMethod); ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL)); if (ckpValue == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } *ckpValue = jBooleanToCKBBool(jValue); @@ -1047,7 +1046,7 @@ CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject) jValue = (*env)->CallByteMethod(env, jObject, jValueMethod); ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE)); if (ckpValue == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } *ckpValue = jByteToCKByte(jValue); @@ -1076,7 +1075,7 @@ CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject) jValue = (*env)->CallIntMethod(env, jObject, jValueMethod); ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG)); if (ckpValue == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } *ckpValue = jLongToCKLong(jValue); @@ -1105,7 +1104,7 @@ CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject) jValue = (*env)->CallLongMethod(env, jObject, jValueMethod); ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG)); if (ckpValue == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } *ckpValue = jLongToCKULong(jValue); @@ -1135,7 +1134,7 @@ CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject) jValue = (*env)->CallCharMethod(env, jObject, jValueMethod); ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR)); if (ckpValue == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } *ckpValue = jCharToCKChar(jValue); @@ -1291,13 +1290,13 @@ CK_VOID_PTR jObjectToPrimitiveCKObjectPtr(JNIEnv *env, jobject jObject, CK_ULONG malloc(strlen(exceptionMsgPrefix) + strlen(classNameString) + 1); if (exceptionMsg == NULL) { (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); return NULL; } strcpy(exceptionMsg, exceptionMsgPrefix); strcat(exceptionMsg, classNameString); (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); - throwPKCS11RuntimeException(env, exceptionMsg); + p11ThrowPKCS11RuntimeException(env, exceptionMsg); free(exceptionMsg); *ckpLength = 0; diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h index 88662edbe9e..8fe06cc3582 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -314,11 +314,10 @@ CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr); jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue); jlong ckAssertReturnValueOK2(JNIEnv *env, CK_RV returnValue, const char *msg); -void throwOutOfMemoryError(JNIEnv *env, const char *message); -void throwNullPointerException(JNIEnv *env, const char *message); -void throwIOException(JNIEnv *env, const char *message); -void throwPKCS11RuntimeException(JNIEnv *env, const char *message); -void throwDisconnectedRuntimeException(JNIEnv *env); +void p11ThrowOutOfMemoryError(JNIEnv *env, const char *message); +void p11ThrowNullPointerException(JNIEnv *env, const char *message); +void p11ThrowIOException(JNIEnv *env, const char *message); +void p11ThrowPKCS11RuntimeException(JNIEnv *env, const char *message); /* functions to free CK structures and pointers */ diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c index d5154eff606..57e4dc925d6 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { if (fAddress == NULL) { char errorMessage[256]; snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName); - throwNullPointerException(env, errorMessage); + p11ThrowNullPointerException(env, errorMessage); return NULL; } return fAddress; @@ -81,7 +81,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary dprintf2("-handle: %u (0X%X)\n", hModule, hModule); if (hModule == NULL) { - throwIOException(env, dlerror()); + p11ThrowIOException(env, dlerror()); return 0; } diff --git a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c index d8b7c3bd70d..85b9cad03a7 100644 --- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c +++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -114,12 +114,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect systemErrorMessage = dlerror(); exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1)); if (exceptionMessage == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } strcpy(exceptionMessage, systemErrorMessage); strcat(exceptionMessage, libraryNameStr); - throwIOException(env, exceptionMessage); + p11ThrowIOException(env, exceptionMessage); free(exceptionMessage); goto cleanup; } @@ -167,12 +167,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr); if ((systemErrorMessage = dlerror()) != NULL){ - throwIOException(env, systemErrorMessage); + p11ThrowIOException(env, systemErrorMessage); goto cleanup; } if (C_GetFunctionList == NULL) { TRACE1("Connect: No %s func\n", getFunctionListStr); - throwIOException(env, "ERROR: C_GetFunctionList == NULL"); + p11ThrowIOException(env, "ERROR: C_GetFunctionList == NULL"); goto cleanup; } TRACE1("Connect: Found %s func\n", getFunctionListStr); @@ -189,12 +189,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, "C_GetFunctionList"); if ((systemErrorMessage = dlerror()) != NULL){ - throwIOException(env, systemErrorMessage); + p11ThrowIOException(env, systemErrorMessage); goto cleanup; } if (C_GetFunctionList == NULL) { TRACE0("Connect: No C_GetFunctionList func\n"); - throwIOException(env, "ERROR: C_GetFunctionList == NULL"); + p11ThrowIOException(env, "ERROR: C_GetFunctionList == NULL"); goto cleanup; } TRACE0("Connect: Found C_GetFunctionList func\n"); @@ -207,7 +207,7 @@ setModuleData: moduleData = (ModuleData *) malloc(sizeof(ModuleData)); if (moduleData == NULL) { dlclose(hModule); - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } moduleData->hModule = hModule; @@ -224,7 +224,7 @@ setModuleData: } } else { // should never happen - throwIOException(env, "ERROR: No function list ptr found"); + p11ThrowIOException(env, "ERROR: No function list ptr found"); goto cleanup; } if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) { diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c index 6e983ce158f..2005e9e7fcb 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,8 @@ #include "j2secmod.h" -extern void throwNullPointerException(JNIEnv *env, const char *message); -extern void throwIOException(JNIEnv *env, const char *message); +extern void p11ThrowNullPointerException(JNIEnv *env, const char *message); +extern void p11ThrowIOException(JNIEnv *env, const char *message); void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { HINSTANCE hModule = (HINSTANCE)jHandle; @@ -40,7 +40,7 @@ void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) { if (fAddress == NULL) { char errorMessage[256]; _snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName); - throwNullPointerException(env, errorMessage); + p11ThrowNullPointerException(env, errorMessage); return NULL; } return fAddress; @@ -81,7 +81,7 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary NULL ); dprintf1("-error: %s\n", lpMsgBuf); - throwIOException(env, (char*)lpMsgBuf); + p11ThrowIOException(env, (char*)lpMsgBuf); LocalFree(lpMsgBuf); return 0; } diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c index 8865967ccb2..d05a341377f 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -116,12 +116,12 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect exceptionMessage = (char *) malloc(sizeof(char) * (strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1)); if (exceptionMessage == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } strcpy(exceptionMessage, (LPTSTR) lpMsgBuf); strcat(exceptionMessage, libraryNameStr); - throwIOException(env, (LPTSTR) exceptionMessage); + p11ThrowIOException(env, (LPTSTR) exceptionMessage); goto cleanup; } @@ -175,7 +175,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect 0, NULL ); - throwIOException(env, (LPTSTR) lpMsgBuf); + p11ThrowIOException(env, (LPTSTR) lpMsgBuf); goto cleanup; } TRACE1("Connect: Found %s func\n", getFunctionListStr); @@ -205,7 +205,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect 0, NULL ); - throwIOException(env, (LPTSTR) lpMsgBuf); + p11ThrowIOException(env, (LPTSTR) lpMsgBuf); goto cleanup; } TRACE0("Connect: Found C_GetFunctionList func\n"); @@ -217,7 +217,7 @@ setModuleData: */ moduleData = (ModuleData *) malloc(sizeof(ModuleData)); if (moduleData == NULL) { - throwOutOfMemoryError(env, 0); + p11ThrowOutOfMemoryError(env, 0); goto cleanup; } moduleData->hModule = hModule; @@ -231,7 +231,7 @@ setModuleData: moduleData->ckFunctionListPtr = interface->pFunctionList; } else { // should never happen - throwIOException(env, "ERROR: No function list ptr found"); + p11ThrowIOException(env, "ERROR: No function list ptr found"); goto cleanup; } if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) { diff --git a/src/jdk.management/share/native/libmanagement_ext/management_ext.c b/src/jdk.management/share/native/libmanagement_ext/management_ext.c index 6809955cafd..88925af2c82 100644 --- a/src/jdk.management/share/native/libmanagement_ext/management_ext.c +++ b/src/jdk.management/share/native/libmanagement_ext/management_ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -53,10 +53,3 @@ JNIEXPORT jint JNICALL jmm_version_management_ext = jmm_interface_management_ext->GetVersion(env); return (*env)->GetVersion(env); } - -void throw_internal_error(JNIEnv* env, const char* msg) { - char errmsg[128]; - - snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg); - JNU_ThrowInternalError(env, errmsg); -} diff --git a/src/jdk.management/share/native/libmanagement_ext/management_ext.h b/src/jdk.management/share/native/libmanagement_ext/management_ext.h index 0d0d23b76af..d80c70122c7 100644 --- a/src/jdk.management/share/native/libmanagement_ext/management_ext.h +++ b/src/jdk.management/share/native/libmanagement_ext/management_ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -36,6 +36,5 @@ // statically linking. extern const JmmInterface* jmm_interface_management_ext; extern jint jmm_version_management_ext; -extern void throw_internal_error(JNIEnv* env, const char* msg); #endif diff --git a/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c b/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c index fc420918987..75b00ce9a64 100644 --- a/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c +++ b/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -82,6 +82,13 @@ static jlong page_size = 0; #define closedir closedir64 #endif +static void throw_internal_error(JNIEnv* env, const char* msg) { + char errmsg[128]; + + snprintf(errmsg, sizeof(errmsg), "errno: %d error: %s\n", errno, msg); + JNU_ThrowInternalError(env, errmsg); +} + // true = get available swap in bytes // false = get total swap in bytes static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) { From a18191fee8347c82764d3b2e2841d24d4670d47d Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 26 Apr 2023 16:06:55 +0000 Subject: [PATCH 156/288] 8302328: [s390x] Simplify asm_assert definition Reviewed-by: lucy, mdoerr --- src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp | 4 +- .../s390/gc/g1/g1BarrierSetAssembler_s390.cpp | 6 +- src/hotspot/cpu/s390/macroAssembler_s390.cpp | 78 +++++++------------ src/hotspot/cpu/s390/macroAssembler_s390.hpp | 16 ++-- src/hotspot/cpu/s390/runtime_s390.cpp | 2 +- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 4 +- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 6 +- src/hotspot/cpu/s390/stubRoutines_s390.cpp | 14 ++-- .../templateInterpreterGenerator_s390.cpp | 2 +- 9 files changed, 48 insertions(+), 84 deletions(-) diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index a32667f65df..c704931a445 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -2984,7 +2984,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ z_bru(next); } } else { - __ asm_assert_ne("unexpected null obj", __LINE__); + __ asm_assert(Assembler::bcondNotZero, "unexpected null obj", __LINE__); } __ bind(update); @@ -2995,7 +2995,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { __ load_klass(tmp1, tmp1); metadata2reg(exact_klass->constant_encoding(), tmp2); __ z_cgr(tmp1, tmp2); - __ asm_assert_eq("exact klass and actual klass differ", __LINE__); + __ asm_assert(Assembler::bcondEqual, "exact klass and actual klass differ", __LINE__); } #endif diff --git a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp index d8243e5aa96..3ed99f68c47 100644 --- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2019 SAP SE. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -177,7 +177,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm, Decorator if (preloaded && not_null) { #ifdef ASSERT __ z_ltgr(Rpre_val, Rpre_val); - __ asm_assert_ne("null oop not allowed (G1 pre)", 0x321); // Checked by caller. + __ asm_assert(Assembler::bcondNotZero, "null oop not allowed (G1 pre)", 0x321); // Checked by caller. #endif } else { __ z_ltgr(Rpre_val, Rpre_val); @@ -289,7 +289,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Decorato if (not_null) { #ifdef ASSERT __ z_ltgr(Rnew_val, Rnew_val); - __ asm_assert_ne("null oop not allowed (G1 post)", 0x322); // Checked by caller. + __ asm_assert(Assembler::bcondNotZero, "null oop not allowed (G1 post)", 0x322); // Checked by caller. #endif } else { __ z_ltgr(Rnew_val, Rnew_val); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index dcd98b3866d..ebd678fea08 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -2074,7 +2074,7 @@ void MacroAssembler::push_frame(Register bytes, Register old_sp, bool copy_sp, b assert_different_registers(bytes, old_sp, Z_SP); if (!copy_sp) { z_cgr(old_sp, Z_SP); - asm_assert_eq("[old_sp]!=[Z_SP]", 0x211); + asm_assert(bcondEqual, "[old_sp]!=[Z_SP]", 0x211); } #endif if (copy_sp) { z_lgr(old_sp, Z_SP); } @@ -5326,47 +5326,25 @@ void MacroAssembler::multiply_to_len(Register x, Register xlen, z_lmg(Z_R7, Z_R13, _z_abi(gpr7), Z_SP); } -#ifndef PRODUCT +void MacroAssembler::asm_assert(branch_condition cond, const char* msg, int id, bool is_static) { +#ifdef ASSERT + Label ok; + z_brc(cond, ok); + is_static ? stop_static(msg, id) : stop(msg, id); + bind(ok); +#endif // ASSERT +} + // Assert if CC indicates "not equal" (check_equal==true) or "equal" (check_equal==false). void MacroAssembler::asm_assert(bool check_equal, const char *msg, int id) { - Label ok; - if (check_equal) { - z_bre(ok); - } else { - z_brne(ok); - } - stop(msg, id); - bind(ok); -} - -// Assert if CC indicates "low". -void MacroAssembler::asm_assert_low(const char *msg, int id) { - Label ok; - z_brnl(ok); - stop(msg, id); - bind(ok); -} - -// Assert if CC indicates "high". -void MacroAssembler::asm_assert_high(const char *msg, int id) { - Label ok; - z_brnh(ok); - stop(msg, id); - bind(ok); -} - -// Assert if CC indicates "not equal" (check_equal==true) or "equal" (check_equal==false) -// generate non-relocatable code. -void MacroAssembler::asm_assert_static(bool check_equal, const char *msg, int id) { - Label ok; - if (check_equal) { z_bre(ok); } - else { z_brne(ok); } - stop_static(msg, id); - bind(ok); +#ifdef ASSERT + asm_assert(check_equal ? bcondEqual : bcondNotEqual, msg, id); +#endif // ASSERT } void MacroAssembler::asm_assert_mems_zero(bool check_equal, bool allow_relocation, int size, int64_t mem_offset, Register mem_base, const char* msg, int id) { +#ifdef ASSERT switch (size) { case 4: load_and_test_int(Z_R0, Address(mem_base, mem_offset)); @@ -5377,8 +5355,9 @@ void MacroAssembler::asm_assert_mems_zero(bool check_equal, bool allow_relocatio default: ShouldNotReachHere(); } - if (allow_relocation) { asm_assert(check_equal, msg, id); } - else { asm_assert_static(check_equal, msg, id); } + // if relocation is not allowed then stop_static() will be called otherwise call stop() + asm_assert(check_equal ? bcondEqual : bcondNotEqual, msg, id, !allow_relocation); +#endif // ASSERT } // Check the condition @@ -5387,18 +5366,13 @@ void MacroAssembler::asm_assert_mems_zero(bool check_equal, bool allow_relocatio // expected_size - FP + SP == 0 // Destroys Register expected_size if no tmp register is passed. void MacroAssembler::asm_assert_frame_size(Register expected_size, Register tmp, const char* msg, int id) { - if (tmp == noreg) { - tmp = expected_size; - } else { - if (tmp != expected_size) { - z_lgr(tmp, expected_size); - } - z_algr(tmp, Z_SP); - z_slg(tmp, 0, Z_R0, Z_SP); - asm_assert_eq(msg, id); - } +#ifdef ASSERT + lgr_if_needed(tmp, expected_size); + z_algr(tmp, Z_SP); + z_slg(tmp, 0, Z_R0, Z_SP); + asm_assert(bcondEqual, msg, id); +#endif // ASSERT } -#endif // !PRODUCT // Save and restore functions: Exclude Z_R0. void MacroAssembler::save_volatile_regs(Register dst, int offset, bool include_fp, bool include_flags) { @@ -5519,8 +5493,8 @@ void MacroAssembler::stop(int type, const char* msg, int id) { // The plain disassembler does not recognize illtrap. It instead displays // a 32-bit value. Issuing two illtraps assures the disassembler finds // the proper beginning of the next instruction. - z_illtrap(); // Illegal instruction. - z_illtrap(); // Illegal instruction. + z_illtrap(id); // Illegal instruction. + z_illtrap(id); // Illegal instruction. BLOCK_COMMENT(" } stop"); } @@ -5559,7 +5533,7 @@ address MacroAssembler::stop_chain(address reentry, int type, const char* msg, i } else { call_VM_leaf_static(CAST_FROM_FN_PTR(address, stop_on_request), Z_ARG1, Z_ARG2); } - z_illtrap(); // Illegal instruction as emergency stop, should the above call return. + z_illtrap(id); // Illegal instruction as emergency stop, should the above call return. } BLOCK_COMMENT(" } stop_chain"); diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.hpp b/src/hotspot/cpu/s390/macroAssembler_s390.hpp index c4ba4562598..fad35cf08b2 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2022 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -863,18 +863,13 @@ class MacroAssembler: public Assembler { // // Assert on CC (condition code in CPU state). - void asm_assert(bool check_equal, const char* msg, int id) PRODUCT_RETURN; - void asm_assert_low(const char *msg, int id) PRODUCT_RETURN; - void asm_assert_high(const char *msg, int id) PRODUCT_RETURN; - void asm_assert_eq(const char* msg, int id) { asm_assert(true, msg, id); } - void asm_assert_ne(const char* msg, int id) { asm_assert(false, msg, id); } - - void asm_assert_static(bool check_equal, const char* msg, int id) PRODUCT_RETURN; + void asm_assert(branch_condition cond, const char* msg, int id, bool is_static=true); + void asm_assert(bool check_equal, const char* msg, int id); private: // Emit assertions. void asm_assert_mems_zero(bool check_equal, bool allow_relocation, int size, int64_t mem_offset, - Register mem_base, const char* msg, int id) PRODUCT_RETURN; + Register mem_base, const char* msg, int id); public: inline void asm_assert_mem4_is_zero(int64_t mem_offset, Register mem_base, const char* msg, int id) { @@ -889,7 +884,6 @@ class MacroAssembler: public Assembler { inline void asm_assert_mem8_isnot_zero(int64_t mem_offset, Register mem_base, const char* msg, int id) { asm_assert_mems_zero(false, true, 8, mem_offset, mem_base, msg, id); } - inline void asm_assert_mem4_is_zero_static(int64_t mem_offset, Register mem_base, const char* msg, int id) { asm_assert_mems_zero(true, false, 4, mem_offset, mem_base, msg, id); } @@ -902,7 +896,7 @@ class MacroAssembler: public Assembler { inline void asm_assert_mem8_isnot_zero_static(int64_t mem_offset, Register mem_base, const char* msg, int id) { asm_assert_mems_zero(false, false, 8, mem_offset, mem_base, msg, id); } - void asm_assert_frame_size(Register expected_size, Register tmp, const char* msg, int id) PRODUCT_RETURN; + void asm_assert_frame_size(Register expected_size, Register tmp, const char* msg, int id); // Save and restore functions: Exclude Z_R0. void save_volatile_regs( Register dst, int offset, bool include_fp, bool include_flags); diff --git a/src/hotspot/cpu/s390/runtime_s390.cpp b/src/hotspot/cpu/s390/runtime_s390.cpp index 6e128d2c393..18f40e87876 100644 --- a/src/hotspot/cpu/s390/runtime_s390.cpp +++ b/src/hotspot/cpu/s390/runtime_s390.cpp @@ -119,7 +119,7 @@ void OptoRuntime::generate_exception_blob() { // (unwind_initial_activation_pending_exception). #ifdef ASSERT __ z_ltgr(handle_exception, handle_exception); - __ asm_assert_ne("handler must not be null", 0x852); + __ asm_assert(Assembler::bcondNotZero, "handler must not be null", 0x852); #endif // Handle_exception contains the handler address. If the associated frame diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 8b7a5b1bc56..089ccb51163 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -2478,7 +2478,7 @@ static void push_skeleton_frames(MacroAssembler* masm, bool deopt, // Make sure that there is at least one entry in the array. DEBUG_ONLY(__ z_ltgr(number_of_frames_reg, number_of_frames_reg)); - __ asm_assert_ne("array_size must be > 0", 0x205); + __ asm_assert(Assembler::bcondNotZero, "array_size must be > 0", 0x205); __ z_bru(loop_entry); @@ -2788,7 +2788,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { } else { __ z_cliy(unpack_kind_byte_offset, unroll_block_reg, Deoptimization::Unpack_uncommon_trap); } - __ asm_assert_eq("SharedRuntime::generate_deopt_blob: expected Unpack_uncommon_trap", 0); + __ asm_assert(Assembler::bcondEqual, "SharedRuntime::generate_deopt_blob: expected Unpack_uncommon_trap", 0); #endif __ zap_from_to(Z_SP, Z_SP, Z_R0_scratch, Z_R1, 500, -1); diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index d8a8560a0e6..d5465343131 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -372,9 +372,9 @@ class StubGenerator: public StubCodeGenerator { #ifdef ASSERT char assertMsg[] = "check BasicType definition in globalDefinitions.hpp"; __ z_chi(r_arg_result_type, T_BOOLEAN); - __ asm_assert_low(assertMsg, 0x0234); + __ asm_assert(Assembler::bcondNotLow, assertMsg, 0x0234); __ z_chi(r_arg_result_type, T_NARROWOOP); - __ asm_assert_high(assertMsg, 0x0235); + __ asm_assert(Assembler::bcondNotHigh, assertMsg, 0x0235); #endif __ add2reg(r_arg_result_type, -T_BOOLEAN); // Remove offset. __ z_larl(Z_R1, firstHandler); // location of first handler @@ -740,7 +740,7 @@ class StubGenerator: public StubCodeGenerator { void assert_positive_int(Register count) { #ifdef ASSERT __ z_srag(Z_R0, count, 31); // Just leave the sign (must be zero) in Z_R0. - __ asm_assert_eq("missing zero extend", 0xAFFE); + __ asm_assert(Assembler::bcondZero, "missing zero extend", 0xAFFE); #endif } diff --git a/src/hotspot/cpu/s390/stubRoutines_s390.cpp b/src/hotspot/cpu/s390/stubRoutines_s390.cpp index 67f96330837..711de63fdea 100644 --- a/src/hotspot/cpu/s390/stubRoutines_s390.cpp +++ b/src/hotspot/cpu/s390/stubRoutines_s390.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2017 SAP SE. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -55,8 +55,7 @@ void StubRoutines::zarch::generate_load_absolute_address(MacroAssembler* masm, R __ load_const_optimized(Z_R0, table_addr); __ z_cgr(table, Z_R0); // safety net __ z_bre(L); - __ z_illtrap(); - __ asm_assert_eq("crc_table: external word relocation required for load_absolute_address", 0x33); + __ stop("crc_table: external word relocation required for load_absolute_address", 0x33); __ bind(L); } { @@ -65,8 +64,7 @@ void StubRoutines::zarch::generate_load_absolute_address(MacroAssembler* masm, R __ z_cl(Z_R0, Address(table, 4)); // safety net __ z_bre(L); __ z_l(Z_R0, Address(table, 4)); // Load data from memory, we know the constant we compared against. - __ z_illtrap(); - __ asm_assert_eq("crc_table: address or contents seems to be messed up", 0x22); + __ stop("crc_table: address or contents seems to be messed up", 0x22); __ bind(L); } #endif @@ -100,8 +98,7 @@ void StubRoutines::zarch::generate_load_trot_table_addr(MacroAssembler* masm, Re __ load_const_optimized(Z_R0, StubRoutines::zarch::_trot_table_addr); __ z_cgr(table, Z_R0); // safety net __ z_bre(L); - __ z_illtrap(); - __ asm_assert_eq("crc_table: external word relocation does not work for load_absolute_address", 0x33); + __ stop("crc_table: external word relocation does not work for load_absolute_address", 0x33); __ bind(L); } { @@ -110,8 +107,7 @@ void StubRoutines::zarch::generate_load_trot_table_addr(MacroAssembler* masm, Re __ z_clg(Z_R0, Address(table, 8)); // safety net __ z_bre(L); __ z_lg(Z_R0, Address(table, 8)); // Load data from memory, we know the constant we compared against. - __ z_illtrap(); - __ asm_assert_eq("trot_table: address or contents seems to be messed up", 0x22); + __ stop("trot_table: address or contents seems to be messed up", 0x22); __ bind(L); } #endif diff --git a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp index 627f0bc44c9..efb4a38315b 100644 --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp @@ -1088,7 +1088,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // asm_assert* is a nop in product builds NOT_PRODUCT(__ z_cg(Z_R14, _z_common_abi(return_pc), Z_SP)); - NOT_PRODUCT(__ asm_assert_eq("killed Z_R14", 0)); + NOT_PRODUCT(__ asm_assert(Assembler::bcondEqual, "killed Z_R14", 0)); __ resize_frame_absolute(sp_after_resize, fp, true); __ save_return_pc(Z_R14); From d0e8aec041d7e0a8a8e72da079b428afff3fcd26 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 26 Apr 2023 16:37:18 +0000 Subject: [PATCH 157/288] 8306374: (bf) Improve performance of DirectCharBuffer::append(CharSequence[,int,int]) Reviewed-by: liach, alanb --- .../java/nio/Direct-X-Buffer.java.template | 63 +++++++++++++++++++ .../classes/java/nio/X-Buffer.java.template | 2 +- .../jdk/java/nio/Buffer/Basic-X.java.template | 28 ++++++--- test/jdk/java/nio/Buffer/Basic.java | 2 +- test/jdk/java/nio/Buffer/BasicChar.java | 28 ++++++--- .../bench/java/nio/CharBufferAppend.java | 38 ++++++++++- 6 files changed, 142 insertions(+), 19 deletions(-) diff --git a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template index 3f444d93568..f7f1d33228d 100644 --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template @@ -446,6 +446,69 @@ class Direct$Type$Buffer$RW$$BO$ // --- Methods to support CharSequence --- +#if[rw] + private static final int APPEND_BUF_SIZE = 1024; + + private $Type$Buffer appendChars(CharSequence csq, int start, int end) { + Objects.checkFromToIndex(start, end, csq.length()); + + int pos = position(); + int lim = limit(); + int rem = (pos <= lim) ? lim - pos : 0; + int length = end - start; + if (length > rem) + throw new BufferOverflowException(); + + char[] buf = new char[Math.min(APPEND_BUF_SIZE, length)]; + int index = pos; + while (start < end) { + int count = end - start; + if (count > buf.length) + count = buf.length; + + if (csq instanceof String str) { + str.getChars(start, start + count, buf, 0); + } else if (csq instanceof StringBuilder sb) { + sb.getChars(start, start + count, buf, 0); + } else if (csq instanceof StringBuffer sb) { + sb.getChars(start, start + count, buf, 0); + } + + putArray(index, buf, 0, count); + + start += count; + index += count; + } + + position(pos + length); + + return this; + } +#end[rw] + + public $Type$Buffer append(CharSequence csq) { +#if[rw] + if (csq instanceof StringBuilder) + return appendChars(csq, 0, csq.length()); + + return super.append(csq); +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + + public $Type$Buffer append(CharSequence csq, int start, int end) { +#if[rw] + if (csq instanceof String || csq instanceof StringBuffer || + csq instanceof StringBuilder) + return appendChars(csq, start, end); + + return super.append(csq, start, end); +#else[rw] + throw new ReadOnlyBufferException(); +#end[rw] + } + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); diff --git a/src/java.base/share/classes/java/nio/X-Buffer.java.template b/src/java.base/share/classes/java/nio/X-Buffer.java.template index 1261e325515..698ecbfc9e4 100644 --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -1319,7 +1319,7 @@ public abstract sealed class $Type$Buffer return put(index, src, 0, src.length); } - private $Type$Buffer putArray(int index, $type$[] src, int offset, int length) { + $Type$Buffer putArray(int index, $type$[] src, int offset, int length) { #if[rw] if ( #if[char] diff --git a/test/jdk/java/nio/Buffer/Basic-X.java.template b/test/jdk/java/nio/Buffer/Basic-X.java.template index 25ba1e2e26d..53982769694 100644 --- a/test/jdk/java/nio/Buffer/Basic-X.java.template +++ b/test/jdk/java/nio/Buffer/Basic-X.java.template @@ -41,6 +41,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Random; #end[byte] +#if[char] +import java.util.function.IntFunction; +#end[char] public class Basic$Type$ @@ -646,15 +649,24 @@ public class Basic$Type$ {cslen/2, cslen + 1} // end > cslen }; - for (CharSequence csq : csqs) { - // append() should throw BufferOverflowException - tryCatch(b, BufferOverflowException.class, () -> - CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2)); + IntFunction[] producers = new IntFunction[] { + (i) -> CharBuffer.allocate(i), + (i) -> ByteBuffer.allocateDirect(2*i).asCharBuffer() + }; - // append() should throw IndexOutOfBoundsException - for (int[] bds : bounds) - tryCatch(b, IndexOutOfBoundsException.class, () -> - CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1])); + for (IntFunction f : producers) { + for (CharSequence csq : csqs) { + // append() should throw BufferOverflowException + final CharBuffer cbBOE = f.apply(cslen/8); + tryCatch(cbBOE, BufferOverflowException.class, () -> + cbBOE.append(csq, cslen/4, cslen/2)); + + // append() should throw IndexOutOfBoundsException + final CharBuffer cbIOOBE = f.apply(cslen + 1); + for (int[] bds : bounds) + tryCatch(cbIOOBE, IndexOutOfBoundsException.class, () -> + cbIOOBE.append(csq, bds[0], bds[1])); + } } // end 8306623 diff --git a/test/jdk/java/nio/Buffer/Basic.java b/test/jdk/java/nio/Buffer/Basic.java index 6bdf901012b..0eac87b765e 100644 --- a/test/jdk/java/nio/Buffer/Basic.java +++ b/test/jdk/java/nio/Buffer/Basic.java @@ -26,7 +26,7 @@ * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431 * 5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219 - * 7199551 8065556 8149469 8230665 8237514 8306623 + * 7199551 8065556 8149469 8230665 8237514 8306374 8306623 * @modules java.base/java.nio:open * java.base/jdk.internal.misc * @author Mark Reinhold diff --git a/test/jdk/java/nio/Buffer/BasicChar.java b/test/jdk/java/nio/Buffer/BasicChar.java index 58cbd0799ec..813b9cff429 100644 --- a/test/jdk/java/nio/Buffer/BasicChar.java +++ b/test/jdk/java/nio/Buffer/BasicChar.java @@ -42,6 +42,9 @@ import java.nio.*; +import java.util.function.IntFunction; + + public class BasicChar extends Basic @@ -646,15 +649,24 @@ public class BasicChar {cslen/2, cslen + 1} // end > cslen }; - for (CharSequence csq : csqs) { - // append() should throw BufferOverflowException - tryCatch(b, BufferOverflowException.class, () -> - CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2)); + IntFunction[] producers = new IntFunction[] { + (i) -> CharBuffer.allocate(i), + (i) -> ByteBuffer.allocateDirect(2*i).asCharBuffer() + }; - // append() should throw IndexOutOfBoundsException - for (int[] bds : bounds) - tryCatch(b, IndexOutOfBoundsException.class, () -> - CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1])); + for (IntFunction f : producers) { + for (CharSequence csq : csqs) { + // append() should throw BufferOverflowException + final CharBuffer cbBOE = f.apply(cslen/8); + tryCatch(cbBOE, BufferOverflowException.class, () -> + cbBOE.append(csq, cslen/4, cslen/2)); + + // append() should throw IndexOutOfBoundsException + final CharBuffer cbIOOBE = f.apply(cslen + 1); + for (int[] bds : bounds) + tryCatch(cbIOOBE, IndexOutOfBoundsException.class, () -> + cbIOOBE.append(csq, bds[0], bds[1])); + } } // end 8306623 diff --git a/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java b/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java index ea3ef4ab0fe..1d4390c1362 100644 --- a/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java +++ b/test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java @@ -44,7 +44,7 @@ import org.openjdk.jmh.annotations.Warmup; @Fork(1) public class CharBufferAppend { - static final int SIZE = 8192; + static final int SIZE = 32768; static String str; static StringBuffer strbuf; @@ -138,4 +138,40 @@ public class CharBufferAppend { hbDst.clear(); return hbDst.append(strbld, SIZE/4, 3*SIZE/4); } + + @Benchmark + public CharBuffer appendStringToDirect() { + dbDst.clear(); + return dbDst.append(str); + } + + @Benchmark + public CharBuffer appendStringBufferToDirect() { + dbDst.clear(); + return dbDst.append(strbuf); + } + + @Benchmark + public CharBuffer appendStringBuilderToDirect() { + dbDst.clear(); + return dbDst.append(strbld); + } + + @Benchmark + public CharBuffer appendSubStringToDirect() { + dbDst.clear(); + return dbDst.append(str, SIZE/4, 3*SIZE/4); + } + + @Benchmark + public CharBuffer appendSubStringBufferToDirect() { + dbDst.clear(); + return dbDst.append(strbuf, SIZE/4, 3*SIZE/4); + } + + @Benchmark + public CharBuffer appendSubStringBuilderToDirect() { + dbDst.clear(); + return dbDst.append(strbld, SIZE/4, 3*SIZE/4); + } } From 8e36c05d6c80f6bdcd8a7530a382810f500885ad Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Wed, 26 Apr 2023 16:53:43 +0000 Subject: [PATCH 158/288] 8305853: java/text/Format/DateFormat/DateFormatRegression.java fails with "Uncaught exception thrown in test method Test4089106" Reviewed-by: naoto, lancea --- .../text/Format/DateFormat/DateFormatRegression.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java index 85e4f859caa..fb92986adf1 100644 --- a/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java +++ b/test/jdk/java/text/Format/DateFormat/DateFormatRegression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -30,7 +30,7 @@ import java.io.*; * @bug 4029195 4052408 4056591 4059917 4060212 4061287 4065240 4071441 4073003 * 4089106 4100302 4101483 4103340 4103341 4104136 4104522 4106807 4108407 * 4134203 4138203 4148168 4151631 4151706 4153860 4162071 4182066 4209272 4210209 - * 4213086 4250359 4253490 4266432 4406615 4413980 8008577 + * 4213086 4250359 4253490 4266432 4406615 4413980 8008577 8305853 * @library /java/text/testlib * @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRegression */ @@ -357,11 +357,11 @@ public class DateFormatRegression extends IntlTest { public void Test4089106() { TimeZone def = TimeZone.getDefault(); try { - TimeZone z = new SimpleTimeZone((int)(1.25 * 3600000), "FAKEZONE"); - TimeZone.setDefault(z); + TimeZone customTz = TimeZone.getTimeZone("GMT-08:15"); + TimeZone.setDefault(customTz); SimpleDateFormat f = new SimpleDateFormat(); - if (!f.getTimeZone().equals(z)) - errln("Fail: SimpleTimeZone should use TimeZone.getDefault()"); + if (!f.getTimeZone().equals(customTz)) + errln("Fail: SimpleDateFormat should use TimeZone.getDefault()"); } finally { TimeZone.setDefault(def); From 01b85129116dd2cc762e518ac631305bd8511764 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 26 Apr 2023 17:30:22 +0000 Subject: [PATCH 159/288] 8302182: Update Public Suffix List to 88467c9 Reviewed-by: mullan --- .../share/data/publicsuffixlist/VERSION | 4 +- .../publicsuffixlist/public_suffix_list.dat | 1600 ++++++++--------- src/java.base/share/legal/public_suffix.md | 2 +- .../util/RegisteredDomain/ParseNames.java | 4 +- .../security/util/RegisteredDomain/tests.dat | 8 + 5 files changed, 784 insertions(+), 834 deletions(-) diff --git a/src/java.base/share/data/publicsuffixlist/VERSION b/src/java.base/share/data/publicsuffixlist/VERSION index be9290a33fc..4ffc88dbd83 100644 --- a/src/java.base/share/data/publicsuffixlist/VERSION +++ b/src/java.base/share/data/publicsuffixlist/VERSION @@ -1,2 +1,2 @@ -Github: https://raw.githubusercontent.com/publicsuffix/list/3c213aab32b3c014f171b1673d4ce9b5cd72bf1c/public_suffix_list.dat -Date: 2021-11-27 +Github: https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat +Date: 2023-04-14 diff --git a/src/java.base/share/data/publicsuffixlist/public_suffix_list.dat b/src/java.base/share/data/publicsuffixlist/public_suffix_list.dat index 5529554d82d..d9f0c71dbb4 100644 --- a/src/java.base/share/data/publicsuffixlist/public_suffix_list.dat +++ b/src/java.base/share/data/publicsuffixlist/public_suffix_list.dat @@ -9,7 +9,7 @@ // ===BEGIN ICANN DOMAINS=== -// ac : https://en.wikipedia.org/wiki/.ac +// ac : http://nic.ac/rules.htm ac com.ac edu.ac @@ -22,8 +22,7 @@ org.ac ad nom.ad -// ae : https://en.wikipedia.org/wiki/.ae -// see also: "Domain Name Eligibility Policy" at http://www.aeda.ae/eng/aepolicy.php +// ae : https://tdra.gov.ae/en/aeda/ae-policies ae co.ae net.ae @@ -381,11 +380,29 @@ org.bi // biz : https://en.wikipedia.org/wiki/.biz biz -// bj : https://en.wikipedia.org/wiki/.bj +// bj : https://nic.bj/bj-suffixes.txt +// submitted by registry bj -asso.bj -barreau.bj -gouv.bj +africa.bj +agro.bj +architectes.bj +assur.bj +avocats.bj +co.bj +com.bj +eco.bj +econo.bj +edu.bj +info.bj +loisirs.bj +money.bj +net.bj +org.bj +ote.bj +resto.bj +restaurant.bj +tourism.bj +univ.bj // bm : http://www.bermudanic.bm/dnr-text.txt bm @@ -865,6 +882,7 @@ gov.cx // cy : http://www.nic.cy/ // Submitted by registry Panayiotou Fotia +// namespace policies URL https://www.nic.cy/portal//sites/default/files/symfonia_gia_eggrafi.pdf cy ac.cy biz.cy @@ -872,10 +890,9 @@ com.cy ekloges.cy gov.cy ltd.cy -name.cy +mil.cy net.cy org.cy -parliament.cy press.cy pro.cy tm.cy @@ -1034,8 +1051,7 @@ fm // fo : https://en.wikipedia.org/wiki/.fo fo -// fr : http://www.afnic.fr/ -// domaines descriptifs : https://www.afnic.fr/medias/documents/Cadre_legal/Afnic_Naming_Policy_12122016_VEN.pdf +// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf fr asso.fr com.fr @@ -1043,7 +1059,7 @@ gouv.fr nom.fr prd.fr tm.fr -// domaines sectoriels : https://www.afnic.fr/en/products-and-services/the-fr-tld/sector-based-fr-domains-4.html +// Former "domaines sectoriels", still registration suffixes aeroport.fr avocat.fr avoues.fr @@ -1316,7 +1332,9 @@ web.id ie gov.ie -// il : http://www.isoc.org.il/domains/ +// il : http://www.isoc.org.il/domains/ +// see also: https://en.isoc.org.il/il-cctld/registration-rules +// ISOC-IL (operated by .il Registry) il ac.il co.il @@ -1326,6 +1344,16 @@ k12.il muni.il net.il org.il +// xn--4dbrk0ce ("Israel", Hebrew) : IL +ישראל +// xn--4dbgdty6c.xn--4dbrk0ce. +אקדמיה.ישראל +// xn--5dbhl8d.xn--4dbrk0ce. +ישוב.ישראל +// xn--8dbq2a.xn--4dbrk0ce. +צהל.ישראל +// xn--hebda8b.xn--4dbrk0ce. +ממשל.ישראל // im : https://www.nic.im/ // Submitted by registry @@ -1341,22 +1369,51 @@ tt.im tv.im // in : https://en.wikipedia.org/wiki/.in -// see also: https://registry.in/Policies +// see also: https://registry.in/policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. in -co.in -firm.in -net.in -org.in -gen.in -ind.in -nic.in +5g.in +6g.in ac.in +ai.in +am.in +bihar.in +biz.in +business.in +ca.in +cn.in +co.in +com.in +coop.in +cs.in +delhi.in +dr.in edu.in -res.in +er.in +firm.in +gen.in gov.in +gujarat.in +ind.in +info.in +int.in +internet.in +io.in +me.in mil.in +net.in +nic.in +org.in +pg.in +post.in +pro.in +res.in +travel.in +tv.in +uk.in +up.in +us.in // info : https://en.wikipedia.org/wiki/.info info @@ -1366,7 +1423,7 @@ info int eu.int -// io : http://www.nic.io/rules.html +// io : http://www.nic.io/rules.htm // list of other 2nd level tlds ? io com.io @@ -3765,11 +3822,10 @@ org.kw // ky : http://www.icta.ky/da_ky_reg_dom.php // Confirmed by registry 2008-06-17 ky -edu.ky -gov.ky com.ky -org.ky +edu.ky net.ky +org.ky // kz : https://en.wikipedia.org/wiki/.kz // see also: http://www.nic.kz/rules/index.jsp @@ -4013,555 +4069,8 @@ ac.mu co.mu or.mu -// museum : http://about.museum/naming/ -// http://index.museum/ +// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ museum -academy.museum -agriculture.museum -air.museum -airguard.museum -alabama.museum -alaska.museum -amber.museum -ambulance.museum -american.museum -americana.museum -americanantiques.museum -americanart.museum -amsterdam.museum -and.museum -annefrank.museum -anthro.museum -anthropology.museum -antiques.museum -aquarium.museum -arboretum.museum -archaeological.museum -archaeology.museum -architecture.museum -art.museum -artanddesign.museum -artcenter.museum -artdeco.museum -arteducation.museum -artgallery.museum -arts.museum -artsandcrafts.museum -asmatart.museum -assassination.museum -assisi.museum -association.museum -astronomy.museum -atlanta.museum -austin.museum -australia.museum -automotive.museum -aviation.museum -axis.museum -badajoz.museum -baghdad.museum -bahn.museum -bale.museum -baltimore.museum -barcelona.museum -baseball.museum -basel.museum -baths.museum -bauern.museum -beauxarts.museum -beeldengeluid.museum -bellevue.museum -bergbau.museum -berkeley.museum -berlin.museum -bern.museum -bible.museum -bilbao.museum -bill.museum -birdart.museum -birthplace.museum -bonn.museum -boston.museum -botanical.museum -botanicalgarden.museum -botanicgarden.museum -botany.museum -brandywinevalley.museum -brasil.museum -bristol.museum -british.museum -britishcolumbia.museum -broadcast.museum -brunel.museum -brussel.museum -brussels.museum -bruxelles.museum -building.museum -burghof.museum -bus.museum -bushey.museum -cadaques.museum -california.museum -cambridge.museum -can.museum -canada.museum -capebreton.museum -carrier.museum -cartoonart.museum -casadelamoneda.museum -castle.museum -castres.museum -celtic.museum -center.museum -chattanooga.museum -cheltenham.museum -chesapeakebay.museum -chicago.museum -children.museum -childrens.museum -childrensgarden.museum -chiropractic.museum -chocolate.museum -christiansburg.museum -cincinnati.museum -cinema.museum -circus.museum -civilisation.museum -civilization.museum -civilwar.museum -clinton.museum -clock.museum -coal.museum -coastaldefence.museum -cody.museum -coldwar.museum -collection.museum -colonialwilliamsburg.museum -coloradoplateau.museum -columbia.museum -columbus.museum -communication.museum -communications.museum -community.museum -computer.museum -computerhistory.museum -comunicações.museum -contemporary.museum -contemporaryart.museum -convent.museum -copenhagen.museum -corporation.museum -correios-e-telecomunicações.museum -corvette.museum -costume.museum -countryestate.museum -county.museum -crafts.museum -cranbrook.museum -creation.museum -cultural.museum -culturalcenter.museum -culture.museum -cyber.museum -cymru.museum -dali.museum -dallas.museum -database.museum -ddr.museum -decorativearts.museum -delaware.museum -delmenhorst.museum -denmark.museum -depot.museum -design.museum -detroit.museum -dinosaur.museum -discovery.museum -dolls.museum -donostia.museum -durham.museum -eastafrica.museum -eastcoast.museum -education.museum -educational.museum -egyptian.museum -eisenbahn.museum -elburg.museum -elvendrell.museum -embroidery.museum -encyclopedic.museum -england.museum -entomology.museum -environment.museum -environmentalconservation.museum -epilepsy.museum -essex.museum -estate.museum -ethnology.museum -exeter.museum -exhibition.museum -family.museum -farm.museum -farmequipment.museum -farmers.museum -farmstead.museum -field.museum -figueres.museum -filatelia.museum -film.museum -fineart.museum -finearts.museum -finland.museum -flanders.museum -florida.museum -force.museum -fortmissoula.museum -fortworth.museum -foundation.museum -francaise.museum -frankfurt.museum -franziskaner.museum -freemasonry.museum -freiburg.museum -fribourg.museum -frog.museum -fundacio.museum -furniture.museum -gallery.museum -garden.museum -gateway.museum -geelvinck.museum -gemological.museum -geology.museum -georgia.museum -giessen.museum -glas.museum -glass.museum -gorge.museum -grandrapids.museum -graz.museum -guernsey.museum -halloffame.museum -hamburg.museum -handson.museum -harvestcelebration.museum -hawaii.museum -health.museum -heimatunduhren.museum -hellas.museum -helsinki.museum -hembygdsforbund.museum -heritage.museum -histoire.museum -historical.museum -historicalsociety.museum -historichouses.museum -historisch.museum -historisches.museum -history.museum -historyofscience.museum -horology.museum -house.museum -humanities.museum -illustration.museum -imageandsound.museum -indian.museum -indiana.museum -indianapolis.museum -indianmarket.museum -intelligence.museum -interactive.museum -iraq.museum -iron.museum -isleofman.museum -jamison.museum -jefferson.museum -jerusalem.museum -jewelry.museum -jewish.museum -jewishart.museum -jfk.museum -journalism.museum -judaica.museum -judygarland.museum -juedisches.museum -juif.museum -karate.museum -karikatur.museum -kids.museum -koebenhavn.museum -koeln.museum -kunst.museum -kunstsammlung.museum -kunstunddesign.museum -labor.museum -labour.museum -lajolla.museum -lancashire.museum -landes.museum -lans.museum -läns.museum -larsson.museum -lewismiller.museum -lincoln.museum -linz.museum -living.museum -livinghistory.museum -localhistory.museum -london.museum -losangeles.museum -louvre.museum -loyalist.museum -lucerne.museum -luxembourg.museum -luzern.museum -mad.museum -madrid.museum -mallorca.museum -manchester.museum -mansion.museum -mansions.museum -manx.museum -marburg.museum -maritime.museum -maritimo.museum -maryland.museum -marylhurst.museum -media.museum -medical.museum -medizinhistorisches.museum -meeres.museum -memorial.museum -mesaverde.museum -michigan.museum -midatlantic.museum -military.museum -mill.museum -miners.museum -mining.museum -minnesota.museum -missile.museum -missoula.museum -modern.museum -moma.museum -money.museum -monmouth.museum -monticello.museum -montreal.museum -moscow.museum -motorcycle.museum -muenchen.museum -muenster.museum -mulhouse.museum -muncie.museum -museet.museum -museumcenter.museum -museumvereniging.museum -music.museum -national.museum -nationalfirearms.museum -nationalheritage.museum -nativeamerican.museum -naturalhistory.museum -naturalhistorymuseum.museum -naturalsciences.museum -nature.museum -naturhistorisches.museum -natuurwetenschappen.museum -naumburg.museum -naval.museum -nebraska.museum -neues.museum -newhampshire.museum -newjersey.museum -newmexico.museum -newport.museum -newspaper.museum -newyork.museum -niepce.museum -norfolk.museum -north.museum -nrw.museum -nyc.museum -nyny.museum -oceanographic.museum -oceanographique.museum -omaha.museum -online.museum -ontario.museum -openair.museum -oregon.museum -oregontrail.museum -otago.museum -oxford.museum -pacific.museum -paderborn.museum -palace.museum -paleo.museum -palmsprings.museum -panama.museum -paris.museum -pasadena.museum -pharmacy.museum -philadelphia.museum -philadelphiaarea.museum -philately.museum -phoenix.museum -photography.museum -pilots.museum -pittsburgh.museum -planetarium.museum -plantation.museum -plants.museum -plaza.museum -portal.museum -portland.museum -portlligat.museum -posts-and-telecommunications.museum -preservation.museum -presidio.museum -press.museum -project.museum -public.museum -pubol.museum -quebec.museum -railroad.museum -railway.museum -research.museum -resistance.museum -riodejaneiro.museum -rochester.museum -rockart.museum -roma.museum -russia.museum -saintlouis.museum -salem.museum -salvadordali.museum -salzburg.museum -sandiego.museum -sanfrancisco.museum -santabarbara.museum -santacruz.museum -santafe.museum -saskatchewan.museum -satx.museum -savannahga.museum -schlesisches.museum -schoenbrunn.museum -schokoladen.museum -school.museum -schweiz.museum -science.museum -scienceandhistory.museum -scienceandindustry.museum -sciencecenter.museum -sciencecenters.museum -science-fiction.museum -sciencehistory.museum -sciences.museum -sciencesnaturelles.museum -scotland.museum -seaport.museum -settlement.museum -settlers.museum -shell.museum -sherbrooke.museum -sibenik.museum -silk.museum -ski.museum -skole.museum -society.museum -sologne.museum -soundandvision.museum -southcarolina.museum -southwest.museum -space.museum -spy.museum -square.museum -stadt.museum -stalbans.museum -starnberg.museum -state.museum -stateofdelaware.museum -station.museum -steam.museum -steiermark.museum -stjohn.museum -stockholm.museum -stpetersburg.museum -stuttgart.museum -suisse.museum -surgeonshall.museum -surrey.museum -svizzera.museum -sweden.museum -sydney.museum -tank.museum -tcm.museum -technology.museum -telekommunikation.museum -television.museum -texas.museum -textile.museum -theater.museum -time.museum -timekeeping.museum -topology.museum -torino.museum -touch.museum -town.museum -transport.museum -tree.museum -trolley.museum -trust.museum -trustee.museum -uhren.museum -ulm.museum -undersea.museum -university.museum -usa.museum -usantiques.museum -usarts.museum -uscountryestate.museum -usculture.museum -usdecorativearts.museum -usgarden.museum -ushistory.museum -ushuaia.museum -uslivinghistory.museum -utah.museum -uvic.museum -valley.museum -vantaa.museum -versailles.museum -viking.museum -village.museum -virginia.museum -virtual.museum -virtuel.museum -vlaanderen.museum -volkenkunde.museum -wales.museum -wallonie.museum -war.museum -washingtondc.museum -watchandclock.museum -watch-and-clock.museum -western.museum -westfalen.museum -whaling.museum -wildlife.museum -williamsburg.museum -windmill.museum -workshop.museum -york.museum -yorkshire.museum -yosemite.museum -youth.museum -zoological.museum -zoology.museum -ירושלים.museum -иком.museum // mv : https://en.wikipedia.org/wiki/.mv // "mv" included because, contra Wikipedia, google.mv exists. @@ -5804,7 +5313,7 @@ zarow.pl zgora.pl zgorzelec.pl -// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm // pn : http://www.government.pn/PnRegistry/policies.htm @@ -5902,7 +5411,7 @@ net.qa org.qa sch.qa -// re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs +// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf re asso.re com.re @@ -6037,7 +5546,7 @@ gov.sg edu.sg per.sg -// sh : http://www.nic.sh/registrar.html +// sh : http://nic.sh/rules.htm sh com.sh net.sh @@ -6159,7 +5668,7 @@ td // http://www.telnic.org/ tel -// tf : https://en.wikipedia.org/wiki/.tf +// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf tf // tg : https://en.wikipedia.org/wiki/.tg @@ -6778,7 +6287,7 @@ edu.vu net.vu org.vu -// wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf wf // ws : https://en.wikipedia.org/wiki/.ws @@ -6790,7 +6299,7 @@ org.ws gov.ws edu.ws -// yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf yt // IDN ccTLDs @@ -7132,7 +6641,7 @@ org.zw // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2021-11-13T15:12:42Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2023-04-14T15:13:16Z // This list is auto-generated, don't edit it manually. // aaa : 2015-02-26 American Automobile Association, Inc. aaa @@ -7182,9 +6691,6 @@ aco // actor : 2013-12-12 Dog Beach, LLC actor -// adac : 2015-07-16 Allgemeiner Deutscher Automobil-Club e.V. (ADAC) -adac - // ads : 2014-12-04 Charleston Road Registry Inc. ads @@ -7197,9 +6703,6 @@ aeg // aetna : 2015-05-21 Aetna Life Insurance Company aetna -// afamilycompany : 2015-07-23 Johnson Shareholdings, Inc. -afamilycompany - // afl : 2014-10-02 Australian Football League afl @@ -7305,7 +6808,7 @@ arab // aramco : 2014-11-20 Aramco Services Company aramco -// archi : 2014-02-06 Afilias Limited +// archi : 2014-02-06 Identity Digital Limited archi // army : 2014-03-06 Dog Beach, LLC @@ -7338,7 +6841,7 @@ audi // audible : 2015-06-25 Amazon Registry Services, Inc. audible -// audio : 2014-03-20 UNR Corp. +// audio : 2014-03-20 XYZ.COM LLC audio // auspost : 2015-08-13 Australian Postal Corporation @@ -7353,7 +6856,7 @@ auto // autos : 2014-01-09 XYZ.COM LLC autos -// avianca : 2015-01-08 Avianca Holdings S.A. +// avianca : 2015-01-08 Avianca Inc. avianca // aws : 2015-06-25 AWS Registry LLC @@ -7449,7 +6952,7 @@ best // bestbuy : 2015-07-31 BBY Solutions, Inc. bestbuy -// bet : 2015-05-07 Afilias Limited +// bet : 2015-05-07 Identity Digital Limited bet // bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited @@ -7470,13 +6973,13 @@ bing // bingo : 2014-12-04 Binky Moon, LLC bingo -// bio : 2014-03-06 Afilias Limited +// bio : 2014-03-06 Identity Digital Limited bio -// black : 2014-01-16 Afilias Limited +// black : 2014-01-16 Identity Digital Limited black -// blackfriday : 2014-01-16 UNR Corp. +// blackfriday : 2014-01-16 Registry Services, LLC blackfriday // blockbuster : 2015-07-30 Dish DBS Corporation @@ -7488,7 +6991,7 @@ blog // bloomberg : 2014-07-17 Bloomberg IP Holdings LLC bloomberg -// blue : 2013-11-07 Afilias Limited +// blue : 2013-11-07 Identity Digital Limited blue // bms : 2014-10-30 Bristol-Myers Squibb Company @@ -7530,7 +7033,7 @@ bosch // bostik : 2015-05-28 Bostik SA bostik -// boston : 2015-12-10 Boston TLD Management, LLC +// boston : 2015-12-10 Registry Services, LLC boston // bot : 2014-12-18 Amazon Registry Services, Inc. @@ -7560,12 +7063,6 @@ brother // brussels : 2014-02-06 DNS.be vzw brussels -// budapest : 2013-11-21 Minds + Machines Group Limited -budapest - -// bugatti : 2015-07-23 Bugatti International SA -bugatti - // build : 2013-11-07 Plan Bee LLC build @@ -7599,7 +7096,7 @@ call // calvinklein : 2015-07-30 PVH gTLD Holdings LLC calvinklein -// cam : 2016-04-21 AC Webconnecting Holding B.V. +// cam : 2016-04-21 Cam Connecting SARL cam // camera : 2013-08-27 Binky Moon, LLC @@ -7608,9 +7105,6 @@ camera // camp : 2013-11-07 Binky Moon, LLC camp -// cancerresearch : 2014-05-15 Australian Cancer Research Foundation -cancerresearch - // canon : 2014-09-12 Canon Inc. canon @@ -7647,7 +7141,7 @@ cars // casa : 2013-11-21 Registry Services, LLC casa -// case : 2015-09-03 Helium TLDs Ltd +// case : 2015-09-03 Digity, LLC case // cash : 2014-03-06 Binky Moon, LLC @@ -7695,7 +7189,7 @@ chanel // channel : 2014-05-08 Charleston Road Registry Inc. channel -// charity : 2018-04-11 Binky Moon, LLC +// charity : 2018-04-11 Public Interest Registry charity // chase : 2015-04-30 JPMorgan Chase Bank, National Association @@ -7710,7 +7204,7 @@ cheap // chintai : 2015-06-11 CHINTAI Corporation chintai -// christmas : 2013-11-21 UNR Corp. +// christmas : 2013-11-21 XYZ.COM LLC christmas // chrome : 2014-07-24 Charleston Road Registry Inc. @@ -7749,7 +7243,7 @@ claims // cleaning : 2013-12-05 Binky Moon, LLC cleaning -// click : 2014-06-05 UNR Corp. +// click : 2014-06-05 Internet Naming Company LLC click // clinic : 2014-03-20 Binky Moon, LLC @@ -7833,7 +7327,7 @@ cool // corsica : 2014-09-25 Collectivité de Corse corsica -// country : 2013-12-19 DotCountry LLC +// country : 2013-12-19 Internet Naming Company LLC country // coupon : 2015-02-26 Amazon Registry Services, Inc. @@ -7842,7 +7336,7 @@ coupon // coupons : 2015-03-26 Binky Moon, LLC coupons -// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD +// courses : 2014-12-04 Registry Services, LLC courses // cpa : 2019-06-10 American Institute of Certified Public Accountants @@ -7872,9 +7366,6 @@ cruise // cruises : 2013-12-05 Binky Moon, LLC cruises -// csc : 2014-09-25 Alliance-One Services, Inc. -csc - // cuisinella : 2014-04-03 SCHMIDT GROUPE S.A.S. cuisinella @@ -7962,7 +7453,7 @@ dhl // diamonds : 2013-09-22 Binky Moon, LLC diamonds -// diet : 2014-06-26 UNR Corp. +// diet : 2014-06-26 XYZ.COM LLC diet // digital : 2014-03-06 Binky Moon, LLC @@ -8016,9 +7507,6 @@ dtv // dubai : 2015-01-01 Dubai Smart Government Department dubai -// duck : 2015-07-23 Johnson Shareholdings, Inc. -duck - // dunlop : 2015-07-02 The Goodyear Tire & Rubber Company dunlop @@ -8034,7 +7522,7 @@ dvag // dvr : 2016-05-26 DISH Technologies L.L.C. dvr -// earth : 2014-12-04 Interlink Co., Ltd. +// earth : 2014-12-04 Interlink Systems Innovation Institute K.K. earth // eat : 2014-01-23 Charleston Road Registry Inc. @@ -8211,7 +7699,7 @@ flir // florist : 2013-11-07 Binky Moon, LLC florist -// flowers : 2014-10-09 UNR Corp. +// flowers : 2014-10-09 XYZ.COM LLC flowers // fly : 2014-05-08 Charleston Road Registry Inc. @@ -8241,7 +7729,7 @@ forsale // forum : 2015-04-02 Fegistry, LLC forum -// foundation : 2013-12-05 Binky Moon, LLC +// foundation : 2013-12-05 Public Interest Registry foundation // fox : 2015-09-11 FOX Registry, LLC @@ -8298,7 +7786,7 @@ gallo // gallup : 2015-02-19 Gallup, Inc. gallup -// game : 2015-05-28 UNR Corp. +// game : 2015-05-28 XYZ.COM LLC game // games : 2015-05-28 Dog Beach, LLC @@ -8322,7 +7810,7 @@ gdn // gea : 2014-12-04 GEA Group Aktiengesellschaft gea -// gent : 2014-01-23 COMBELL NV +// gent : 2014-01-23 Easyhost BV gent // genting : 2015-03-12 Resorts World Inc Pte. Ltd. @@ -8340,22 +7828,19 @@ gift // gifts : 2014-07-03 Binky Moon, LLC gifts -// gives : 2014-03-06 Dog Beach, LLC +// gives : 2014-03-06 Public Interest Registry gives -// giving : 2014-11-13 Giving Limited +// giving : 2014-11-13 Public Interest Registry giving -// glade : 2015-07-23 Johnson Shareholdings, Inc. -glade - // glass : 2013-11-07 Binky Moon, LLC glass // gle : 2014-07-24 Charleston Road Registry Inc. gle -// global : 2014-04-17 Dot Global Domain Registry Limited +// global : 2014-04-17 Identity Digital Limited global // globo : 2013-12-19 Globo Comunicação e Participações S.A @@ -8412,7 +7897,7 @@ graphics // gratis : 2014-03-20 Binky Moon, LLC gratis -// green : 2014-05-08 Afilias Limited +// green : 2014-05-08 Identity Digital Limited green // gripe : 2014-03-06 Binky Moon, LLC @@ -8436,7 +7921,7 @@ guge // guide : 2013-09-13 Binky Moon, LLC guide -// guitars : 2013-11-14 UNR Corp. +// guitars : 2013-11-14 XYZ.COM LLC guitars // guru : 2013-08-27 Binky Moon, LLC @@ -8469,7 +7954,7 @@ health // healthcare : 2014-06-12 Binky Moon, LLC healthcare -// help : 2014-06-26 UNR Corp. +// help : 2014-06-26 Innovation service Limited help // helsinki : 2015-02-05 City of Helsinki @@ -8484,7 +7969,7 @@ hermes // hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc. hgtv -// hiphop : 2014-03-06 UNR Corp. +// hiphop : 2014-03-06 Dot Hip Hop, LLC hiphop // hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc. @@ -8493,7 +7978,7 @@ hisamitsu // hitachi : 2014-10-31 Hitachi, Ltd. hitachi -// hiv : 2014-03-13 UNR Corp. +// hiv : 2014-03-13 Internet Naming Company LLC hiv // hkt : 2015-05-14 PCCW-HKT DataCom Services Limited @@ -8532,7 +8017,7 @@ hospital // host : 2014-04-17 Radix FZC host -// hosting : 2014-05-29 UNR Corp. +// hosting : 2014-05-29 XYZ.COM LLC hosting // hot : 2015-08-27 Amazon Registry Services, Inc. @@ -8697,7 +8182,7 @@ jpmorgan // jprs : 2014-09-18 Japan Registry Services Co., Ltd. jprs -// juegos : 2014-03-20 UNR Corp. +// juegos : 2014-03-20 Internet Naming Company LLC juegos // juniper : 2015-07-30 JUNIPER NETWORKS, INC. @@ -8727,7 +8212,7 @@ kia // kids : 2021-08-13 DotKids Foundation Limited kids -// kim : 2013-09-23 Afilias Limited +// kim : 2013-09-23 Identity Digital Limited kim // kinder : 2014-11-07 Ferrero Trading Lux S.A. @@ -8796,7 +8281,7 @@ lanxess // lasalle : 2015-04-02 Jones Lang LaSalle Incorporated lasalle -// lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico +// lat : 2014-10-16 XYZ.COM LLC lat // latino : 2015-07-30 Dish DBS Corporation @@ -8832,7 +8317,7 @@ lego // lexus : 2015-04-23 TOYOTA MOTOR CORPORATION lexus -// lgbt : 2014-05-08 Afilias Limited +// lgbt : 2014-05-08 Identity Digital Limited lgbt // lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG @@ -8865,10 +8350,7 @@ limo // lincoln : 2014-11-13 Ford Motor Company lincoln -// linde : 2014-12-04 Linde Aktiengesellschaft -linde - -// link : 2013-11-14 UNR Corp. +// link : 2013-11-14 Nova Registry Ltd link // lipsy : 2015-06-25 Lipsy Ltd @@ -8880,13 +8362,10 @@ live // living : 2015-07-30 Lifestyle Domain Holdings, Inc. living -// lixil : 2015-03-19 LIXIL Group Corporation -lixil - -// llc : 2017-12-14 Afilias Limited +// llc : 2017-12-14 Identity Digital Limited llc -// llp : 2019-08-26 UNR Corp. +// llp : 2019-08-26 Intercap Registry Inc. llp // loan : 2014-11-20 dot Loan Limited @@ -8901,10 +8380,7 @@ locker // locus : 2015-06-25 Locus Analytics LLC locus -// loft : 2015-07-30 Annco, Inc. -loft - -// lol : 2015-01-30 UNR Corp. +// lol : 2015-01-30 XYZ.COM LLC lol // london : 2013-11-14 Dot London Domains Limited @@ -8913,7 +8389,7 @@ london // lotte : 2014-11-07 Lotte Holdings Co., Ltd. lotte -// lotto : 2014-04-10 Afilias Limited +// lotto : 2014-04-10 Identity Digital Limited lotto // love : 2014-12-22 Merchant Law Group LLP @@ -8940,9 +8416,6 @@ luxe // luxury : 2013-10-17 Luxury Partners, LLC luxury -// macys : 2015-07-31 Macys, Inc. -macys - // madrid : 2014-05-01 Comunidad de Madrid madrid @@ -9021,7 +8494,7 @@ menu // merckmsd : 2016-07-14 MSD Registry Holdings, Inc. merckmsd -// miami : 2013-12-19 Minds + Machines Group Limited +// miami : 2013-12-19 Registry Services, LLC miami // microsoft : 2014-12-18 Microsoft Corporation @@ -9054,13 +8527,13 @@ mobile // moda : 2013-11-07 Dog Beach, LLC moda -// moe : 2013-11-13 Interlink Co., Ltd. +// moe : 2013-11-13 Interlink Systems Innovation Institute K.K. moe // moi : 2014-12-18 Amazon Registry Services, Inc. moi -// mom : 2015-04-16 UNR Corp. +// mom : 2015-04-16 XYZ.COM LLC mom // monash : 2013-09-30 Monash University @@ -9216,9 +8689,6 @@ obi // observer : 2015-04-30 Dog Beach, LLC observer -// off : 2015-07-23 Johnson Shareholdings, Inc. -off - // office : 2015-03-12 Microsoft Corporation office @@ -9264,7 +8734,7 @@ oracle // orange : 2015-03-12 Orange Brand Services Limited orange -// organic : 2014-03-27 Afilias Limited +// organic : 2014-03-27 Identity Digital Limited organic // origins : 2015-10-01 The Estée Lauder Companies Inc. @@ -9285,7 +8755,7 @@ ovh // page : 2014-12-04 Charleston Road Registry Inc. page -// panasonic : 2015-07-30 Panasonic Corporation +// panasonic : 2015-07-30 Panasonic Holdings Corporation panasonic // paris : 2014-01-30 City of Paris @@ -9312,7 +8782,7 @@ pay // pccw : 2015-05-14 PCCW Enterprises Limited pccw -// pet : 2015-05-07 Afilias Limited +// pet : 2015-05-07 Identity Digital Limited pet // pfizer : 2015-09-11 Pfizer Inc. @@ -9330,7 +8800,7 @@ philips // phone : 2016-06-02 Dish DBS Corporation phone -// photo : 2013-11-14 UNR Corp. +// photo : 2013-11-14 Registry Services, LLC photo // photography : 2013-09-20 Binky Moon, LLC @@ -9342,7 +8812,7 @@ photos // physio : 2014-05-01 PhysBiz Pty Ltd physio -// pics : 2013-11-14 UNR Corp. +// pics : 2013-11-14 XYZ.COM LLC pics // pictet : 2014-06-26 Pictet Europe S.A. @@ -9360,7 +8830,7 @@ pin // ping : 2015-06-11 Ping Registry Provider, Inc. ping -// pink : 2013-10-01 Afilias Limited +// pink : 2013-10-01 Identity Digital Limited pink // pioneer : 2015-07-16 Pioneer Corporation @@ -9390,7 +8860,7 @@ pnc // pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG pohl -// poker : 2014-07-03 Afilias Limited +// poker : 2014-07-03 Identity Digital Limited poker // politie : 2015-08-20 Politie Nederland @@ -9423,13 +8893,13 @@ prof // progressive : 2015-07-23 Progressive Casualty Insurance Company progressive -// promo : 2014-12-18 Afilias Limited +// promo : 2014-12-18 Identity Digital Limited promo // properties : 2013-12-05 Binky Moon, LLC properties -// property : 2014-05-22 UNR Corp. +// property : 2014-05-22 Internet Naming Company LLC property // protection : 2015-04-23 XYZ.COM LLC @@ -9447,7 +8917,7 @@ pub // pwc : 2015-10-29 PricewaterhouseCoopers LLP pwc -// qpon : 2013-11-14 dotCOOL, Inc. +// qpon : 2013-11-14 dotQPON LLC qpon // quebec : 2013-12-19 PointQuébec Inc @@ -9462,9 +8932,6 @@ racing // radio : 2016-07-21 European Broadcasting Union (EBU) radio -// raid : 2015-07-23 Johnson Shareholdings, Inc. -raid - // read : 2014-12-18 Amazon Registry Services, Inc. read @@ -9480,7 +8947,7 @@ realty // recipes : 2013-10-17 Binky Moon, LLC recipes -// red : 2013-11-07 Afilias Limited +// red : 2013-11-07 Identity Digital Limited red // redstone : 2014-10-31 Redstone Haute Couture Co., Ltd. @@ -9576,7 +9043,7 @@ rsvp // rugby : 2016-12-15 World Rugby Strategic Developments Limited rugby -// ruhr : 2013-10-02 regiodot GmbH & Co. KG +// ruhr : 2013-10-02 dotSaarland GmbH ruhr // run : 2015-03-19 Binky Moon, LLC @@ -9669,9 +9136,6 @@ schwarz // science : 2014-09-11 dot Science Limited science -// scjohnson : 2015-07-23 Johnson Shareholdings, Inc. -scjohnson - // scot : 2014-01-23 Dot Scot Registry Limited scot @@ -9699,9 +9163,6 @@ sener // services : 2014-02-27 Binky Moon, LLC services -// ses : 2015-07-23 SES -ses - // seven : 2015-08-06 Seven West Media Ltd seven @@ -9711,7 +9172,7 @@ sew // sex : 2014-11-13 ICM Registry SX LLC sex -// sexy : 2013-09-11 UNR Corp. +// sexy : 2013-09-11 Internet Naming Company LLC sexy // sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR @@ -9732,7 +9193,7 @@ shell // shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. shia -// shiksha : 2013-11-14 Afilias Limited +// shiksha : 2013-11-14 Identity Digital Limited shiksha // shoes : 2013-10-02 Binky Moon, LLC @@ -9765,7 +9226,7 @@ singles // site : 2015-01-15 Radix FZC site -// ski : 2015-04-09 Afilias Limited +// ski : 2015-04-09 Identity Digital Limited ski // skin : 2015-01-15 XYZ.COM LLC @@ -9786,7 +9247,7 @@ smart // smile : 2014-12-18 Amazon Registry Services, Inc. smile -// sncf : 2015-02-19 Société Nationale des Chemins de fer Francais S N C F +// sncf : 2015-02-19 Société Nationale SNCF sncf // soccer : 2015-03-26 Binky Moon, LLC @@ -9870,7 +9331,7 @@ stream // studio : 2015-02-11 Dog Beach, LLC studio -// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD +// study : 2014-12-11 Registry Services, LLC study // style : 2014-12-04 Binky Moon, LLC @@ -9930,7 +9391,7 @@ tatamotors // tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" tatar -// tattoo : 2013-08-30 UNR Corp. +// tattoo : 2013-08-30 Top Level Design, LLC tattoo // tax : 2014-03-20 Binky Moon, LLC @@ -10023,7 +9484,7 @@ toray // toshiba : 2014-04-10 TOSHIBA Corporation toshiba -// total : 2015-08-06 Total SA +// total : 2015-08-06 TotalEnergies SE total // tours : 2015-01-22 Binky Moon, LLC @@ -10059,7 +9520,7 @@ travelers // travelersinsurance : 2015-03-26 Travelers TLD, LLC travelersinsurance -// trust : 2014-10-16 UNR Corp. +// trust : 2014-10-16 Internet Naming Company LLC trust // trv : 2015-03-26 Travelers TLD, LLC @@ -10206,7 +9667,7 @@ wanggou // watch : 2013-11-14 Binky Moon, LLC watch -// watches : 2014-12-22 Afilias Limited +// watches : 2014-12-22 Identity Digital Limited watches // weather : 2015-01-08 International Business Machines Corporation @@ -10341,7 +9802,7 @@ xin // xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited 网站 -// xn--6frz82g : 2013-09-23 Afilias Limited +// xn--6frz82g : 2013-09-23 Identity Digital Limited 移动 // xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited @@ -10458,9 +9919,6 @@ xin // xn--jlq480n2rg : 2019-12-19 Amazon Registry Services, Inc. 亚马逊 -// xn--jlq61u9w7b : 2015-01-08 Nokia Corporation -诺基亚 - // xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc. 食品 @@ -10648,6 +10106,14 @@ graphox.us // Submitted by accesso Team *.devcdnaccesso.com +// Acorn Labs : https://acorn.io +// Submitted by Craig Jellick +*.on-acorn.io + +// ActiveTrail: https://www.activetrail.biz/ +// Submitted by Ofer Kalaora +activetrail.biz + // Adobe : https://www.adobe.com/ // Submitted by Ian Boston and Lars Trieloff adobeaemcloud.com @@ -10657,10 +10123,43 @@ adobeaemcloud.net hlx.page hlx3.page +// Adobe Developer Platform : https://developer.adobe.com +// Submitted by Jesse MacFadyen +adobeio-static.net +adobeioruntime.net + // Agnat sp. z o.o. : https://domena.pl // Submitted by Przemyslaw Plewa beep.pl +// Airkit : https://www.airkit.com/ +// Submitted by Grant Cooksey +airkitapps.com +airkitapps-au.com +airkitapps.eu + +// Aiven: https://aiven.io/ +// Submitted by Etienne Stalmans +aivencloud.com + +// Akamai : https://www.akamai.com/ +// Submitted by Akamai Team +akadns.net +akamai.net +akamai-staging.net +akamaiedge.net +akamaiedge-staging.net +akamaihd.net +akamaihd-staging.net +akamaiorigin.net +akamaiorigin-staging.net +akamaized.net +akamaized-staging.net +edgekey.net +edgekey-staging.net +edgesuite.net +edgesuite-staging.net + // alboto.ca : http://alboto.ca // Submitted by Anton Avramov barsy.ca @@ -10682,19 +10181,134 @@ altervista.org // Submitted by Cyril alwaysdata.net -// Amazon CloudFront : https://aws.amazon.com/cloudfront/ +// Amaze Software : https://amaze.co +// Submitted by Domain Admin +myamaze.net + +// Amazon : https://www.amazon.com/ +// Submitted by AWS Security +// Subsections of Amazon/subsidiaries will appear until "concludes" tag + +// Amazon CloudFront // Submitted by Donavan Miller +// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 cloudfront.net -// Amazon Elastic Compute Cloud : https://aws.amazon.com/ec2/ +// Amazon EC2 // Submitted by Luke Wells +// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 *.compute.amazonaws.com *.compute-1.amazonaws.com *.compute.amazonaws.com.cn us-east-1.amazonaws.com -// Amazon Elastic Beanstalk : https://aws.amazon.com/elasticbeanstalk/ +// Amazon S3 // Submitted by Luke Wells +// Reference: d068bd97-f0a9-4838-a6d8-954b622ef4ae +s3.cn-north-1.amazonaws.com.cn +s3.dualstack.ap-northeast-1.amazonaws.com +s3.dualstack.ap-northeast-2.amazonaws.com +s3.ap-northeast-2.amazonaws.com +s3-website.ap-northeast-2.amazonaws.com +s3.dualstack.ap-south-1.amazonaws.com +s3.ap-south-1.amazonaws.com +s3-website.ap-south-1.amazonaws.com +s3.dualstack.ap-southeast-1.amazonaws.com +s3.dualstack.ap-southeast-2.amazonaws.com +s3.dualstack.ca-central-1.amazonaws.com +s3.ca-central-1.amazonaws.com +s3-website.ca-central-1.amazonaws.com +s3.dualstack.eu-central-1.amazonaws.com +s3.eu-central-1.amazonaws.com +s3-website.eu-central-1.amazonaws.com +s3.dualstack.eu-west-1.amazonaws.com +s3.dualstack.eu-west-2.amazonaws.com +s3.eu-west-2.amazonaws.com +s3-website.eu-west-2.amazonaws.com +s3.dualstack.eu-west-3.amazonaws.com +s3.eu-west-3.amazonaws.com +s3-website.eu-west-3.amazonaws.com +s3.amazonaws.com +s3-ap-northeast-1.amazonaws.com +s3-ap-northeast-2.amazonaws.com +s3-ap-south-1.amazonaws.com +s3-ap-southeast-1.amazonaws.com +s3-ap-southeast-2.amazonaws.com +s3-ca-central-1.amazonaws.com +s3-eu-central-1.amazonaws.com +s3-eu-west-1.amazonaws.com +s3-eu-west-2.amazonaws.com +s3-eu-west-3.amazonaws.com +s3-external-1.amazonaws.com +s3-fips-us-gov-west-1.amazonaws.com +s3-sa-east-1.amazonaws.com +s3-us-east-2.amazonaws.com +s3-us-gov-west-1.amazonaws.com +s3-us-west-1.amazonaws.com +s3-us-west-2.amazonaws.com +s3-website-ap-northeast-1.amazonaws.com +s3-website-ap-southeast-1.amazonaws.com +s3-website-ap-southeast-2.amazonaws.com +s3-website-eu-west-1.amazonaws.com +s3-website-sa-east-1.amazonaws.com +s3-website-us-east-1.amazonaws.com +s3-website-us-west-1.amazonaws.com +s3-website-us-west-2.amazonaws.com +s3.dualstack.sa-east-1.amazonaws.com +s3.dualstack.us-east-1.amazonaws.com +s3.dualstack.us-east-2.amazonaws.com +s3.us-east-2.amazonaws.com +s3-website.us-east-2.amazonaws.com + +// AWS Cloud9 +// Submitted by: AWS Security +// Reference: 2b6dfa9a-3a7f-4367-b2e7-0321e77c0d59 +vfs.cloud9.af-south-1.amazonaws.com +webview-assets.cloud9.af-south-1.amazonaws.com +vfs.cloud9.ap-east-1.amazonaws.com +webview-assets.cloud9.ap-east-1.amazonaws.com +vfs.cloud9.ap-northeast-1.amazonaws.com +webview-assets.cloud9.ap-northeast-1.amazonaws.com +vfs.cloud9.ap-northeast-2.amazonaws.com +webview-assets.cloud9.ap-northeast-2.amazonaws.com +vfs.cloud9.ap-northeast-3.amazonaws.com +webview-assets.cloud9.ap-northeast-3.amazonaws.com +vfs.cloud9.ap-south-1.amazonaws.com +webview-assets.cloud9.ap-south-1.amazonaws.com +vfs.cloud9.ap-southeast-1.amazonaws.com +webview-assets.cloud9.ap-southeast-1.amazonaws.com +vfs.cloud9.ap-southeast-2.amazonaws.com +webview-assets.cloud9.ap-southeast-2.amazonaws.com +vfs.cloud9.ca-central-1.amazonaws.com +webview-assets.cloud9.ca-central-1.amazonaws.com +vfs.cloud9.eu-central-1.amazonaws.com +webview-assets.cloud9.eu-central-1.amazonaws.com +vfs.cloud9.eu-north-1.amazonaws.com +webview-assets.cloud9.eu-north-1.amazonaws.com +vfs.cloud9.eu-south-1.amazonaws.com +webview-assets.cloud9.eu-south-1.amazonaws.com +vfs.cloud9.eu-west-1.amazonaws.com +webview-assets.cloud9.eu-west-1.amazonaws.com +vfs.cloud9.eu-west-2.amazonaws.com +webview-assets.cloud9.eu-west-2.amazonaws.com +vfs.cloud9.eu-west-3.amazonaws.com +webview-assets.cloud9.eu-west-3.amazonaws.com +vfs.cloud9.me-south-1.amazonaws.com +webview-assets.cloud9.me-south-1.amazonaws.com +vfs.cloud9.sa-east-1.amazonaws.com +webview-assets.cloud9.sa-east-1.amazonaws.com +vfs.cloud9.us-east-1.amazonaws.com +webview-assets.cloud9.us-east-1.amazonaws.com +vfs.cloud9.us-east-2.amazonaws.com +webview-assets.cloud9.us-east-2.amazonaws.com +vfs.cloud9.us-west-1.amazonaws.com +webview-assets.cloud9.us-west-1.amazonaws.com +vfs.cloud9.us-west-2.amazonaws.com +webview-assets.cloud9.us-west-2.amazonaws.com + +// AWS Elastic Beanstalk +// Submitted by Luke Wells +// Reference: aa202394-43a0-4857-b245-8db04549137e cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com @@ -10716,71 +10330,24 @@ us-gov-west-1.elasticbeanstalk.com us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com -// Amazon Elastic Load Balancing : https://aws.amazon.com/elasticloadbalancing/ +// (AWS) Elastic Load Balancing // Submitted by Luke Wells -*.elb.amazonaws.com +// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 *.elb.amazonaws.com.cn +*.elb.amazonaws.com -// Amazon Global Accelerator : https://aws.amazon.com/global-accelerator/ +// AWS Global Accelerator // Submitted by Daniel Massaguer +// Reference: d916759d-a08b-4241-b536-4db887383a6a awsglobalaccelerator.com -// Amazon S3 : https://aws.amazon.com/s3/ -// Submitted by Luke Wells -s3.amazonaws.com -s3-ap-northeast-1.amazonaws.com -s3-ap-northeast-2.amazonaws.com -s3-ap-south-1.amazonaws.com -s3-ap-southeast-1.amazonaws.com -s3-ap-southeast-2.amazonaws.com -s3-ca-central-1.amazonaws.com -s3-eu-central-1.amazonaws.com -s3-eu-west-1.amazonaws.com -s3-eu-west-2.amazonaws.com -s3-eu-west-3.amazonaws.com -s3-external-1.amazonaws.com -s3-fips-us-gov-west-1.amazonaws.com -s3-sa-east-1.amazonaws.com -s3-us-gov-west-1.amazonaws.com -s3-us-east-2.amazonaws.com -s3-us-west-1.amazonaws.com -s3-us-west-2.amazonaws.com -s3.ap-northeast-2.amazonaws.com -s3.ap-south-1.amazonaws.com -s3.cn-north-1.amazonaws.com.cn -s3.ca-central-1.amazonaws.com -s3.eu-central-1.amazonaws.com -s3.eu-west-2.amazonaws.com -s3.eu-west-3.amazonaws.com -s3.us-east-2.amazonaws.com -s3.dualstack.ap-northeast-1.amazonaws.com -s3.dualstack.ap-northeast-2.amazonaws.com -s3.dualstack.ap-south-1.amazonaws.com -s3.dualstack.ap-southeast-1.amazonaws.com -s3.dualstack.ap-southeast-2.amazonaws.com -s3.dualstack.ca-central-1.amazonaws.com -s3.dualstack.eu-central-1.amazonaws.com -s3.dualstack.eu-west-1.amazonaws.com -s3.dualstack.eu-west-2.amazonaws.com -s3.dualstack.eu-west-3.amazonaws.com -s3.dualstack.sa-east-1.amazonaws.com -s3.dualstack.us-east-1.amazonaws.com -s3.dualstack.us-east-2.amazonaws.com -s3-website-us-east-1.amazonaws.com -s3-website-us-west-1.amazonaws.com -s3-website-us-west-2.amazonaws.com -s3-website-ap-northeast-1.amazonaws.com -s3-website-ap-southeast-1.amazonaws.com -s3-website-ap-southeast-2.amazonaws.com -s3-website-eu-west-1.amazonaws.com -s3-website-sa-east-1.amazonaws.com -s3-website.ap-northeast-2.amazonaws.com -s3-website.ap-south-1.amazonaws.com -s3-website.ca-central-1.amazonaws.com -s3-website.eu-central-1.amazonaws.com -s3-website.eu-west-2.amazonaws.com -s3-website.eu-west-3.amazonaws.com -s3-website.us-east-2.amazonaws.com +// eero +// Submitted by Yue Kang +// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 +eero.online +eero-stage.online + +// concludes Amazon // Amune : https://amune.org/ // Submitted by Team Amune @@ -10833,6 +10400,14 @@ myasustor.com // Submitted by Sam Smyth cdn.prod.atlassian-dev.net +// Authentick UG (haftungsbeschränkt) : https://authentick.net +// Submitted by Lukas Reschke +translated.page + +// Autocode : https://autocode.com +// Submitted by Jacob Lee +autocode.dev + // AVM : https://avm.de // Submitted by Andreas Weise myfritz.net @@ -10847,7 +10422,7 @@ onavstack.net *.advisor.ws // AZ.pl sp. z.o.o: https://az.pl -// Submited by Krzysztof Wolski +// Submitted by Krzysztof Wolski ecommerce-shop.pl // b-data GmbH : https://www.b-data.io @@ -10873,6 +10448,26 @@ rs.ba app.banzaicloud.io *.backyards.banzaicloud.io +// BASE, Inc. : https://binc.jp +// Submitted by Yuya NAGASAWA +base.ec +official.ec +buyshop.jp +fashionstore.jp +handcrafted.jp +kawaiishop.jp +supersale.jp +theshop.jp +shopselect.net +base.shop + +// BeagleBoard.org Foundation : https://beagleboard.org +// Submitted by Jason Kridner +beagleboard.io + +// Beget Ltd +// Submitted by Lev Nekrasov +*.beget.app // BetaInABox // Submitted by Adrian @@ -10941,6 +10536,11 @@ cafjs.com // Submitted by Marcus Popp mycd.eu +// Canva Pty Ltd : https://canva.com/ +// Submitted by Joel Aquilina +canva-apps.cn +canva-apps.com + // Carrd : https://carrd.co // Submitted by AJ drr.ac @@ -11070,8 +10670,11 @@ cloudcontrolapp.com // Cloudflare, Inc. : https://www.cloudflare.com/ // Submitted by Cloudflare Team -pages.dev +cf-ipfs.com +cloudflare-ipfs.com trycloudflare.com +pages.dev +r2.dev workers.dev // Clovyr : https://clovyr.io @@ -11115,6 +10718,10 @@ cloudns.us // Submitted by Angelo Gladding cnpy.gdn +// Codeberg e. V. : https://codeberg.org +// Submitted by Moritz Marquardt +codeberg.page + // CoDNS B.V. co.nl co.no @@ -11241,11 +10848,21 @@ deno-staging.dev // Submitted by Peter Thomassen dedyn.io +// Deta: https://www.deta.sh/ +// Submitted by Aavash Shrestha +deta.app +deta.dev + // Diher Solutions : https://diher.solutions // Submitted by Didi Hermawan *.rss.my.id *.diher.solutions +// Discord Inc : https://discord.com +// Submitted by Sahn Lam +discordsays.com +discordsez.com + // DNS Africa Ltd https://dns.business // Submitted by Calvin Browne jozi.biz @@ -11634,10 +11251,10 @@ dynv6.net // Submitted by Vladimir Dudr e4.cz -// eero : https://eero.com/ -// Submitted by Yue Kang -eero.online -eero-stage.online +// Easypanel : https://easypanel.io +// Submitted by Andrei Canta +easypanel.app +easypanel.host // Elementor : Elementor Ltd. // Submitted by Anton Barkan @@ -11653,11 +11270,20 @@ en-root.fr mytuleap.com tuleap-partners.com +// Encoretivity AB: https://encore.dev +// Submitted by André Eriksson +encr.app +encoreapi.com + // ECG Robotics, Inc: https://ecgrobotics.org // Submitted by onred.one staging.onred.one +// encoway GmbH : https://www.encoway.de +// Submitted by Marcel Daus +eu.encoway.cloud + // EU.org https://eu.org/ // Submitted by Pierre Beyssac eu.org @@ -11832,6 +11458,7 @@ u.channelsdvr.net // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security edgecompute.app +fastly-edge.com fastly-terrarium.com fastlylb.net map.fastlylb.net @@ -11843,6 +11470,10 @@ a.ssl.fastly.net b.ssl.fastly.net global.ssl.fastly.net +// Fastmail : https://www.fastmail.com/ +// Submitted by Marc Bradshaw +*.user.fm + // FASTVPS EESTI OU : https://fastvps.ru/ // Submitted by Likhachev Vasiliy fastvps-server.com @@ -11861,8 +11492,6 @@ app.os.stg.fedoraproject.org // FearWorks Media Ltd. : https://fearworksmedia.co.uk // submitted by Keith Fairley -couk.me -ukco.me conn.uk copro.uk hosp.uk @@ -11921,6 +11550,10 @@ id.forgerock.io // Submitted by Koen Rouwhorst framer.app framercanvas.com +framer.media +framer.photos +framer.website +framer.wiki // Frusky MEDIA&PR : https://www.frusky.de // Submitted by Victor Pupynin @@ -11966,10 +11599,22 @@ futuremailing.at *.kunden.ortsinfo.at *.statics.cloud -// GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains -// Submitted by David Illsley +// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names +// Submitted by Stephen Ford +independent-commission.uk +independent-inquest.uk +independent-inquiry.uk +independent-panel.uk +independent-review.uk +public-inquiry.uk +royal-commission.uk +campaign.gov.uk service.gov.uk +// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk +// Submitted by Jamie Tanna +api.gov.uk + // Gehirn Inc. : https://www.gehirn.co.jp/ // Submitted by Kohei YOSHIDA gehirn.ne.jp @@ -12019,8 +11664,114 @@ co.ro shop.ro // GMO Pepabo, Inc. : https://pepabo.com/ -// Submitted by dojineko +// Submitted by Hosting Div lolipop.io +angry.jp +babyblue.jp +babymilk.jp +backdrop.jp +bambina.jp +bitter.jp +blush.jp +boo.jp +boy.jp +boyfriend.jp +but.jp +candypop.jp +capoo.jp +catfood.jp +cheap.jp +chicappa.jp +chillout.jp +chips.jp +chowder.jp +chu.jp +ciao.jp +cocotte.jp +coolblog.jp +cranky.jp +cutegirl.jp +daa.jp +deca.jp +deci.jp +digick.jp +egoism.jp +fakefur.jp +fem.jp +flier.jp +floppy.jp +fool.jp +frenchkiss.jp +girlfriend.jp +girly.jp +gloomy.jp +gonna.jp +greater.jp +hacca.jp +heavy.jp +her.jp +hiho.jp +hippy.jp +holy.jp +hungry.jp +icurus.jp +itigo.jp +jellybean.jp +kikirara.jp +kill.jp +kilo.jp +kuron.jp +littlestar.jp +lolipopmc.jp +lolitapunk.jp +lomo.jp +lovepop.jp +lovesick.jp +main.jp +mods.jp +mond.jp +mongolian.jp +moo.jp +namaste.jp +nikita.jp +nobushi.jp +noor.jp +oops.jp +parallel.jp +parasite.jp +pecori.jp +peewee.jp +penne.jp +pepper.jp +perma.jp +pigboat.jp +pinoko.jp +punyu.jp +pupu.jp +pussycat.jp +pya.jp +raindrop.jp +readymade.jp +sadist.jp +schoolbus.jp +secret.jp +staba.jp +stripper.jp +sub.jp +sunnyday.jp +thick.jp +tonkotsu.jp +under.jp +upper.jp +velvet.jp +verse.jp +versus.jp +vivian.jp +watson.jp +weblike.jp +whitesnow.jp +zombie.jp +heteml.net // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell @@ -12142,6 +11893,10 @@ blogspot.vn // Submitted by Niels Martignene goupile.fr +// Government of the Netherlands: https://www.government.nl +// Submitted by +gov.nl + // Group 53, LLC : https://www.group53.com // Submitted by Tyler Todd awsmppl.com @@ -12152,7 +11907,7 @@ günstigbestellen.de günstigliefern.de // Hakaran group: http://hakaran.cz -// Submited by Arseniy Sokolov +// Submitted by Arseniy Sokolov fin.ci free.hr caa.li @@ -12187,20 +11942,25 @@ herokussl.com // Hibernating Rhinos // Submitted by Oren Eini -myravendb.com +ravendb.cloud ravendb.community ravendb.me development.run ravendb.run // home.pl S.A.: https://home.pl -// Submited by Krzysztof Wolski +// Submitted by Krzysztof Wolski homesklep.pl // Hong Kong Productivity Council: https://www.hkpc.org/ // Submitted by SECaaS Team secaas.hk +// Hoplix : https://www.hoplix.com +// Submitted by Danilo De Franco +hoplix.shop + + // HOSTBIP REGISTRY : https://www.hostbip.com/ // Submitted by Atanunu Igbunuroghene orx.biz @@ -12212,7 +11972,10 @@ ltd.ng ngo.ng edu.scot sch.so -org.yt + +// HostFly : https://www.ie.ua +// Submitted by Bohdan Dub +ie.ua // HostyHosting (hostyhosting.com) hostyhosting.io @@ -12230,6 +11993,11 @@ moonscale.net // Submitted by Hannu Aronsson iki.fi +// iliad italia: https://www.iliad.it +// Submitted by Marios Makassikis +ibxos.it +iliadboxos.it + // Impertrix Solutions : // Submitted by Zhixiang Zhao impertrixcdn.com @@ -12299,7 +12067,7 @@ to.leg.br pixolino.com // Internet-Pro, LLP: https://netangels.ru/ -// Submited by Vasiliy Sheredeko +// Submitted by Vasiliy Sheredeko na4u.ru // iopsys software solutions AB : https://iopsys.eu/ @@ -12310,9 +12078,11 @@ iopsys.se // Submitted by Matthew Hardeman ipifony.net -// IServ GmbH : https://iserv.eu -// Submitted by Kim-Alexander Brodowski +// IServ GmbH : https://iserv.de +// Submitted by Mario Hoberg +iservschule.de mein-iserv.de +schulplattform.de schulserver.de test-iserv.de iserv.dev @@ -12322,7 +12092,7 @@ iserv.dev iobb.net // Jelastic, Inc. : https://jelastic.com/ -// Submited by Ihor Kolodyuk +// Submitted by Ihor Kolodyuk mel.cloudlets.com.au cloud.interhostsolutions.be users.scale.virtualcloud.com.br @@ -12433,6 +12203,14 @@ js.org kaas.gg khplay.nl +// Kakao : https://www.kakaocorp.com/ +// Submitted by JaeYoong Lee +ktistory.com + +// Kapsi : https://kapsi.fi +// Submitted by Tomi Juntunen +kapsi.fi + // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de @@ -12446,6 +12224,10 @@ uni5.net // Submitted by Roy Keene knightpoint.systems +// KoobinEvent, SL: https://www.koobin.com +// Submitted by Iván Oliva +koobin.events + // KUROKU LTD : https://kuroku.ltd/ // Submitted by DisposaBoy oya.to @@ -12510,6 +12292,10 @@ ip.linodeusercontent.com // Submitted by Victor Velchev we.bs +// Localcert : https://localcert.dev +// Submitted by Lann Martin +*.user.localcert.dev + // localzone.xyz // Submitted by Kenny Niehage localzone.xyz @@ -12618,6 +12404,10 @@ hra.health miniserver.com memset.net +// Messerli Informatik AG : https://www.messerli.ch/ +// Submitted by Ruben Schmidmeister +messerli.app + // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr *.cloud.metacentrum.cz @@ -12637,12 +12427,15 @@ eu.meteorapp.com co.pl // Microsoft Corporation : http://microsoft.com -// Submitted by Mitch Webster +// Submitted by Public Suffix List Admin *.azurecontainer.io azurewebsites.net azure-mobile.net cloudapp.net azurestaticapps.net +1.azurestaticapps.net +2.azurestaticapps.net +3.azurestaticapps.net centralus.azurestaticapps.net eastasia.azurestaticapps.net eastus2.azurestaticapps.net @@ -12695,24 +12488,9 @@ cust.retrosnub.co.uk // Submitted by Paulus Schoutsen ui.nabu.casa -// Names.of.London : https://names.of.london/ -// Submitted by James Stevens or -pony.club -of.fashion -in.london -of.london -from.marketing -with.marketing -for.men -repair.men -and.mom -for.mom -for.one -under.one -for.sale -that.win -from.work -to.work +// Net at Work Gmbh : https://www.netatwork.de +// Submitted by Jan Jaeschke +cloud.nospamproxy.com // Netlify : https://www.netlify.com // Submitted by Jessica Parsons @@ -12724,7 +12502,19 @@ netlify.app // ngrok : https://ngrok.com/ // Submitted by Alan Shreve +ngrok.app +ngrok-free.app +ngrok.dev +ngrok-free.dev ngrok.io +ap.ngrok.io +au.ngrok.io +eu.ngrok.io +in.ngrok.io +jp.ngrok.io +sa.ngrok.io +us.ngrok.io +ngrok.pizza // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ // Submitted by Nicholas Ford @@ -12742,7 +12532,10 @@ noop.app // Northflank Ltd. : https://northflank.com/ // Submitted by Marco Suter *.northflank.app +*.build.run *.code.run +*.database.run +*.migration.run // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino @@ -12873,11 +12666,6 @@ zapto.org // Submitted by Konstantin Nosov stage.nodeart.io -// Nodum B.V. : https://nodum.io/ -// Submitted by Wietse Wind -nodum.co -nodum.io - // Nucleos Inc. : https://nucleos.com // Submitted by Piotr Zduniak pcloud.host @@ -12908,7 +12696,26 @@ omniwe.site // One.com: https://www.one.com/ // Submitted by Jacob Bunk Nielsen +123hjemmeside.dk +123hjemmeside.no +123homepage.it +123kotisivu.fi +123minsida.se +123miweb.es +123paginaweb.pt +123sait.ru +123siteweb.fr +123webseite.at +123webseite.de +123website.be +123website.ch +123website.lu +123website.nl service.one +simplesite.com +simplesite.com.br +simplesite.gr +simplesite.pl // One Fold Media : http://www.onefoldmedia.com/ // Submitted by Eddie Jones @@ -12930,8 +12737,12 @@ orsites.com // Submitted by Yngve Pettersen operaunite.com +// Orange : https://www.orange.com +// Submitted by Alexandre Linte +tech.orange + // Oursky Limited : https://authgear.com/, https://skygear.io/ -// Submited by Authgear Team , Skygear Developer +// Submitted by Authgear Team , Skygear Developer authgear-staging.com authgearapps.com skygearapp.com @@ -13039,6 +12850,10 @@ pleskns.com // Submitted by Maximilian Schieder dyn53.io +// Porter : https://porter.run/ +// Submitted by Rudraksh MK +onporter.run + // Positive Codes Technology Company : http://co.bn/faq.html // Submitted by Zulfais co.bn @@ -13096,6 +12911,10 @@ qoto.io // Submitted by Xavier De Cock qualifioapp.com +// Quality Unit: https://qualityunit.com +// Submitted by Vasyl Tsalko +ladesk.com + // QuickBackend: https://www.quickbackend.com // Submitted by Dani Biro qbuser.com @@ -13169,7 +12988,9 @@ app.render.com onrender.com // Repl.it : https://repl.it -// Submitted by Mason Clayton +// Submitted by Lincoln Bergeson +firewalledreplit.co +id.firewalledreplit.co repl.co id.repl.co repl.run @@ -13200,6 +13021,10 @@ itcouldbewor.se // Submitted by Jennifer Herting git-pages.rit.edu +// Rocky Enterprise Software Foundation : https://resf.org +// Submitted by Neil Hanlon +rocky.page + // Rusnames Limited: http://rusnames.ru/ // Submitted by Sergey Zotov биз.рус @@ -13213,6 +13038,62 @@ git-pages.rit.edu спб.рус я.рус +// SAKURA Internet Inc. : https://www.sakura.ad.jp/ +// Submitted by Internet Service Department +180r.com +dojin.com +sakuratan.com +sakuraweb.com +x0.com +2-d.jp +bona.jp +crap.jp +daynight.jp +eek.jp +flop.jp +halfmoon.jp +jeez.jp +matrix.jp +mimoza.jp +ivory.ne.jp +mail-box.ne.jp +mints.ne.jp +mokuren.ne.jp +opal.ne.jp +sakura.ne.jp +sumomo.ne.jp +topaz.ne.jp +netgamers.jp +nyanta.jp +o0o0.jp +rdy.jp +rgr.jp +rulez.jp +s3.isk01.sakurastorage.jp +s3.isk02.sakurastorage.jp +saloon.jp +sblo.jp +skr.jp +tank.jp +uh-oh.jp +undo.jp +rs.webaccel.jp +user.webaccel.jp +websozai.jp +xii.jp +squares.net +jpn.org +kirara.st +x0.to +from.tv +sakura.tv + +// Salesforce.com, Inc. https://salesforce.com/ +// Submitted by Michael Biven +*.builder.code.com +*.dev-builder.code.com +*.stg-builder.code.com + // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia sandcats.io @@ -13222,6 +13103,34 @@ sandcats.io logoip.de logoip.com +// Scaleway : https://www.scaleway.com/ +// Submitted by Rémy Léone +fr-par-1.baremetal.scw.cloud +fr-par-2.baremetal.scw.cloud +nl-ams-1.baremetal.scw.cloud +fnc.fr-par.scw.cloud +functions.fnc.fr-par.scw.cloud +k8s.fr-par.scw.cloud +nodes.k8s.fr-par.scw.cloud +s3.fr-par.scw.cloud +s3-website.fr-par.scw.cloud +whm.fr-par.scw.cloud +priv.instances.scw.cloud +pub.instances.scw.cloud +k8s.scw.cloud +k8s.nl-ams.scw.cloud +nodes.k8s.nl-ams.scw.cloud +s3.nl-ams.scw.cloud +s3-website.nl-ams.scw.cloud +whm.nl-ams.scw.cloud +k8s.pl-waw.scw.cloud +nodes.k8s.pl-waw.scw.cloud +s3.pl-waw.scw.cloud +s3-website.pl-waw.scw.cloud +scalebook.scw.cloud +smartlabeling.scw.cloud +dedibox.fr + // schokokeks.org GbR : https://schokokeks.org/ // Submitted by Hanno Böck schokokeks.net @@ -13329,6 +13238,13 @@ small-web.org // Submitted by Dan Kozak vp4.me +// Snowflake Inc : https://www.snowflake.com/ +// Submitted by Faith Olapade +snowflake.app +privatelink.snowflake.app +streamlit.app +streamlitapp.com + // Snowplow Analytics : https://snowplowanalytics.com/ // Submitted by Ian Streeter try-snowplow.com @@ -13342,6 +13258,8 @@ srht.site stackhero-network.com // Staclar : https://staclar.com +// Submitted by Q Misell +musician.io // Submitted by Matthias Merkel novecore.site @@ -13440,25 +13358,28 @@ syncloud.it // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng -diskstation.me dscloud.biz -dscloud.me -dscloud.mobi +direct.quickconnect.cn dsmynas.com -dsmynas.net -dsmynas.org familyds.com -familyds.net -familyds.org +diskstation.me +dscloud.me i234.me myds.me synology.me +dscloud.mobi +dsmynas.net +familyds.net +dsmynas.org +familyds.org vpnplus.to direct.quickconnect.to // Tabit Technologies Ltd. : https://tabit.cloud/ // Submitted by Oren Agiv tabitorder.co.il +mytabit.co.il +mytabit.com // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke @@ -13476,9 +13397,14 @@ gdynia.pl med.pl sopot.pl +// team.blue https://team.blue +// Submitted by Cedric Dubois +site.tb-hosting.com + // Teckids e.V. : https://www.teckids.org // Submitted by Dominik George -edugit.org +edugit.io +s3.teckids.org // Telebit : https://telebit.cloud // Submitted by AJ ONeal @@ -13486,10 +13412,6 @@ telebit.app telebit.io *.telebit.xyz -// The Gwiddle Foundation : https://gwiddlefoundation.org.uk -// Submitted by Joshua Bayfield -gwiddle.co.uk - // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden *.firenet.ch @@ -13524,10 +13446,6 @@ pages.torproject.net bloxcms.com townnews-staging.com -// TradableBits: https://tradablebits.com -// Submitted by Dmitry Khrisanov dmitry@tradablebits.com -tbits.me - // TrafficPlex GmbH : https://www.trafficplex.de/ // Submitted by Phillipp Röll 12hp.at @@ -13556,6 +13474,10 @@ lima.zone *.transurl.eu *.transurl.nl +// TransIP: https://www.transip.nl +// Submitted by Cedric Dubois +site.transip.me + // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators tuxfamily.org @@ -13576,6 +13498,14 @@ syno-ds.de synology-diskstation.de synology-ds.de +// Typedream : https://typedream.com +// Submitted by Putri Karunia +typedream.app + +// Typeform : https://www.typeform.com +// Submitted by Sergi Ferriz +pro.typeform.com + // Uberspace : https://uberspace.de // Submitted by Moritz Werner uber.space @@ -13588,6 +13518,19 @@ hk.org ltd.hk inc.hk +// UK Intis Telecom LTD : https://it.com +// Submitted by ITComdomains +it.com + +// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ +// see also: whois -h whois.udr.org.yt help +// Submitted by Atanunu Igbunuroghene +name.pm +sch.tf +biz.wf +sch.wf +org.yt + // United Gameserver GmbH : https://united-gameserver.de // Submitted by Stefan Schwarz virtualuser.de @@ -13674,19 +13617,14 @@ me.vu // Submitted by Serhii Rostilo v.ua +// Vultr Objects : https://www.vultr.com/products/object-storage/ +// Submitted by Niels Maumenee +*.vultrobjects.com + // Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com // Submitted by Masayuki Note wafflecell.com -// WapBlog.ID : https://www.wapblog.id -// Submitted by Fajar Sodik -idnblogger.com -indowapblog.com -bloger.id -wblog.id -wbq.me -fastblog.net - // WebHare bv: https://www.webhare.com/ // Submitted by Arnold Hendriks *.webhare.dev @@ -13723,6 +13661,10 @@ wmcloud.org panel.gg daemon.panel.gg +// Wizard Zines : https://wizardzines.com +// Submitted by Julia Evans +messwithdns.com + // WoltLab GmbH : https://www.woltlab.com // Submitted by Tim Düsterhus woltlab-demo.com diff --git a/src/java.base/share/legal/public_suffix.md b/src/java.base/share/legal/public_suffix.md index 7856d03ae08..24924b6968a 100644 --- a/src/java.base/share/legal/public_suffix.md +++ b/src/java.base/share/legal/public_suffix.md @@ -11,7 +11,7 @@ If you do not wish to use the Public Suffix List, you may remove the The Source Code of this file is available under the Mozilla Public License, v. 2.0 and is located at -https://raw.githubusercontent.com/publicsuffix/list/3c213aab32b3c014f171b1673d4ce9b5cd72bf1c/public_suffix_list.dat. +https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat. If a copy of the MPL was not distributed with this file, you can obtain one at https://mozilla.org/MPL/2.0/. diff --git a/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java b/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java index 69ca9577c68..74045b533c2 100644 --- a/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java +++ b/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8228969 8244087 8255266 + * @bug 8228969 8244087 8255266 8302182 * @modules java.base/sun.security.util * @summary unit test for RegisteredDomain */ diff --git a/test/jdk/sun/security/util/RegisteredDomain/tests.dat b/test/jdk/sun/security/util/RegisteredDomain/tests.dat index e4cf659c634..8d8ba34c832 100644 --- a/test/jdk/sun/security/util/RegisteredDomain/tests.dat +++ b/test/jdk/sun/security/util/RegisteredDomain/tests.dat @@ -84,6 +84,10 @@ foo.fj fj foo.fj www.foo.ie ie foo.ie www.foo.gov.ie gov.ie foo.gov.ie +# in +5g.in 5g.in null +www.5g.in 5g.in www.5g.in + # it has a large number of entries www.gr.it gr.it www.gr.it www.blahblahblah.it it blahblahblah.it @@ -153,4 +157,8 @@ w.s.pvt.k12.ma.us pvt.k12.ma.us s.pvt.k12.ma.us foo.السعودية السعودية foo.السعودية w.foo.السعودية السعودية foo.السعودية +# Microsoft +1.azurestaticapps.net 1.azurestaticapps.net null +app.1.azurestaticapps.net 1.azurestaticapps.net app.1.azurestaticapps.net + ## END From 38cc0391f3f7272167f92a4c2faa9fae21a26ef9 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Wed, 26 Apr 2023 17:32:05 +0000 Subject: [PATCH 160/288] 8306705: com/sun/jdi/PopAndInvokeTest.java fails with NativeMethodException Reviewed-by: lmesnik, amenkov, sspitsyn --- test/jdk/com/sun/jdi/PopAndInvokeTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/com/sun/jdi/PopAndInvokeTest.java b/test/jdk/com/sun/jdi/PopAndInvokeTest.java index 0b270a4fee0..2b2953cb303 100644 --- a/test/jdk/com/sun/jdi/PopAndInvokeTest.java +++ b/test/jdk/com/sun/jdi/PopAndInvokeTest.java @@ -50,8 +50,9 @@ class PopAndInvokeTarg { if (waiting) { return; } - waiting = true; System.out.println(" debuggee: in waiter"); + // No printlns or other calls allowed after this point. + waiting = true; while (true) { } } From 732179ca84ee1dab6530255c33de7f35cab649c2 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 26 Apr 2023 19:07:25 +0000 Subject: [PATCH 161/288] 8306409: Open source AWT KeyBoardFocusManger, LightWeightComponent related tests Reviewed-by: psadhukhan, tr, serb --- .../KeyboardFocusmanager/ChangeKFMTest.java | 93 ++++++++++ .../PropertySupportNPETest.java | 47 +++++ test/jdk/java/awt/Label/NullLabelTest.java | 59 ++++++ test/jdk/java/awt/Layout/InsetsTest.java | 96 ++++++++++ .../LWClobberDragEvent.java | 169 ++++++++++++++++++ .../LightweightDragTest.java | 151 ++++++++++++++++ 6 files changed, 615 insertions(+) create mode 100644 test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java create mode 100644 test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java create mode 100644 test/jdk/java/awt/Label/NullLabelTest.java create mode 100644 test/jdk/java/awt/Layout/InsetsTest.java create mode 100644 test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java create mode 100644 test/jdk/java/awt/LightweightComponent/LightweightDragTest.java diff --git a/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java b/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java new file mode 100644 index 00000000000..08d24e40114 --- /dev/null +++ b/test/jdk/java/awt/KeyboardFocusmanager/ChangeKFMTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4467840 + @summary Generate a PropertyChange when KeyboardFocusManager changes + @key headful + @run main ChangeKFMTest +*/ + +import java.awt.BorderLayout; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class ChangeKFMTest implements PropertyChangeListener { + static final String CURRENT_PROP_NAME = "managingFocus"; + boolean current_fired; + boolean not_current_fired; + KeyboardFocusManager kfm; + public static void main(String[] args) throws Exception { + ChangeKFMTest test = new ChangeKFMTest(); + test.start(); + } + + public void start () throws Exception { + EventQueue.invokeAndWait(() -> { + kfm = new DefaultKeyboardFocusManager(); + kfm.addPropertyChangeListener(CURRENT_PROP_NAME, this); + current_fired = false; + not_current_fired = false; + KeyboardFocusManager.setCurrentKeyboardFocusManager(kfm); + if (!current_fired) { + throw new RuntimeException("Change to current was not fired on KFM instalation"); + } + if (not_current_fired) { + throw new RuntimeException("Change to non-current was fired on KFM instalation"); + } else { + System.out.println("Installation was complete correctly"); + } + + current_fired = false; + not_current_fired = false; + KeyboardFocusManager.setCurrentKeyboardFocusManager(null); + if (!not_current_fired) { + throw new RuntimeException("Change to non-current was not fired on KFM uninstalation"); + } + if (current_fired) { + throw new RuntimeException("Change to current was fired on KFM uninstalation"); + } else { + System.out.println("Uninstallation was complete correctly"); + } + }); + } + + public void propertyChange(PropertyChangeEvent e) { + System.out.println(e.toString()); + if (!CURRENT_PROP_NAME.equals(e.getPropertyName())) { + throw new RuntimeException("Unexpected property name - " + e.getPropertyName()); + } + if (((Boolean)e.getNewValue()).booleanValue()) { + current_fired = true; + } else { + not_current_fired = true; + } + System.out.println("current_fired = " + current_fired); + System.out.println("not_current_fired = " + not_current_fired); + } +} diff --git a/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java b/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java new file mode 100644 index 00000000000..14466c0623b --- /dev/null +++ b/test/jdk/java/awt/KeyboardFocusmanager/PropertySupportNPETest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4458016 + @summary KeyboardFocusManager.get[Property|Vetoable]ChangeListeners throw NPE + @key headful + @run main PropertySupportNPETest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; + +public class PropertySupportNPETest { + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + KeyboardFocusManager kfm = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + kfm.getVetoableChangeListeners(); + kfm.getVetoableChangeListeners(""); + kfm.getPropertyChangeListeners(); + kfm.getPropertyChangeListeners(""); + }); + } + } diff --git a/test/jdk/java/awt/Label/NullLabelTest.java b/test/jdk/java/awt/Label/NullLabelTest.java new file mode 100644 index 00000000000..c7580a8a57b --- /dev/null +++ b/test/jdk/java/awt/Label/NullLabelTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 6215905 + @summary Tests that passing null value to Label.setText(String) doesn't + lead to VM crash. + @key headful + @run main NullLabelTest +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Label; +import java.awt.Frame; + +public class NullLabelTest { + + static Frame frame; + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + try { + frame = new Frame(); + Label l = new Label("A"); + frame.add(l); + frame.setLayout(new BorderLayout()); + frame.setSize(200, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + l.setText(null); + } finally { + if (frame != null) { + frame.dispose(); + } + } + }); + } +} diff --git a/test/jdk/java/awt/Layout/InsetsTest.java b/test/jdk/java/awt/Layout/InsetsTest.java new file mode 100644 index 00000000000..62ef70e0f16 --- /dev/null +++ b/test/jdk/java/awt/Layout/InsetsTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4087971 + @summary Insets does not layout a component correctly + @key headful + @run main InsetsTest +*/ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +public class InsetsTest { + private int leftInsetValue; + private InsetsClass IC; + + public static void main(String[] args) throws Exception { + InsetsTest test = new InsetsTest(); + test.start(); + } + + public void start() throws Exception { + EventQueue.invokeAndWait(() -> { + try { + IC = new InsetsClass(); + IC.setLayout(new BorderLayout()); + IC.setSize(200, 200); + IC.setVisible(true); + + leftInsetValue = IC.returnLeftInset(); + if (leftInsetValue != 30) { + throw new RuntimeException("Test Failed - Left inset" + + "is not taken correctly"); + } + } finally { + if (IC != null) { + IC.dispose(); + } + } + }); + } +} + +class InsetsClass extends JFrame { + private int value; + private JPanel panel; + + public InsetsClass() { + super("TestFrame"); + setBackground(Color.lightGray); + + panel = new JPanel(); + panel.setBorder(new EmptyBorder(new Insets(30, 30, 30, 30))); + panel.add(new JButton("Test Button")); + + getContentPane().add(panel); + pack(); + setVisible(true); + } + + public int returnLeftInset() { + // Getting the left inset value + Insets insets = panel.getInsets(); + value = insets.left; + return value; + } +} diff --git a/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java b/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java new file mode 100644 index 00000000000..a29b7da8172 --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/LWClobberDragEvent.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4092418 + @summary Test for drag events been taking by Lightweight Component + @key headful + @run main LWClobberDragEvent +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public class LWClobberDragEvent implements MouseListener, MouseMotionListener { + boolean isDragging; + + static Frame frame; + LightweightComp lc; + final static int LWWidth = 200; + final static int LWHeight = 100; + final static int MAX_COUNT = 100; + Point locationOfLW; + + public static void main(String[] args) throws Exception { + LWClobberDragEvent test = new LWClobberDragEvent(); + try { + test.init(); + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame(); + frame.setLayout(new BorderLayout()); + isDragging = false; + frame.addMouseMotionListener(this); + frame.addMouseListener(this); + + frame.setBackground(Color.white); + + lc = new LightweightComp(); + lc.setSize(LWWidth, LWHeight); + lc.setLocation(50, 50); + lc.addMouseListener(this); + lc.addMouseMotionListener(this); + frame.add(lc); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.delay(1000); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + locationOfLW = getLocation(lc); + robot.mouseMove(locationOfLW.x + lc.getWidth() / 2, + locationOfLW.y - lc.getHeight() / 2); + }); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(1000); + //move mouse till the bottom of LWComponent + for (int i = 1; i < LWHeight + lc.getHeight() / 2; i++) { + robot.mouseMove(locationOfLW.x + lc.getWidth() / 2, + locationOfLW.y - lc.getHeight() / 2 + i); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(1000); + System.out.println("Test Passed."); + } + + public void mouseClicked(MouseEvent evt) { } + + public void mouseReleased(MouseEvent evt) { + if (evt.getSource() == this) { + if (isDragging) { + isDragging = false; + } + } else { + } + } + public Point getLocation( Component co ) throws RuntimeException { + Point pt = null; + boolean bFound = false; + int count = 0; + while ( !bFound ) { + try { + pt = co.getLocationOnScreen(); + bFound = true; + } catch ( Exception ex ) { + bFound = false; + count++; + } + if ( !bFound && count > MAX_COUNT ) { + throw new RuntimeException("don't see a component to get location"); + } + } + return pt; + } + + public void mousePressed(MouseEvent evt) { } + public void mouseEntered(MouseEvent evt) { } + public void mouseExited(MouseEvent evt) { } + public void mouseMoved(MouseEvent evt) { } + + public void mouseDragged(MouseEvent evt) { + if (evt.getSource() == this) { + if (!isDragging) { + isDragging = true; + } + } else { + if (isDragging) { + throw new RuntimeException("Test failed: Lightweight got dragging event."); + } + } + } +} + +class LightweightComp extends Component { + public void paint(Graphics g) { + Dimension d = getSize(); + g.setColor(Color.red); + g.fillRect(0, 0, d.width, d.height); + } +} diff --git a/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java b/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java new file mode 100644 index 00000000000..2b3324c2523 --- /dev/null +++ b/test/jdk/java/awt/LightweightComponent/LightweightDragTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 4050138 + @summary Lightweight components: Enter/Exit mouse events + incorrectly reported during drag + @key headful + @run main LightweightDragTest +*/ + +import java.awt.AWTException; +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + +public class LightweightDragTest { + MyComponent c,c2; + static Frame frame; + volatile int x = 0; + volatile int y = 0; + volatile int x2 = 0; + volatile int y2 = 0; + + public static void main(String[] args) throws Exception { + LightweightDragTest test = new LightweightDragTest(); + try { + EventQueue.invokeAndWait(() -> { + test.init(); + }); + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame("Test LightWeight Component Drag"); + c = new MyComponent(); + c2 = new MyComponent(); + frame.add(c, BorderLayout.WEST); + frame.add(c2, BorderLayout.EAST); + frame.setSize(250, 200); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public void start() throws Exception { + Robot rb; + try { + rb = new Robot(); + } catch (AWTException e) { + throw new Error("Could not create robot"); + } + rb.setAutoDelay(10); + rb.delay(1000); + rb.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + x = c.getLocationOnScreen().x + c.getWidth() / 2; + y = c.getLocationOnScreen().y + c.getHeight() / 2; + x2 = c2.getLocationOnScreen().x + c2.getWidth() / 2; + y2 = c2.getLocationOnScreen().y + c2.getHeight() / 2; + }); + int xt = x; + int yt = y; + rb.mouseMove(xt, yt); + rb.mousePress(InputEvent.BUTTON1_MASK); + EventQueue.invokeAndWait(() -> { + c.isInside = true; + c2.isInside = false; + }); + // drag + while (xt != x2 || yt != y2) { + if (x2 > xt) ++xt; + if (x2 < xt) --xt; + if (y2 > yt) ++yt; + if (y2 < yt) --yt; + rb.mouseMove(xt, yt); + } + rb.mouseRelease(InputEvent.BUTTON1_MASK); + EventQueue.invokeAndWait(() -> { + if (c.isInside || !c2.isInside) { + throw new Error("Test failed: mouse events did not arrive"); + } + }); + } +} + +class MyComponent extends Component { + public boolean isInside; + public void paint(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0,0,getSize().width,getSize().height); + } + public MyComponent() { + enableEvents(AWTEvent.MOUSE_EVENT_MASK); + setBackground(Color.blue); + } + + public Dimension getPreferredSize() { + return new Dimension(100, 100); + } + + public void processEvent(AWTEvent e) { + int eventID = e.getID(); + if ((eventID == MouseEvent.MOUSE_ENTERED)) { + setBackground(Color.red); + repaint(); + isInside = true; + } else if (eventID == MouseEvent.MOUSE_EXITED) { + setBackground(Color.blue); + repaint(); + isInside = false; + } + super.processEvent(e); + } +} From b81c9c844228c39ea7625c30fddb8f44065ce8b0 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 26 Apr 2023 20:03:47 +0000 Subject: [PATCH 162/288] 8306951: [BACKOUT] JDK-8305252 make_method_handle_intrinsic may call java code under a lock Reviewed-by: dcubed --- .../share/classfile/systemDictionary.cpp | 76 +++++++------------ src/hotspot/share/runtime/mutexLocker.cpp | 8 +- src/hotspot/share/runtime/mutexLocker.hpp | 3 +- 3 files changed, 30 insertions(+), 57 deletions(-) diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 9702c4ae9f9..3dec3cb1b4a 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1583,13 +1583,11 @@ void SystemDictionary::methods_do(void f(Method*)) { } auto doit = [&] (InvokeMethodKey key, Method* method) { - if (method != nullptr) { - f(method); - } + f(method); }; { - MutexLocker ml(InvokeMethodIntrinsicTable_lock); + MutexLocker ml(InvokeMethodTable_lock); _invoke_method_intrinsic_table.iterate_all(doit); } @@ -1941,62 +1939,40 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, iid != vmIntrinsics::_invokeGeneric, "must be a known MH intrinsic iid=%d: %s", iid_as_int, vmIntrinsics::name_at(iid)); - InvokeMethodKey key(signature, iid_as_int); - Method** met = nullptr; - - // We only want one entry in the table for this (signature/id, method) pair but the code - // to create the intrinsic method needs to be outside the lock. - // The first thread claims the entry by adding the key and the other threads wait, until the - // Method has been added as the value. { - MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock); - while (met == nullptr) { - bool created; - met = _invoke_method_intrinsic_table.put_if_absent(key, &created); - if (met != nullptr && *met != nullptr) { - return *met; - } else if (!created) { - // Second thread waits for first to actually create the entry and returns - // it after notify. Loop until method return is non-null. - ml.wait(); - } + MutexLocker ml(THREAD, InvokeMethodTable_lock); + InvokeMethodKey key(signature, iid_as_int); + Method** met = _invoke_method_intrinsic_table.get(key); + if (met != nullptr) { + return *met; } - } - methodHandle m = Method::make_method_handle_intrinsic(iid, signature, THREAD); - bool throw_error = HAS_PENDING_EXCEPTION; - if (!throw_error && (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative)) { - // Generate a compiled form of the MH intrinsic - // linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version. - AdapterHandlerLibrary::create_native_wrapper(m); - // Check if have the compiled code. - throw_error = (!m->has_compiled_code()); - } + bool throw_error = false; + // This function could get an OOM but it is safe to call inside of a lock because + // throwing OutOfMemoryError doesn't call Java code. + methodHandle m = Method::make_method_handle_intrinsic(iid, signature, CHECK_NULL); + if (!Arguments::is_interpreter_only() || iid == vmIntrinsics::_linkToNative) { + // Generate a compiled form of the MH intrinsic + // linkToNative doesn't have interpreter-specific implementation, so always has to go through compiled version. + AdapterHandlerLibrary::create_native_wrapper(m); + // Check if have the compiled code. + throw_error = (!m->has_compiled_code()); + } - { - MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock); - if (throw_error) { - // Remove the entry and let another thread try, or get the same exception. - bool removed = _invoke_method_intrinsic_table.remove(key); - assert(removed, "must be the owner"); - ml.notify_all(); - } else { + if (!throw_error) { signature->make_permanent(); // The signature is never unloaded. + bool created = _invoke_method_intrinsic_table.put(key, m()); + assert(created, "must be since we still hold the lock"); assert(Arguments::is_interpreter_only() || (m->has_compiled_code() && m->code()->entry_point() == m->from_compiled_entry()), "MH intrinsic invariant"); - *met = m(); // insert the element - ml.notify_all(); return m(); } } - // Throw VirtualMachineError or the pending exception in the JavaThread - if (throw_error && !HAS_PENDING_EXCEPTION) { - THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), - "Out of space in CodeCache for method handle intrinsic"); - } - return nullptr; + // Throw error outside of the lock. + THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), + "Out of space in CodeCache for method handle intrinsic"); } // Helper for unpacking the return value from linkMethod and linkCallSite. @@ -2139,7 +2115,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, Handle empty; OopHandle* o; { - MutexLocker ml(THREAD, InvokeMethodTypeTable_lock); + MutexLocker ml(THREAD, InvokeMethodTable_lock); o = _invoke_method_type_table.get(signature); } @@ -2208,7 +2184,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, if (can_be_cached) { // We can cache this MethodType inside the JVM. - MutexLocker ml(THREAD, InvokeMethodTypeTable_lock); + MutexLocker ml(THREAD, InvokeMethodTable_lock); bool created = false; assert(method_type != nullptr, "unexpected null"); OopHandle* h = _invoke_method_type_table.get(signature); diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index a46f0ba0063..a954d685cf4 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -39,8 +39,7 @@ Mutex* Patching_lock = nullptr; Mutex* CompiledMethod_lock = nullptr; Monitor* SystemDictionary_lock = nullptr; -Mutex* InvokeMethodTypeTable_lock = nullptr; -Monitor* InvokeMethodIntrinsicTable_lock = nullptr; +Mutex* InvokeMethodTable_lock = nullptr; Mutex* SharedDictionary_lock = nullptr; Monitor* ClassInitError_lock = nullptr; Mutex* Module_lock = nullptr; @@ -255,9 +254,7 @@ void mutex_init() { } MUTEX_DEFN(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2); // used for creating jmethodIDs. - MUTEX_DEFN(InvokeMethodTypeTable_lock , PaddedMutex , safepoint); - MUTEX_DEFN(InvokeMethodIntrinsicTable_lock , PaddedMonitor, safepoint); - MUTEX_DEFN(AdapterHandlerLibrary_lock , PaddedMutex , safepoint); + MUTEX_DEFN(InvokeMethodTable_lock , PaddedMutex , safepoint); MUTEX_DEFN(SharedDictionary_lock , PaddedMutex , safepoint); MUTEX_DEFN(VMStatistic_lock , PaddedMutex , safepoint); MUTEX_DEFN(SignatureHandlerLibrary_lock , PaddedMutex , safepoint); @@ -347,6 +344,7 @@ void mutex_init() { MUTEX_DEFL(Threads_lock , PaddedMonitor, CompileThread_lock, true); MUTEX_DEFL(Compile_lock , PaddedMutex , MethodCompileQueue_lock); + MUTEX_DEFL(AdapterHandlerLibrary_lock , PaddedMutex , InvokeMethodTable_lock); MUTEX_DEFL(Heap_lock , PaddedMonitor, AdapterHandlerLibrary_lock); MUTEX_DEFL(PerfDataMemAlloc_lock , PaddedMutex , Heap_lock); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 46329eb830e..64b527f97b2 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -34,8 +34,7 @@ extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code extern Mutex* CompiledMethod_lock; // a lock used to guard a compiled method and OSR queues extern Monitor* SystemDictionary_lock; // a lock on the system dictionary -extern Mutex* InvokeMethodTypeTable_lock; -extern Monitor* InvokeMethodIntrinsicTable_lock; +extern Mutex* InvokeMethodTable_lock; extern Mutex* SharedDictionary_lock; // a lock on the CDS shared dictionary extern Monitor* ClassInitError_lock; // a lock on the class initialization error table extern Mutex* Module_lock; // a lock on module and package related data structures From 750bece0c2f331025590e7358c7b69f4811f0d24 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Wed, 26 Apr 2023 20:54:39 +0000 Subject: [PATCH 163/288] 8305771: SA ClassWriter.java fails to skip overpass methods Reviewed-by: kevinw, cjplummer --- .../classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java index 382eae2e8cb..3ac826d56e2 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -438,8 +438,8 @@ public class ClassWriter implements /* imports */ ClassConstants ArrayList valid_methods = new ArrayList(); for (int i = 0; i < methods.length(); i++) { Method m = methods.at(i); - long accessFlags = m.getAccessFlags(); - // overpass method + long accessFlags = m.getAccessFlags() & JVM_RECOGNIZED_METHOD_MODIFIERS; + // skip overpass methods if (accessFlags == (JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE)) { continue; } From 1e4eafb4fe70832294a12938d93e7860073cf4cf Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Wed, 26 Apr 2023 22:45:10 +0000 Subject: [PATCH 164/288] 8071693: Introspector ignores default interface methods Reviewed-by: prr, aivanov, serb --- .../com/sun/beans/introspect/MethodInfo.java | 40 +++- .../DefaultMethodBeanPropertyTest.java | 211 ++++++++++++++++++ 2 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java 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 5216f4423d4..25c95988393 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 @@ -25,18 +25,35 @@ package com.sun.beans.introspect; +import java.io.Closeable; +import java.io.Externalizable; +import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Set; import com.sun.beans.TypeResolver; import com.sun.beans.finder.MethodFinder; final class MethodInfo { + + // These are some common interfaces that we know a priori + // will not contain any bean property getters or setters. + static final Set> IGNORABLE_INTERFACES = Set.of( + AutoCloseable.class, + Cloneable.class, + Closeable.class, + Comparable.class, + Externalizable.class, + Serializable.class + ); + final Method method; final Class type; @@ -66,6 +83,8 @@ final class MethodInfo { static List get(Class type) { List list = null; if (type != null) { + + // Add declared methods boolean inaccessible = !Modifier.isPublic(type.getModifiers()); for (Method method : type.getMethods()) { if (method.getDeclaringClass().equals(type)) { @@ -81,10 +100,19 @@ final class MethodInfo { } } if (method != null) { - if (list == null) { - list = new ArrayList<>(); - } - list.add(method); + (list = createIfNeeded(list)).add(method); + } + } + } + + // Add default methods inherited from interfaces + for (Class iface : type.getInterfaces()) { + if (IGNORABLE_INTERFACES.contains(iface)) { + continue; + } + for (Method method : iface.getMethods()) { + if (!Modifier.isAbstract(method.getModifiers())) { + (list = createIfNeeded(list)).add(method); } } } @@ -96,6 +124,10 @@ final class MethodInfo { return Collections.emptyList(); } + private static List createIfNeeded(List list) { + return list != null ? list : new ArrayList<>(); + } + /** * A comparator that defines a total order so that methods have the same * name and identical signatures appear next to each others. diff --git a/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java b/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java new file mode 100644 index 00000000000..a1e528880ef --- /dev/null +++ b/test/jdk/java/beans/Introspector/DefaultMethodBeanPropertyTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8071693 + * @summary Verify that the Introspector finds default methods inherited + * from interfaces + */ + +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.NavigableSet; +import java.util.Set; +import java.util.stream.Collectors; + +public class DefaultMethodBeanPropertyTest { + +////////////////////////////////////// +// // +// SCENARIO 1 // +// // +////////////////////////////////////// + + public interface A1 { + default int getValue() { + return 0; + } + default Object getObj() { + return null; + } + + public static int getStaticValue() { + return 0; + } + } + + public interface B1 extends A1 { + } + + public interface C1 extends A1 { + Number getFoo(); + } + + public class D1 implements C1 { + @Override + public Integer getFoo() { + return null; + } + @Override + public Float getObj() { + return null; + } + } + + public static void testScenario1() { + verifyProperties(D1.class, + "getClass", // inherited method + "getValue", // inherited default method + "getFoo", // overridden interface method + "getObj" // overridden default method + ); + } + +////////////////////////////////////// +// // +// SCENARIO 2 // +// // +////////////////////////////////////// + + public interface A2 { + default Object getFoo() { + return null; + } + } + + public interface B2 extends A2 { + } + + public interface C2 extends A2 { + } + + public class D2 implements B2, C2 { + } + + public static void testScenario2() { + verifyProperties(D2.class, + "getClass", + "getFoo" + ); + } + +////////////////////////////////////// +// // +// SCENARIO 3 // +// // +////////////////////////////////////// + + public interface A3 { + default Object getFoo() { + return null; + } + } + + public interface B3 extends A3 { + @Override + Set getFoo(); + } + + public interface C3 extends A3 { + @Override + Collection getFoo(); + } + + public class D3 implements B3, C3 { + @Override + public NavigableSet getFoo() { + return null; + } + } + + public static void testScenario3() { + verifyProperties(D3.class, + "getClass", + "getFoo" + ); + } + +// 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 + 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 "))); + } + } + +// Main method + + public static void main(String[] args) throws Exception { + testScenario1(); + testScenario2(); + testScenario3(); + } +} From 9ebcda2165c42e3f7b82a9ae8074badb69c0d270 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 26 Apr 2023 22:47:54 +0000 Subject: [PATCH 165/288] 8229147: Linux os::create_thread() overcounts guardpage size with newer glibc (>=2.27) Reviewed-by: shade, stuefe --- src/hotspot/os/linux/os_linux.cpp | 97 ++++++++++++++++++++----------- src/hotspot/os/linux/os_linux.hpp | 2 + src/hotspot/os/posix/os_posix.cpp | 4 +- 3 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 86de46df3d1..5d771b75669 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -760,20 +760,14 @@ static void *thread_native_entry(Thread *thread) { // As a workaround, we call a private but assumed-stable glibc function, // __pthread_get_minstack() to obtain the minstack size and derive the // static TLS size from it. We then increase the user requested stack -// size by this TLS size. +// size by this TLS size. The same function is used to determine whether +// adjustStackSizeForGuardPages() needs to be true. // // Due to compatibility concerns, this size adjustment is opt-in and // controlled via AdjustStackSizeForTLS. typedef size_t (*GetMinStack)(const pthread_attr_t *attr); -GetMinStack _get_minstack_func = nullptr; - -static void get_minstack_init() { - _get_minstack_func = - (GetMinStack)dlsym(RTLD_DEFAULT, "__pthread_get_minstack"); - log_info(os, thread)("Lookup of __pthread_get_minstack %s", - _get_minstack_func == nullptr ? "failed" : "succeeded"); -} +GetMinStack _get_minstack_func = nullptr; // Initialized via os::init_2() // Returns the size of the static TLS area glibc puts on thread stacks. // The value is cached on first use, which occurs when the first thread @@ -786,8 +780,8 @@ static size_t get_static_tls_area_size(const pthread_attr_t *attr) { // Remove non-TLS area size included in minstack size returned // by __pthread_get_minstack() to get the static TLS size. - // In glibc before 2.27, minstack size includes guard_size. - // In glibc 2.27 and later, guard_size is automatically added + // If adjustStackSizeForGuardPages() is true, minstack size includes + // guard_size. Otherwise guard_size is automatically added // to the stack size by pthread_create and is no longer included // in minstack size. In both cases, the guard_size is taken into // account, so there is no need to adjust the result for that. @@ -816,6 +810,42 @@ static size_t get_static_tls_area_size(const pthread_attr_t *attr) { return tls_size; } +// In glibc versions prior to 2.27 the guard size mechanism +// was not implemented properly. The POSIX standard requires adding +// the size of the guard pages to the stack size, instead glibc +// took the space out of 'stacksize'. Thus we need to adapt the requested +// stack_size by the size of the guard pages to mimic proper behaviour. +// The fix in glibc 2.27 has now been backported to numerous earlier +// glibc versions so we need to do a dynamic runtime check. +static bool _adjustStackSizeForGuardPages = true; +bool os::Linux::adjustStackSizeForGuardPages() { + return _adjustStackSizeForGuardPages; +} + +#ifdef __GLIBC__ +static void init_adjust_stacksize_for_guard_pages() { + assert(_get_minstack_func == nullptr, "initialization error"); + _get_minstack_func =(GetMinStack)dlsym(RTLD_DEFAULT, "__pthread_get_minstack"); + log_info(os, thread)("Lookup of __pthread_get_minstack %s", + _get_minstack_func == nullptr ? "failed" : "succeeded"); + + if (_get_minstack_func != nullptr) { + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t min_stack = _get_minstack_func(&attr); + size_t guard = 16 * K; // Actual value doesn't matter as it is not examined + pthread_attr_setguardsize(&attr, guard); + size_t min_stack2 = _get_minstack_func(&attr); + pthread_attr_destroy(&attr); + // If the minimum stack size changed when we added the guard page space + // then we need to perform the adjustment. + _adjustStackSizeForGuardPages = (min_stack2 != min_stack); + log_info(os)("Glibc stack size guard page adjustment is %sneeded", + _adjustStackSizeForGuardPages ? "" : "not "); + } +} +#endif // GLIBC + bool os::create_thread(Thread* thread, ThreadType thr_type, size_t req_stack_size) { assert(thread->osthread() == nullptr, "caller responsible"); @@ -841,23 +871,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, // Calculate stack size if it's not specified by caller. size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); - // In glibc versions prior to 2.27 the guard size mechanism - // is not implemented properly. The posix standard requires adding - // the size of the guard pages to the stack size, instead Linux - // takes the space out of 'stacksize'. Thus we adapt the requested - // stack_size by the size of the guard pages to mimic proper - // behaviour. However, be careful not to end up with a size - // of zero due to overflow. Don't add the guard page in that case. size_t guard_size = os::Linux::default_guard_size(thr_type); // Configure glibc guard page. Must happen before calling // get_static_tls_area_size(), which uses the guard_size. pthread_attr_setguardsize(&attr, guard_size); + // Apply stack size adjustments if needed. However, be careful not to end up + // with a size of zero due to overflow. Don't add the adjustment in that case. size_t stack_adjust_size = 0; if (AdjustStackSizeForTLS) { // Adjust the stack_size for on-stack TLS - see get_static_tls_area_size(). stack_adjust_size += get_static_tls_area_size(&attr); - } else { + } else if (os::Linux::adjustStackSizeForGuardPages()) { stack_adjust_size += guard_size; } @@ -1002,7 +1027,7 @@ bool os::create_attached_thread(JavaThread* thread) { log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", os::current_thread_id(), (uintx) pthread_self(), - p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } @@ -1326,7 +1351,7 @@ void os::Linux::fast_thread_clock_init() { // Note, that some kernels may support the current thread // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks // returned by the pthread_getcpuclockid(). - // If the fast Posix clocks are supported then the clock_getres() + // If the fast POSIX clocks are supported then the clock_getres() // must return at least tp.tv_sec == 0 which means a resolution // better than 1 sec. This is extra check for reliability. @@ -4499,10 +4524,6 @@ jint os::init_2(void) { return JNI_ERR; } - if (AdjustStackSizeForTLS) { - get_minstack_init(); - } - // Check and sets minimum stack sizes against command line options if (set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; @@ -4525,6 +4546,11 @@ jint os::init_2(void) { log_info(os)("HotSpot is running with %s, %s", Linux::libc_version(), Linux::libpthread_version()); +#ifdef __GLIBC__ + // Check if we need to adjust the stack size for glibc guard pages. + init_adjust_stacksize_for_guard_pages(); +#endif + if (UseNUMA || UseNUMAInterleaving) { Linux::numa_init(); } @@ -5244,9 +5270,9 @@ bool os::start_debugging(char *buf, int buflen) { // // ** P1 (aka bottom) and size (P2 = P1 - size) are the address and stack size // returned from pthread_attr_getstack(). -// ** Due to NPTL implementation error, linux takes the glibc guard page out -// of the stack size given in pthread_attr. We work around this for -// threads created by the VM. (We adapt bottom to be P1 and size accordingly.) +// ** If adjustStackSizeForGuardPages() is true the guard pages have been taken +// out of the stack size given in pthread_attr. We work around this for +// threads created by the VM. We adjust bottom to be P1 and size accordingly. // #ifndef ZERO static void current_stack_region(address * bottom, size_t * size) { @@ -5273,14 +5299,15 @@ static void current_stack_region(address * bottom, size_t * size) { fatal("Cannot locate current stack attributes!"); } - // Work around NPTL stack guard error. - size_t guard_size = 0; - rslt = pthread_attr_getguardsize(&attr, &guard_size); - if (rslt != 0) { - fatal("pthread_attr_getguardsize failed with error = %d", rslt); + if (os::Linux::adjustStackSizeForGuardPages()) { + size_t guard_size = 0; + rslt = pthread_attr_getguardsize(&attr, &guard_size); + if (rslt != 0) { + fatal("pthread_attr_getguardsize failed with error = %d", rslt); + } + *bottom += guard_size; + *size -= guard_size; } - *bottom += guard_size; - *size -= guard_size; pthread_attr_destroy(&attr); diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index 20639e4031f..e33a1af1072 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -149,6 +149,8 @@ class os::Linux { // Return default guard size for the specified thread type static size_t default_guard_size(os::ThreadType thr_type); + static bool adjustStackSizeForGuardPages(); // See comments in os_linux.cpp + static void capture_initial_stack(size_t max_size); // Stack overflow handling diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 9bd67526600..1b12d91fd90 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -905,8 +905,8 @@ char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_a int detachstate = 0; pthread_attr_getstacksize(attr, &stack_size); pthread_attr_getguardsize(attr, &guard_size); - // Work around linux NPTL implementation error, see also os::create_thread() in os_linux.cpp. - LINUX_ONLY(stack_size -= guard_size); + // Work around glibc stack guard issue, see os::create_thread() in os_linux.cpp. + LINUX_ONLY(if (os::Linux::adjustStackSizeForGuardPages()) stack_size -= guard_size;) pthread_attr_getdetachstate(attr, &detachstate); jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s", stack_size / K, guard_size / K, From 27c5c1070ac559caa8dbad598337046f59355464 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 27 Apr 2023 04:57:29 +0000 Subject: [PATCH 166/288] 8306883: Thread stacksize is reported with wrong units in os::create_thread logging Reviewed-by: shade --- src/hotspot/os/aix/os_aix.cpp | 4 ++-- src/hotspot/os/bsd/os_bsd.cpp | 4 ++-- src/hotspot/os/linux/os_linux.cpp | 2 +- src/hotspot/os/windows/os_windows.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index a4c5a03b847..e0b24e639db 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -892,9 +892,9 @@ bool os::create_attached_thread(JavaThread* thread) { PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) kernel_thread_id, - p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index c8af751250b..f4799e76a32 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -708,9 +708,9 @@ bool os::create_attached_thread(JavaThread* thread) { PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) pthread_self(), - p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 5d771b75669..b6d2721343c 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -1025,7 +1025,7 @@ bool os::create_attached_thread(JavaThread* thread) { PosixSignals::hotspot_sigmask(thread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT - ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), (uintx) pthread_self(), p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 686e27add56..9edd4b892bb 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -621,9 +621,9 @@ bool os::create_attached_thread(JavaThread* thread) { thread->set_osthread(osthread); log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", stack: " - PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "K) ).", os::current_thread_id(), p2i(thread->stack_base()), - p2i(thread->stack_end()), thread->stack_size()); + p2i(thread->stack_end()), thread->stack_size() / K); return true; } From 748476fd80ec93c25d823bc5088c706fcf3c7e65 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Thu, 27 Apr 2023 06:56:22 +0000 Subject: [PATCH 167/288] 8306732: TruncatedSeq::predict_next() attempts linear regression with only one data point Reviewed-by: tschatzl, kbarrett --- src/hotspot/share/utilities/numberSeq.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/utilities/numberSeq.cpp b/src/hotspot/share/utilities/numberSeq.cpp index db2f8d92d73..bce17d558cd 100644 --- a/src/hotspot/share/utilities/numberSeq.cpp +++ b/src/hotspot/share/utilities/numberSeq.cpp @@ -206,8 +206,15 @@ double TruncatedSeq::oldest() const { } double TruncatedSeq::predict_next() const { - if (_num == 0) + if (_num == 0) { + // No data points, pick function: y = 0 + 0*x return 0.0; + } + + if (_num == 1) { + // Only one point P, pick function: y = P_y + 0*x + return _sequence[0]; + } double num = (double) _num; double x_squared_sum = 0.0; From de0c05da07859ee4552b73a39a35cc8cd37b78b0 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 27 Apr 2023 07:06:24 +0000 Subject: [PATCH 168/288] 6995195: Static initialization deadlock in sun.java2d.loops.Blit and GraphicsPrimitiveMgr Reviewed-by: serb, aivanov --- .../share/classes/sun/java2d/loops/Blit.java | 3 +- .../classes/sun/java2d/loops/BlitBg.java | 3 +- .../sun/java2d/loops/DrawGlyphList.java | 3 +- .../sun/java2d/loops/DrawGlyphListAA.java | 3 +- .../sun/java2d/loops/DrawGlyphListColor.java | 3 +- .../classes/sun/java2d/loops/FillRect.java | 3 +- .../java2d/loops/GraphicsPrimitiveMgr.java | 75 ++++++++++--------- .../classes/sun/java2d/loops/MaskBlit.java | 3 +- .../classes/sun/java2d/loops/MaskFill.java | 3 +- .../loops/GraphicsPrimitiveMgrTest.java | 70 +++++++++++++++++ 10 files changed, 127 insertions(+), 42 deletions(-) create mode 100644 test/jdk/sun/java2d/loops/GraphicsPrimitiveMgrTest.java diff --git a/src/java.desktop/share/classes/sun/java2d/loops/Blit.java b/src/java.desktop/share/classes/sun/java2d/loops/Blit.java index 0d3a4ac4f24..c5d29bb3e9c 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/Blit.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/Blit.java @@ -36,6 +36,7 @@ import java.lang.ref.WeakReference; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; import sun.java2d.pipe.SpanIterator; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * Blit @@ -111,7 +112,7 @@ public class Blit extends GraphicsPrimitive int width, int height); static { - GraphicsPrimitiveMgr.registerGeneral(new Blit(null, null, null)); + GeneralPrimitives.register(new Blit(null, null, null)); } protected GraphicsPrimitive makePrimitive(SurfaceType srctype, diff --git a/src/java.desktop/share/classes/sun/java2d/loops/BlitBg.java b/src/java.desktop/share/classes/sun/java2d/loops/BlitBg.java index ffe5901a57d..8531c2d429f 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/BlitBg.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/BlitBg.java @@ -37,6 +37,7 @@ import sun.awt.image.BufImgSurfaceData; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * BlitBg @@ -114,7 +115,7 @@ public class BlitBg extends GraphicsPrimitive int width, int height); static { - GraphicsPrimitiveMgr.registerGeneral(new BlitBg(null, null, null)); + GeneralPrimitives.register(new BlitBg(null, null, null)); } protected GraphicsPrimitive makePrimitive(SurfaceType srctype, diff --git a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphList.java b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphList.java index dfc4fa34928..35a3aa75bf6 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphList.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphList.java @@ -29,6 +29,7 @@ import sun.font.GlyphList; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * DrawGlyphList - loops for SolidTextRenderer pipe. @@ -73,7 +74,7 @@ public class DrawGlyphList extends GraphicsPrimitive { // This instance is used only for lookup. static { - GraphicsPrimitiveMgr.registerGeneral( + GeneralPrimitives.register( new DrawGlyphList(null, null, null)); } diff --git a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListAA.java b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListAA.java index dd1f2b3e8f9..e4b5b51661a 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListAA.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListAA.java @@ -29,6 +29,7 @@ import sun.font.GlyphList; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * DrawGlyphListAA - loops for AATextRenderer pipe @@ -71,7 +72,7 @@ public class DrawGlyphListAA extends GraphicsPrimitive { int fromGlyph, int toGlyph); static { - GraphicsPrimitiveMgr.registerGeneral( + GeneralPrimitives.register( new DrawGlyphListAA(null, null, null)); } diff --git a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListColor.java b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListColor.java index 55ceaf4ce4e..262a0c16b56 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListColor.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/DrawGlyphListColor.java @@ -29,6 +29,7 @@ import sun.font.GlyphList; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; import java.awt.*; @@ -67,7 +68,7 @@ public class DrawGlyphListColor extends GraphicsPrimitive { // This instance is used only for lookup. static { - GraphicsPrimitiveMgr.registerGeneral( + GeneralPrimitives.register( new DrawGlyphListColor(null, null, null)); } diff --git a/src/java.desktop/share/classes/sun/java2d/loops/FillRect.java b/src/java.desktop/share/classes/sun/java2d/loops/FillRect.java index e12a05da0ab..0edf701c9f2 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/FillRect.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/FillRect.java @@ -31,6 +31,7 @@ package sun.java2d.loops; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * FillRect @@ -75,7 +76,7 @@ public class FillRect extends GraphicsPrimitive int x, int y, int w, int h); static { - GraphicsPrimitiveMgr.registerGeneral(new FillRect(null, null, null)); + GeneralPrimitives.register(new FillRect(null, null, null)); } protected GraphicsPrimitive makePrimitive(SurfaceType srctype, diff --git a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java index 5fb4e26f118..b029a437b35 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitiveMgr.java @@ -42,7 +42,6 @@ public final class GraphicsPrimitiveMgr { private static final boolean debugTrace = false; private static GraphicsPrimitive[] primitives; - private static GraphicsPrimitive[] generalPrimitives; private static boolean needssort = true; private static native void initIDs(Class GP, Class ST, Class CT, @@ -121,24 +120,6 @@ public final class GraphicsPrimitiveMgr { primitives = temp; } - /** - * Registers the general loop which will be used to produce specific - * primitives by the {@link GraphicsPrimitive#makePrimitive} function. - * - * @param gen the graphics primitive to be registered as the general loop - */ - public static synchronized void registerGeneral(GraphicsPrimitive gen) { - if (generalPrimitives == null) { - generalPrimitives = new GraphicsPrimitive[] {gen}; - return; - } - int len = generalPrimitives.length; - GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1]; - System.arraycopy(generalPrimitives, 0, newGen, 0, len); - newGen[len] = gen; - generalPrimitives = newGen; - } - public static synchronized GraphicsPrimitive locate(int primTypeID, SurfaceType dsttype) { @@ -165,7 +146,7 @@ public final class GraphicsPrimitiveMgr { if (prim == null) { //System.out.println("Trying general loop"); - prim = locateGeneral(primTypeID); + prim = GeneralPrimitives.locate(primTypeID); if (prim != null) { prim = prim.makePrimitive(srctype, comptype, dsttype); if (prim != null && GraphicsPrimitive.traceflags != 0) { @@ -218,20 +199,6 @@ public final class GraphicsPrimitiveMgr { return null; } - private static GraphicsPrimitive locateGeneral(int primTypeID) { - if (generalPrimitives == null) { - return null; - } - for (int i = 0; i < generalPrimitives.length; i++) { - GraphicsPrimitive prim = generalPrimitives[i]; - if (prim.getPrimTypeID() == primTypeID) { - return prim; - } - } - return null; - //throw new InternalError("No general handler registered for"+signature); - } - private static GraphicsPrimitive locate(PrimitiveSpec spec) { if (needssort) { if (GraphicsPrimitive.traceflags != 0) { @@ -274,6 +241,46 @@ public final class GraphicsPrimitiveMgr { } } + /** + * A holder for general primitives to avoid circular dependencies + * between GraphicsPrimitiveMgr and Blit/etc classes. + */ + final static class GeneralPrimitives { + + private static GraphicsPrimitive[] primitives; + + /** + * Registers the general loop which will be used to produce specific + * primitives by the {@link GraphicsPrimitive#makePrimitive} function. + * + * @param gen the graphics primitive to be registered as the general loop + */ + static synchronized void register(GraphicsPrimitive gen) { + if (primitives == null) { + primitives = new GraphicsPrimitive[]{gen}; + return; + } + int len = primitives.length; + GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1]; + System.arraycopy(primitives, 0, newGen, 0, len); + newGen[len] = gen; + primitives = newGen; + } + + static synchronized GraphicsPrimitive locate(int primTypeID) { + if (primitives == null) { + return null; + } + for (int i = 0; i < primitives.length; i++) { + GraphicsPrimitive prim = primitives[i]; + if (prim.getPrimTypeID() == primTypeID) { + return prim; + } + } + return null; + } + } + /** * Test that all of the GraphicsPrimitiveProxy objects actually * resolve to something. Throws a RuntimeException if anything diff --git a/src/java.desktop/share/classes/sun/java2d/loops/MaskBlit.java b/src/java.desktop/share/classes/sun/java2d/loops/MaskBlit.java index 414e800dd1b..c80981184b8 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/MaskBlit.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/MaskBlit.java @@ -30,6 +30,7 @@ import java.lang.ref.WeakReference; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * MaskBlit @@ -109,7 +110,7 @@ public class MaskBlit extends GraphicsPrimitive byte[] mask, int maskoff, int maskscan); static { - GraphicsPrimitiveMgr.registerGeneral(new MaskBlit(null, null, null)); + GeneralPrimitives.register(new MaskBlit(null, null, null)); } protected GraphicsPrimitive makePrimitive(SurfaceType srctype, diff --git a/src/java.desktop/share/classes/sun/java2d/loops/MaskFill.java b/src/java.desktop/share/classes/sun/java2d/loops/MaskFill.java index 108b235d585..9a04e34186f 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/MaskFill.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/MaskFill.java @@ -32,6 +32,7 @@ import sun.awt.image.BufImgSurfaceData; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; +import sun.java2d.loops.GraphicsPrimitiveMgr.GeneralPrimitives; /** * MaskFill @@ -141,7 +142,7 @@ public class MaskFill extends GraphicsPrimitive } static { - GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null)); + GeneralPrimitives.register(new MaskFill(null, null, null)); } protected GraphicsPrimitive makePrimitive(SurfaceType srctype, diff --git a/test/jdk/sun/java2d/loops/GraphicsPrimitiveMgrTest.java b/test/jdk/sun/java2d/loops/GraphicsPrimitiveMgrTest.java new file mode 100644 index 00000000000..3dacf7083d2 --- /dev/null +++ b/test/jdk/sun/java2d/loops/GraphicsPrimitiveMgrTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023, Azul Systems, Inc. All rights reserved. + * 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. + */ + +import java.util.concurrent.CountDownLatch; + +/** + * @test + * @bug 6995195 + * @summary Verify that concurrent classloading of GraphicsPrimitiveMgr + * and Blit doesn't deadlock + * @run main/othervm/timeout=20 GraphicsPrimitiveMgrTest + */ +public class GraphicsPrimitiveMgrTest { + + private static volatile CountDownLatch latch; + + private static final String C1 = "sun.java2d.loops.GraphicsPrimitiveMgr"; + private static final String C2 = "sun.java2d.loops.Blit"; + + public static void main(final String[] args) + throws ClassNotFoundException, InterruptedException + { + // force loading awt library + Class.forName("java.awt.Toolkit"); + + latch = new CountDownLatch(2); + + Thread t1 = new Thread(() -> loadClass(C1)); + Thread t2 = new Thread(() -> loadClass(C2)); + + t1.start(); + t2.start(); + + t1.join(); + t2.join(); + } + + private static void loadClass(String className) { + System.out.println(Thread.currentThread().getName() + " loading " + className); + try { + latch.countDown(); + latch.await(); + Class.forName(className); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} From a83c02fe2ca52a39018be630b6373f73361fcf3d Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 27 Apr 2023 07:26:34 +0000 Subject: [PATCH 169/288] 8306654: Disable NMT location_printing_cheap_dead_xx tests again Reviewed-by: dholmes --- .../gtest/nmt/test_nmt_locationprinting.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp b/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp index 98b4910a121..8760f22baa9 100644 --- a/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_locationprinting.cpp @@ -99,13 +99,13 @@ TEST_VM(NMT, location_printing_cheap_live_6) { test_for_live_c_heap_block(4, 0); TEST_VM(NMT, location_printing_cheap_live_7) { test_for_live_c_heap_block(4, 4); } // just outside a very small block #ifdef LINUX -TEST_VM(NMT, location_printing_cheap_dead_1) { test_for_dead_c_heap_block(2 * K, 0); } // start of payload -TEST_VM(NMT, location_printing_cheap_dead_2) { test_for_dead_c_heap_block(2 * K, -7); } // into header -TEST_VM(NMT, location_printing_cheap_dead_3) { test_for_dead_c_heap_block(2 * K, K + 1); } // into payload -TEST_VM(NMT, location_printing_cheap_dead_4) { test_for_dead_c_heap_block(2 * K, K + 2); } // into payload (check for even/odd errors) -TEST_VM(NMT, location_printing_cheap_dead_5) { test_for_dead_c_heap_block(2 * K + 1, 2 * K + 2); } // just outside payload -TEST_VM(NMT, location_printing_cheap_dead_6) { test_for_dead_c_heap_block(4, 0); } // into a very small block -TEST_VM(NMT, location_printing_cheap_dead_7) { test_for_dead_c_heap_block(4, 4); } // just outside a very small block +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_1) { test_for_dead_c_heap_block(2 * K, 0); } // start of payload +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_2) { test_for_dead_c_heap_block(2 * K, -7); } // into header +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_3) { test_for_dead_c_heap_block(2 * K, K + 1); } // into payload +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_4) { test_for_dead_c_heap_block(2 * K, K + 2); } // into payload (check for even/odd errors) +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_5) { test_for_dead_c_heap_block(2 * K + 1, 2 * K + 2); } // just outside payload +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_6) { test_for_dead_c_heap_block(4, 0); } // into a very small block +TEST_VM(NMT, DISABLED_location_printing_cheap_dead_7) { test_for_dead_c_heap_block(4, 4); } // just outside a very small block #endif static void test_for_mmap(size_t sz, ssize_t offset) { From d94ce6566d50fc0a6218adbb64d8f90e9eeb844a Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 27 Apr 2023 07:28:06 +0000 Subject: [PATCH 170/288] 8306858: Remove some remnants of CMS from SA agent Reviewed-by: shade, cjplummer, kbarrett, ysr --- .../sun/jvm/hotspot/gc/shared/CollectedHeapName.java | 3 +-- .../share/classes/sun/jvm/hotspot/gc/shared/GCCause.java | 5 ----- .../classes/sun/jvm/hotspot/gc/shared/Generation.java | 3 +-- .../share/classes/sun/jvm/hotspot/oops/Mark.java | 9 ++------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java index f6f63bd99ec..b0c0125efe8 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -33,7 +33,6 @@ public class CollectedHeapName { public static final CollectedHeapName SERIAL = new CollectedHeapName("Serial"); public static final CollectedHeapName PARALLEL = new CollectedHeapName("Parallel"); - public static final CollectedHeapName CMS = new CollectedHeapName("CMS"); public static final CollectedHeapName G1 = new CollectedHeapName("G1"); public static final CollectedHeapName EPSILON = new CollectedHeapName("Epsilon"); public static final CollectedHeapName Z = new CollectedHeapName("Z"); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java index 93aed2031e2..5bed5831259 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java @@ -46,11 +46,6 @@ public enum GCCause { _metadata_GC_threshold ("Metadata GC Threshold"), _metadata_GC_clear_soft_refs ("Metadata GC Clear Soft References"), - _cms_generation_full ("CMS Generation Full"), - _cms_initial_mark ("CMS Initial Mark"), - _cms_final_remark ("CMS Final Remark"), - _cms_concurrent_mark ("CMS Concurrent Mark"), - _old_generation_expanded_on_last_scavenge ("Old Generation Expanded On Last Scavenge"), _old_generation_too_full_to_scavenge ("Old Generation Too Full To Scavenge"), _adaptive_size_policy ("Ergonomics"), diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/Generation.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/Generation.java index 8b312e9be89..e9854c3d683 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/Generation.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/Generation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -57,7 +57,6 @@ public abstract class Generation extends VMObject { private static int NAME_DEF_NEW; private static int NAME_PAR_NEW; private static int NAME_MARK_SWEEP_COMPACT; - private static int NAME_CONCURRENT_MARK_SWEEP; private static int NAME_OTHER; static { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Mark.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Mark.java index 31f56fbf0bc..7512257a197 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Mark.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Mark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -102,11 +102,6 @@ public class Mark extends VMObject { private static long maxAge; - /* Constants in markWord used by CMS. */ - private static long cmsShift; - private static long cmsMask; - private static long sizeShift; - public Mark(Address addr) { super(addr); } @@ -202,5 +197,5 @@ public class Mark extends VMObject { } } - public long getSize() { return (long)(value() >> sizeShift); } + public long getSize() { return (long)value(); } } From 41d58533aca29d439db264540e85c4fa165f19f6 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Thu, 27 Apr 2023 08:25:40 +0000 Subject: [PATCH 171/288] 8306940: test/jdk/java/net/httpclient/XxxxInURI.java should call HttpClient::close Reviewed-by: jpai, djelinski --- .../net/httpclient/EncodedCharsInURI.java | 110 +++++---- .../net/httpclient/EscapedOctetsInURI.java | 214 +++++++++++------- .../net/httpclient/NonAsciiCharsInURI.java | 185 +++++++++------ 3 files changed, 315 insertions(+), 194 deletions(-) diff --git a/test/jdk/java/net/httpclient/EncodedCharsInURI.java b/test/jdk/java/net/httpclient/EncodedCharsInURI.java index c25fe1b6560..bcda1f32539 100644 --- a/test/jdk/java/net/httpclient/EncodedCharsInURI.java +++ b/test/jdk/java/net/httpclient/EncodedCharsInURI.java @@ -36,9 +36,6 @@ */ //* -Djdk.internal.httpclient.debug=true -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterTest; @@ -48,6 +45,7 @@ import org.testng.annotations.Test; import javax.net.ServerSocketFactory; import javax.net.ssl.SSLContext; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -57,6 +55,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.URI; import java.net.http.HttpClient; +import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpRequest.BodyPublishers; @@ -74,14 +73,11 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; -import static java.lang.String.format; -import static java.lang.System.in; +import static java.lang.System.err; import static java.lang.System.out; import static java.net.http.HttpClient.Version.HTTP_1_1; import static java.net.http.HttpClient.Version.HTTP_2; -import static java.nio.charset.StandardCharsets.US_ASCII; import static java.nio.charset.StandardCharsets.UTF_8; import static java.net.http.HttpClient.Builder.NO_PROXY; import static org.testng.Assert.assertEquals; @@ -94,8 +90,8 @@ public class EncodedCharsInURI implements HttpServerAdapters { HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) HttpTestServer https2TestServer; // HTTP/2 ( h2 ) - DummyServer httpDummyServer; // HTTP/1.1 [ 2 servers ] - DummyServer httpsDummyServer; // HTTPS/1.1 + DummyServer httpDummyServer; // HTTP/1.1 [ 2 servers ] + DummyServer httpsDummyServer; // HTTPS/1.1 String httpURI_fixed; String httpURI_chunk; String httpsURI_fixed; @@ -140,8 +136,8 @@ public class EncodedCharsInURI implements HttpServerAdapters { command.run(); } catch (Throwable t) { tasksFailed = true; - System.out.printf(now() + "Task %s failed: %s%n", id, t); - System.err.printf(now() + "Task %s failed: %s%n", id, t); + out.printf(now() + "Task %s failed: %s%n", id, t); + err.printf(now() + "Task %s failed: %s%n", id, t); FAILURES.putIfAbsent("Task " + id, t); throw t; } @@ -162,7 +158,7 @@ public class EncodedCharsInURI implements HttpServerAdapters { e.getValue().printStackTrace(out); }); if (tasksFailed) { - System.out.println("WARNING: Some tasks failed"); + out.println("WARNING: Some tasks failed"); } } finally { out.println("\n=========================\n"); @@ -201,6 +197,14 @@ public class EncodedCharsInURI implements HttpServerAdapters { return result; } + static Version version(String uri) { + if (uri.contains("/http1/") || uri.contains("/https1/")) + return HTTP_1_1; + if (uri.contains("/http2/") || uri.contains("/https2/")) + return HTTP_2; + return null; + } + private HttpClient makeNewClient() { clientCount.incrementAndGet(); return HttpClient.newBuilder() @@ -225,6 +229,14 @@ public class EncodedCharsInURI implements HttpServerAdapters { final String ENCODED = "/01%252F03/"; + record CloseableClient(HttpClient client, boolean shared) + implements Closeable { + public void close() { + if (shared) return; + client.close(); + } + } + @Test(dataProvider = "noThrows") public void testEncodedChars(String uri, boolean sameClient) throws Exception { @@ -232,29 +244,34 @@ public class EncodedCharsInURI implements HttpServerAdapters { out.printf("%n%s testEncodedChars(%s, %b)%n", now(), uri, sameClient); uri = uri + ENCODED; for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) + if (!sameClient || client == null) { client = newHttpClient(sameClient); + } + try (var cl = new CloseableClient(client, sameClient)) { + BodyPublisher bodyPublisher = BodyPublishers.ofString(uri); - BodyPublisher bodyPublisher = BodyPublishers.ofString(uri); - - HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) - .POST(bodyPublisher) - .build(); - BodyHandler handler = BodyHandlers.ofString(); - CompletableFuture> responseCF = client.sendAsync(req, handler); - HttpResponse response = responseCF.join(); - String body = response.body(); - if (!uri.contains(body)) { - System.err.println("Test failed: " + response); - throw new RuntimeException(uri + " doesn't contain '" + body + "'"); - } else { - System.out.println("Found expected " + body + " in " + uri); + HttpRequest req = HttpRequest.newBuilder(URI.create(uri)) + .POST(bodyPublisher) + .build(); + BodyHandler handler = BodyHandlers.ofString(); + CompletableFuture> responseCF = client.sendAsync(req, handler); + HttpResponse response = responseCF.join(); + String body = response.body(); + if (!uri.contains(body)) { + err.println("Test failed: " + response); + throw new RuntimeException(uri + " doesn't contain '" + body + "'"); + } else { + out.println("Found expected " + body + " in " + uri); + } + assertEquals(response.version(), version(uri)); } } } @BeforeTest public void setup() throws Exception { + out.println(now() + "begin setup"); + sslContext = new SimpleSSLContext().get(); if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); @@ -297,6 +314,7 @@ public class EncodedCharsInURI implements HttpServerAdapters { httpDummy = "http://" + httpDummyServer.serverAuthority() + "/http1/dummy/x"; httpsDummy = "https://" + httpsDummyServer.serverAuthority() + "/https1/dummy/x"; + err.println(now() + "Starting servers"); serverCount.addAndGet(6); httpTestServer.start(); @@ -305,11 +323,21 @@ public class EncodedCharsInURI implements HttpServerAdapters { https2TestServer.start(); httpDummyServer.start(); httpsDummyServer.start(); + + out.println("HTTP/1.1 dummy server (http) listening at: " + httpDummyServer.serverAuthority()); + out.println("HTTP/1.1 dummy server (TLS) listening at: " + httpsDummyServer.serverAuthority()); + out.println("HTTP/1.1 server (http) listening at: " + httpTestServer.serverAuthority()); + out.println("HTTP/1.1 server (TLS) listening at: " + httpsTestServer.serverAuthority()); + out.println("HTTP/2 server (h2c) listening at: " + http2TestServer.serverAuthority()); + out.println("HTTP/2 server (h2) listening at: " + https2TestServer.serverAuthority()); + + out.println(now() + "setup done"); + err.println(now() + "setup done"); } @AfterTest public void teardown() throws Exception { - sharedClient = null; + sharedClient.close(); httpTestServer.stop(); httpsTestServer.stop(); http2TestServer.stop(); @@ -390,14 +418,13 @@ public class EncodedCharsInURI implements HttpServerAdapters { while(!stopped) { Socket clientConnection = ss.accept(); connections.add(clientConnection); - System.out.println(now() + getName() + ": Client accepted"); + out.println(now() + getName() + ": Client accepted"); StringBuilder headers = new StringBuilder(); - Socket targetConnection = null; InputStream ccis = clientConnection.getInputStream(); OutputStream ccos = clientConnection.getOutputStream(); - System.out.println(now() + getName() + ": Reading request line"); + out.println(now() + getName() + ": Reading request line"); String requestLine = readLine(ccis); - System.out.println(now() + getName() + ": Request line: " + requestLine); + out.println(now() + getName() + ": Request line: " + requestLine); StringTokenizer tokenizer = new StringTokenizer(requestLine); String method = tokenizer.nextToken(); @@ -408,7 +435,7 @@ public class EncodedCharsInURI implements HttpServerAdapters { String hostport = serverAuthority(); uri = new URI((secure ? "https" : "http") +"://" + hostport + path); } catch (Throwable x) { - System.err.printf("Bad target address: \"%s\" in \"%s\"%n", + err.printf("Bad target address: \"%s\" in \"%s\"%n", path, requestLine); clientConnection.close(); continue; @@ -418,7 +445,7 @@ public class EncodedCharsInURI implements HttpServerAdapters { // signals the end of all headers. String line = requestLine; while (!line.equals("")) { - System.out.println(now() + getName() + ": Reading header: " + out.println(now() + getName() + ": Reading header: " + (line = readLine(ccis))); headers.append(line).append("\r\n"); } @@ -435,11 +462,11 @@ public class EncodedCharsInURI implements HttpServerAdapters { StringTokenizer tk = new StringTokenizer(cl); int len = Integer.parseInt(tk.nextToken()); assert len < b.length * 2; - System.out.println(now() + getName() + out.println(now() + getName() + ": received body: " + new String(ccis.readNBytes(len), UTF_8)); } - System.out.println(now() + out.println(now() + getName() + ": sending back " + uri); response.append("HTTP/1.1 200 OK\r\nContent-Length: ") @@ -447,21 +474,21 @@ public class EncodedCharsInURI implements HttpServerAdapters { .append("\r\n\r\n"); // Then send the 200 OK response to the client - System.out.println(now() + getName() + ": Sending " + out.println(now() + getName() + ": Sending " + response); ccos.write(response.toString().getBytes(UTF_8)); ccos.flush(); - System.out.println(now() + getName() + ": sent response headers"); + out.println(now() + getName() + ": sent response headers"); ccos.write(b); ccos.flush(); ccos.close(); - System.out.println(now() + getName() + ": sent " + b.length + " body bytes"); + out.println(now() + getName() + ": sent " + b.length + " body bytes"); connections.remove(clientConnection); clientConnection.close(); } } catch (Throwable t) { if (!stopped) { - System.out.println(now() + getName() + ": failed: " + t); + out.println(now() + getName() + ": failed: " + t); t.printStackTrace(); try { stopServer(); @@ -470,7 +497,7 @@ public class EncodedCharsInURI implements HttpServerAdapters { } } } finally { - System.out.println(now() + getName() + ": exiting"); + out.println(now() + getName() + ": exiting"); } } @@ -504,7 +531,6 @@ public class EncodedCharsInURI implements HttpServerAdapters { return new DummyServer(ss, true); } - } } diff --git a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java index 00061c1edf0..8a17cea78c4 100644 --- a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java +++ b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java @@ -32,11 +32,7 @@ * EscapedOctetsInURI */ -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -45,37 +41,43 @@ import java.net.InetSocketAddress; import java.net.URI; import javax.net.ssl.SSLContext; import java.net.http.HttpClient; +import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import jdk.httpclient.test.lib.http2.Http2TestServer; -import jdk.httpclient.test.lib.http2.Http2TestExchange; -import jdk.httpclient.test.lib.http2.Http2Handler; + +import jdk.httpclient.test.lib.common.HttpServerAdapters; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; + +import static java.lang.System.err; import static java.lang.System.out; +import static java.net.http.HttpClient.Version.HTTP_1_1; +import static java.net.http.HttpClient.Version.HTTP_2; import static java.nio.charset.StandardCharsets.US_ASCII; import static java.net.http.HttpClient.Builder.NO_PROXY; import static org.testng.Assert.assertEquals; -public class EscapedOctetsInURI { +public class EscapedOctetsInURI implements HttpServerAdapters { SSLContext sslContext; - HttpServer httpTestServer; // HTTP/1.1 [ 4 servers ] - HttpsServer httpsTestServer; // HTTPS/1.1 - Http2TestServer http2TestServer; // HTTP/2 ( h2c ) - Http2TestServer https2TestServer; // HTTP/2 ( h2 ) + HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] + HttpTestServer httpsTestServer; // HTTPS/1.1 + HttpTestServer http2TestServer; // HTTP/2 ( h2c ) + HttpTestServer https2TestServer; // HTTP/2 ( h2 ) String httpURI; String httpsURI; String http2URI; String https2URI; + private volatile HttpClient sharedClient; + static final String[][] pathsAndQueryStrings = new String[][] { // partial-path URI query { "/001/noSpace", "?noQuotedOctets" }, @@ -110,6 +112,52 @@ public class EscapedOctetsInURI { static final int ITERATION_COUNT = 3; // checks upgrade and re-use + static final long start = System.nanoTime(); + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } + + static Version version(String uri) { + if (uri.contains("/http1/") || uri.contains("/https1/")) + return HTTP_1_1; + if (uri.contains("/http2/") || uri.contains("/https2/")) + return HTTP_2; + return null; + } + + + private HttpClient makeNewClient() { + return HttpClient.newBuilder() + .proxy(NO_PROXY) + .sslContext(sslContext) + .build(); + } + + HttpClient newHttpClient(boolean share) { + if (!share) return makeNewClient(); + HttpClient shared = sharedClient; + if (shared != null) return shared; + synchronized (this) { + shared = sharedClient; + if (shared == null) { + shared = sharedClient = makeNewClient(); + } + return shared; + } + } + + record CloseableClient(HttpClient client, boolean shared) + implements Closeable { + public void close() { + if (shared) return; + client.close(); + } + } + @Test(dataProvider = "variants") void test(String uriString, boolean sameClient) throws Exception { System.out.println("\n--- Starting "); @@ -121,122 +169,114 @@ public class EscapedOctetsInURI { HttpClient client = null; for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); + if (!sameClient || client == null) { + client = newHttpClient(sameClient); + } - HttpRequest request = HttpRequest.newBuilder(uri).build(); - HttpResponse resp = client.send(request, BodyHandlers.ofString()); + try (var cl = new CloseableClient(client, sameClient)) { + HttpRequest request = HttpRequest.newBuilder(uri).build(); + HttpResponse resp = client.send(request, BodyHandlers.ofString()); - out.println("Got response: " + resp); - out.println("Got body: " + resp.body()); - assertEquals(resp.statusCode(), 200, - "Expected 200, got:" + resp.statusCode()); + out.println("Got response: " + resp); + out.println("Got body: " + resp.body()); + assertEquals(resp.statusCode(), 200, + "Expected 200, got:" + resp.statusCode()); - // the response body should contain the exact escaped request URI - URI retrievedURI = URI.create(resp.body()); - assertEquals(retrievedURI.getRawPath(), uri.getRawPath()); - assertEquals(retrievedURI.getRawQuery(), uri.getRawQuery()); + // the response body should contain the exact escaped request URI + URI retrievedURI = URI.create(resp.body()); + assertEquals(retrievedURI.getRawPath(), uri.getRawPath()); + assertEquals(retrievedURI.getRawQuery(), uri.getRawQuery()); + assertEquals(resp.version(), version(uriString)); + } } } @Test(dataProvider = "variants") - void testAsync(String uriString, boolean sameClient) { + void testAsync(String uriString, boolean sameClient) throws Exception { System.out.println("\n--- Starting "); URI uri = URI.create(uriString); HttpClient client = null; for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); + if (!sameClient || client == null) { + client = newHttpClient(sameClient); + } - HttpRequest request = HttpRequest.newBuilder(uri).build(); - - client.sendAsync(request, BodyHandlers.ofString()) - .thenApply(response -> { - out.println("Got response: " + response); - out.println("Got body: " + response.body()); - assertEquals(response.statusCode(), 200); - return response.body(); }) - .thenApply(body -> URI.create(body)) - .thenAccept(retrievedURI -> { - // the body should contain the exact escaped request URI - assertEquals(retrievedURI.getRawPath(), uri.getRawPath()); - assertEquals(retrievedURI.getRawQuery(), uri.getRawQuery()); }) - .join(); + try (var cl = new CloseableClient(client, sameClient)) { + HttpRequest request = HttpRequest.newBuilder(uri).build(); + client.sendAsync(request, BodyHandlers.ofString()) + .thenApply(response -> { + out.println("Got response: " + response); + out.println("Got body: " + response.body()); + assertEquals(response.statusCode(), 200); + assertEquals(response.version(), version(uriString)); + return response.body(); + }) + .thenApply(body -> URI.create(body)) + .thenAccept(retrievedURI -> { + // the body should contain the exact escaped request URI + assertEquals(retrievedURI.getRawPath(), uri.getRawPath()); + assertEquals(retrievedURI.getRawQuery(), uri.getRawQuery()); + }).join(); + } } } - static String serverAuthority(HttpServer server) { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + server.getAddress().getPort(); - } - @BeforeTest public void setup() throws Exception { + out.println(now() + "begin setup"); + sslContext = new SimpleSSLContext().get(); if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); - httpTestServer = HttpServer.create(sa, 0); - httpTestServer.createContext("/http1", new Http1ASCIIUriStringHandler()); - httpURI = "http://" + serverAuthority(httpTestServer) + "/http1"; + httpTestServer = HttpTestServer.create(HTTP_1_1); + httpTestServer.addHandler(new HttpASCIIUriStringHandler(), "/http1/get"); + httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/get"; - httpsTestServer = HttpsServer.create(sa, 0); - httpsTestServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); - httpsTestServer.createContext("/https1", new Http1ASCIIUriStringHandler()); - httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1"; + httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); + httpsTestServer.addHandler(new HttpASCIIUriStringHandler(), "/https1/get"); + httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/get"; - http2TestServer = new Http2TestServer("localhost", false, 0); - http2TestServer.addHandler(new HttpASCIIUriStringHandler(), "/http2"); - http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; + http2TestServer = HttpTestServer.create(HTTP_2); + http2TestServer.addHandler(new HttpASCIIUriStringHandler(), "/http2/get"); + http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/get"; - https2TestServer = new Http2TestServer("localhost", true, sslContext); - https2TestServer.addHandler(new HttpASCIIUriStringHandler(), "/https2"); - https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; + https2TestServer = HttpTestServer.create(HTTP_2, sslContext); + https2TestServer.addHandler(new HttpASCIIUriStringHandler(), "/https2/get"); + https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/get"; + err.println(now() + "Starting servers"); httpTestServer.start(); httpsTestServer.start(); http2TestServer.start(); https2TestServer.start(); + + out.println("HTTP/1.1 server (http) listening at: " + httpTestServer.serverAuthority()); + out.println("HTTP/1.1 server (TLS) listening at: " + httpsTestServer.serverAuthority()); + out.println("HTTP/2 server (h2c) listening at: " + http2TestServer.serverAuthority()); + out.println("HTTP/2 server (h2) listening at: " + https2TestServer.serverAuthority()); + + out.println(now() + "setup done"); + err.println(now() + "setup done"); } @AfterTest public void teardown() throws Exception { - httpTestServer.stop(0); - httpsTestServer.stop(0); + sharedClient.close(); + httpTestServer.stop(); + httpsTestServer.stop(); http2TestServer.stop(); https2TestServer.stop(); } /** A handler that returns as its body the exact escaped request URI. */ - static class Http1ASCIIUriStringHandler implements HttpHandler { + static class HttpASCIIUriStringHandler implements HttpTestHandler { @Override - public void handle(HttpExchange t) throws IOException { + public void handle(HttpTestExchange t) throws IOException { String asciiUriString = t.getRequestURI().toASCIIString(); - out.println("Http1ASCIIUriString received, asciiUriString: " + asciiUriString); - try (InputStream is = t.getRequestBody(); - OutputStream os = t.getResponseBody()) { - is.readAllBytes(); - byte[] bytes = asciiUriString.getBytes(US_ASCII); - t.sendResponseHeaders(200, bytes.length); - os.write(bytes); - } - } - } - - /** A handler that returns as its body the exact escaped request URI. */ - static class HttpASCIIUriStringHandler implements Http2Handler { - @Override - public void handle(Http2TestExchange t) throws IOException { - String asciiUriString = t.getRequestURI().toASCIIString(); - out.println("Http2ASCIIUriString received, asciiUriString: " + asciiUriString); + out.println("HttpASCIIUriString received, asciiUriString: " + asciiUriString); try (InputStream is = t.getRequestBody(); OutputStream os = t.getResponseBody()) { is.readAllBytes(); diff --git a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java index 84519feeac1..56a35119ae2 100644 --- a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java +++ b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java @@ -34,17 +34,14 @@ * NonAsciiCharsInURI */ -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; +import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.URI; import javax.net.ssl.SSLContext; import java.net.http.HttpClient; +import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; @@ -52,7 +49,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -78,6 +74,8 @@ public class NonAsciiCharsInURI implements HttpServerAdapters { String http2URI; String https2URI; + private volatile HttpClient sharedClient; + // € = '\u20AC' => 0xE20x820xAC static final String[][] pathsAndQueryStrings = new String[][] { // partial-path @@ -110,6 +108,51 @@ public class NonAsciiCharsInURI implements HttpServerAdapters { return list.stream().toArray(Object[][]::new); } + static final long start = System.nanoTime(); + public static String now() { + long now = System.nanoTime() - start; + long secs = now / 1000_000_000; + long mill = (now % 1000_000_000) / 1000_000; + long nan = now % 1000_000; + return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan); + } + + static Version version(String uri) { + if (uri.contains("/http1/") || uri.contains("/https1/")) + return HTTP_1_1; + if (uri.contains("/http2/") || uri.contains("/https2/")) + return HTTP_2; + return null; + } + + private HttpClient makeNewClient() { + return HttpClient.newBuilder() + .proxy(NO_PROXY) + .sslContext(sslContext) + .build(); + } + + HttpClient newHttpClient(boolean share) { + if (!share) return makeNewClient(); + HttpClient shared = sharedClient; + if (shared != null) return shared; + synchronized (this) { + shared = sharedClient; + if (shared == null) { + shared = sharedClient = makeNewClient(); + } + return shared; + } + } + + record CloseableClient(HttpClient client, boolean shared) + implements Closeable { + public void close() { + if (shared) return; + client.close(); + } + } + static final int ITERATION_COUNT = 3; // checks upgrade and re-use @Test(dataProvider = "variants") @@ -122,106 +165,118 @@ public class NonAsciiCharsInURI implements HttpServerAdapters { HttpClient client = null; for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); + if (!sameClient || client == null) { + client = newHttpClient(sameClient); + } - HttpRequest request = HttpRequest.newBuilder(uri).build(); - HttpResponse resp = client.send(request, BodyHandlers.ofString()); - out.println("Got response: " + resp); - out.println("Got body: " + resp.body()); - assertEquals(resp.statusCode(), 200, - "Expected 200, got:" + resp.statusCode()); + try (var cl = new CloseableClient(client, sameClient)) { + HttpRequest request = HttpRequest.newBuilder(uri).build(); + HttpResponse resp = client.send(request, BodyHandlers.ofString()); - // the response body should contain the toASCIIString - // representation of the URI - String expectedURIString = uri.toASCIIString(); - if (!expectedURIString.contains(resp.body())) { - err.println("Test failed: " + resp); - throw new AssertionError(expectedURIString + - " does not contain '" + resp.body() + "'"); - } else { - out.println("Found expected " + resp.body() + " in " + expectedURIString); + out.println("Got response: " + resp); + out.println("Got body: " + resp.body()); + assertEquals(resp.statusCode(), 200, + "Expected 200, got:" + resp.statusCode()); + + // the response body should contain the toASCIIString + // representation of the URI + String expectedURIString = uri.toASCIIString(); + if (!expectedURIString.contains(resp.body())) { + err.println("Test failed: " + resp); + throw new AssertionError(expectedURIString + + " does not contain '" + resp.body() + "'"); + } else { + out.println("Found expected " + resp.body() + " in " + expectedURIString); + } + assertEquals(resp.version(), version(uriString)); } } } @Test(dataProvider = "variants") - void testAsync(String uriString, boolean sameClient) { + void testAsync(String uriString, boolean sameClient) throws Exception { out.println("\n--- Starting "); URI uri = URI.create(uriString); HttpClient client = null; for (int i=0; i< ITERATION_COUNT; i++) { - if (!sameClient || client == null) - client = HttpClient.newBuilder() - .proxy(NO_PROXY) - .sslContext(sslContext) - .build(); + if (!sameClient || client == null) { + client = newHttpClient(sameClient); + } - HttpRequest request = HttpRequest.newBuilder(uri).build(); + try (var cl = new CloseableClient(client, sameClient)) { + HttpRequest request = HttpRequest.newBuilder(uri).build(); - client.sendAsync(request, BodyHandlers.ofString()) - .thenApply(response -> { - out.println("Got response: " + response); - out.println("Got body: " + response.body()); - assertEquals(response.statusCode(), 200); - return response.body(); }) - .thenAccept(body -> { - // the response body should contain the toASCIIString - // representation of the URI - String expectedURIString = uri.toASCIIString(); - if (!expectedURIString.contains(body)) { - err.println("Test failed: " + body); - throw new AssertionError(expectedURIString + - " does not contain '" + body + "'"); - } else { - out.println("Found expected " + body + " in " + client.sendAsync(request, BodyHandlers.ofString()) + .thenApply(response -> { + out.println("Got response: " + response); + out.println("Got body: " + response.body()); + assertEquals(response.statusCode(), 200); + assertEquals(response.version(), version(uriString)); + return response.body(); + }) + .thenAccept(body -> { + // the response body should contain the toASCIIString + // representation of the URI + String expectedURIString = uri.toASCIIString(); + if (!expectedURIString.contains(body)) { + err.println("Test failed: " + body); + throw new AssertionError(expectedURIString + + " does not contain '" + body + "'"); + } else { + out.println("Found expected " + body + " in " + expectedURIString); - } }) - .join(); + } + }) + .join(); + } } } - static String serverAuthority(HttpTestServer server) { - return InetAddress.getLoopbackAddress().getHostName() + ":" - + server.getAddress().getPort(); - } - @BeforeTest public void setup() throws Exception { + out.println(now() + "begin setup"); + sslContext = new SimpleSSLContext().get(); if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); HttpTestHandler handler = new HttpUriStringHandler(); httpTestServer = HttpTestServer.create(HTTP_1_1); - httpTestServer.addHandler(handler, "/http1"); - httpURI = "http://" + serverAuthority(httpTestServer) + "/http1"; + httpTestServer.addHandler(handler, "/http1/get"); + httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/get"; httpsTestServer = HttpTestServer.create(HTTP_1_1, sslContext); - httpsTestServer.addHandler(handler, "/https1"); - httpsURI = "https://" + serverAuthority(httpsTestServer) + "/https1"; + httpsTestServer.addHandler(handler, "/https1/get"); + httpsURI = "https://" + httpsTestServer.serverAuthority() + "/https1/get"; http2TestServer = HttpTestServer.create(HTTP_2); - http2TestServer.addHandler(handler, "/http2"); - http2URI = "http://" + http2TestServer.serverAuthority() + "/http2"; + http2TestServer.addHandler(handler, "/http2/get"); + http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/get"; https2TestServer = HttpTestServer.create(HTTP_2, sslContext); - https2TestServer.addHandler(handler, "/https2"); - https2URI = "https://" + https2TestServer.serverAuthority() + "/https2"; + https2TestServer.addHandler(handler, "/https2/get"); + https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/get"; + err.println(now() + "Starting servers"); httpTestServer.start(); httpsTestServer.start(); http2TestServer.start(); https2TestServer.start(); + + out.println("HTTP/1.1 server (http) listening at: " + httpTestServer.serverAuthority()); + out.println("HTTP/1.1 server (TLS) listening at: " + httpsTestServer.serverAuthority()); + out.println("HTTP/2 server (h2c) listening at: " + http2TestServer.serverAuthority()); + out.println("HTTP/2 server (h2) listening at: " + https2TestServer.serverAuthority()); + + out.println(now() + "setup done"); + err.println(now() + "setup done"); } @AfterTest public void teardown() throws Exception { + sharedClient.close(); httpTestServer.stop(); httpsTestServer.stop(); http2TestServer.stop(); @@ -233,7 +288,7 @@ public class NonAsciiCharsInURI implements HttpServerAdapters { @Override public void handle(HttpTestExchange t) throws IOException { String uri = t.getRequestURI().toString(); - out.println("Http1UriStringHandler received, uri: " + uri); + out.println("HttpUriStringHandler received, uri: " + uri); try (InputStream is = t.getRequestBody(); OutputStream os = t.getResponseBody()) { is.readAllBytes(); From cbccc4c8172797ea2f1b7c301d00add3f517546d Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Thu, 27 Apr 2023 09:00:58 +0000 Subject: [PATCH 172/288] 8304265: Implementation of Foreign Function and Memory API (Third Preview) Co-authored-by: Maurizio Cimadamore Co-authored-by: Jorn Vernee Co-authored-by: Paul Sandoz Co-authored-by: Feilong Jiang Co-authored-by: Per Minborg Reviewed-by: erikj, jvernee, vlivanov, psandoz --- make/autoconf/configure.ac | 4 + make/autoconf/jdk-options.m4 | 19 + make/autoconf/libraries.m4 | 2 +- make/autoconf/spec.gmk.in | 3 + make/conf/jib-profiles.js | 46 +- make/data/hotspot-symbols/symbols-shared | 3 +- make/devkit/createLibffiBundle.sh | 111 ++ make/modules/java.base/Lib.gmk | 17 +- .../cpu/aarch64/downcallLinker_aarch64.cpp | 154 +-- .../cpu/aarch64/foreignGlobals_aarch64.cpp | 6 +- src/hotspot/cpu/arm/downcallLinker_arm.cpp | 5 +- src/hotspot/cpu/arm/foreignGlobals_arm.cpp | 6 +- src/hotspot/cpu/ppc/downcallLinker_ppc.cpp | 5 +- src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp | 6 +- .../cpu/riscv/downcallLinker_riscv.cpp | 150 +-- .../cpu/riscv/foreignGlobals_riscv.cpp | 6 +- src/hotspot/cpu/s390/downcallLinker_s390.cpp | 5 +- src/hotspot/cpu/s390/foreignGlobals_s390.cpp | 6 +- src/hotspot/cpu/x86/downcallLinker_x86_32.cpp | 5 +- src/hotspot/cpu/x86/downcallLinker_x86_64.cpp | 170 +-- src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp | 6 +- src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp | 6 +- src/hotspot/cpu/zero/downcallLinker_zero.cpp | 5 +- src/hotspot/cpu/zero/foreignGlobals_zero.cpp | 6 +- .../cpu/zero/globalDefinitions_zero.hpp | 4 +- src/hotspot/share/include/jvm.h | 3 + src/hotspot/share/prims/downcallLinker.cpp | 6 +- src/hotspot/share/prims/downcallLinker.hpp | 5 +- src/hotspot/share/prims/foreignGlobals.hpp | 4 +- src/hotspot/share/prims/jvm.cpp | 5 + src/hotspot/share/prims/nativeEntryPoint.cpp | 10 +- src/hotspot/share/prims/upcallLinker.cpp | 1 + .../java/lang/foreign/AddressLayout.java | 130 +++ .../classes/java/lang/foreign/Arena.java | 257 ++++- .../java/lang/foreign/FunctionDescriptor.java | 4 +- .../java/lang/foreign/GroupLayout.java | 11 +- .../classes/java/lang/foreign/Linker.java | 587 +++++++--- .../java/lang/foreign/MemoryLayout.java | 161 +-- .../java/lang/foreign/MemorySegment.java | 1008 +++++++++-------- .../java/lang/foreign/PaddingLayout.java | 7 + .../java/lang/foreign/SegmentAllocator.java | 38 +- .../java/lang/foreign/SegmentScope.java | 132 --- .../java/lang/foreign/SequenceLayout.java | 15 +- .../java/lang/foreign/StructLayout.java | 15 +- .../java/lang/foreign/SymbolLookup.java | 83 +- .../java/lang/foreign/UnionLayout.java | 9 +- .../classes/java/lang/foreign/VaList.java | 352 ------ .../java/lang/foreign/ValueLayout.java | 164 ++- .../java/lang/foreign/package-info.java | 160 +-- .../share/classes/java/nio/Buffer.java | 4 +- .../java/nio/channels/FileChannel.java | 24 +- .../foreign/AbstractMemorySegmentImpl.java | 101 +- .../classes/jdk/internal/foreign/CABI.java | 84 +- .../foreign/HeapMemorySegmentImpl.java | 98 +- .../jdk/internal/foreign/LayoutPath.java | 110 +- .../foreign/MappedMemorySegmentImpl.java | 54 +- .../internal/foreign/MemorySessionImpl.java | 39 +- .../foreign/NativeMemorySegmentImpl.java | 43 +- .../internal/foreign/SlicingAllocator.java | 6 +- .../jdk/internal/foreign/SystemLookup.java | 42 +- .../classes/jdk/internal/foreign/Utils.java | 94 +- .../internal/foreign/abi/AbstractLinker.java | 22 +- .../jdk/internal/foreign/abi/Binding.java | 186 +-- .../foreign/abi/BindingInterpreter.java | 11 +- .../foreign/abi/BindingSpecializer.java | 61 +- .../internal/foreign/abi/CallingSequence.java | 6 +- .../internal/foreign/abi/CapturableState.java | 31 +- .../internal/foreign/abi/DowncallLinker.java | 25 +- .../internal/foreign/abi/LinkerOptions.java | 56 +- .../foreign/abi/NativeEntryPoint.java | 17 +- .../jdk/internal/foreign/abi/SharedUtils.java | 175 ++- .../internal/foreign/abi/UpcallLinker.java | 8 +- .../jdk/internal/foreign/abi/UpcallStubs.java | 10 +- .../abi/aarch64/AArch64Architecture.java | 5 +- .../foreign/abi/aarch64/CallArranger.java | 31 +- .../abi/aarch64/linux/LinuxAArch64Linker.java | 21 +- .../abi/aarch64/linux/LinuxAArch64VaList.java | 568 ---------- .../abi/aarch64/macos/MacOsAArch64Linker.java | 21 +- .../abi/aarch64/macos/MacOsAArch64VaList.java | 257 ----- .../aarch64/windows/WindowsAArch64Linker.java | 22 +- .../aarch64/windows/WindowsAArch64VaList.java | 261 ----- .../internal/foreign/abi/fallback/FFIABI.java | 42 + .../foreign/abi/fallback/FFIStatus.java | 52 + .../foreign/abi/fallback/FFIType.java | 146 +++ .../foreign/abi/fallback/FallbackLinker.java | 272 +++++ .../foreign/abi/fallback/LibFallback.java | 219 ++++ .../abi/riscv64/RISCV64Architecture.java | 5 +- .../linux/LinuxRISCV64CallArranger.java | 13 +- .../abi/riscv64/linux/LinuxRISCV64Linker.java | 22 +- .../abi/riscv64/linux/LinuxRISCV64VaList.java | 302 ----- .../foreign/abi/x64/X86_64Architecture.java | 9 +- .../foreign/abi/x64/sysv/CallArranger.java | 20 +- .../foreign/abi/x64/sysv/SysVVaList.java | 479 -------- .../foreign/abi/x64/sysv/SysVx64Linker.java | 21 +- .../foreign/abi/x64/windows/CallArranger.java | 13 +- .../foreign/abi/x64/windows/WinVaList.java | 246 ---- .../abi/x64/windows/Windowsx64Linker.java | 22 +- .../foreign/layout/AbstractGroupLayout.java | 59 +- .../foreign/layout/AbstractLayout.java | 68 +- .../foreign/layout/MemoryLayoutUtil.java | 16 +- .../foreign/layout/PaddingLayoutImpl.java | 18 +- .../foreign/layout/SequenceLayoutImpl.java | 28 +- .../foreign/layout/StructLayoutImpl.java | 21 +- .../foreign/layout/UnionLayoutImpl.java | 18 +- .../internal/foreign/layout/ValueLayouts.java | 315 +++--- .../jdk/internal/javac/PreviewFeature.java | 2 +- .../jdk/internal/vm/ForeignLinkerSupport.java | 44 + .../classes/sun/nio/ch/FileChannelImpl.java | 12 +- .../native/libfallbackLinker/fallbackLinker.c | 203 ++++ .../native/libjava/ForeignLinkerSupport.c | 34 + test/jdk/TEST.groups | 1 + test/jdk/java/foreign/LibraryLookupTest.java | 40 +- .../MemoryLayoutPrincipalTotalityTest.java | 6 +- .../MemoryLayoutTypeRetentionTest.java | 61 +- test/jdk/java/foreign/NativeTestHelper.java | 11 +- .../java/foreign/SafeFunctionAccessTest.java | 46 +- test/jdk/java/foreign/StdLibTest.java | 87 +- .../jdk/java/foreign/TestAdaptVarHandles.java | 40 +- .../java/foreign/TestAddressDereference.java | 201 ++++ test/jdk/java/foreign/TestArrays.java | 23 +- test/jdk/java/foreign/TestByteBuffer.java | 229 ++-- .../foreign/TestClassLoaderFindNative.java | 9 +- .../jdk/java/foreign/TestDereferencePath.java | 141 +++ test/jdk/java/foreign/TestDowncallScope.java | 12 +- test/jdk/java/foreign/TestDowncallStack.java | 4 +- .../java/foreign/TestFunctionDescriptor.java | 21 +- test/jdk/java/foreign/TestHandshake.java | 30 +- test/jdk/java/foreign/TestHeapAlignment.java | 9 +- test/jdk/java/foreign/TestIllegalLink.java | 48 +- test/jdk/java/foreign/TestIntrinsics.java | 4 +- .../java/foreign/TestLargeSegmentCopy.java | 6 +- test/jdk/java/foreign/TestLayoutPaths.java | 191 +--- test/jdk/java/foreign/TestLayouts.java | 199 +++- test/jdk/java/foreign/TestMemoryAccess.java | 21 +- .../foreign/TestMemoryAccessInstance.java | 39 +- .../jdk/java/foreign/TestMemoryAlignment.java | 39 +- test/jdk/java/foreign/TestMemorySession.java | 171 +-- test/jdk/java/foreign/TestMismatch.java | 25 +- test/jdk/java/foreign/TestNULLAddress.java | 6 +- test/jdk/java/foreign/TestNative.java | 39 +- test/jdk/java/foreign/TestNulls.java | 60 +- .../java/foreign/TestScopedOperations.java | 109 +- .../java/foreign/TestSegmentAllocators.java | 54 +- test/jdk/java/foreign/TestSegmentCopy.java | 6 +- test/jdk/java/foreign/TestSegmentOffset.java | 6 +- test/jdk/java/foreign/TestSegmentOverlap.java | 10 +- test/jdk/java/foreign/TestSegments.java | 140 ++- test/jdk/java/foreign/TestSharedAccess.java | 18 +- test/jdk/java/foreign/TestSlices.java | 117 +- test/jdk/java/foreign/TestSpliterator.java | 44 +- test/jdk/java/foreign/TestStringEncoding.java | 4 +- test/jdk/java/foreign/TestTypeAccess.java | 18 +- .../java/foreign/TestUnsupportedLinker.java | 22 +- test/jdk/java/foreign/TestUpcallAsync.java | 6 +- .../jdk/java/foreign/TestUpcallException.java | 86 +- .../jdk/java/foreign/TestUpcallHighArity.java | 4 +- test/jdk/java/foreign/TestUpcallScope.java | 4 +- test/jdk/java/foreign/TestUpcallStack.java | 4 +- .../java/foreign/TestUpcallStructScope.java | 18 +- test/jdk/java/foreign/TestVarArgs.java | 17 +- .../foreign/TestVarHandleCombinators.java | 10 +- test/jdk/java/foreign/ThrowingUpcall.java | 95 -- test/jdk/java/foreign/UpcallTestHelper.java | 18 +- .../arraystructs/TestArrayStructs.java | 2 +- .../TestLayoutEquality.java | 18 +- .../TestLinuxAArch64CallArranger.java | 3 +- .../TestMacOsAArch64CallArranger.java | 3 +- .../callarranger/TestRISCV64CallArranger.java | 34 +- .../callarranger/TestSysVCallArranger.java | 65 +- .../TestWindowsAArch64CallArranger.java | 6 +- .../callarranger/TestWindowsCallArranger.java | 6 +- .../platform}/PlatformLayouts.java | 107 +- .../TestCaptureCallState.java | 11 +- .../channels/AbstractChannelsTest.java | 15 +- .../channels/TestAsyncSocketChannels.java | 26 +- .../foreign/channels/TestSocketChannels.java | 23 +- .../foreign/dontrelease/TestDontRelease.java | 8 +- .../openjdk/foreigntest/PanamaMainDirect.java | 6 +- .../openjdk/foreigntest/PanamaMainInvoke.java | 10 +- .../foreigntest/PanamaMainReflection.java | 8 +- .../handle/invoker/MethodHandleInvoker.java | 12 +- .../handle/lookup/MethodHandleLookup.java | 27 +- test/jdk/java/foreign/libAddressDereference.c | 37 + test/jdk/java/foreign/nested/TestNested.java | 2 +- .../java/foreign/normalize/TestNormalize.java | 16 +- .../foreign/stackwalk/TestAsyncStackWalk.java | 6 +- .../stackwalk/TestReentrantUpcalls.java | 4 +- .../java/foreign/stackwalk/TestStackWalk.java | 6 +- .../jdk/java/foreign/trivial/TestTrivial.java | 98 ++ .../foreign/trivial/TestTrivialUpcall.java | 64 ++ .../java/foreign/trivial/libTrivial.c} | 34 +- .../foreign/upcalldeopt/TestUpcallDeopt.java | 6 +- test/jdk/java/foreign/valist/VaListTest.java | 933 --------------- test/jdk/java/foreign/valist/libVaList.c | 188 --- .../AttachCurrentThread/ImplicitAttach.java | 6 +- .../invoke/VarHandles/VarHandleTestExact.java | 10 +- .../channels/FileChannel/LargeMapTest.java | 4 +- .../FileChannel/MapToMemorySegmentTest.java | 13 +- .../java/util/stream/SpliteratorTest.java | 2 +- .../vector/AbstractVectorLoadStoreTest.java | 6 +- .../vector/Byte128VectorLoadStoreTests.java | 18 +- .../vector/Byte256VectorLoadStoreTests.java | 18 +- .../vector/Byte512VectorLoadStoreTests.java | 18 +- .../vector/Byte64VectorLoadStoreTests.java | 18 +- .../vector/ByteMaxVectorLoadStoreTests.java | 18 +- .../vector/Double128VectorLoadStoreTests.java | 18 +- .../vector/Double256VectorLoadStoreTests.java | 18 +- .../vector/Double512VectorLoadStoreTests.java | 18 +- .../vector/Double64VectorLoadStoreTests.java | 18 +- .../vector/DoubleMaxVectorLoadStoreTests.java | 18 +- .../vector/Float128VectorLoadStoreTests.java | 18 +- .../vector/Float256VectorLoadStoreTests.java | 18 +- .../vector/Float512VectorLoadStoreTests.java | 18 +- .../vector/Float64VectorLoadStoreTests.java | 18 +- .../vector/FloatMaxVectorLoadStoreTests.java | 18 +- .../vector/Int128VectorLoadStoreTests.java | 18 +- .../vector/Int256VectorLoadStoreTests.java | 18 +- .../vector/Int512VectorLoadStoreTests.java | 18 +- .../vector/Int64VectorLoadStoreTests.java | 18 +- .../vector/IntMaxVectorLoadStoreTests.java | 18 +- .../vector/Long128VectorLoadStoreTests.java | 18 +- .../vector/Long256VectorLoadStoreTests.java | 18 +- .../vector/Long512VectorLoadStoreTests.java | 18 +- .../vector/Long64VectorLoadStoreTests.java | 18 +- .../vector/LongMaxVectorLoadStoreTests.java | 18 +- .../vector/Short128VectorLoadStoreTests.java | 18 +- .../vector/Short256VectorLoadStoreTests.java | 18 +- .../vector/Short512VectorLoadStoreTests.java | 18 +- .../vector/Short64VectorLoadStoreTests.java | 18 +- .../vector/ShortMaxVectorLoadStoreTests.java | 18 +- .../templates/X-LoadStoreTest.java.template | 18 +- .../lang/foreign/BulkMismatchAcquire.java | 165 --- .../bench/java/lang/foreign/BulkOps.java | 19 +- .../bench/java/lang/foreign/CLayouts.java | 9 +- .../lang/foreign/CallOverheadConstant.java | 10 + .../java/lang/foreign/CallOverheadHelper.java | 47 +- .../lang/foreign/CallOverheadVirtual.java | 10 + .../bench/java/lang/foreign/JavaLayouts.java | 1 - .../bench/java/lang/foreign/LinkUpcall.java | 7 +- .../java/lang/foreign/LoopOverConstant.java | 6 +- .../bench/java/lang/foreign/LoopOverNew.java | 17 +- .../lang/foreign/LoopOverNonConstant.java | 4 +- .../lang/foreign/LoopOverNonConstantFP.java | 6 +- .../lang/foreign/LoopOverNonConstantHeap.java | 5 +- .../foreign/LoopOverNonConstantMapped.java | 4 +- .../foreign/LoopOverNonConstantShared.java | 4 +- .../java/lang/foreign/LoopOverOfAddress.java | 8 +- .../foreign/LoopOverPollutedSegments.java | 10 +- .../java/lang/foreign/LoopOverSlice.java | 4 +- .../lang/foreign/MemorySegmentVsBits.java | 158 +++ .../java/lang/foreign/MemorySessionClose.java | 11 +- .../bench/java/lang/foreign/ParallelSum.java | 10 +- .../java/lang/foreign/PointerInvoke.java | 54 +- .../bench/java/lang/foreign/QSort.java | 13 +- .../bench/java/lang/foreign/StrLenTest.java | 63 +- .../java/lang/foreign/TestLoadBytes.java | 5 +- .../java/lang/foreign/UnrolledAccess.java | 8 +- .../bench/java/lang/foreign/Upcalls.java | 9 +- .../bench/java/lang/foreign/VaList.java | 84 -- .../java/lang/foreign/VarHandleExact.java | 4 +- .../openjdk/bench/java/lang/foreign/libPtr.c | 18 +- .../lang/foreign/pointers/NativeType.java | 6 +- .../lang/foreign/pointers/PointerBench.java | 7 +- .../foreign/points/support/PanamaPoint.java | 11 +- .../vector/MemorySegmentVectorAccess.java | 8 +- .../incubator/vector/TestLoadStoreBytes.java | 11 +- .../incubator/vector/TestLoadStoreShorts.java | 11 +- 267 files changed, 6947 insertions(+), 8029 deletions(-) create mode 100644 make/devkit/createLibffiBundle.sh create mode 100644 src/java.base/share/classes/java/lang/foreign/AddressLayout.java delete mode 100644 src/java.base/share/classes/java/lang/foreign/SegmentScope.java delete mode 100644 src/java.base/share/classes/java/lang/foreign/VaList.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/linux/LinuxAArch64VaList.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/macos/MacOsAArch64VaList.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/windows/WindowsAArch64VaList.java create mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FFIABI.java create mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FFIStatus.java create mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FFIType.java create mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java create mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/riscv64/linux/LinuxRISCV64VaList.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/SysVVaList.java delete mode 100644 src/java.base/share/classes/jdk/internal/foreign/abi/x64/windows/WinVaList.java create mode 100644 src/java.base/share/classes/jdk/internal/vm/ForeignLinkerSupport.java create mode 100644 src/java.base/share/native/libfallbackLinker/fallbackLinker.c create mode 100644 src/java.base/share/native/libjava/ForeignLinkerSupport.c create mode 100644 test/jdk/java/foreign/TestAddressDereference.java create mode 100644 test/jdk/java/foreign/TestDereferencePath.java delete mode 100644 test/jdk/java/foreign/ThrowingUpcall.java rename test/jdk/java/foreign/{ => callarranger}/TestLayoutEquality.java (81%) rename {src/java.base/share/classes/jdk/internal/foreign => test/jdk/java/foreign/callarranger/platform}/PlatformLayouts.java (71%) create mode 100644 test/jdk/java/foreign/libAddressDereference.c create mode 100644 test/jdk/java/foreign/trivial/TestTrivial.java create mode 100644 test/jdk/java/foreign/trivial/TestTrivialUpcall.java rename test/{micro/org/openjdk/bench/java/lang/foreign/libVaList.c => jdk/java/foreign/trivial/libTrivial.c} (69%) delete mode 100644 test/jdk/java/foreign/valist/VaListTest.java delete mode 100644 test/jdk/java/foreign/valist/libVaList.c delete mode 100644 test/micro/org/openjdk/bench/java/lang/foreign/BulkMismatchAcquire.java create mode 100644 test/micro/org/openjdk/bench/java/lang/foreign/MemorySegmentVsBits.java delete mode 100644 test/micro/org/openjdk/bench/java/lang/foreign/VaList.java diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index 7c5d7b13ada..6afa36ac18d 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -223,6 +223,10 @@ JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER # LeakSanitizer JDKOPT_SETUP_LEAK_SANITIZER +# Fallback linker +# This needs to go before 'LIB_DETERMINE_DEPENDENCIES' +JDKOPT_SETUP_FALLBACK_LINKER + ############################################################################### # # Check dependencies for external and internal libraries. diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index a76fdab5ae5..f08cc6ddd41 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -903,3 +903,22 @@ AC_DEFUN([JDKOPT_SETUP_MACOSX_SIGNING], AC_SUBST(MACOSX_CODESIGN_MODE) fi ]) + +################################################################################ +# +# fallback linker +# +AC_DEFUN_ONCE([JDKOPT_SETUP_FALLBACK_LINKER], +[ + FALLBACK_LINKER_DEFAULT=false + + if HOTSPOT_CHECK_JVM_VARIANT(zero); then + FALLBACK_LINKER_DEFAULT=true + fi + + UTIL_ARG_ENABLE(NAME: fallback-linker, DEFAULT: $FALLBACK_LINKER_DEFAULT, + RESULT: ENABLE_FALLBACK_LINKER, + DESC: [enable libffi-based fallback implementation of java.lang.foreign.Linker], + CHECKING_MSG: [if fallback linker enabled]) + AC_SUBST(ENABLE_FALLBACK_LINKER) +]) diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 index 9e746b470c9..a1fc81564b1 100644 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -82,7 +82,7 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES], fi # Check if ffi is needed - if HOTSPOT_CHECK_JVM_VARIANT(zero); then + if HOTSPOT_CHECK_JVM_VARIANT(zero) || test "x$ENABLE_FALLBACK_LINKER" = "xtrue"; then NEEDS_LIB_FFI=true else NEEDS_LIB_FFI=false diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 6be074f95e0..0f85917814e 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -409,6 +409,9 @@ TEST_JOBS?=@TEST_JOBS@ DEFAULT_MAKE_TARGET:=@DEFAULT_MAKE_TARGET@ DEFAULT_LOG:=@DEFAULT_LOG@ +# Fallback linker +ENABLE_FALLBACK_LINKER:=@ENABLE_FALLBACK_LINKER@ + FREETYPE_TO_USE:=@FREETYPE_TO_USE@ FREETYPE_LIBS:=@FREETYPE_LIBS@ FREETYPE_CFLAGS:=@FREETYPE_CFLAGS@ diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index d3b5aa2459d..2c6742c94e7 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -587,11 +587,12 @@ var getJibProfilesProfiles = function (input, common, data) { "linux-x64-zero": { target_os: "linux", target_cpu: "x64", - dependencies: ["devkit", "gtest"], + dependencies: ["devkit", "gtest", "libffi"], configure_args: concat(common.configure_args_64bit, [ "--with-zlib=system", "--with-jvm-variants=zero", - "--enable-libffi-bundling" + "--with-libffi=" + input.get("libffi", "home_path"), + "--enable-libffi-bundling", ]) }, @@ -744,6 +745,40 @@ var getJibProfilesProfiles = function (input, common, data) { common.debug_profile_artifacts(artifactData[name])); }); + // Define artifact just for linux-x64-zero, which is the only one we test on + ["linux-x64"].forEach(function (name) { + var o = artifactData[name] + var pf = o.platform + var jdk_subdir = (o.jdk_subdir != null ? o.jdk_subdir : "jdk-" + data.version); + var jdk_suffix = (o.jdk_suffix != null ? o.jdk_suffix : "tar.gz"); + var zeroName = name + "-zero"; + profiles[zeroName].artifacts = { + jdk: { + local: "bundles/\\(jdk.*bin." + jdk_suffix + "\\)", + remote: [ + "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-zero." + jdk_suffix, + ], + subdir: jdk_subdir, + exploded: "images/jdk", + }, + test: { + local: "bundles/\\(jdk.*bin-tests.tar.gz\\)", + remote: [ + "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-zero-tests.tar.gz", + ], + exploded: "images/test" + }, + jdk_symbols: { + local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)", + remote: [ + "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-zero-symbols.tar.gz", + ], + subdir: jdk_subdir, + exploded: "images/jdk" + }, + }; + }); + buildJdkDep = input.build_os + "-" + input.build_cpu + ".jdk"; docsProfiles = { "docs": { @@ -1234,6 +1269,13 @@ var getJibProfilesDependencies = function (input, common) { ext: "tar.gz", revision: "1.13.0+1.0" }, + + libffi: { + organization: common.organization, + module: "libffi-" + input.build_platform, + ext: "tar.gz", + revision: "3.4.2+1.0" + }, }; return dependencies; diff --git a/make/data/hotspot-symbols/symbols-shared b/make/data/hotspot-symbols/symbols-shared index ab6adf06d4d..c5b13ef1ee8 100644 --- a/make/data/hotspot-symbols/symbols-shared +++ b/make/data/hotspot-symbols/symbols-shared @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 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 @@ -30,5 +30,6 @@ jio_vsnprintf JNI_CreateJavaVM JNI_GetCreatedJavaVMs JNI_GetDefaultJavaVMInitArgs +JVM_IsForeignLinkerSupported JVM_FindClassFromBootLoader JVM_InitAgentProperties diff --git a/make/devkit/createLibffiBundle.sh b/make/devkit/createLibffiBundle.sh new file mode 100644 index 00000000000..62d714a5148 --- /dev/null +++ b/make/devkit/createLibffiBundle.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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 script generates a libffi bundle. On linux by building it from source +# using a devkit, which should match the devkit used to build the JDK. +# +# Set MAKE_ARGS to add parameters to make. Ex: +# +# $ MAKE_ARGS=-j32 bash createLibffiBundle.sh +# +# The script tries to behave well on multiple invocations, only performing steps +# not already done. To redo a step, manually delete the target files from that +# step. +# +# Note that the libtool and texinfo packages are needed to build libffi +# $ sudo apt install libtool texinfo + +LIBFFI_VERSION=3.4.2 + +BUNDLE_NAME=libffi-$LIBFFI_VERSION.tar.gz + +SCRIPT_FILE="$(basename $0)" +SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)" +OUTPUT_DIR="${SCRIPT_DIR}/../../build/libffi" +SRC_DIR="$OUTPUT_DIR/src" +DOWNLOAD_DIR="$OUTPUT_DIR/download" +INSTALL_DIR="$OUTPUT_DIR/install" +IMAGE_DIR="$OUTPUT_DIR/image" + +USAGE="$0 " + +if [ "$1" = "" ]; then + echo $USAGE + exit 1 +fi +DEVKIT_DIR="$1" + +# Download source distros +mkdir -p $DOWNLOAD_DIR +cd $DOWNLOAD_DIR +SOURCE_TAR=v$LIBFFI_VERSION.tar.gz +if [ ! -f $SOURCE_TAR ]; then + wget https://github.com/libffi/libffi/archive/refs/tags/v$LIBFFI_VERSION.tar.gz +fi + +# Unpack src +mkdir -p $SRC_DIR +cd $SRC_DIR +LIBFFI_DIRNAME=libffi-$LIBFFI_VERSION +LIBFFI_DIR=$SRC_DIR/$LIBFFI_DIRNAME +if [ ! -d $LIBFFI_DIRNAME ]; then + echo "Unpacking $SOURCE_TAR" + tar xf $DOWNLOAD_DIR/$SOURCE_TAR +fi + +# Build +cd $LIBFFI_DIR +if [ ! -e $LIBFFI_DIR/configure ]; then + bash ./autogen.sh +fi +bash ./configure --prefix=$INSTALL_DIR CC=$DEVKIT_DIR/bin/gcc CXX=$DEVKIT_DIR/bin/g++ + +# Run with nice to keep system usable during build. +nice make $MAKE_ARGS install + +mkdir -p $IMAGE_DIR +# Extract what we need into an image +if [ ! -e $IMAGE_DIR/lib/libffi.so ]; then + echo "Copying libffi.so* to image" + mkdir -p $IMAGE_DIR/lib + cp -a $INSTALL_DIR/lib64/libffi.so* $IMAGE_DIR/lib/ +fi +if [ ! -e $IMAGE_DIR/include/ ]; then + echo "Copying include to image" + mkdir -p $IMAGE_DIR/include + cp -a $INSTALL_DIR/include/. $IMAGE_DIR/include/ +fi +if [ ! -e $IMAGE_DIR/$SCRIPT_FILE ]; then + echo "Copying this script to image" + cp -a $SCRIPT_DIR/$SCRIPT_FILE $IMAGE_DIR/ +fi + +# Create bundle +if [ ! -e $OUTPUT_DIR/$BUNDLE_NAME ]; then + echo "Creating $OUTPUT_DIR/$BUNDLE_NAME" + cd $IMAGE_DIR + tar zcf $OUTPUT_DIR/$BUNDLE_NAME * +fi diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk index 93c0a361671..d6ca2932914 100644 --- a/make/modules/java.base/Lib.gmk +++ b/make/modules/java.base/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -215,3 +215,18 @@ $(eval $(call SetupJdkLibrary, BUILD_SYSLOOKUPLIB, \ )) TARGETS += $(BUILD_SYSLOOKUPLIB) + +################################################################################ +# Create fallback linker lib + +ifeq ($(ENABLE_FALLBACK_LINKER), true) + $(eval $(call SetupJdkLibrary, BUILD_LIBFALLBACKLINKER, \ + NAME := fallbackLinker, \ + CFLAGS := $(CFLAGS_JDKLIB) $(LIBFFI_CFLAGS), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(LIBFFI_LIBS), \ + )) + + TARGETS += $(BUILD_LIBFALLBACKLINKER) +endif diff --git a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp index 9c9d78e8d29..458ab541e32 100644 --- a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp @@ -47,6 +47,7 @@ class DowncallStubGenerator : public StubCodeGenerator { bool _needs_return_buffer; int _captured_state_mask; + bool _needs_transition; int _frame_complete; int _frame_size_slots; @@ -60,7 +61,8 @@ public: const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) + int captured_state_mask, + bool needs_transition) : StubCodeGenerator(buffer, PrintMethodHandleStubs), _signature(signature), _num_args(num_args), @@ -70,6 +72,7 @@ public: _output_registers(output_registers), _needs_return_buffer(needs_return_buffer), _captured_state_mask(captured_state_mask), + _needs_transition(needs_transition), _frame_complete(0), _frame_size_slots(0), _oop_maps(NULL) { @@ -100,13 +103,15 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, - needs_return_buffer, captured_state_mask); + needs_return_buffer, captured_state_mask, + needs_transition); g.generate(); code.log_section_sizes("nep_invoker_blob"); @@ -163,7 +168,7 @@ void DowncallStubGenerator::generate() { assert(_abi._shadow_space_bytes == 0, "not expecting shadow space on AArch64"); allocated_frame_size += arg_shuffle.out_arg_bytes(); - bool should_save_return_value = !_needs_return_buffer; + bool should_save_return_value = !_needs_return_buffer && _needs_transition; RegSpiller out_reg_spiller(_output_registers); int spill_offset = -1; @@ -191,7 +196,7 @@ void DowncallStubGenerator::generate() { _frame_size_slots = align_up(framesize + (allocated_frame_size >> LogBytesPerInt), 4); assert(is_even(_frame_size_slots/2), "sp not 16-byte aligned"); - _oop_maps = new OopMapSet(); + _oop_maps = _needs_transition ? new OopMapSet() : nullptr; address start = __ pc(); __ enter(); @@ -201,15 +206,17 @@ void DowncallStubGenerator::generate() { _frame_complete = __ pc() - start; - address the_pc = __ pc(); - __ set_last_Java_frame(sp, rfp, the_pc, tmp1); - OopMap* map = new OopMap(_frame_size_slots, 0); - _oop_maps->add_gc_map(the_pc - start, map); + if (_needs_transition) { + address the_pc = __ pc(); + __ set_last_Java_frame(sp, rfp, the_pc, tmp1); + OopMap* map = new OopMap(_frame_size_slots, 0); + _oop_maps->add_gc_map(the_pc - start, map); - // State transition - __ mov(tmp1, _thread_in_native); - __ lea(tmp2, Address(rthread, JavaThread::thread_state_offset())); - __ stlrw(tmp1, tmp2); + // State transition + __ mov(tmp1, _thread_in_native); + __ lea(tmp2, Address(rthread, JavaThread::thread_state_offset())); + __ stlrw(tmp1, tmp2); + } __ block_comment("{ argument shuffle"); arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes, locs); @@ -257,86 +264,89 @@ void DowncallStubGenerator::generate() { ////////////////////////////////////////////////////////////////////////////// - __ mov(tmp1, _thread_in_native_trans); - __ strw(tmp1, Address(rthread, JavaThread::thread_state_offset())); - - // Force this write out before the read below - if (!UseSystemMemoryBarrier) { - __ membar(Assembler::LoadLoad | Assembler::LoadStore | - Assembler::StoreLoad | Assembler::StoreStore); - } - - __ verify_sve_vector_length(tmp1); - Label L_after_safepoint_poll; Label L_safepoint_poll_slow_path; - - __ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */, tmp1); - - __ ldrw(tmp1, Address(rthread, JavaThread::suspend_flags_offset())); - __ cbnzw(tmp1, L_safepoint_poll_slow_path); - - __ bind(L_after_safepoint_poll); - - // change thread state - __ mov(tmp1, _thread_in_Java); - __ lea(tmp2, Address(rthread, JavaThread::thread_state_offset())); - __ stlrw(tmp1, tmp2); - - __ block_comment("reguard stack check"); Label L_reguard; Label L_after_reguard; - __ ldrb(tmp1, Address(rthread, JavaThread::stack_guard_state_offset())); - __ cmpw(tmp1, StackOverflow::stack_guard_yellow_reserved_disabled); - __ br(Assembler::EQ, L_reguard); - __ bind(L_after_reguard); + if (_needs_transition) { + __ mov(tmp1, _thread_in_native_trans); + __ strw(tmp1, Address(rthread, JavaThread::thread_state_offset())); - __ reset_last_Java_frame(true); + // Force this write out before the read below + if (!UseSystemMemoryBarrier) { + __ membar(Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore); + } + + __ verify_sve_vector_length(tmp1); + + __ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */, tmp1); + + __ ldrw(tmp1, Address(rthread, JavaThread::suspend_flags_offset())); + __ cbnzw(tmp1, L_safepoint_poll_slow_path); + + __ bind(L_after_safepoint_poll); + + // change thread state + __ mov(tmp1, _thread_in_Java); + __ lea(tmp2, Address(rthread, JavaThread::thread_state_offset())); + __ stlrw(tmp1, tmp2); + + __ block_comment("reguard stack check"); + __ ldrb(tmp1, Address(rthread, JavaThread::stack_guard_state_offset())); + __ cmpw(tmp1, StackOverflow::stack_guard_yellow_reserved_disabled); + __ br(Assembler::EQ, L_reguard); + __ bind(L_after_reguard); + + __ reset_last_Java_frame(true); + } __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_safepoint_poll_slow_path"); - __ bind(L_safepoint_poll_slow_path); + if (_needs_transition) { + __ block_comment("{ L_safepoint_poll_slow_path"); + __ bind(L_safepoint_poll_slow_path); - if (should_save_return_value) { - // Need to save the native result registers around any runtime calls. - out_reg_spiller.generate_spill(_masm, spill_offset); - } + if (should_save_return_value) { + // Need to save the native result registers around any runtime calls. + out_reg_spiller.generate_spill(_masm, spill_offset); + } - __ mov(c_rarg0, rthread); - assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); - __ lea(tmp1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); - __ blr(tmp1); + __ mov(c_rarg0, rthread); + assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); + __ lea(tmp1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); + __ blr(tmp1); - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_offset); - } + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_offset); + } - __ b(L_after_safepoint_poll); - __ block_comment("} L_safepoint_poll_slow_path"); + __ b(L_after_safepoint_poll); + __ block_comment("} L_safepoint_poll_slow_path"); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_reguard"); - __ bind(L_reguard); + __ block_comment("{ L_reguard"); + __ bind(L_reguard); - if (should_save_return_value) { - out_reg_spiller.generate_spill(_masm, spill_offset); + if (should_save_return_value) { + out_reg_spiller.generate_spill(_masm, spill_offset); + } + + __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), tmp1); + + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_offset); + } + + __ b(L_after_reguard); + + __ block_comment("} L_reguard"); } - __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), tmp1); - - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_offset); - } - - __ b(L_after_reguard); - - __ block_comment("} L_reguard"); - ////////////////////////////////////////////////////////////////////////////// __ flush(); diff --git a/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp b/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp index 90c1942c32d..2692054bcdc 100644 --- a/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/foreignGlobals_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2022, Arm Limited. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,6 +33,10 @@ #include "prims/vmstorage.hpp" #include "utilities/formatBuffer.hpp" +bool ForeignGlobals::is_foreign_linker_supported() { + return true; +} + bool ABIDescriptor::is_volatile_reg(Register reg) const { return _integer_argument_registers.contains(reg) || _integer_additional_volatile_registers.contains(reg); diff --git a/src/hotspot/cpu/arm/downcallLinker_arm.cpp b/src/hotspot/cpu/arm/downcallLinker_arm.cpp index 37b6f43ac14..baee7d7a043 100644 --- a/src/hotspot/cpu/arm/downcallLinker_arm.cpp +++ b/src/hotspot/cpu/arm/downcallLinker_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { Unimplemented(); return nullptr; } diff --git a/src/hotspot/cpu/arm/foreignGlobals_arm.cpp b/src/hotspot/cpu/arm/foreignGlobals_arm.cpp index 5438cbe5cd6..d3a318536bd 100644 --- a/src/hotspot/cpu/arm/foreignGlobals_arm.cpp +++ b/src/hotspot/cpu/arm/foreignGlobals_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,10 @@ class MacroAssembler; +bool ForeignGlobals::is_foreign_linker_supported() { + return false; +} + const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { Unimplemented(); return {}; diff --git a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp index 13679cf6669..0a4c2c31086 100644 --- a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020 SAP SE. All rights reserved. - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { Unimplemented(); return nullptr; } diff --git a/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp b/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp index b685023656d..cf9904cfae5 100644 --- a/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp +++ b/src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2020, 2023, SAP SE. All rights reserved. * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,10 @@ class MacroAssembler; +bool ForeignGlobals::is_foreign_linker_supported() { + return false; +} + // Stubbed out, implement later const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { Unimplemented(); diff --git a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp index 994402bc2b4..6f0e4e97246 100644 --- a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp @@ -48,6 +48,7 @@ class DowncallStubGenerator : public StubCodeGenerator { bool _needs_return_buffer; int _captured_state_mask; + bool _needs_transition; int _frame_complete; int _frame_size_slots; @@ -61,7 +62,8 @@ public: const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) + int captured_state_mask, + bool needs_transition) : StubCodeGenerator(buffer, PrintMethodHandleStubs), _signature(signature), _num_args(num_args), @@ -71,6 +73,7 @@ public: _output_registers(output_registers), _needs_return_buffer(needs_return_buffer), _captured_state_mask(captured_state_mask), + _needs_transition(needs_transition), _frame_complete(0), _frame_size_slots(0), _oop_maps(nullptr) { @@ -101,13 +104,15 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, - needs_return_buffer, captured_state_mask); + needs_return_buffer, captured_state_mask, + needs_transition); g.generate(); code.log_section_sizes("nep_invoker_blob"); @@ -160,7 +165,7 @@ void DowncallStubGenerator::generate() { assert(_abi._shadow_space_bytes == 0, "not expecting shadow space on RISCV64"); allocated_frame_size += arg_shuffle.out_arg_bytes(); - bool should_save_return_value = !_needs_return_buffer; + bool should_save_return_value = !_needs_return_buffer && _needs_transition; RegSpiller out_reg_spiller(_output_registers); int spill_offset = -1; @@ -190,7 +195,7 @@ void DowncallStubGenerator::generate() { _frame_size_slots += framesize + (allocated_frame_size >> LogBytesPerInt); assert(is_even(_frame_size_slots / 2), "sp not 16-byte aligned"); - _oop_maps = new OopMapSet(); + _oop_maps = _needs_transition ? new OopMapSet() : nullptr; address start = __ pc(); __ enter(); @@ -200,17 +205,19 @@ void DowncallStubGenerator::generate() { _frame_complete = __ pc() - start; // frame build complete. - __ block_comment("{ thread java2native"); - address the_pc = __ pc(); - __ set_last_Java_frame(sp, fp, the_pc, t0); - OopMap* map = new OopMap(_frame_size_slots, 0); - _oop_maps->add_gc_map(the_pc - start, map); + if (_needs_transition) { + __ block_comment("{ thread java2native"); + address the_pc = __ pc(); + __ set_last_Java_frame(sp, fp, the_pc, t0); + OopMap* map = new OopMap(_frame_size_slots, 0); + _oop_maps->add_gc_map(the_pc - start, map); - // State transition - __ mv(t0, _thread_in_native); - __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); - __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); - __ block_comment("} thread java2native"); + // State transition + __ mv(t0, _thread_in_native); + __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); + __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); + __ block_comment("} thread java2native"); + } __ block_comment("{ argument shuffle"); arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes, locs); @@ -260,80 +267,85 @@ void DowncallStubGenerator::generate() { ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ thread native2java"); - __ mv(t0, _thread_in_native_trans); - __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); - - // Force this write out before the read below - if (!UseSystemMemoryBarrier) { - __ membar(MacroAssembler::AnyAny); - } - Label L_after_safepoint_poll; Label L_safepoint_poll_slow_path; - __ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */); - __ lwu(t0, Address(xthread, JavaThread::suspend_flags_offset())); - __ bnez(t0, L_safepoint_poll_slow_path); - - __ bind(L_after_safepoint_poll); - - __ mv(t0, _thread_in_Java); - __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); - __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); - - __ block_comment("reguard stack check"); Label L_reguard; Label L_after_reguard; - __ lbu(t0, Address(xthread, JavaThread::stack_guard_state_offset())); - __ mv(t1, StackOverflow::stack_guard_yellow_reserved_disabled); - __ beq(t0, t1, L_reguard); - __ bind(L_after_reguard); + if (_needs_transition) { + __ block_comment("{ thread native2java"); + __ mv(t0, _thread_in_native_trans); + __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); - __ reset_last_Java_frame(true); - __ block_comment("} thread native2java"); + // Force this write out before the read below + if (!UseSystemMemoryBarrier) { + __ membar(MacroAssembler::AnyAny); + } + + __ safepoint_poll(L_safepoint_poll_slow_path, true /* at_return */, true /* acquire */, false /* in_nmethod */); + __ lwu(t0, Address(xthread, JavaThread::suspend_flags_offset())); + __ bnez(t0, L_safepoint_poll_slow_path); + + __ bind(L_after_safepoint_poll); + + // change thread state + __ mv(t0, _thread_in_Java); + __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); + __ sw(t0, Address(xthread, JavaThread::thread_state_offset())); + + __ block_comment("reguard stack check"); + __ lbu(t0, Address(xthread, JavaThread::stack_guard_state_offset())); + __ mv(t1, StackOverflow::stack_guard_yellow_reserved_disabled); + __ beq(t0, t1, L_reguard); + __ bind(L_after_reguard); + + __ reset_last_Java_frame(true); + __ block_comment("} thread native2java"); + } __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_safepoint_poll_slow_path"); - __ bind(L_safepoint_poll_slow_path); + if (_needs_transition) { + __ block_comment("{ L_safepoint_poll_slow_path"); + __ bind(L_safepoint_poll_slow_path); - if (should_save_return_value) { - // Need to save the native result registers around any runtime calls. - out_reg_spiller.generate_spill(_masm, spill_offset); - } + if (should_save_return_value) { + // Need to save the native result registers around any runtime calls. + out_reg_spiller.generate_spill(_masm, spill_offset); + } - __ mv(c_rarg0, xthread); - assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); - __ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); + __ mv(c_rarg0, xthread); + assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); + __ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_offset); - } - __ j(L_after_safepoint_poll); - __ block_comment("} L_safepoint_poll_slow_path"); + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_offset); + } + __ j(L_after_safepoint_poll); + __ block_comment("} L_safepoint_poll_slow_path"); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_reguard"); - __ bind(L_reguard); + __ block_comment("{ L_reguard"); + __ bind(L_reguard); - if (should_save_return_value) { - // Need to save the native result registers around any runtime calls. - out_reg_spiller.generate_spill(_masm, spill_offset); + if (should_save_return_value) { + // Need to save the native result registers around any runtime calls. + out_reg_spiller.generate_spill(_masm, spill_offset); + } + + __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); + + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_offset); + } + + __ j(L_after_reguard); + __ block_comment("} L_reguard"); } - __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)); - - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_offset); - } - - __ j(L_after_reguard); - __ block_comment("} L_reguard"); - ////////////////////////////////////////////////////////////////////////////// __ flush(); diff --git a/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp b/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp index 44cff28b119..7ecfe0c38d3 100644 --- a/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp +++ b/src/hotspot/cpu/riscv/foreignGlobals_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -44,6 +44,10 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { || _float_additional_volatile_registers.contains(reg); } +bool ForeignGlobals::is_foreign_linker_supported() { + return true; +} + const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { oop abi_oop = JNIHandles::resolve_non_null(jabi); ABIDescriptor abi; diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp index 37b6f43ac14..baee7d7a043 100644 --- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,7 +33,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { Unimplemented(); return nullptr; } diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp index 5438cbe5cd6..d3a318536bd 100644 --- a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp +++ b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,6 +29,10 @@ class MacroAssembler; +bool ForeignGlobals::is_foreign_linker_supported() { + return false; +} + const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { Unimplemented(); return {}; diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp index 3f1241970f2..aabe49a3002 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -31,7 +31,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { Unimplemented(); return nullptr; } diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 787a66eb9e5..6c6b44a158b 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -46,6 +46,7 @@ class DowncallStubGenerator : public StubCodeGenerator { bool _needs_return_buffer; int _captured_state_mask; + bool _needs_transition; int _frame_complete; int _frame_size_slots; @@ -59,7 +60,8 @@ public: const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) + int captured_state_mask, + bool needs_transition) : StubCodeGenerator(buffer, PrintMethodHandleStubs), _signature(signature), _num_args(num_args), @@ -69,6 +71,7 @@ public: _output_registers(output_registers), _needs_return_buffer(needs_return_buffer), _captured_state_mask(captured_state_mask), + _needs_transition(needs_transition), _frame_complete(0), _frame_size_slots(0), _oop_maps(nullptr) { @@ -99,13 +102,15 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // can not be zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, - needs_return_buffer, captured_state_mask); + needs_return_buffer, captured_state_mask, + needs_transition); g.generate(); code.log_section_sizes("nep_invoker_blob"); @@ -161,7 +166,7 @@ void DowncallStubGenerator::generate() { allocated_frame_size += arg_shuffle.out_arg_bytes(); // when we don't use a return buffer we need to spill the return value around our slow path calls - bool should_save_return_value = !_needs_return_buffer; + bool should_save_return_value = !_needs_return_buffer && _needs_transition; RegSpiller out_reg_spiller(_output_registers); int spill_rsp_offset = -1; @@ -190,7 +195,7 @@ void DowncallStubGenerator::generate() { _frame_size_slots += framesize_base + (allocated_frame_size >> LogBytesPerInt); assert(is_even(_frame_size_slots/2), "sp not 16-byte aligned"); - _oop_maps = new OopMapSet(); + _oop_maps = _needs_transition ? new OopMapSet() : nullptr; address start = __ pc(); __ enter(); @@ -200,16 +205,17 @@ void DowncallStubGenerator::generate() { _frame_complete = __ pc() - start; - address the_pc = __ pc(); + if (_needs_transition) { + __ block_comment("{ thread java2native"); + address the_pc = __ pc(); + __ set_last_Java_frame(rsp, rbp, (address)the_pc, rscratch1); + OopMap* map = new OopMap(_frame_size_slots, 0); + _oop_maps->add_gc_map(the_pc - start, map); - __ block_comment("{ thread java2native"); - __ set_last_Java_frame(rsp, rbp, (address)the_pc, rscratch1); - OopMap* map = new OopMap(_frame_size_slots, 0); - _oop_maps->add_gc_map(the_pc - start, map); - - // State transition - __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); - __ block_comment("} thread java2native"); + // State transition + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); + __ block_comment("} thread java2native"); + } __ block_comment("{ argument shuffle"); arg_shuffle.generate(_masm, shuffle_reg, 0, _abi._shadow_space_bytes, locs); @@ -263,93 +269,95 @@ void DowncallStubGenerator::generate() { ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ thread native2java"); - __ restore_cpu_control_state_after_jni(rscratch1); - - __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); - - // Force this write out before the read below - if (!UseSystemMemoryBarrier) { - __ membar(Assembler::Membar_mask_bits( - Assembler::LoadLoad | Assembler::LoadStore | - Assembler::StoreLoad | Assembler::StoreStore)); - } - Label L_after_safepoint_poll; Label L_safepoint_poll_slow_path; - - __ safepoint_poll(L_safepoint_poll_slow_path, r15_thread, true /* at_return */, false /* in_nmethod */); - __ cmpl(Address(r15_thread, JavaThread::suspend_flags_offset()), 0); - __ jcc(Assembler::notEqual, L_safepoint_poll_slow_path); - - __ bind(L_after_safepoint_poll); - - // change thread state - __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); - - __ block_comment("reguard stack check"); Label L_reguard; Label L_after_reguard; - __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), StackOverflow::stack_guard_yellow_reserved_disabled); - __ jcc(Assembler::equal, L_reguard); - __ bind(L_after_reguard); + if (_needs_transition) { + __ block_comment("{ thread native2java"); + __ restore_cpu_control_state_after_jni(rscratch1); - __ reset_last_Java_frame(r15_thread, true); - __ block_comment("} thread native2java"); + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); + + // Force this write out before the read below + if (!UseSystemMemoryBarrier) { + __ membar(Assembler::Membar_mask_bits( + Assembler::LoadLoad | Assembler::LoadStore | + Assembler::StoreLoad | Assembler::StoreStore)); + } + + __ safepoint_poll(L_safepoint_poll_slow_path, r15_thread, true /* at_return */, false /* in_nmethod */); + __ cmpl(Address(r15_thread, JavaThread::suspend_flags_offset()), 0); + __ jcc(Assembler::notEqual, L_safepoint_poll_slow_path); + + __ bind(L_after_safepoint_poll); + + // change thread state + __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); + + __ block_comment("reguard stack check"); + __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), StackOverflow::stack_guard_yellow_reserved_disabled); + __ jcc(Assembler::equal, L_reguard); + __ bind(L_after_reguard); + + __ reset_last_Java_frame(r15_thread, true); + __ block_comment("} thread native2java"); + } __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_safepoint_poll_slow_path"); - __ bind(L_safepoint_poll_slow_path); - __ vzeroupper(); + if (_needs_transition) { + __ block_comment("{ L_safepoint_poll_slow_path"); + __ bind(L_safepoint_poll_slow_path); + __ vzeroupper(); - if (should_save_return_value) { - out_reg_spiller.generate_spill(_masm, spill_rsp_offset); - } + if (should_save_return_value) { + out_reg_spiller.generate_spill(_masm, spill_rsp_offset); + } - __ mov(c_rarg0, r15_thread); - __ mov(r12, rsp); // remember sp - __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows - __ andptr(rsp, -16); // align stack as required by ABI - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); - __ mov(rsp, r12); // restore sp - __ reinit_heapbase(); + __ mov(c_rarg0, r15_thread); + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); + __ mov(rsp, r12); // restore sp + __ reinit_heapbase(); - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_rsp_offset); - } + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_rsp_offset); + } - __ jmp(L_after_safepoint_poll); - __ block_comment("} L_safepoint_poll_slow_path"); + __ jmp(L_after_safepoint_poll); + __ block_comment("} L_safepoint_poll_slow_path"); ////////////////////////////////////////////////////////////////////////////// - __ block_comment("{ L_reguard"); - __ bind(L_reguard); - __ vzeroupper(); + __ block_comment("{ L_reguard"); + __ bind(L_reguard); + __ vzeroupper(); - if (should_save_return_value) { - out_reg_spiller.generate_spill(_masm, spill_rsp_offset); + if (should_save_return_value) { + out_reg_spiller.generate_spill(_masm, spill_rsp_offset); + } + + __ mov(r12, rsp); // remember sp + __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows + __ andptr(rsp, -16); // align stack as required by ABI + __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); + __ mov(rsp, r12); // restore sp + __ reinit_heapbase(); + + if (should_save_return_value) { + out_reg_spiller.generate_fill(_masm, spill_rsp_offset); + } + + __ jmp(L_after_reguard); + + __ block_comment("} L_reguard"); } - - __ mov(r12, rsp); // remember sp - __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows - __ andptr(rsp, -16); // align stack as required by ABI - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); - __ mov(rsp, r12); // restore sp - __ reinit_heapbase(); - - if (should_save_return_value) { - out_reg_spiller.generate_fill(_masm, spill_rsp_offset); - } - - __ jmp(L_after_reguard); - - __ block_comment("} L_reguard"); - ////////////////////////////////////////////////////////////////////////////// __ flush(); diff --git a/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp b/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp index 8a31955f4d1..3752bf577d5 100644 --- a/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp +++ b/src/hotspot/cpu/x86/foreignGlobals_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,10 @@ class MacroAssembler; +bool ForeignGlobals::is_foreign_linker_supported() { + return false; +} + const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { Unimplemented(); return {}; diff --git a/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp b/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp index 74afbe4fd61..8710d4f79f9 100644 --- a/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp +++ b/src/hotspot/cpu/x86/foreignGlobals_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -30,6 +30,10 @@ #include "runtime/sharedRuntime.hpp" #include "utilities/formatBuffer.hpp" +bool ForeignGlobals::is_foreign_linker_supported() { + return true; +} + bool ABIDescriptor::is_volatile_reg(Register reg) const { return _integer_argument_registers.contains(reg) || _integer_additional_volatile_registers.contains(reg); diff --git a/src/hotspot/cpu/zero/downcallLinker_zero.cpp b/src/hotspot/cpu/zero/downcallLinker_zero.cpp index 3f1241970f2..aabe49a3002 100644 --- a/src/hotspot/cpu/zero/downcallLinker_zero.cpp +++ b/src/hotspot/cpu/zero/downcallLinker_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -31,7 +31,8 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask) { + int captured_state_mask, + bool needs_transition) { Unimplemented(); return nullptr; } diff --git a/src/hotspot/cpu/zero/foreignGlobals_zero.cpp b/src/hotspot/cpu/zero/foreignGlobals_zero.cpp index 7c35da7e3e0..2cd83af6b6e 100644 --- a/src/hotspot/cpu/zero/foreignGlobals_zero.cpp +++ b/src/hotspot/cpu/zero/foreignGlobals_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -28,6 +28,10 @@ class MacroAssembler; +bool ForeignGlobals::is_foreign_linker_supported() { + return false; +} + const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { ShouldNotCallThis(); return {}; diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp index 9db2060b8dd..271d95ee72c 100644 --- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp +++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2021, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,7 +32,7 @@ #define SUPPORT_MONITOR_COUNT -#ifndef FFI_GO_CLOSURES +#ifdef __APPLE__ #define FFI_GO_CLOSURES 0 #endif diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 55e640cd8b0..d18c8d1f6de 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -174,6 +174,9 @@ JVM_IsPreviewEnabled(void); JNIEXPORT jboolean JNICALL JVM_IsContinuationsSupported(void); +JNIEXPORT jboolean JNICALL +JVM_IsForeignLinkerSupported(void); + JNIEXPORT void JNICALL JVM_InitializeFromArchive(JNIEnv* env, jclass cls); diff --git a/src/hotspot/share/prims/downcallLinker.cpp b/src/hotspot/share/prims/downcallLinker.cpp index ec20fd17d80..b2d5ae2e551 100644 --- a/src/hotspot/share/prims/downcallLinker.cpp +++ b/src/hotspot/share/prims/downcallLinker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,12 @@ void DowncallLinker::capture_state(int32_t* value_ptr, int captured_state_mask) #ifdef _WIN64 if (captured_state_mask & GET_LAST_ERROR) { *value_ptr = GetLastError(); - value_ptr++; } + value_ptr++; if (captured_state_mask & WSA_GET_LAST_ERROR) { *value_ptr = WSAGetLastError(); - value_ptr++; } + value_ptr++; #endif if (captured_state_mask & ERRNO) { *value_ptr = errno; diff --git a/src/hotspot/share/prims/downcallLinker.hpp b/src/hotspot/share/prims/downcallLinker.hpp index 86849c05158..6840a3c7f69 100644 --- a/src/hotspot/share/prims/downcallLinker.hpp +++ b/src/hotspot/share/prims/downcallLinker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -37,7 +37,8 @@ public: const GrowableArray& input_registers, const GrowableArray& output_registers, bool needs_return_buffer, - int captured_state_mask); + int captured_state_mask, + bool needs_transition); static void capture_state(int32_t* value_ptr, int captured_state_mask); }; diff --git a/src/hotspot/share/prims/foreignGlobals.hpp b/src/hotspot/share/prims/foreignGlobals.hpp index d0160f23226..009fd974d0b 100644 --- a/src/hotspot/share/prims/foreignGlobals.hpp +++ b/src/hotspot/share/prims/foreignGlobals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -76,6 +76,8 @@ private: static void parse_register_array(objArrayOop jarray, StorageType type_index, GrowableArray& array, T (*converter)(int)); public: + static bool is_foreign_linker_supported(); + static const ABIDescriptor parse_abi_descriptor(jobject jabi); static const CallRegs parse_call_regs(jobject jconv); static VMStorage parse_vmstorage(oop storage); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 221c5b95d70..2a3420a8fbb 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -63,6 +63,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" +#include "prims/foreignGlobals.hpp" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.inline.hpp" @@ -3462,6 +3463,10 @@ JVM_LEAF(jboolean, JVM_IsContinuationsSupported(void)) return VMContinuations ? JNI_TRUE : JNI_FALSE; JVM_END +JVM_LEAF(jboolean, JVM_IsForeignLinkerSupported(void)) + return ForeignGlobals::is_foreign_linker_supported() ? JNI_TRUE : JNI_FALSE; +JVM_END + // String support /////////////////////////////////////////////////////////////////////////// JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str)) diff --git a/src/hotspot/share/prims/nativeEntryPoint.cpp b/src/hotspot/share/prims/nativeEntryPoint.cpp index 1a7ba6fe67b..ef962f8ee41 100644 --- a/src/hotspot/share/prims/nativeEntryPoint.cpp +++ b/src/hotspot/share/prims/nativeEntryPoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -37,7 +37,8 @@ JNI_ENTRY(jlong, NEP_makeDowncallStub(JNIEnv* env, jclass _unused, jobject method_type, jobject jabi, jobjectArray arg_moves, jobjectArray ret_moves, - jboolean needs_return_buffer, jint captured_state_mask)) + jboolean needs_return_buffer, jint captured_state_mask, + jboolean needs_transition)) ResourceMark rm; const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); @@ -77,7 +78,8 @@ JNI_ENTRY(jlong, NEP_makeDowncallStub(JNIEnv* env, jclass _unused, jobject metho return (jlong) DowncallLinker::make_downcall_stub(basic_type, pslots, ret_bt, abi, input_regs, output_regs, - needs_return_buffer, captured_state_mask)->code_begin(); + needs_return_buffer, captured_state_mask, + needs_transition)->code_begin(); JNI_END JNI_ENTRY(jboolean, NEP_freeDowncallStub(JNIEnv* env, jclass _unused, jlong invoker)) @@ -97,7 +99,7 @@ JNI_END #define VM_STORAGE_ARR "[Ljdk/internal/foreign/abi/VMStorage;" static JNINativeMethod NEP_methods[] = { - {CC "makeDowncallStub", CC "(" METHOD_TYPE ABI_DESC VM_STORAGE_ARR VM_STORAGE_ARR "ZI)J", FN_PTR(NEP_makeDowncallStub)}, + {CC "makeDowncallStub", CC "(" METHOD_TYPE ABI_DESC VM_STORAGE_ARR VM_STORAGE_ARR "ZIZ)J", FN_PTR(NEP_makeDowncallStub)}, {CC "freeDowncallStub0", CC "(J)Z", FN_PTR(NEP_freeDowncallStub)}, }; diff --git a/src/hotspot/share/prims/upcallLinker.cpp b/src/hotspot/share/prims/upcallLinker.cpp index 13ae00fa027..7be41f7447f 100644 --- a/src/hotspot/share/prims/upcallLinker.cpp +++ b/src/hotspot/share/prims/upcallLinker.cpp @@ -75,6 +75,7 @@ JavaThread* UpcallLinker::maybe_attach_and_get_thread() { // modelled after JavaCallWrapper::JavaCallWrapper JavaThread* UpcallLinker::on_entry(UpcallStub::FrameData* context) { JavaThread* thread = maybe_attach_and_get_thread(); + guarantee(thread->thread_state() == _thread_in_native, "wrong thread state for upcall"); context->thread = thread; assert(thread->can_call_java(), "must be able to call Java"); diff --git a/src/java.base/share/classes/java/lang/foreign/AddressLayout.java b/src/java.base/share/classes/java/lang/foreign/AddressLayout.java new file mode 100644 index 00000000000..fc98f558133 --- /dev/null +++ b/src/java.base/share/classes/java/lang/foreign/AddressLayout.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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 java.lang.foreign; + +import jdk.internal.foreign.layout.ValueLayouts; +import jdk.internal.javac.PreviewFeature; +import jdk.internal.reflect.CallerSensitive; + +import java.lang.foreign.Linker.Option; +import java.lang.invoke.MethodHandle; +import java.nio.ByteOrder; +import java.util.Optional; + +/** + * A value layout used to model the address of some region of memory. The carrier associated with an address layout is + * {@code MemorySegment.class}. The size and alignment of an address layout are platform dependent + * (e.g. on a 64-bit platform, the size and alignment of an address layout are set to 64 bits). + *

+ * An address layout may optionally feature a {@linkplain #targetLayout() target layout}. An address layout with + * target layout {@code T} can be used to model the address of a region of memory whose layout is {@code T}. + * For instance, an address layout with target layout {@link ValueLayout#JAVA_INT} can be used to model the address + * of a region of memory that is 4 bytes long. Specifying a target layout can be useful in the following situations: + *

    + *
  • When accessing a memory segment that has been obtained by reading an address from another + * memory segment, e.g. using {@link MemorySegment#getAtIndex(AddressLayout, long)};
  • + *
  • When creating a downcall method handle, using {@link Linker#downcallHandle(FunctionDescriptor, Option...)}; + *
  • When creating an upcall stub, using {@link Linker#upcallStub(MethodHandle, FunctionDescriptor, Arena, Option...)}. + *
+ * + * @see #ADDRESS + * @see #ADDRESS_UNALIGNED + * @since 19 + */ +@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) +public sealed interface AddressLayout extends ValueLayout permits ValueLayouts.OfAddressImpl { + + /** + * {@inheritDoc} + */ + @Override + AddressLayout withName(String name); + + /** + * {@inheritDoc} + */ + @Override + AddressLayout withoutName(); + + /** + * {@inheritDoc} + */ + @Override + AddressLayout withBitAlignment(long bitAlignment); + + /** + * {@inheritDoc} + */ + @Override + AddressLayout withOrder(ByteOrder order); + + /** + * Returns an address layout with the same carrier, alignment constraint, name and order as this address layout, + * but associated with the specified target layout. The returned address layout allows raw addresses to be accessed + * as {@linkplain MemorySegment memory segments} whose size is set to the size of the specified layout. Moreover, + * if the accessed raw address is not compatible with the alignment constraint in the provided layout, + * {@linkplain IllegalArgumentException} will be thrown. + * @apiNote + * This method can also be used to create an address layout which, when used, creates native memory + * segments with maximal size (e.g. {@linkplain Long#MAX_VALUE}). This can be done by using a target sequence + * layout with unspecified size, as follows: + * {@snippet lang = java: + * AddressLayout addressLayout = ... + * AddressLayout unboundedLayout = addressLayout.withTargetLayout( + * MemoryLayout.sequenceLayout(ValueLayout.JAVA_BYTE)); + *} + *

+ * This method is restricted. + * Restricted methods are unsafe, and, if used incorrectly, their use might crash + * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on + * restricted methods, and use safe and supported functionalities, where possible. + * + * @param layout the target layout. + * @return an address layout with same characteristics as this layout, but with the provided target layout. + * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. + * @see #targetLayout() + */ + @CallerSensitive + AddressLayout withTargetLayout(MemoryLayout layout); + + /** + * Returns an address layout with the same carrier, alignment constraint, name and order as this address layout, + * but without any specified target layout. + *

+ * This can be useful to compare two address layouts that have different target layouts, but are otherwise equal. + * + * @return an address layout with same characteristics as this layout, but with no target layout. + * @see #targetLayout() + */ + AddressLayout withoutTargetLayout(); + + /** + * {@return the target layout associated with this address layout (if any)}. + */ + Optional targetLayout(); + +} diff --git a/src/java.base/share/classes/java/lang/foreign/Arena.java b/src/java.base/share/classes/java/lang/foreign/Arena.java index 2fff341e658..287f466b7f7 100644 --- a/src/java.base/share/classes/java/lang/foreign/Arena.java +++ b/src/java.base/share/classes/java/lang/foreign/Arena.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,40 +27,105 @@ package java.lang.foreign; import jdk.internal.foreign.MemorySessionImpl; import jdk.internal.javac.PreviewFeature; +import jdk.internal.ref.CleanerFactory; + +import java.lang.foreign.MemorySegment.Scope; /** - * An arena controls the lifecycle of memory segments, providing both flexible allocation and timely deallocation. + * An arena controls the lifecycle of native memory segments, providing both flexible allocation and timely deallocation. *

- * An arena has a {@linkplain #scope() scope}, called the arena scope. When the arena is {@linkplain #close() closed}, - * the arena scope is no longer {@linkplain SegmentScope#isAlive() alive}. As a result, all the - * segments associated with the arena scope are invalidated, safely and atomically, their backing memory regions are - * deallocated (where applicable) and can no longer be accessed after the arena is closed: + * An arena has a {@linkplain MemorySegment.Scope scope} - the arena scope. All the segments allocated + * by the arena are associated with the arena scope. As such, the arena determines the temporal bounds + * of all the memory segments allocated by it. + *

+ * Moreover, an arena also determines whether access to memory segments allocated by it should be + * {@linkplain MemorySegment#isAccessibleBy(Thread) restricted} to specific threads. + * An arena is a {@link SegmentAllocator} and features several allocation methods that can be used by clients + * to obtain native segments. + *

+ * The simplest arena is the {@linkplain Arena#global() global arena}. The global arena + * features an unbounded lifetime. As such, native segments allocated with the global arena are always + * accessible and their backing regions of memory are never deallocated. Moreover, memory segments allocated with the + * global arena can be {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} from any thread. + * {@snippet lang = java: + * MemorySegment segment = Arena.global().allocate(100, 1); + * ... + * // segment is never deallocated! + *} + *

+ * Alternatively, clients can obtain an {@linkplain Arena#ofAuto() automatic arena}, that is an arena + * which features a bounded lifetime that is managed, automatically, by the garbage collector. As such, the regions + * of memory backing memory segments allocated with the automatic arena are deallocated at some unspecified time + * after the automatic arena (and all the segments allocated by it) become + * unreachable, as shown below: * * {@snippet lang = java: - * try (Arena arena = Arena.openConfined()) { - * MemorySegment segment = MemorySegment.allocateNative(100, arena.scope()); - * ... - * } // memory released here + * MemorySegment segment = Arena.ofAuto().allocate(100, 1); + * ... + * segment = null; // the segment region becomes available for deallocation after this point *} - * - * Furthermore, an arena is a {@link SegmentAllocator}. All the segments {@linkplain #allocate(long, long) allocated} by the - * arena are associated with the arena scope. This makes arenas extremely useful when interacting with foreign code, as shown below: + * Memory segments allocated with an automatic arena can also be {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} from any thread. + *

+ * Rather than leaving deallocation in the hands of the Java runtime, clients will often wish to exercise control over + * the timing of deallocation for regions of memory that back memory segments. Two kinds of arenas support this, + * namely {@linkplain #ofConfined() confined} and {@linkplain #ofShared() shared} arenas. They both feature + * bounded lifetimes that are managed manually. For instance, the lifetime of a confined arena starts when the confined + * arena is created, and ends when the confined arena is {@linkplain #close() closed}. As a result, the regions of memory + * backing memory segments allocated with a confined arena are deallocated when the confined arena is closed. + * When this happens, all the segments allocated with the confined arena are invalidated, and subsequent access + * operations on these segments will fail {@link IllegalStateException}: * * {@snippet lang = java: - * try (Arena arena = Arena.openConfined()) { - * MemorySegment nativeArray = arena.allocateArray(ValueLayout.JAVA_INT, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - * MemorySegment nativeString = arena.allocateUtf8String("Hello!"); - * MemorySegment upcallStub = linker.upcallStub(handle, desc, arena.scope()); + * MemorySegment segment = null; + * try (Arena arena = Arena.ofConfined()) { + * segment = arena.allocate(100); * ... - * } // memory released here + * } // segment region deallocated here + * segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateException *} * + * Memory segments allocated with a {@linkplain #ofConfined() confined arena} can only be accessed (and closed) by the + * thread that created the arena. If access to a memory segment from multiple threads is required, clients can allocate + * segments in a {@linkplain #ofShared() shared arena} instead. + *

+ * The characteristics of the various arenas are summarized in the following table: + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Arenas characteristics
KindBounded lifetimeExplicitly closeableAccessible from multiple threads
GlobalNoNoYes
AutomaticYesNoYes
ConfinedYesYesNo
SharedYesYesYes
+ * *

Safety and thread-confinement

* * Arenas provide strong temporal safety guarantees: a memory segment allocated by an arena cannot be accessed * after the arena has been closed. The cost of providing this guarantee varies based on the * number of threads that have access to the memory segments allocated by the arena. For instance, if an arena - * is always created and closed by one thread, and the memory segments associated with the arena's scope are always + * is always created and closed by one thread, and the memory segments allocated by the arena are always * accessed by that same thread, then ensuring correctness is trivial. *

* Conversely, if an arena allocates segments that can be accessed by multiple threads, or if the arena can be closed @@ -70,34 +135,120 @@ import jdk.internal.javac.PreviewFeature; * impact, arenas are divided into thread-confined arenas, and shared arenas. *

* Confined arenas, support strong thread-confinement guarantees. Upon creation, they are assigned an - * {@linkplain #isCloseableBy(Thread) owner thread}, typically the thread which initiated the creation operation. - * The segments created by a confined arena can only be {@linkplain SegmentScope#isAccessibleBy(Thread) accessed} + * owner thread, typically the thread which initiated the creation operation. + * The segments created by a confined arena can only be {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} * by the owner thread. Moreover, any attempt to close the confined arena from a thread other than the owner thread will * fail with {@link WrongThreadException}. *

* Shared arenas, on the other hand, have no owner thread. The segments created by a shared arena - * can be {@linkplain SegmentScope#isAccessibleBy(Thread) accessed} by any thread. This might be useful when + * can be {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. This might be useful when * multiple threads need to access the same memory segment concurrently (e.g. in the case of parallel processing). - * Moreover, a shared arena {@linkplain #isCloseableBy(Thread) can be closed} by any thread. + * Moreover, a shared arena can be closed by any thread. + * + *

Custom arenas

+ * + * Clients can define custom arenas to implement more efficient allocation strategies, or to have better control over + * when (and by whom) an arena can be closed. As an example, the following code defines a slicing arena that behaves + * like a confined arena (i.e., single-threaded access), but internally uses a + * {@linkplain SegmentAllocator#slicingAllocator(MemorySegment) slicing allocator} to respond to allocation requests. + * When the slicing arena is closed, the underlying confined arena is also closed; this will invalidate all segments + * allocated with the slicing arena (since the scope of the slicing arena is the same as that of the underlying + * confined arena): + * + * {@snippet lang = java: + * class SlicingArena implements Arena { + * final Arena arena = Arena.ofConfined(); + * final SegmentAllocator slicingAllocator; + * + * SlicingArena(long size) { + * slicingAllocator = SegmentAllocator.slicingAllocator(arena.allocate(size)); + * } + * + * public void allocate(long byteSize, long byteAlignment) { + * return slicingAllocator.allocate(byteSize, byteAlignment); + * } + * + * public MemorySegment.Scope scope() { + * return arena.scope(); + * } + * + * public void close() { + * return arena.close(); + * } + * } + * } + * + * In other words, a slicing arena provides a vastly more efficient and scalable allocation strategy, while still retaining + * the timely deallocation guarantee provided by the underlying confined arena: + * + * {@snippet lang = java: + * try (Arena slicingArena = new SlicingArena(1000)) { + * for (int i = 0 ; i < 10 ; i++) { + * MemorySegment s = slicingArena.allocateArray(JAVA_INT, 1, 2, 3, 4, 5); + * ... + * } + * } // all memory allocated is released here + * } + * + * @implSpec + * Implementations of this interface are thread-safe. + * + * @see MemorySegment * * @since 20 */ @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) public interface Arena extends SegmentAllocator, AutoCloseable { + /** + * Creates a new arena that is managed, automatically, by the garbage collector. + * Segments obtained with the returned arena can be + * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. + * Calling {@link #close()} on the returned arena will result in an {@link UnsupportedOperationException}. + * + * @return a new arena that is managed, automatically, by the garbage collector. + */ + static Arena ofAuto() { + return MemorySessionImpl.createImplicit(CleanerFactory.cleaner()).asArena(); + } + + /** + * Obtains the global arena. Segments obtained with the global arena can be + * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. + * Calling {@link #close()} on the returned arena will result in an {@link UnsupportedOperationException}. + * + * @return the global arena. + */ + static Arena global() { + class Holder { + static final Arena GLOBAL = MemorySessionImpl.GLOBAL.asArena(); + } + return Holder.GLOBAL; + } + + /** + * {@return a new confined arena, owned by the current thread} + */ + static Arena ofConfined() { + return MemorySessionImpl.createConfined(Thread.currentThread()).asArena(); + } + + /** + * {@return a new shared arena} + */ + static Arena ofShared() { + return MemorySessionImpl.createShared().asArena(); + } + /** * Returns a native memory segment with the given size (in bytes) and alignment constraint (in bytes). - * The returned segment is associated with the arena scope. + * The returned segment is associated with this {@linkplain #scope() arena scope}. * The segment's {@link MemorySegment#address() address} is the starting address of the * allocated off-heap memory region backing the segment, and the address is * aligned according the provided alignment constraint. * * @implSpec - * The default implementation of this method is equivalent to the following code: - * {@snippet lang = java: - * MemorySegment.allocateNative(bytesSize, byteAlignment, scope()); - *} - * More generally implementations of this method must return a native segment featuring the requested size, + * Implementations of this method must return a native segment featuring the requested size, * and that is compatible with the provided alignment constraint. Furthermore, for any two segments * {@code S1, S2} returned by this method, the following invariant must hold: * @@ -110,57 +261,43 @@ public interface Arena extends SegmentAllocator, AutoCloseable { * @return a new native memory segment. * @throws IllegalArgumentException if {@code bytesSize < 0}, {@code alignmentBytes <= 0}, or if {@code alignmentBytes} * is not a power of 2. - * @throws IllegalStateException if the arena has already been {@linkplain #close() closed}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. - * @see MemorySegment#allocateNative(long, long, SegmentScope) + * @throws IllegalStateException if this arena has already been {@linkplain #close() closed}. + * @throws WrongThreadException if this arena is confined, and this method is called from a thread {@code T} + * other than the arena owner thread. */ @Override default MemorySegment allocate(long byteSize, long byteAlignment) { - return MemorySegment.allocateNative(byteSize, byteAlignment, scope()); + return ((MemorySessionImpl)scope()).allocate(byteSize, byteAlignment); } /** * {@return the arena scope} */ - SegmentScope scope(); + Scope scope(); /** - * Closes this arena. If this method completes normally, the arena scope is no longer {@linkplain SegmentScope#isAlive() alive}, + * Closes this arena. If this method completes normally, the arena scope is no longer {@linkplain Scope#isAlive() alive}, * and all the memory segments associated with it can no longer be accessed. Furthermore, any off-heap region of memory backing the - * segments associated with that scope are also released. + * segments obtained from this arena are also released. * * @apiNote This operation is not idempotent; that is, closing an already closed arena always results in an * exception being thrown. This reflects a deliberate design choice: failure to close an arena might reveal a bug * in the underlying application logic. * - * @see SegmentScope#isAlive() + * @implSpec If this method completes normally, then {@code this.scope().isAlive() == false}. + * Implementations are allowed to throw {@link UnsupportedOperationException} if an explicit close operation is + * not supported. + * + * @see Scope#isAlive() * * @throws IllegalStateException if the arena has already been closed. - * @throws IllegalStateException if the arena scope is {@linkplain SegmentScope#whileAlive(Runnable) kept alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code isCloseableBy(T) == false}. + * @throws IllegalStateException if a segment associated with this arena is being accessed concurrently, e.g. + * by a {@linkplain Linker#downcallHandle(FunctionDescriptor, Linker.Option...) downcall method handle}. + * @throws WrongThreadException if this arena is confined, and this method is called from a thread {@code T} + * other than the arena owner thread. + * @throws UnsupportedOperationException if this arena does not support explicit closure. */ @Override void close(); - /** - * {@return {@code true} if the provided thread can close this arena} - * @param thread the thread to be tested. - */ - boolean isCloseableBy(Thread thread); - - /** - * {@return a new confined arena, owned by the current thread} - */ - static Arena openConfined() { - return MemorySessionImpl.createConfined(Thread.currentThread()).asArena(); - } - - /** - * {@return a new shared arena} - */ - static Arena openShared() { - return MemorySessionImpl.createShared().asArena(); - } } diff --git a/src/java.base/share/classes/java/lang/foreign/FunctionDescriptor.java b/src/java.base/share/classes/java/lang/foreign/FunctionDescriptor.java index 3b6627d7f92..27759a78845 100644 --- a/src/java.base/share/classes/java/lang/foreign/FunctionDescriptor.java +++ b/src/java.base/share/classes/java/lang/foreign/FunctionDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -37,7 +37,7 @@ import jdk.internal.javac.PreviewFeature; * A function descriptor models the signature of foreign functions. A function descriptor is made up of zero or more * argument layouts and zero or one return layout. A function descriptor is typically used when creating * {@linkplain Linker#downcallHandle(MemorySegment, FunctionDescriptor, Linker.Option...) downcall method handles} or - * {@linkplain Linker#upcallStub(MethodHandle, FunctionDescriptor, SegmentScope) upcall stubs}. + * {@linkplain Linker#upcallStub(MethodHandle, FunctionDescriptor, Arena, Linker.Option...) upcall stubs}. * * @implSpec * Implementing classes are immutable, thread-safe and value-based. diff --git a/src/java.base/share/classes/java/lang/foreign/GroupLayout.java b/src/java.base/share/classes/java/lang/foreign/GroupLayout.java index 56ace4ee135..872f4923992 100644 --- a/src/java.base/share/classes/java/lang/foreign/GroupLayout.java +++ b/src/java.base/share/classes/java/lang/foreign/GroupLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -63,5 +63,14 @@ public sealed interface GroupLayout extends MemoryLayout permits StructLayout, U * {@inheritDoc} */ @Override + GroupLayout withoutName(); + + /** + * {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + * @throws IllegalArgumentException if {@code bitAlignment} is less than {@code M}, where {@code M} is the maximum alignment + * constraint in any of the member layouts associated with this group layout. + */ + @Override GroupLayout withBitAlignment(long bitAlignment); } diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java index 12ba7f6ce5f..3e6bfbb9e0f 100644 --- a/src/java.base/share/classes/java/lang/foreign/Linker.java +++ b/src/java.base/share/classes/java/lang/foreign/Linker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -34,8 +34,10 @@ import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import java.lang.invoke.MethodHandle; -import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -54,46 +56,340 @@ import java.util.stream.Stream; *
  • A linker allows Java code to link against foreign functions, via * {@linkplain #downcallHandle(MemorySegment, FunctionDescriptor, Option...) downcall method handles}; and
  • *
  • A linker allows foreign functions to call Java method handles, - * via the generation of {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, SegmentScope) upcall stubs}.
  • + * via the generation of {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, Arena, Option...) upcall stubs}. * * In addition, a linker provides a way to look up foreign functions in libraries that conform to the ABI. Each linker * chooses a set of libraries that are commonly used on the OS and processor combination associated with the ABI. * For example, a linker for Linux/x64 might choose two libraries: {@code libc} and {@code libm}. The functions in these * libraries are exposed via a {@linkplain #defaultLookup() symbol lookup}. - *

    - * The {@link #nativeLinker()} method provides a linker for the ABI associated with the OS and processor where the Java runtime - * is currently executing. This linker also provides access, via its {@linkplain #defaultLookup() default lookup}, - * to the native libraries loaded with the Java runtime. * - *

    Downcall method handles

    + *

    Calling native functions

    * - * {@linkplain #downcallHandle(FunctionDescriptor, Option...) Linking a foreign function} is a process which requires a function descriptor, - * a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns, - * when complete, a downcall method handle, that is, a method handle that can be used to invoke the target foreign function. - *

    - * The Java {@linkplain java.lang.invoke.MethodType method type} associated with the returned method handle is - * {@linkplain FunctionDescriptor#toMethodType() derived} from the argument and return layouts in the function descriptor. - * The downcall method handle type, might then be decorated by additional leading parameters, in the given order if both are present: - *

      - *
    • If the downcall method handle is created {@linkplain #downcallHandle(FunctionDescriptor, Option...) without specifying a target address}, - * the downcall method handle type features a leading parameter of type {@link MemorySegment}, from which the - * address of the target foreign function can be derived.
    • - *
    • If the function descriptor's return layout is a group layout, the resulting downcall method handle accepts - * an additional leading parameter of type {@link SegmentAllocator}, which is used by the linker runtime to allocate the - * memory region associated with the struct returned by the downcall method handle.
    • - *
    + * The {@linkplain #nativeLinker() native linker} can be used to link against functions + * defined in C libraries (native functions). Suppose we wish to downcall from Java to the {@code strlen} function + * defined in the standard C library: + * {@snippet lang = c: + * size_t strlen(const char *s); + * } + * A downcall method handle that exposes {@code strlen} is obtained, using the native linker, as follows: * - *

    Upcall stubs

    + * {@snippet lang = java: + * Linker linker = Linker.nativeLinker(); + * MethodHandle strlen = linker.downcallHandle( + * linker.defaultLookup().find("strlen").get(), + * FunctionDescriptor.of(JAVA_LONG, ADDRESS) + * ); + * } * - * {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, SegmentScope) Creating an upcall stub} requires a method - * handle and a function descriptor; in this case, the set of memory layouts in the function descriptor - * specify the signature of the function pointer associated with the upcall stub. + * Note how the native linker also provides access, via its {@linkplain #defaultLookup() default lookup}, + * to the native functions defined by the C libraries loaded with the Java runtime. Above, the default lookup + * is used to search the address of the {@code strlen} native function. That address is then passed, along with + * a platform-dependent description of the signature of the function expressed as a + * {@link FunctionDescriptor} (more on that below) to the native linker's + * {@link #downcallHandle(MemorySegment, FunctionDescriptor, Option...)} method. + * The obtained downcall method handle is then invoked as follows: + * + * {@snippet lang = java: + * try (Arena arena = Arena.openConfined()) { + * MemorySegment str = arena.allocateUtf8String("Hello"); + * long len = strlen.invoke(str); // 5 + * } + * } + *

    Describing C signatures

    + * + * When interacting with the native linker, clients must provide a platform-dependent description of the signature + * of the C function they wish to link against. This description, a {@link FunctionDescriptor function descriptor}, + * defines the layouts associated with the parameter types and return type (if any) of the C function. *

    - * The type of the provided method handle's type has to match the method type associated with the upcall stub, - * which is {@linkplain FunctionDescriptor#toMethodType() derived} from the provided function descriptor. + * Scalar C types such as {@code bool}, {@code int} are modelled as {@linkplain ValueLayout value layouts} + * of a suitable carrier. The mapping between a scalar type and its corresponding layout is dependent on the ABI + * implemented by the native linker. For instance, the C type {@code long} maps to the layout constant + * {@link ValueLayout#JAVA_LONG} on Linux/x64, but maps to the layout constant {@link ValueLayout#JAVA_INT} on + * Windows/x64. Similarly, the C type {@code size_t} maps to the layout constant {@link ValueLayout#JAVA_LONG} + * on 64-bit platforms, but maps to the layout constant {@link ValueLayout#JAVA_INT} on 32-bit platforms. *

    - * Upcall stubs are modelled by instances of type {@link MemorySegment}; upcall stubs can be passed by reference to other - * downcall method handles and, they are released via their associated {@linkplain SegmentScope scope}. + * Composite types are modelled as {@linkplain GroupLayout group layouts}. More specifically, a C {@code struct} type + * maps to a {@linkplain StructLayout struct layout}, whereas a C {@code union} type maps to a {@link UnionLayout union + * layout}. When defining a struct or union layout, clients must pay attention to the size and alignment constraint + * of the corresponding composite type definition in C. For instance, padding between two struct fields + * must be modelled explicitly, by adding an adequately sized {@linkplain PaddingLayout padding layout} member + * to the resulting struct layout. + *

    + * Finally, pointer types such as {@code int**} and {@code int(*)(size_t*, size_t*)} are modelled as + * {@linkplain AddressLayout address layouts}. When the spatial bounds of the pointer type are known statically, + * the address layout can be associated with a {@linkplain AddressLayout#targetLayout() target layout}. For instance, + * a pointer that is known to point to a C {@code int[2]} array can be modelled as an address layout whose + * target layout is a sequence layout whose element count is 2, and whose element type is {@link ValueLayout#JAVA_INT}. + *

    + * The following table shows some examples of how C types are modelled in Linux/x64: + * + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Mapping C types
    C typeLayoutJava type
    {@code bool}{@link ValueLayout#JAVA_BOOLEAN}{@code boolean}
    {@code char}{@link ValueLayout#JAVA_BYTE}{@code byte}
    {@code short}{@link ValueLayout#JAVA_SHORT}{@code short}
    {@code int}{@link ValueLayout#JAVA_INT}{@code int}
    {@code long}{@link ValueLayout#JAVA_LONG}{@code long}
    {@code long long}{@link ValueLayout#JAVA_LONG}{@code long}
    {@code float}{@link ValueLayout#JAVA_FLOAT}{@code float}
    {@code double}{@link ValueLayout#JAVA_DOUBLE}{@code double}
    {@code size_t}{@link ValueLayout#JAVA_LONG}{@code long}
    {@code char*}, {@code int**}, {@code struct Point*}{@link ValueLayout#ADDRESS}{@link MemorySegment}
    {@code int (*ptr)[10]} + *
    + * ValueLayout.ADDRESS.withTargetLayout(
    + *     MemoryLayout.sequenceLayout(10,
    + *         ValueLayout.JAVA_INT)
    + * );
    + * 
    + *
    {@link MemorySegment}
    struct Point { int x; long y; }; + *
    + * MemoryLayout.structLayout(
    + *     ValueLayout.JAVA_INT.withName("x"),
    + *     MemoryLayout.paddingLayout(32),
    + *     ValueLayout.JAVA_LONG.withName("y")
    + * );
    + * 
    + *
    {@link MemorySegment}
    union Choice { float a; int b; } + *
    + * MemoryLayout.unionLayout(
    + *     ValueLayout.JAVA_FLOAT.withName("a"),
    + *     ValueLayout.JAVA_INT.withName("b")
    + * );
    + * 
    + *
    {@link MemorySegment}
    + * + *

    Function pointers

    + * + * Sometimes, it is useful to pass Java code as a function pointer to some native function; this is achieved by using + * an {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, Arena, Option...) upcall stub}. To demonstrate this, + * let's consider the following function from the C standard library: + * + * {@snippet lang = c: + * void qsort(void *base, size_t nmemb, size_t size, + * int (*compar)(const void *, const void *)); + * } + * + * The {@code qsort} function can be used to sort the contents of an array, using a custom comparator function which is + * passed as a function pointer (the {@code compar} parameter). To be able to call the {@code qsort} function from Java, + * we must first create a downcall method handle for it, as follows: + * + * {@snippet lang = java: + * Linker linker = Linker.nativeLinker(); + * MethodHandle qsort = linker.downcallHandle( + * linker.defaultLookup().find("qsort").get(), + * FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG, JAVA_LONG, ADDRESS) + * ); + * } + * + * As before, we use {@link ValueLayout#JAVA_LONG} to map the C type {@code size_t} type, and {@link ValueLayout#ADDRESS} + * for both the first pointer parameter (the array pointer) and the last parameter (the function pointer). + *

    + * To invoke the {@code qsort} downcall handle obtained above, we need a function pointer to be passed as the last + * parameter. That is, we need to create a function pointer out of an existing method handle. First, let's write a + * Java method that can compare two int elements passed as pointers (i.e. as {@linkplain MemorySegment memory segments}): + * + * {@snippet lang = java: + * class Qsort { + * static int qsortCompare(MemorySegment elem1, MemorySegmet elem2) { + * return Integer.compare(elem1.get(JAVA_INT, 0), elem2.get(JAVA_INT, 0)); + * } + * } + * } + * + * Now let's create a method handle for the comparator method defined above: + * + * {@snippet lang = java: + * FunctionDescriptor comparDesc = FunctionDescriptor.of(JAVA_INT, + * ADDRESS.withTargetLayout(JAVA_INT), + * ADDRESS.withTargetLayout(JAVA_INT)); + * MethodHandle comparHandle = MethodHandles.lookup() + * .findStatic(Qsort.class, "qsortCompare", + * comparDesc.toMethodType()); + * } + * + * First, we create a function descriptor for the function pointer type. Since we know that the parameters passed to + * the comparator method will be pointers to elements of a C {@code int[]} array, we can specify {@link ValueLayout#JAVA_INT} + * as the target layout for the address layouts of both parameters. This will allow the comparator method to access + * the contents of the array elements to be compared. We then {@linkplain FunctionDescriptor#toMethodType() turn} + * that function descriptor into a suitable {@linkplain java.lang.invoke.MethodType method type} which we then use to look up + * the comparator method handle. We can now create an upcall stub which points to that method, and pass it, as a function + * pointer, to the {@code qsort} downcall handle, as follows: + * + * {@snippet lang = java: + * try (Arena arena = Arena.ofConfined()) { + * MemorySegment comparFunc = linker.upcallStub(comparHandle, comparDesc, arena); + * MemorySegment array = session.allocateArray(0, 9, 3, 4, 6, 5, 1, 8, 2, 7); + * qsort.invokeExact(array, 10L, 4L, comparFunc); + * int[] sorted = array.toArray(JAVA_INT); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] + * } + * } + * + * This code creates an off-heap array, copies the contents of a Java array into it, and then passes the array to the + * {@code qsort} method handle along with the comparator function we obtained from the native linker. After the invocation, the contents + * of the off-heap array will be sorted according to our comparator function, written in Java. We then extract a + * new Java array from the segment, which contains the sorted elements. + * + *

    Functions returning pointers

    + * + * When interacting with native functions, it is common for those functions to allocate a region of memory and return + * a pointer to that region. Let's consider the following function from the C standard library: + * + * {@snippet lang = c: + * void *malloc(size_t size); + * } + * + * The {@code malloc} function allocates a region of memory of given size, + * and returns a pointer to that region of memory, which is later deallocated using another function from + * the C standard library: + * + * {@snippet lang = c: + * void free(void *ptr); + * } + * + * The {@code free} function takes a pointer to a region of memory and deallocates that region. In this section we + * will show how to interact with these native functions, with the aim of providing a safe allocation + * API (the approach outlined below can of course be generalized to allocation functions other than {@code malloc} + * and {@code free}). + *

    + * First, we need to create the downcall method handles for {@code malloc} and {@code free}, as follows: + * + * {@snippet lang = java: + * Linker linker = Linker.nativeLinker(); + * + * MethodHandle malloc = linker.downcallHandle( + * linker.defaultLookup().find("malloc").get(), + * FunctionDescriptor.of(ADDRESS, JAVA_LONG) + * ); + * + * MethodHandle free = linker.downcallHandle( + * linker.defaultLookup().find("free").get(), + * FunctionDescriptor.ofVoid(ADDRESS) + * ); + * } + * + * When interacting with a native functions returning a pointer (such as {@code malloc}), the Java runtime has no insight + * into the size or the lifetime of the returned pointer. Consider the following code: + * + * {@snippet lang = java: + * MemorySegment segment = (MemorySegment)malloc.invokeExact(100); + * } + * + * The size of the segment returned by the {@code malloc} downcall method handle is + * zero. Moreover, the scope of the + * returned segment is a fresh scope that is always alive. To provide safe access to the segment, we must, + * unsafely, resize the segment to the desired size (100, in this case). It might also be desirable to + * attach the segment to some existing {@linkplain Arena arena}, so that the lifetime of the region of memory + * backing the segment can be managed automatically, as for any other native segment created directly from Java code. + * Both these operations are accomplished using the restricted {@link MemorySegment#reinterpret(long, Arena, Consumer)} + * method, as follows: + * + * {@snippet lang = java: + * MemorySegment allocateMemory(long byteSize, Arena arena) { + * MemorySegment segment = (MemorySegment)malloc.invokeExact(byteSize); // size = 0, scope = always alive + * return segment.reinterpret(byteSize, arena, s -> free.invokeExact(s)); // size = byteSize, scope = arena.scope() + * } + * } + * + * The {@code allocateMemory} method defined above accepts two parameters: a size and an arena. The method calls the + * {@code malloc} downcall method handle, and unsafely reinterprets the returned segment, by giving it a new size + * (the size passed to the {@code allocateMemory} method) and a new scope (the scope of the provided arena). + * The method also specifies a cleanup action to be executed when the provided arena is closed. Unsurprisingly, + * the cleanup action passes the segment to the {@code free} downcall method handle, to deallocate the underlying + * region of memory. We can use the {@code allocateMemory} method as follows: + * + * {@snippet lang = java: + * try (Arena arena = Arena.ofConfined()) { + * MemorySegment segment = allocateMemory(100, arena); + * } // 'free' called here + * } + * + * Note how the segment obtained from {@code allocateMemory} acts as any other segment managed by the confined arena. More + * specifically, the obtained segment has the desired size, can only be accessed by a single thread (the thread which created + * the confined arena), and its lifetime is tied to the surrounding try-with-resources block. + * + *

    Variadic functions

    + * + * Variadic functions (e.g. a C function declared with a trailing ellipses {@code ...} at the end of the formal parameter + * list or with an empty formal parameter list) are not supported directly by the native linker. However, it is still possible + * to link a variadic function by using a specialized function descriptor, together with a + * {@linkplain Linker.Option#firstVariadicArg(int) a linker option} which indicates the position of the first variadic argument + * in that specialized descriptor. + *

    + * A well-known variadic function is the {@code printf} function, defined in the C standard library: + * + * {@snippet lang = c: + * int printf(const char *format, ...); + * } + * + * This function takes a format string, and a number of additional arguments (the number of such arguments is + * dictated by the format string). Consider the following variadic call: + * + * {@snippet lang = c: + * printf("%d plus %d equals %d", 2, 2, 4); + * } + * + * To perform an equivalent call using a downcall method handle we must create a function descriptor which + * describes the specialized signature of the C function we want to call. This descriptor must include layouts for any + * additional variadic argument we intend to provide. In this case, the specialized signature of the C + * function is {@code (char*, int, int, int)} as the format string accepts three integer parameters. Then, we need to use + * a linker option to specify the position of the first variadic layout in the provided function descriptor (starting from 0). + * In this case, since the first parameter is the format string (a non-variadic argument), the first variadic index + * needs to be set to 1, as follows: + * + * {@snippet lang = java: + * Linker linker = Linker.nativeLinker(); + * MethodHandle printf = linker.downcallHandle( + * linker.defaultLookup().lookup("printf").get(), + * FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT), + * Linker.Option.firstVariadicArg(1) // first int is variadic + * ); + * } + * + * We can then call the specialized downcall handle as usual: + * + * {@snippet lang = java: + * try (Arena arena = Arena.ofConfined()) { + * int res = (int)printf.invokeExact(arena.allocateUtf8String("%d plus %d equals %d"), 2, 2, 4); //prints "2 plus 2 equals 4" + * } + * } * *

    Safety considerations

    * @@ -101,21 +397,7 @@ import java.util.stream.Stream; * contain enough signature information (e.g. arity and types of foreign function parameters). As a consequence, * the linker runtime cannot validate linkage requests. When a client interacts with a downcall method handle obtained * through an invalid linkage request (e.g. by specifying a function descriptor featuring too many argument layouts), - * the result of such interaction is unspecified and can lead to JVM crashes. On downcall handle invocation, - * the linker runtime guarantees the following for any argument {@code A} of type {@link MemorySegment} whose corresponding - * layout is {@link ValueLayout#ADDRESS}: - *
      - *
    • The scope of {@code A} is {@linkplain SegmentScope#isAlive() alive}. Otherwise, the invocation throws - * {@link IllegalStateException};
    • - *
    • The invocation occurs in a thread {@code T} such that {@code A.scope().isAccessibleBy(T) == true}. - * Otherwise, the invocation throws {@link WrongThreadException}; and
    • - *
    • The scope of {@code A} is {@linkplain SegmentScope#whileAlive(Runnable) kept alive} during the invocation.
    • - *
    - * A downcall method handle created from a function descriptor whose return layout is an - * {@linkplain ValueLayout.OfAddress address layout} returns a native segment associated with - * the {@linkplain SegmentScope#global() global scope}. Under normal conditions, the size of the returned segment is {@code 0}. - * However, if the return layout is an {@linkplain ValueLayout.OfAddress#asUnbounded() unbounded} address layout, - * then the size of the returned segment is {@code Long.MAX_VALUE}. + * the result of such interaction is unspecified and can lead to JVM crashes. *

    * When creating upcall stubs the linker runtime validates the type of the target method handle against the provided * function descriptor and report an error if any mismatch is detected. As for downcalls, JVM crashes might occur, @@ -124,12 +406,6 @@ import java.util.stream.Stream; * handle associated with an upcall stub returns a {@linkplain MemorySegment memory segment}, clients must ensure * that this address cannot become invalid after the upcall completes. This can lead to unspecified behavior, * and even JVM crashes, since an upcall is typically executed in the context of a downcall method handle invocation. - *

    - * An upcall stub argument whose corresponding layout is an {@linkplain ValueLayout.OfAddress address layout} - * is a native segment associated with the {@linkplain SegmentScope#global() global scope}. - * Under normal conditions, the size of this segment argument is {@code 0}. However, if the layout associated with - * the upcall stub argument is an {@linkplain ValueLayout.OfAddress#asUnbounded() unbounded} address layout, - * then the size of the segment argument is {@code Long.MAX_VALUE}. * * @implSpec * Implementations of this interface are immutable, thread-safe and value-based. @@ -143,31 +419,6 @@ public sealed interface Linker permits AbstractLinker { * Returns a linker for the ABI associated with the underlying native platform. The underlying native platform * is the combination of OS and processor where the Java runtime is currently executing. *

    - * When interacting with the returned linker, clients must describe the signature of a foreign function using a - * {@link FunctionDescriptor function descriptor} whose argument and return layouts are specified as follows: - *

      - *
    • Scalar types are modelled by a {@linkplain ValueLayout value layout} instance of a suitable carrier. Example - * of scalar types in C are {@code int}, {@code long}, {@code size_t}, etc. The mapping between a scalar type - * and its corresponding layout is dependent on the ABI of the returned linker; - *
    • Composite types are modelled by a {@linkplain GroupLayout group layout}. Depending on the ABI of the - * returned linker, additional {@linkplain MemoryLayout#paddingLayout(long) padding} member layouts might be required to conform - * to the size and alignment constraint of a composite type definition in C (e.g. using {@code struct} or {@code union}); and
    • - *
    • Pointer types are modelled by a {@linkplain ValueLayout value layout} instance with carrier {@link MemorySegment}. - * Examples of pointer types in C are {@code int**} and {@code int(*)(size_t*, size_t*)};
    • - *
    - *

    - * Any layout not listed above is unsupported; function descriptors containing unsupported layouts - * will cause an {@link IllegalArgumentException} to be thrown, when used to create a - * {@link #downcallHandle(MemorySegment, FunctionDescriptor, Option...) downcall method handle} or an - * {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, SegmentScope) upcall stub}. - *

    - * Variadic functions (e.g. a C function declared with a trailing ellipses {@code ...} at the end of the formal parameter - * list or with an empty formal parameter list) are not supported directly. However, it is possible to link a - * variadic function by using {@linkplain Linker.Option#firstVariadicArg(int) a linker option} to indicate - * the start of the list of variadic arguments, together with a specialized function descriptor describing a - * given variable arity callsite. Alternatively, where the foreign library allows it, clients might be able to - * interact with variadic functions by passing a trailing parameter of type {@link VaList} (e.g. as in {@code vsprintf}). - *

    * This method is restricted. * Restricted methods are unsafe, and, if used incorrectly, their use might crash * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on @@ -178,7 +429,7 @@ public sealed interface Linker permits AbstractLinker { * linker are the native libraries loaded in the process where the Java runtime is currently executing. For example, * on Linux, these libraries typically include {@code libc}, {@code libm} and {@code libdl}. * - * @return a linker for the ABI associated with the OS and processor where the Java runtime is currently executing. + * @return a linker for the ABI associated with the underlying native platform. * @throws UnsupportedOperationException if the underlying native platform is not supported. * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. */ @@ -189,11 +440,7 @@ public sealed interface Linker permits AbstractLinker { } /** - * Creates a method handle which can be used to call a foreign function with the given signature and address. - *

    - * If the provided method type's return type is {@code MemorySegment}, then the resulting method handle features - * an additional prefix parameter, of type {@link SegmentAllocator}, which will be used by the linker to allocate - * structs returned by-value. + * Creates a method handle which is used to call a foreign function with the given signature and address. *

    * Calling this method is equivalent to the following code: * {@snippet lang=java : @@ -214,17 +461,35 @@ public sealed interface Linker permits AbstractLinker { } /** - * Creates a method handle which can be used to call a foreign function with the given signature. - * The resulting method handle features a prefix parameter (as the first parameter) corresponding to the foreign function - * entry point, of type {@link MemorySegment}, which is used to specify the address of the target function - * to be called. + * Creates a method handle which is used to call a foreign function with the given signature. *

    - * If the provided function descriptor's return layout is a {@link GroupLayout}, then the resulting method handle features an - * additional prefix parameter (inserted immediately after the address parameter), of type {@link SegmentAllocator}), - * which will be used by the linker to allocate structs returned by-value. + * The Java {@linkplain java.lang.invoke.MethodType method type} associated with the returned method handle is + * {@linkplain FunctionDescriptor#toMethodType() derived} from the argument and return layouts in the function descriptor, + * but features an additional leading parameter of type {@link MemorySegment}, from which the address of the target + * foreign function is derived. Moreover, if the function descriptor's return layout is a group layout, the resulting + * downcall method handle accepts an additional leading parameter of type {@link SegmentAllocator}, which is used by + * the linker runtime to allocate the memory region associated with the struct returned by the downcall method handle. *

    - * The returned method handle will throw an {@link IllegalArgumentException} if the {@link MemorySegment} parameter passed to it is - * associated with the {@link MemorySegment#NULL} address, or a {@link NullPointerException} if that parameter is {@code null}. + * Upon invoking a downcall method handle, the linker runtime will guarantee the following for any argument + * {@code A} of type {@link MemorySegment} whose corresponding layout is an {@linkplain AddressLayout address layout}: + *

      + *
    • {@code A.scope().isAlive() == true}. Otherwise, the invocation throws {@link IllegalStateException};
    • + *
    • The invocation occurs in a thread {@code T} such that {@code A.isAccessibleBy(T) == true}. + * Otherwise, the invocation throws {@link WrongThreadException}; and
    • + *
    • {@code A} is kept alive during the invocation. For instance, if {@code A} has been obtained using a + * {@linkplain Arena#ofShared()} shared arena}, any attempt to {@linkplain Arena#close() close} + * the shared arena while the downcall method handle is executing will result in an {@link IllegalStateException}.
    • + *
    + *

    + * Moreover, if the provided function descriptor's return layout is an {@linkplain AddressLayout address layout}, + * invoking the returned method handle will return a native segment associated with + * a fresh scope that is always alive. Under normal conditions, the size of the returned segment is {@code 0}. + * However, if the function descriptor's return layout has a {@linkplain AddressLayout#targetLayout()} {@code T}, + * then the size of the returned segment is set to {@code T.byteSize()}. + *

    + * The returned method handle will throw an {@link IllegalArgumentException} if the {@link MemorySegment} + * representing the target address of the foreign function is the {@link MemorySegment#NULL} address. + * The returned method handle will additionally throw {@link NullPointerException} if any argument passed to it is {@code null}. * * @param function the function descriptor of the target function. * @param options any linker options. @@ -237,12 +502,19 @@ public sealed interface Linker permits AbstractLinker { /** * Creates a stub which can be passed to other foreign functions as a function pointer, associated with the given - * scope. Calling such a function pointer from foreign code will result in the execution of the provided + * arena. Calling such a function pointer from foreign code will result in the execution of the provided * method handle. *

    * The returned memory segment's address points to the newly allocated upcall stub, and is associated with - * the provided scope. As such, the corresponding upcall stub will be deallocated - * when the scope becomes not {@linkplain SegmentScope#isAlive() alive}. + * the provided arena. As such, the lifetime of the returned upcall stub segment is controlled by the + * provided arena. For instance, if the provided arena is a confined arena, the returned + * upcall stub segment will be deallocated when the provided confined arena is {@linkplain Arena#close() closed}. + *

    + * An upcall stub argument whose corresponding layout is an {@linkplain AddressLayout address layout} + * is a native segment associated with a fresh scope that is always alive. + * Under normal conditions, the size of this segment argument is {@code 0}. + * However, if the address layout has a {@linkplain AddressLayout#targetLayout()} {@code T}, then the size of the + * segment argument is set to {@code T.byteSize()}. *

    * The target method handle should not throw any exceptions. If the target method handle does throw an exception, * the VM will exit with a non-zero exit code. To avoid the VM aborting due to an uncaught exception, clients @@ -252,16 +524,17 @@ public sealed interface Linker permits AbstractLinker { * * @param target the target method handle. * @param function the upcall stub function descriptor. - * @param scope the scope associated with the returned upcall stub segment. + * @param arena the arena associated with the returned upcall stub segment. + * @param options any linker options. * @return a zero-length segment whose address is the address of the upcall stub. * @throws IllegalArgumentException if the provided function descriptor is not supported by this linker. * @throws IllegalArgumentException if it is determined that the target method handle can throw an exception, or if the target method handle * has a type that does not match the upcall stub inferred type. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. + * @throws IllegalStateException if {@code arena.scope().isAlive() == false} + * @throws WrongThreadException if {@code arena} is a confined arena, and this method is called from a + * thread {@code T}, other than the arena's owner thread. */ - MemorySegment upcallStub(MethodHandle target, FunctionDescriptor function, SegmentScope scope); + MemorySegment upcallStub(MethodHandle target, FunctionDescriptor function, Arena arena, Linker.Option... options); /** * Returns a symbol lookup for symbols in a set of commonly used libraries. @@ -285,8 +558,7 @@ public sealed interface Linker permits AbstractLinker { */ @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) sealed interface Option - permits LinkerOptions.LinkerOptionImpl, - Option.CaptureCallState { + permits LinkerOptions.LinkerOptionImpl { /** * {@return a linker option used to denote the index of the first variadic argument layout in a @@ -302,70 +574,91 @@ public sealed interface Linker permits AbstractLinker { * calling a foreign function associated with a downcall method handle, * before it can be overwritten by the Java runtime, or read through conventional means} *

    - * A downcall method handle linked with this option will feature an additional {@link MemorySegment} - * parameter directly following the target address, and optional {@link SegmentAllocator} parameters. - * This memory segment must be a native segment into which the captured state is written. - * - * @param capturedState the names of the values to save. - * @see CaptureCallState#supported() - */ - static CaptureCallState captureCallState(String... capturedState) { - Set set = Stream.of(capturedState) - .map(CapturableState::forName) - .collect(Collectors.toSet()); - return new LinkerOptions.CaptureCallStateImpl(set); - } - - /** - * A linker option for saving portions of the execution state immediately - * after calling a foreign function associated with a downcall method handle, - * before it can be overwritten by the runtime, or read through conventional means. - *

    * Execution state is captured by a downcall method handle on invocation, by writing it * to a native segment provided by the user to the downcall method handle. - * For this purpose, a downcall method handle linked with the {@link #captureCallState(String[])} + * For this purpose, a downcall method handle linked with this * option will feature an additional {@link MemorySegment} parameter directly * following the target address, and optional {@link SegmentAllocator} parameters. - * This parameter represents the native segment into which the captured state is written. + * This parameter, called the 'capture state segment', represents the native segment into which + * the captured state is written. *

    - * The native segment should have the layout {@linkplain CaptureCallState#layout associated} - * with the particular {@code CaptureCallState} instance used to link the downcall handle. + * The capture state segment should have the layout returned by {@linkplain #captureStateLayout}. + * This layout is a struct layout which has a named field for each captured value. *

    - * Captured state can be retrieved from this native segment by constructing var handles - * from the {@linkplain #layout layout} associated with the {@code CaptureCallState} instance. + * Captured state can be retrieved from the capture state segment by constructing var handles + * from the {@linkplain #captureStateLayout capture state layout}. *

    * The following example demonstrates the use of this linker option: * {@snippet lang = "java": * MemorySegment targetAddress = ... - * CaptureCallState ccs = Linker.Option.captureCallState("errno"); + * Linker.Option ccs = Linker.Option.captureCallState("errno"); * MethodHandle handle = Linker.nativeLinker().downcallHandle(targetAddress, FunctionDescriptor.ofVoid(), ccs); * - * VarHandle errnoHandle = ccs.layout().varHandle(PathElement.groupElement("errno")); - * try (Arena arena = Arena.openConfined()) { - * MemorySegment capturedState = arena.allocate(ccs.layout()); + * StructLayout capturedStateLayout = Linker.Option.capturedStateLayout(); + * VarHandle errnoHandle = capturedStateLayout.varHandle(PathElement.groupElement("errno")); + * try (Arena arena = Arena.ofConfined()) { + * MemorySegment capturedState = arena.allocate(capturedStateLayout); * handle.invoke(capturedState); * int errno = errnoHandle.get(capturedState); * // use errno * } * } + * + * @param capturedState the names of the values to save. + * @throws IllegalArgumentException if at least one of the provided {@code capturedState} names + * is unsupported on the current platform. + * @see #captureStateLayout() */ - @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) - sealed interface CaptureCallState extends Option - permits LinkerOptions.CaptureCallStateImpl { - /** - * {@return A struct layout that represents the layout of the native segment passed - * to a downcall handle linked with this {@code CapturedCallState} instance} - */ - StructLayout layout(); + static Option captureCallState(String... capturedState) { + Set set = Stream.of(Objects.requireNonNull(capturedState)) + .map(Objects::requireNonNull) + .map(CapturableState::forName) + .collect(Collectors.toSet()); + return new LinkerOptions.CaptureCallState(set); + } - /** - * {@return the names of the state that can be capture by this implementation} - */ - static Set supported() { - return Arrays.stream(CapturableState.values()) - .map(CapturableState::stateName) - .collect(Collectors.toSet()); - } + /** + * {@return A struct layout that represents the layout of the capture state segment that is passed + * to a downcall handle linked with {@link #captureCallState(String...)}}. + *

    + * The capture state layout is platform dependent but is guaranteed to be + * a {@linkplain StructLayout struct layout} containing only {@linkplain ValueLayout value layouts} + * and possibly {@linkplain PaddingLayout padding layouts}. + * As an example, on Windows, the returned layout might contain three value layouts named: + *

      + *
    • GetLastError
    • + *
    • WSAGetLastError
    • + *
    • errno
    • + *
    + * The following snipet shows how to obtain the names of the supported captured value layouts: + * {@snippet lang = java: + * String capturedNames = Linker.Option.captureStateLayout().memberLayouts().stream() + * .map(MemoryLayout::name) + * .flatMap(Optional::stream) + * .map(Objects::toString) + * .collect(Collectors.joining(", ")); + * } + * + * @see #captureCallState(String...) + */ + static StructLayout captureStateLayout() { + return CapturableState.LAYOUT; + } + + /** + * {@return A linker option used to mark a foreign function as trivial} + *

    + * A trivial function is a function that has an extremely short running time + * in all cases (similar to calling an empty function), and does not call back into Java (e.g. using an upcall stub). + *

    + * Using this linker option is a hint which some implementations may use to apply + * optimizations that are only valid for trivial functions. + *

    + * Using this linker option when linking non trivial functions is likely to have adverse effects, + * such as loss of performance, or JVM crashes. + */ + static Option isTrivial() { + return LinkerOptions.IsTrivial.INSTANCE; } } } diff --git a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java index 8d56202a04a..ecef9f55a82 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java +++ b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -28,7 +28,6 @@ package java.lang.foreign; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; import java.util.EnumSet; import java.util.Objects; import java.util.Optional; @@ -36,6 +35,7 @@ import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; + import jdk.internal.foreign.LayoutPath; import jdk.internal.foreign.LayoutPath.PathElementImpl.PathKind; import jdk.internal.foreign.Utils; @@ -44,7 +44,6 @@ import jdk.internal.foreign.layout.PaddingLayoutImpl; import jdk.internal.foreign.layout.SequenceLayoutImpl; import jdk.internal.foreign.layout.StructLayoutImpl; import jdk.internal.foreign.layout.UnionLayoutImpl; -import jdk.internal.foreign.layout.ValueLayouts; import jdk.internal.javac.PreviewFeature; /** @@ -200,6 +199,17 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin */ MemoryLayout withName(String name); + /** + * Returns a memory layout of the same type with the same size and alignment constraint as this layout, + * but without a name. + *

    + * This can be useful to compare two layouts that have different names, but are otherwise equal. + * + * @return a memory layout without a name. + * @see MemoryLayout#name() + */ + MemoryLayout withoutName(); + /** * Returns the alignment constraint associated with this layout, expressed in bits. Layout alignment defines a power * of two {@code A} which is the bit-wise alignment of the layout. If {@code A <= 8} then {@code A/8} is the number of @@ -235,10 +245,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @return the layout alignment constraint, in bytes. * @throws UnsupportedOperationException if {@code bitAlignment()} is not a multiple of 8. */ - default long byteAlignment() { - return Utils.bitsToBytesOrThrow(bitAlignment(), - () -> new UnsupportedOperationException("Cannot compute byte alignment; bit alignment is not a multiple of 8")); - } + long byteAlignment(); /** * Returns a memory layout of the same type with the same size and name as this layout, @@ -259,12 +266,14 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout, or if the * layout path contains one or more path elements that select multiple sequence element indices * (see {@link PathElement#sequenceElement()} and {@link PathElement#sequenceElement(long, long)}). + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). * @throws NullPointerException if either {@code elements == null}, or if any of the elements * in {@code elements} is {@code null}. */ default long bitOffset(PathElement... elements) { return computePathOp(LayoutPath.rootPath(this), LayoutPath::offset, - EnumSet.of(PathKind.SEQUENCE_ELEMENT, PathKind.SEQUENCE_RANGE), elements); + EnumSet.of(PathKind.SEQUENCE_ELEMENT, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements); } /** @@ -293,10 +302,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * specified by the given layout path elements, when supplied with the missing sequence element indices. * @throws IllegalArgumentException if the layout path contains one or more path elements that select * multiple sequence element indices (see {@link PathElement#sequenceElement(long, long)}). + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). */ default MethodHandle bitOffsetHandle(PathElement... elements) { return computePathOp(LayoutPath.rootPath(this), LayoutPath::offsetHandle, - EnumSet.of(PathKind.SEQUENCE_RANGE), elements); + EnumSet.of(PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements); } /** @@ -308,12 +319,14 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout, or if the * layout path contains one or more path elements that select multiple sequence element indices * (see {@link PathElement#sequenceElement()} and {@link PathElement#sequenceElement(long, long)}). + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). * @throws UnsupportedOperationException if {@code bitOffset(elements)} is not a multiple of 8. * @throws NullPointerException if either {@code elements == null}, or if any of the elements * in {@code elements} is {@code null}. */ default long byteOffset(PathElement... elements) { - return Utils.bitsToBytesOrThrow(bitOffset(elements), Utils.BITS_TO_BYTES_THROW_OFFSET); + return Utils.bitsToBytes(bitOffset(elements)); } /** @@ -346,10 +359,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * specified by the given layout path elements, when supplied with the missing sequence element indices. * @throws IllegalArgumentException if the layout path contains one or more path elements that select * multiple sequence element indices (see {@link PathElement#sequenceElement(long, long)}). + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). */ default MethodHandle byteOffsetHandle(PathElement... elements) { MethodHandle mh = bitOffsetHandle(elements); - mh = MethodHandles.filterReturnValue(mh, Utils.MH_BITS_TO_BYTES_OR_THROW_FOR_OFFSET); + mh = MethodHandles.filterReturnValue(mh, Utils.BITS_TO_BYTES); return mh; } @@ -379,6 +394,28 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin *

    * Additionally, the provided dynamic values must conform to some bound which is derived from the layout path, that is, * {@code 0 <= x_i < b_i}, where {@code 1 <= i <= n}, or {@link IndexOutOfBoundsException} is thrown. + *

    + * Multiple paths can be chained, by using {@linkplain PathElement#dereferenceElement() dereference path elements}. + * A dereference path element allows to obtain a native memory segment whose base address is the address obtained + * by following the layout path elements immediately preceding the dereference path element. In other words, + * if a layout path contains one or more dereference path elements, the final address accessed by the returned + * var handle can be computed as follows: + * + *

    {@code
    +     * address_1 = base(segment) + offset_1
    +     * address_2 = base(segment_1) + offset_2
    +     * ...
    +     * address_k = base(segment_k-1) + offset_k
    +     * }
    + * + * where {@code k} is the number of dereference path elements in a layout path, {@code segment} is the input segment, + * {@code segment_1}, ... {@code segment_k-1} are the segments obtained by dereferencing the address associated with + * a given dereference path element (e.g. {@code segment_1} is a native segment whose base address is {@code address_1}), + * and {@code offset_1}, {@code offset_2}, ... {@code offset_k} are the offsets computed by evaluating + * the path elements after a given dereference operation (these offsets are obtained using the computation described + * above). In these more complex access operations, all memory accesses immediately preceding a dereference operation + * (e.g. those at addresses {@code address_1}, {@code address_2}, ..., {@code address_k-1} are performed using the + * {@link VarHandle.AccessMode#GET} access mode. * * @apiNote the resulting var handle will feature an additional {@code long} access coordinate for every * unspecified sequence access component contained in this layout path. Moreover, the resulting var handle @@ -388,6 +425,8 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @return a var handle which can be used to access a memory segment at the (possibly nested) layout selected by the layout path in {@code elements}. * @throws UnsupportedOperationException if the layout path has one or more elements with incompatible alignment constraint. * @throws IllegalArgumentException if the layout path in {@code elements} does not select a value layout (see {@link ValueLayout}). + * @throws IllegalArgumentException if the layout path in {@code elements} contains a {@linkplain PathElement#dereferenceElement() + * dereference path element} for an address layout that has no {@linkplain AddressLayout#targetLayout() target layout}. * @see MethodHandles#memorySegmentViewVarHandle(ValueLayout) */ default VarHandle varHandle(PathElement... elements) { @@ -432,6 +471,8 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @param elements the layout path elements. * @return a method handle which can be used to create a slice of the selected layout element, given a segment. * @throws UnsupportedOperationException if the size of the selected layout in bits is not a multiple of 8. + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). */ default MethodHandle sliceHandle(PathElement... elements) { return computePathOp(LayoutPath.rootPath(this), LayoutPath::sliceHandle, @@ -446,10 +487,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout, * or if the layout path contains one or more path elements that select one or more sequence element indices * (see {@link PathElement#sequenceElement(long)} and {@link PathElement#sequenceElement(long, long)}). + * @throws IllegalArgumentException if the layout path contains one or more dereference path elements + * (see {@link PathElement#dereferenceElement()}). */ default MemoryLayout select(PathElement... elements) { return computePathOp(LayoutPath.rootPath(this), LayoutPath::layout, - EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE), elements); + EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements); } private static Z computePathOp(LayoutPath path, Function finalizer, @@ -489,6 +532,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * * @implSpec in case multiple group elements with a matching name exist, the path element returned by this * method will select the first one; that is, the group element with the lowest offset from current path is selected. + * In such cases, using {@link #groupElement(long)} might be preferable. * * @param name the name of the group element to be selected. * @return a path element which selects the group element with the given name. @@ -499,6 +543,23 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin path -> path.groupElement(name)); } + /** + * Returns a path element which selects a member layout with the given index in a group layout. + * The path element returned by this method does not alter the number of free dimensions of any path + * that is combined with such element. + * + * @param index the index of the group element to be selected. + * @return a path element which selects the group element with the given index. + * @throws IllegalArgumentException if {@code index < 0}. + */ + static PathElement groupElement(long index) { + if (index < 0) { + throw new IllegalArgumentException("Index < 0"); + } + return new LayoutPath.PathElementImpl(PathKind.GROUP_ELEMENT, + path -> path.groupElement(index)); + } + /** * Returns a path element which selects the element layout at the specified position in a sequence layout. * The path element returned by this method does not alter the number of free dimensions of any path @@ -578,6 +639,21 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin return new LayoutPath.PathElementImpl(PathKind.SEQUENCE_ELEMENT, LayoutPath::sequenceElement); } + + /** + * Returns a path element which dereferences an address layout as its + * {@linkplain AddressLayout#targetLayout() target layout} (where set). + * The path element returned by this method does not alter the number of free dimensions of any path + * that is combined with such element. Using this path layout to dereference an address layout + * that has no target layout results in an {@link IllegalArgumentException} (e.g. when + * a var handle is {@linkplain #varHandle(PathElement...) obtained}). + * + * @return a path element which dereferences an address layout. + */ + static PathElement dereferenceElement() { + return new LayoutPath.PathElementImpl(PathKind.DEREF_ELEMENT, + LayoutPath::derefElement); + } } /** @@ -611,60 +687,14 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin String toString(); /** - * Creates a padding layout with the given size. + * Creates a padding layout with the given bitSize and a bit-alignment of eight. * - * @param size the padding size in bits. + * @param bitSize the padding size in bits. * @return the new selector layout. - * @throws IllegalArgumentException if {@code size <= 0}. + * @throws IllegalArgumentException if {@code bitSize <= 0} or {@code bitSize % 8 != 0} */ - static PaddingLayout paddingLayout(long size) { - MemoryLayoutUtil.checkSize(size); - return PaddingLayoutImpl.of(size); - } - - /** - * Creates a value layout of given Java carrier and byte order. The type of resulting value layout is determined - * by the carrier provided: - *
      - *
    • {@link ValueLayout.OfBoolean}, for {@code boolean.class}
    • - *
    • {@link ValueLayout.OfByte}, for {@code byte.class}
    • - *
    • {@link ValueLayout.OfShort}, for {@code short.class}
    • - *
    • {@link ValueLayout.OfChar}, for {@code char.class}
    • - *
    • {@link ValueLayout.OfInt}, for {@code int.class}
    • - *
    • {@link ValueLayout.OfFloat}, for {@code float.class}
    • - *
    • {@link ValueLayout.OfLong}, for {@code long.class}
    • - *
    • {@link ValueLayout.OfDouble}, for {@code double.class}
    • - *
    • {@link ValueLayout.OfAddress}, for {@code MemorySegment.class}
    • - *
    - * @param carrier the value layout carrier. - * @param order the value layout's byte order. - * @return a value layout with the given Java carrier and byte-order. - * @throws IllegalArgumentException if the carrier type is not supported. - */ - static ValueLayout valueLayout(Class carrier, ByteOrder order) { - Objects.requireNonNull(carrier); - Objects.requireNonNull(order); - if (carrier == boolean.class) { - return ValueLayouts.OfBooleanImpl.of(order); - } else if (carrier == char.class) { - return ValueLayouts.OfCharImpl.of(order); - } else if (carrier == byte.class) { - return ValueLayouts.OfByteImpl.of(order); - } else if (carrier == short.class) { - return ValueLayouts.OfShortImpl.of(order); - } else if (carrier == int.class) { - return ValueLayouts.OfIntImpl.of(order); - } else if (carrier == float.class) { - return ValueLayouts.OfFloatImpl.of(order); - } else if (carrier == long.class) { - return ValueLayouts.OfLongImpl.of(order); - } else if (carrier == double.class) { - return ValueLayouts.OfDoubleImpl.of(order); - } else if (carrier == MemorySegment.class) { - return ValueLayouts.OfAddressImpl.of(order); - } else { - throw new IllegalArgumentException("Unsupported carrier: " + carrier.getName()); - } + static PaddingLayout paddingLayout(long bitSize) { + return PaddingLayoutImpl.of(MemoryLayoutUtil.requireBitSizeValid(bitSize, false)); } /** @@ -674,10 +704,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * @param elementLayout the sequence element layout. * @return the new sequence layout with the given element layout and size. * @throws IllegalArgumentException if {@code elementCount } is negative. + * @throws IllegalArgumentException if {@code elementLayout.bitAlignment() > elementLayout.bitSize()}. */ static SequenceLayout sequenceLayout(long elementCount, MemoryLayout elementLayout) { - MemoryLayoutUtil.checkSize(elementCount, true); + MemoryLayoutUtil.requireNonNegative(elementCount); Objects.requireNonNull(elementLayout); + Utils.checkElementAlignment(elementLayout, "Element layout alignment greater than its size"); return wrapOverflow(() -> SequenceLayoutImpl.of(elementCount, elementLayout)); } @@ -693,6 +725,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin * * @param elementLayout the sequence element layout. * @return a new sequence layout with the given element layout and maximum element count. + * @throws IllegalArgumentException if {@code elementLayout.bitAlignment() > elementLayout.bitSize()}. */ static SequenceLayout sequenceLayout(MemoryLayout elementLayout) { Objects.requireNonNull(elementLayout); diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java index 11633df2ce7..1580787431f 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -27,6 +27,8 @@ package java.lang.foreign; import java.io.UncheckedIOException; +import java.lang.foreign.Linker.Option; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.nio.Buffer; import java.nio.ByteBuffer; @@ -39,17 +41,17 @@ import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.Spliterator; +import java.util.function.Consumer; import java.util.stream.Stream; import jdk.internal.foreign.AbstractMemorySegmentImpl; import jdk.internal.foreign.HeapMemorySegmentImpl; +import jdk.internal.foreign.MemorySessionImpl; import jdk.internal.foreign.NativeMemorySegmentImpl; import jdk.internal.foreign.Utils; import jdk.internal.foreign.abi.SharedUtils; import jdk.internal.foreign.layout.ValueLayouts; import jdk.internal.javac.PreviewFeature; -import jdk.internal.misc.ScopedMemoryAccess; import jdk.internal.reflect.CallerSensitive; -import jdk.internal.reflect.Reflection; import jdk.internal.vm.annotation.ForceInline; /** @@ -63,10 +65,10 @@ import jdk.internal.vm.annotation.ForceInline; * Heap segments can be obtained by calling one of the {@link MemorySegment#ofArray(int[])} factory methods. * These methods return a memory segment backed by the on-heap region that holds the specified Java array. *

    - * Native segments can be obtained by calling one of the {@link MemorySegment#allocateNative(long, long, SegmentScope)} + * Native segments can be obtained by calling one of the {@link Arena#allocate(long, long)} * factory methods, which return a memory segment backed by a newly allocated off-heap region with the given size * and aligned to the given alignment constraint. Alternatively, native segments can be obtained by - * {@link FileChannel#map(MapMode, long, long, SegmentScope) mapping} a file into a new off-heap region + * {@link FileChannel#map(MapMode, long, long, Arena) mapping} a file into a new off-heap region * (in some systems, this operation is sometimes referred to as {@code mmap}). * Segments obtained in this way are called mapped segments, and their contents can be {@linkplain #force() persisted} and * {@linkplain #load() loaded} to and from the underlying memory-mapped file. @@ -91,23 +93,22 @@ import jdk.internal.vm.annotation.ForceInline; * Every memory segment has a {@linkplain #byteSize() size}. The size of a heap segment is derived from the Java array * from which it is obtained. This size is predictable across Java runtimes. * The size of a native segment is either passed explicitly - * (as in {@link MemorySegment#allocateNative(long, SegmentScope)}) or derived from a {@link MemoryLayout} - * (as in {@link MemorySegment#allocateNative(MemoryLayout, SegmentScope)}). The size of a memory segment is typically + * (as in {@link Arena#allocate(long, long)}) or derived from a {@link MemoryLayout} + * (as in {@link Arena#allocate(MemoryLayout)}). The size of a memory segment is typically * a positive number but may be zero, but never negative. *

    * The address and size of a memory segment jointly ensure that access operations on the segment cannot fall * outside the boundaries of the region of memory which backs the segment. * That is, a memory segment has spatial bounds. *

    - * Every memory segment is associated with a {@linkplain SegmentScope scope}. This ensures that access operations + * Every memory segment is associated with a {@linkplain Scope scope}. This ensures that access operations * on a memory segment cannot occur when the region of memory which backs the memory segment is no longer available - * (e.g., after the scope associated with the accessed memory segment is no longer {@linkplain SegmentScope#isAlive() alive}). + * (e.g., after the scope associated with the accessed memory segment is no longer {@linkplain Scope#isAlive() alive}). * That is, a memory segment has temporal bounds. *

    - * Finally, access operations on a memory segment are subject to the thread-confinement checks enforced by the associated - * scope; that is, if the segment is associated with the {@linkplain SegmentScope#global() global scope} or an {@linkplain SegmentScope#auto() automatic scope}, - * it can be accessed by multiple threads. If the segment is associated with an arena scope, then it can only be - * accessed compatibly with the arena confinement characteristics. + * Finally, access operations on a memory segment can be subject to additional thread-confinement checks. + * Heap segments can be accessed from any thread. Conversely, native segments can only be accessed compatibly with the + * confinement characteristics of the arena used to obtain them. * *

    Accessing memory segments

    * @@ -161,28 +162,28 @@ import jdk.internal.vm.annotation.ForceInline; * segment is derived from the address of the original segment, by adding an offset (expressed in bytes). The size of * the sliced segment is either derived implicitly (by subtracting the specified offset from the size of the original segment), * or provided explicitly. In other words, a sliced segment has stricter spatial bounds than those of the original segment: - * {@snippet lang=java : + * {@snippet lang = java: * Arena arena = ... * MemorySegment segment = arena.allocate(100); * MemorySegment slice = segment.asSlice(50, 10); * slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds! * arena.close(); * slice.get(ValueLayout.JAVA_INT, 0); // Already closed! - * } + *} * The above code creates a native segment that is 100 bytes long; then, it creates a slice that starts at offset 50 * of {@code segment}, and is 10 bytes long. That is, the address of the {@code slice} is {@code segment.address() + 50}, * and its size is 10. As a result, attempting to read an int value at offset 20 of the - * {@code slice} segment will result in an exception. The {@linkplain SegmentScope temporal bounds} of the original segment - * is inherited by its slices; that is, when the scope associated with {@code segment} is no longer {@linkplain SegmentScope#isAlive() alive}, + * {@code slice} segment will result in an exception. The {@linkplain Arena temporal bounds} of the original segment + * is inherited by its slices; that is, when the scope associated with {@code segment} is no longer {@linkplain Scope#isAlive() alive}, * {@code slice} will also be become inaccessible. *

    * A client might obtain a {@link Stream} from a segment, which can then be used to slice the segment (according to a given * element layout) and even allow multiple threads to work in parallel on disjoint segment slices - * (to do this, the segment has to be associated with a scope that allows {@linkplain SegmentScope#isAccessibleBy(Thread) access} + * (to do this, the segment has to be {@linkplain MemorySegment#isAccessibleBy(Thread) accessible} * from multiple threads). The following code can be used to sum all int values in a memory segment in parallel: * * {@snippet lang = java: - * try (Arena arena = Arena.openShared()) { + * try (Arena arena = Arena.ofShared()) { * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); * MemorySegment segment = arena.allocate(SEQUENCE_LAYOUT); * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() @@ -241,8 +242,8 @@ import jdk.internal.vm.annotation.ForceInline; *

    * The alignment constraint used to access a segment is typically dictated by the shape of the data structure stored * in the segment. For example, if the programmer wishes to store a sequence of 8-byte values in a native segment, then - * the segment should be allocated by specifying a 8-byte alignment constraint, either via {@link #allocateNative(long, long, SegmentScope)} - * or {@link #allocateNative(MemoryLayout, SegmentScope)}. These factories ensure that the off-heap region of memory backing + * the segment should be allocated by specifying a 8-byte alignment constraint, either via {@link Arena#allocate(long, long)} + * or {@link Arena#allocate(MemoryLayout)}. These factories ensure that the off-heap region of memory backing * the returned segment has a starting address that is 8-byte aligned. Subsequently, the programmer can access the * segment at the offsets of interest -- 0, 8, 16, 24, etc -- in the knowledge that every such access is aligned. *

    @@ -343,53 +344,82 @@ import jdk.internal.vm.annotation.ForceInline; * the region, stored in the pointer, is available. For example, a C function with return type {@code char*} might return * a pointer to a region containing a single {@code char} value, or to a region containing an array of {@code char} values, * where the size of the array might be provided in a separate parameter. The size of the array is not readily apparent - * to the code calling the foreign function and hoping to use its result. + * to the code calling the foreign function and hoping to use its result. In addition to having no insight + * into the size of the region of memory backing a pointer returned from a foreign function, it also has no insight + * into the lifetime intended for said region of memory by the foreign function that allocated it. *

    - * The {@link Linker} represents a pointer returned from a foreign function with a zero-length memory segment. - * The address of the segment is the address stored in the pointer. The size of the segment is zero. Similarly, when a - * client reads an address from a memory segment, a zero-length memory segment is returned. + * The {@code MemorySegment} API uses zero-length memory segments to represent: + *

    + * The address of the zero-length segment is the address stored in the pointer. The spatial and temporal bounds of the + * zero-length segment are as follows: + *
      + *
    • The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}. + * This is a crucial safety feature: as these segments are associated with a region + * of memory whose size is not known, any access operations involving these segments cannot be validated. + * In effect, a zero-length memory segment wraps an address, and it cannot be used without explicit intent + * (see below);
    • + *
    • The segment is associated with a fresh scope that is always alive. Thus, while zero-length + * memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.
    • + *
    *

    - * Since a zero-length segment features trivial spatial bounds, any attempt to access these segments will fail with - * {@link IndexOutOfBoundsException}. This is a crucial safety feature: as these segments are associated with a region - * of memory whose size is not known, any access operations involving these segments cannot be validated. - * In effect, a zero-length memory segment wraps an address, and it cannot be used without explicit intent. + * To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants + * to read a pointer from some memory segment. This can be done via the + * {@linkplain MemorySegment#get(AddressLayout, long)} access method. This method accepts an + * {@linkplain AddressLayout address layout} (e.g. {@link ValueLayout#ADDRESS}), the layout of the pointer + * to be read. For instance on a 64-bit platform, the size of an address layout is 64 bits. The access operation + * also accepts an offset, expressed in bytes, which indicates the position (relative to the start of the memory segment) + * at which the pointer is stored. The access operation returns a zero-length native memory segment, backed by a region + * of memory whose starting address is the 64-bit value read at the specified offset. *

    - * Zero-length memory segments obtained when interacting with foreign functions are associated with the - * {@link SegmentScope#global() global scope}. This is because the Java runtime, in addition to having no insight - * into the size of the region of memory backing a pointer returned from a foreign function, also has no insight - * into the lifetime intended for said region of memory by the foreign function that allocated it. The global scope - * ensures that the obtained segment can be passed, opaquely, to other pointer-accepting foreign functions. - *

    - * To access native zero-length memory segments, clients have two options, both of which are unsafe. Clients - * can {@linkplain java.lang.foreign.MemorySegment#ofAddress(long, long, SegmentScope) obtain} - * a new native segment, with new spatial and temporal bounds, as follows: + * The returned zero-length memory segment cannot be accessed directly by the client: since the size of the segment + * is zero, any access operation would result in out-of-bounds access. Instead, the client must, unsafely, + * assign new spatial bounds to the zero-length memory segment. This can be done via the + * {@link #reinterpret(long)} method, as follows: * * {@snippet lang = java: - * SegmentScope scope = ... // obtains a scope - * MemorySegment foreign = someSegment.get(ValueLayout.ADDRESS, 0); // wrap address into segment (size = 0) - * MemorySegment segment = MemorySegment.ofAddress(foreign.address(), 4, scope); // create new segment (size = 4) - * int x = segment.get(ValueLayout.JAVA_INT, 0); //ok + * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0 + * MemorySegment ptr = z.reinterpret(16); // size = 16 + * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok *} - * - * Alternatively, clients can obtain an {@linkplain java.lang.foreign.ValueLayout.OfAddress#asUnbounded() unbounded} - * address value layout. When an access operation, or a function descriptor that is passed to a downcall method handle, - * uses an unbounded address value layouts, the runtime will wrap any corresponding raw addresses with native segments - * with maximal size (i.e. {@linkplain java.lang.Long#MAX_VALUE}). As such, these segments can be accessed directly, as follows: + *

    + * In some cases, the client might additionally want to assign new temporal bounds to a zero-length memory segment. + * This can be done via the {@link #reinterpret(long, Arena, Consumer)} method, which returns a + * new native segment with the desired size and the same temporal bounds as those of the provided arena: * * {@snippet lang = java: - * MemorySegment foreign = someSegment.get(ValueLayout.ADDRESS.asUnbounded(), 0); // wrap address into segment (size = Long.MAX_VALUE) - * int x = foreign.get(ValueLayout.JAVA_INT, 0); //ok + * MemorySegment ptr = null; + * try (Arena arena = Arena.ofConfined()) { + * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0, scope = always alive + * ptr = z.reinterpret(16, arena, null); // size = 4, scope = arena.scope() + * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok + * } + * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // throws IllegalStateException *} * - * Both {@link #ofAddress(long, long, SegmentScope)} and {@link ValueLayout.OfAddress#asUnbounded()} are + * Alternatively, if the size of the region of memory backing the zero-length memory segment is known statically, + * the client can overlay a {@linkplain AddressLayout#withTargetLayout(MemoryLayout) target layout} on the address + * layout used when reading a pointer. The target layout is then used to dynamically + * expand the size of the native memory segment returned by the access operation, so that the size + * of the segment is the same as the size of the target layout. In other words, the returned segment is no + * longer a zero-length memory segment, and the pointer it represents can be dereferenced directly: + * + * {@snippet lang = java: + * AddressLayout intArrPtrLayout = ValueLayout.ADDRESS.withTargetLayout( + * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT)); // layout for int (*ptr)[4] + * MemorySegment ptr = segment.get(intArrPtrLayout, ...); // size = 16 + * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok + *} + *

    + * All the methods which can be used to manipulate zero-length memory segments + * ({@link #reinterpret(long)}, {@link #reinterpret(Arena, Consumer)}, {@link #reinterpret(long, Arena, Consumer)} and + * {@link AddressLayout#withTargetLayout(MemoryLayout)}) are * restricted methods, and should be used with caution: - * for instance, sizing a segment incorrectly could result in a VM crash when attempting to access the memory segment. - *

    - * Which approach is taken largely depends on the information that a client has available when obtaining a memory segment - * wrapping a native pointer. For instance, if such pointer points to a C struct, the client might prefer to resize the - * segment unsafely, to match the size of the struct (so that out-of-bounds access will be detected by the API). - * In other instances, however, there will be no, or little information as to what spatial and/or temporal bounds should - * be associated with a given native pointer. In these cases using an unbounded address layout might be preferable. + * assigning a segment incorrect spatial and/or temporal bounds could result in a VM crash when attempting to access + * the memory segment. * * @implSpec * Implementations of this interface are immutable, thread-safe and value-based. @@ -405,9 +435,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { long address(); /** - * {@return the Java array associated with this memory segment, if any} + * Returns the Java object stored in the on-heap memory region backing this memory segment, if any. For instance, if this + * memory segment is a heap segment created with the {@link #ofArray(byte[])} factory method, this method will return the + * {@code byte[]} object which was used to obtain the segment. This method returns an empty {@code Optional} value + * if either this segment is a {@linkplain #isNative() native} segment, or if this segment is {@linkplain #isReadOnly() read-only}. + * @return the Java object associated with this memory segment, if any. */ - Optional array(); + Optional heapBase(); /** * Returns a spliterator for this memory segment. The returned spliterator reports {@link Spliterator#SIZED}, @@ -418,7 +452,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving * approximately {@code S/N} elements (depending on whether N is even or not), where {@code S} is the size of * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that - * are associated with the same scope as that associated with this segment. + * have the same lifetime as that of this segment. *

    * The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices}, * which can then be processed in parallel by multiple threads. @@ -451,7 +485,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * {@return the scope associated with this memory segment} */ - SegmentScope scope(); + Scope scope(); + + /** + * {@return {@code true} if this segment can be accessed from the provided thread} + * @param thread the thread to be tested. + */ + boolean isAccessibleBy(Thread thread); /** * {@return the size (in bytes) of this memory segment} @@ -461,8 +501,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address * of this segment plus the given offset; its size is specified by the given argument. + *

    + * Equivalent to the following code: + * {@snippet lang=java : + * asSlice(offset, layout.byteSize(), 1); + * } * - * @see #asSlice(long) + * @see #asSlice(long, long, long) * * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. * @param newSize The new segment size, specified in bytes. @@ -471,6 +516,44 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { */ MemorySegment asSlice(long offset, long newSize); + /** + * Returns a slice of this memory segment, at the given offset, with the provided alignment constraint. + * The returned segment's address is the address of this segment plus the given offset; its size is specified by the given argument. + * + * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. + * @param newSize The new segment size, specified in bytes. + * @param byteAlignment The alignment constraint (in bytes) of the returned slice. + * @return a slice of this memory segment. + * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, or {@code newSize > byteSize() - offset} + * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under + * the provided alignment constraint. + */ + MemorySegment asSlice(long offset, long newSize, long byteAlignment); + + /** + * Returns a slice of this memory segment with the given layout, at the given offset. The returned segment's address is the address + * of this segment plus the given offset; its size is the same as the size of the provided layout. + *

    + * Equivalent to the following code: + * {@snippet lang=java : + * asSlice(offset, layout.byteSize(), layout.byteAlignment()); + * } + * + * @see #asSlice(long, long, long) + * + * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. + * @param layout The layout of the segment slice. + * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > layout.byteSize()}, + * {@code newSize < 0}, or {@code newSize > layout.byteSize() - offset} + * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under + * the alignment constraint specified by {@code layout}. + * @return a slice of this memory segment. + */ + default MemorySegment asSlice(long offset, MemoryLayout layout) { + Objects.requireNonNull(layout); + return asSlice(offset, layout.byteSize(), layout.byteAlignment()); + } + /** * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address * of this segment plus the given offset; its size is computed by subtracting the specified offset from this segment size. @@ -486,9 +569,110 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @return a slice of this memory segment. * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}. */ - default MemorySegment asSlice(long offset) { - return asSlice(offset, byteSize() - offset); - } + MemorySegment asSlice(long offset); + + /** + * Returns a new memory segment that has the same address and scope as this segment, but with the provided size. + *

    + * This method is restricted. + * Restricted methods are unsafe, and, if used incorrectly, their use might crash + * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on + * restricted methods, and use safe and supported functionalities, where possible. + * + * @param newSize the size of the returned segment. + * @return a new memory segment that has the same address and scope as this segment, but the new + * provided size. + * @throws IllegalArgumentException if {@code newSize < 0}. + * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. + * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. + */ + @CallerSensitive + MemorySegment reinterpret(long newSize); + + /** + * Returns a new memory segment with the same address and size as this segment, but with the provided scope. + * As such, the returned segment cannot be accessed after the provided arena has been closed. + * Moreover, the returned segment can be accessed compatibly with the confinement restrictions associated with the + * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena}, + * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions + * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated + * using the provided arena. + *

    + * Clients can specify an optional cleanup action that should be executed when the provided scope becomes + * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows: + * {@snippet lang=java : + * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address()); + * } + * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive, + * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}. + *

    + * This method is restricted. + * Restricted methods are unsafe, and, if used incorrectly, their use might crash + * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on + * restricted methods, and use safe and supported functionalities, where possible. + * + * @apiNote The cleanup action (if present) should take care not to leak the received segment to external + * clients which might access the segment after its backing region of memory is no longer available. Furthermore, + * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action + * must not prevent the scope from becoming unreachable. + * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated. + *

    + * This method is restricted. + * Restricted methods are unsafe, and, if used incorrectly, their use might crash + * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on + * restricted methods, and use safe and supported functionalities, where possible. + * + * @param arena the arena to be associated with the returned segment. + * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}). + * @return a new memory segment with unbounded size. + * @throws IllegalArgumentException if {@code newSize < 0}. + * @throws IllegalStateException if {@code scope.isAlive() == false}. + * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. + * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. + */ + @CallerSensitive + MemorySegment reinterpret(Arena arena, Consumer cleanup); + + /** + * Returns a new segment with the same address as this segment, but with the provided size and scope. + * As such, the returned segment cannot be accessed after the provided arena has been closed. + * Moreover, if the returned segment can be accessed compatibly with the confinement restrictions associated with the + * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena}, + * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions + * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated + * using the provided arena. + *

    + * Clients can specify an optional cleanup action that should be executed when the provided scope becomes + * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows: + * {@snippet lang=java : + * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address()); + * } + * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive, + * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}. + *

    + * This method is restricted. + * Restricted methods are unsafe, and, if used incorrectly, their use might crash + * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on + * restricted methods, and use safe and supported functionalities, where possible. + * + * @apiNote The cleanup action (if present) should take care not to leak the received segment to external + * clients which might access the segment after its backing region of memory is no longer available. Furthermore, + * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action + * must not prevent the scope from becoming unreachable. + * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated. + * + * @param newSize the size of the returned segment. + * @param arena the arena to be associated with the returned segment. + * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}). + * @return a new segment that has the same address as this segment, but with new size and its scope set to + * that of the provided arena. + * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. + * @throws IllegalArgumentException if {@code newSize < 0}. + * @throws IllegalStateException if {@code scope.isAlive() == false}. + * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. + */ + @CallerSensitive + MemorySegment reinterpret(long newSize, Arena arena, Consumer cleanup); /** * {@return {@code true}, if this segment is read-only} @@ -506,7 +690,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Returns {@code true} if this segment is a native segment. A native segment is - * created e.g. using the {@link #allocateNative(long, SegmentScope)} (and related) factory, or by + * created e.g. using the {@link Arena#allocate(long, long)} (and related) factory, or by * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain ByteBuffer#allocateDirect(int) direct buffer}. * @return {@code true} if this segment is native segment. */ @@ -514,7 +698,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Returns {@code true} if this segment is a mapped segment. A mapped memory segment is created e.g. using the - * {@link FileChannel#map(FileChannel.MapMode, long, long, SegmentScope)} factory, or by + * {@link FileChannel#map(FileChannel.MapMode, long, long, Arena)} factory, or by * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain java.nio.MappedByteBuffer mapped byte buffer}. * @return {@code true} if this segment is a mapped segment. */ @@ -581,9 +765,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param value the value to fill into this segment * @return this memory segment * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}). */ MemorySegment fill(byte value); @@ -600,13 +784,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param src the source segment. * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code src} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code src.scope().isAccessibleBy(T) == false}. + * such that {@code src.isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}). * @return this segment. */ @@ -634,13 +818,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @return the relative offset, in bytes, of the first mismatch between this * and the given other segment, otherwise -1 if no mismatch * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code other} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code other.scope().isAccessibleBy(T) == false}. + * such that {@code other.isAccessibleBy(T) == false}. */ default long mismatch(MemorySegment other) { Objects.requireNonNull(other); @@ -666,9 +850,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * is resident in physical memory * * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if * {@code isMapped() == false}. */ @@ -683,9 +867,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * occur.

    * * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if * {@code isMapped() == false}. */ @@ -700,9 +884,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * occur (as this segment's contents might need to be paged back in).

    * * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if * {@code isMapped() == false}. */ @@ -729,9 +913,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { *

    * * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if * {@code isMapped() == false}. * @throws UncheckedIOException if there is an I/O error writing the contents of this segment to the associated storage device @@ -751,11 +935,11 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * returned if this segment' size is greater than {@link Integer#MAX_VALUE}. *

    * The life-cycle of the returned buffer will be tied to that of this segment. That is, accessing the returned buffer - * after the scope associated with this segment is no longer {@linkplain SegmentScope#isAlive() alive}, will + * after the scope associated with this segment is no longer {@linkplain Scope#isAlive() alive}, will * throw an {@link IllegalStateException}. Similarly, accessing the returned buffer from a thread {@code T} - * such that {@code scope().isAccessible(T) == false} will throw a {@link WrongThreadException}. + * such that {@code isAccessible(T) == false} will throw a {@link WrongThreadException}. *

    - * If this segment is associated with a scope that can only be accessed from a single thread, calling read/write I/O + * If this segment is accessible from a single thread, calling read/write I/O * operations on the resulting buffer might result in an unspecified exception being thrown. Examples of such problematic operations are * {@link java.nio.channels.AsynchronousSocketChannel#read(ByteBuffer)} and * {@link java.nio.channels.AsynchronousSocketChannel#write(ByteBuffer)}. @@ -776,9 +960,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new byte array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code byte[]} instance, * e.g. its size is greater than {@link Integer#MAX_VALUE}. */ @@ -790,9 +974,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new short array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code short[]} instance, * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE} */ @@ -804,9 +988,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new char array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code char[]} instance, * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE}. */ @@ -818,9 +1002,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new int array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code int[]} instance, * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}. */ @@ -832,9 +1016,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new float array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code float[]} instance, * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}. */ @@ -846,9 +1030,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new long array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code long[]} instance, * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}. */ @@ -860,9 +1044,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. * @return a new double array whose contents are copied from this memory segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalStateException if this segment's contents cannot be copied into a {@code double[]} instance, * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}. */ @@ -882,9 +1066,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code S + offset > byteSize()}, where {@code S} is the size of the UTF-8 * string (including the terminator character). * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. */ default String getUtf8String(long offset) { return SharedUtils.toJavaStringInternal(this, offset); @@ -907,9 +1091,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param str the Java string to be written into this segment. * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code str.getBytes().length() + offset >= byteSize()}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. */ default void setUtf8String(long offset, String str) { Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset))); @@ -924,15 +1108,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * {@linkplain ByteBuffer#isReadOnly() read-only}. Moreover, if the buffer is a {@linkplain Buffer#isDirect() direct buffer}, * the returned segment is a native segment; otherwise the returned memory segment is a heap segment. *

    - * The scope {@code S} associated with the returned segment is computed as follows: - *

      - *
    • if the buffer has been obtained by calling {@link #asByteBuffer()} on a memory segment whose scope - * is {@code S'}, then {@code S = S'}; or
    • - *
    • if the buffer is a heap buffer, then {@code S} is the {@linkplain SegmentScope#global() global scope}; or - *
    • if the buffer is a direct buffer, then {@code S} is a scope that is always alive and which keeps the buffer reachable. - * Therefore, the off-heap region of memory backing the buffer instance will remain available as long as the - * returned segment is reachable.
    • - *
    + * If the provided buffer has been obtained by calling {@link #asByteBuffer()} on a memory segment whose + * {@linkplain Scope scope} is {@code S}, the returned segment will be associated with the + * same scope {@code S}. Otherwise, the scope of the returned segment is a fresh scope that is always alive. + *

    + * The scope associated with the returned segment keeps the provided buffer reachable. As such, if + * the provided buffer is a direct buffer, its backing memory region will not be deallocated as long as the + * returned segment (or any of its slices) are kept reachable. * * @param buffer the buffer instance to be turned into a new memory segment. * @return a memory segment, derived from the given buffer instance. @@ -947,8 +1129,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given byte array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param byteArray the primitive array backing the heap memory segment. * @return a heap memory segment backed by a byte array. @@ -959,8 +1141,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given char array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param charArray the primitive array backing the heap segment. * @return a heap memory segment backed by a char array. @@ -971,8 +1153,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given short array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param shortArray the primitive array backing the heap segment. * @return a heap memory segment backed by a short array. @@ -983,8 +1165,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given int array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param intArray the primitive array backing the heap segment. * @return a heap memory segment backed by an int array. @@ -995,8 +1177,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given float array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param floatArray the primitive array backing the heap segment. * @return a heap memory segment backed by a float array. @@ -1007,8 +1189,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given long array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param longArray the primitive array backing the heap segment. * @return a heap memory segment backed by a long array. @@ -1019,8 +1201,8 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Creates a heap segment backed by the on-heap region of memory that holds the given double array. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}, and - * its {@link #address()} is set to zero. + * The scope of the returned segment is a fresh scope that is always alive, and keeps the given byte array reachable. + * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. * * @param doubleArray the primitive array backing the heap segment. * @return a heap memory segment backed by a double array. @@ -1032,16 +1214,16 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * A zero-length native segment modelling the {@code NULL} address. */ - MemorySegment NULL = NativeMemorySegmentImpl.makeNativeSegmentUnchecked(0L, 0); + MemorySegment NULL = new NativeMemorySegmentImpl(); /** * Creates a zero-length native segment from the given {@linkplain #address() address value}. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}. + * The returned segment is always accessible, from any thread. *

    - * This is equivalent to the following code: - * {@snippet lang = java: - * ofAddress(address, 0); - *} + * On 32-bit platforms, the given address value will be normalized such that the + * highest-order ("leftmost") 32 bits of the {@link MemorySegment#address() address} + * of the returned memory segment are set to zero. + * * @param address the address of the returned native segment. * @return a zero-length native segment with the given address. */ @@ -1049,208 +1231,6 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, 0); } - /** - * Creates a native segment with the given size and {@linkplain #address() address value}. - * The returned segment is associated with the {@linkplain SegmentScope#global() global scope}. - *

    - * This is equivalent to the following code: - * {@snippet lang = java: - * ofAddress(address, byteSize, SegmentScope.global()); - *} - * This method is restricted. - * Restricted methods are unsafe, and, if used incorrectly, their use might crash - * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on - * restricted methods, and use safe and supported functionalities, where possible. - * @param address the address of the returned native segment. - * @param byteSize the size (in bytes) of the returned native segment. - * @return a zero-length native segment with the given address and size. - * @throws IllegalArgumentException if {@code byteSize < 0}. - * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. - */ - @CallerSensitive - static MemorySegment ofAddress(long address, long byteSize) { - Reflection.ensureNativeAccess(Reflection.getCallerClass(), MemorySegment.class, "ofAddress"); - return MemorySegment.ofAddress(address, byteSize, SegmentScope.global()); - } - - /** - * Creates a native segment with the given size, address, and scope. - * This method can be useful when interacting with custom memory sources (e.g. custom allocators), - * where an address to some underlying region of memory is typically obtained from foreign code - * (often as a plain {@code long} value). - *

    - * The returned segment is not read-only (see {@link MemorySegment#isReadOnly()}), and is associated with the - * provided scope. - *

    - * This is equivalent to the following code: - * {@snippet lang = java: - * ofAddress(address, byteSize, scope, null); - *} - * This method is restricted. - * Restricted methods are unsafe, and, if used incorrectly, their use might crash - * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on - * restricted methods, and use safe and supported functionalities, where possible. - * @param address the returned segment's address. - * @param byteSize the desired size. - * @param scope the scope associated with the returned native segment. - * @return a native segment with the given address, size and scope. - * @throws IllegalArgumentException if {@code byteSize < 0}. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. - * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. - */ - @CallerSensitive - @ForceInline - static MemorySegment ofAddress(long address, long byteSize, SegmentScope scope) { - Reflection.ensureNativeAccess(Reflection.getCallerClass(), MemorySegment.class, "ofAddress"); - Objects.requireNonNull(scope); - Utils.checkAllocationSizeAndAlign(byteSize, 1); - return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, byteSize, scope, null); - } - - /** - * Creates a native segment with the given size, address, and scope. - * This method can be useful when interacting with custom memory sources (e.g. custom allocators), - * where an address to some underlying region of memory is typically obtained from foreign code - * (often as a plain {@code long} value). - *

    - * The returned segment is not read-only (see {@link MemorySegment#isReadOnly()}), and is associated with the - * provided scope. - *

    - * The provided cleanup action (if any) will be invoked when the scope becomes not {@linkplain SegmentScope#isAlive() alive}. - *

    - * Clients should ensure that the address and bounds refer to a valid region of memory that is accessible for reading and, - * if appropriate, writing; an attempt to access an invalid address from Java code will either return an arbitrary value, - * have no visible effect, or cause an unspecified exception to be thrown. - *

    - * This method is restricted. - * Restricted methods are unsafe, and, if used incorrectly, their use might crash - * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on - * restricted methods, and use safe and supported functionalities, where possible. - * - * - * @param address the returned segment's address. - * @param byteSize the desired size. - * @param scope the scope associated with the returned native segment. - * @param cleanupAction the custom cleanup action to be associated to the returned segment (can be null). - * @return a native segment with the given address, size and scope. - * @throws IllegalArgumentException if {@code byteSize < 0}. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. - * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. - */ - @CallerSensitive - static MemorySegment ofAddress(long address, long byteSize, SegmentScope scope, Runnable cleanupAction) { - Reflection.ensureNativeAccess(Reflection.getCallerClass(), MemorySegment.class, "ofAddress"); - Objects.requireNonNull(scope); - Utils.checkAllocationSizeAndAlign(byteSize, 1); - return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, byteSize, scope, cleanupAction); - } - - /** - * Creates a native segment with the given layout and scope. - *

    - * The lifetime off-heap region of memory associated with the returned native segment is determined by the - * provided scope. The off-heap memory region is deallocated when the scope becomes not - * {@linkplain SegmentScope#isAlive() alive}. If the scope has been obtained using an {@link Arena}, - * clients are responsible for ensuring that the arena is closed when the returned segment is no longer in use - * Failure to do so will result in off-heap memory leaks. As an alternative, an {@linkplain SegmentScope#auto() automatic scope} - * can be used, allowing the off-heap memory region associated with the returned native segment to be - * automatically released some unspecified time after the scope is no longer referenced. - *

    - * The {@linkplain #address() address} of the returned memory segment is the starting address of - * the newly allocated off-heap region backing the segment. Moreover, the {@linkplain #address() address} - * of the returned segment will be aligned according to the alignment constraint of the provided layout. - *

    - * This is equivalent to the following code: - * {@snippet lang=java : - * allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope); - * } - *

    - * The region of off-heap region backing the returned native segment is initialized to zero. - * - * @param layout the layout of the off-heap memory region backing the native segment. - * @param scope the scope associated with the returned native segment. - * @return a new native segment. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. - */ - static MemorySegment allocateNative(MemoryLayout layout, SegmentScope scope) { - Objects.requireNonNull(layout); - Objects.requireNonNull(scope); - return allocateNative(layout.byteSize(), layout.byteAlignment(), scope); - } - - /** - * Creates a native segment with the given size (in bytes) and scope. - *

    - * The lifetime off-heap region of memory associated with the returned native segment is determined by the - * provided scope. The off-heap memory region is deallocated when the scope becomes not - * {@linkplain SegmentScope#isAlive() alive}. If the scope has been obtained using an {@link Arena}, - * clients are responsible for ensuring that the arena is closed when the returned segment is no longer in use - * Failure to do so will result in off-heap memory leaks. As an alternative, an {@linkplain SegmentScope#auto() automatic scope} - * can be used, allowing the off-heap memory region associated with the returned native segment to be - * automatically released some unspecified time after the scope is no longer referenced. - *

    - * The {@linkplain #address() address} of the returned memory segment is the starting address of - * the newly allocated off-heap region backing the segment. Moreover, the {@linkplain #address() address} - * of the returned segment is guaranteed to be at least 1-byte aligned. - *

    - * This is equivalent to the following code: - * {@snippet lang=java : - * allocateNative(bytesSize, 1, scope); - * } - *

    - * The region of off-heap region backing the returned native segment is initialized to zero. - * - * @param byteSize the size (in bytes) of the off-heap memory region of memory backing the native memory segment. - * @param scope the scope associated with the returned native segment. - * @return a new native memory segment. - * @throws IllegalArgumentException if {@code byteSize < 0}. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. - */ - static MemorySegment allocateNative(long byteSize, SegmentScope scope) { - return allocateNative(byteSize, 1, scope); - } - - /** - * Creates a native segment with the given size (in bytes), alignment (in bytes) and scope. - *

    - * The lifetime off-heap region of memory associated with the returned native segment is determined by the - * provided scope. The off-heap memory region is deallocated when the scope becomes not - * {@linkplain SegmentScope#isAlive() alive}. If the scope has been obtained using an {@link Arena}, - * clients are responsible for ensuring that the arena is closed when the returned segment is no longer in use - * Failure to do so will result in off-heap memory leaks. As an alternative, an {@linkplain SegmentScope#auto() automatic scope} - * can be used, allowing the off-heap memory region associated with the returned native segment to be - * automatically released some unspecified time after the scope is no longer referenced. - *

    - * The {@linkplain #address() address} of the returned memory segment is the starting address of - * the newly allocated off-heap region backing the segment. Moreover, the {@linkplain #address() address} - * of the returned segment will be aligned according to the provided alignment constraint. - *

    - * The region of off-heap region backing the returned native segment is initialized to zero. - * - * @param byteSize the size (in bytes) of the off-heap region of memory backing the native memory segment. - * @param byteAlignment the alignment constraint (in bytes) of the off-heap region of memory backing the native memory segment. - * @param scope the scope associated with the returned native segment. - * @return a new native memory segment. - * @throws IllegalArgumentException if {@code byteSize < 0}, {@code byteAlignment <= 0}, or if {@code byteAlignment} - * is not a power of 2. - * @throws IllegalStateException if {@code scope} is not {@linkplain SegmentScope#isAlive() alive}. - * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope.isAccessibleBy(T) == false}. - */ - static MemorySegment allocateNative(long byteSize, long byteAlignment, SegmentScope scope) { - Objects.requireNonNull(scope); - Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment); - return NativeMemorySegmentImpl.makeNativeSegment(byteSize, byteAlignment, scope); - } - /** * Performs a bulk copy from source segment to destination segment. More specifically, the bytes at offset * {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment are copied into the destination @@ -1275,20 +1255,21 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param dstOffset the starting offset, in bytes, of the destination segment. * @param bytes the number of bytes to be copied. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code srcSegment.scope().isAccessibleBy(T) == false}. + * such that {@code srcSegment.isAccessibleBy(T) == false}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code dstSegment.scope().isAccessibleBy(T) == false}. + * such that {@code dstSegment.isAccessibleBy(T) == false}. * @throws IndexOutOfBoundsException if {@code srcOffset + bytes > srcSegment.byteSize()} or if * {@code dstOffset + bytes > dstSegment.byteSize()}, or if either {@code srcOffset}, {@code dstOffset} * or {@code bytes} are {@code < 0}. * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}). */ @ForceInline - static void copy(MemorySegment srcSegment, long srcOffset, MemorySegment dstSegment, long dstOffset, long bytes) { + static void copy(MemorySegment srcSegment, long srcOffset, + MemorySegment dstSegment, long dstOffset, long bytes) { copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); } @@ -1322,50 +1303,27 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * incompatible with the alignment constraint in the source * (resp. destination) element layout, or if the source (resp. destination) element layout alignment is greater than its size. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code srcSegment().scope().isAccessibleBy(T) == false}. + * such that {@code srcSegment().isAccessibleBy(T) == false}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code dstSegment().scope().isAccessibleBy(T) == false}. + * such that {@code dstSegment().isAccessibleBy(T) == false}. * @throws IndexOutOfBoundsException if {@code srcOffset + (elementCount * S) > srcSegment.byteSize()} or if * {@code dstOffset + (elementCount * S) > dstSegment.byteSize()}, where {@code S} is the byte size * of the element layouts, or if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}. * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}). */ @ForceInline - static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, MemorySegment dstSegment, - ValueLayout dstElementLayout, long dstOffset, long elementCount) { + static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, + MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset, + long elementCount) { Objects.requireNonNull(srcSegment); Objects.requireNonNull(srcElementLayout); Objects.requireNonNull(dstSegment); Objects.requireNonNull(dstElementLayout); - AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment; - AbstractMemorySegmentImpl dstImpl = (AbstractMemorySegmentImpl)dstSegment; - if (srcElementLayout.byteSize() != dstElementLayout.byteSize()) { - throw new IllegalArgumentException("Source and destination layouts must have same size"); - } - Utils.checkElementAlignment(srcElementLayout, "Source layout alignment greater than its size"); - Utils.checkElementAlignment(dstElementLayout, "Destination layout alignment greater than its size"); - if (!srcImpl.isAlignedForElement(srcOffset, srcElementLayout)) { - throw new IllegalArgumentException("Source segment incompatible with alignment constraints"); - } - if (!dstImpl.isAlignedForElement(dstOffset, dstElementLayout)) { - throw new IllegalArgumentException("Destination segment incompatible with alignment constraints"); - } - long size = elementCount * srcElementLayout.byteSize(); - srcImpl.checkAccess(srcOffset, size, true); - dstImpl.checkAccess(dstOffset, size, false); - if (srcElementLayout.byteSize() == 1 || srcElementLayout.order() == dstElementLayout.order()) { - ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(srcImpl.sessionImpl(), dstImpl.sessionImpl(), - srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset, - dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size); - } else { - ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(srcImpl.sessionImpl(), dstImpl.sessionImpl(), - srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset, - dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size, srcElementLayout.byteSize()); - } + AbstractMemorySegmentImpl.copy(srcSegment, srcElementLayout, srcOffset, dstSegment, dstElementLayout, dstOffset, elementCount); } /** @@ -1375,9 +1333,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a byte value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1395,9 +1353,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the byte value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1416,9 +1374,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a boolean value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1436,9 +1394,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the boolean value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1457,9 +1415,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a char value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1477,9 +1435,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the char value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1498,9 +1456,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a short value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1518,9 +1476,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the short value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1539,9 +1497,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return an int value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1559,9 +1517,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the int value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1580,9 +1538,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a float value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1600,9 +1558,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the float value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1621,9 +1579,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a long value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1641,9 +1599,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the long value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1662,9 +1620,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a double value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1682,9 +1640,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the double value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1698,24 +1656,27 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in - * a native segment, associated with the {@linkplain SegmentScope#global() global scope}. Under normal conditions, - * the size of the returned segment is {@code 0}. However, if the provided layout is an - * {@linkplain ValueLayout.OfAddress#asUnbounded() unbounded} address layout, then the size of the returned - * segment is {@code Long.MAX_VALUE}. + * a native segment, associated with a fresh scope that is always alive. Under normal conditions, + * the size of the returned segment is {@code 0}. However, if the provided address layout has a + * {@linkplain AddressLayout#targetLayout()} {@code T}, then the size of the returned segment + * is set to {@code T.byteSize()}. * @param layout the layout of the region of memory to be read. * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @return a native segment wrapping an address read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. + * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout} + * {@code T}, and the address of the returned segment + * incompatible with the alignment constraint in {@code T}. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the * memory segment. */ @ForceInline - default MemorySegment get(ValueLayout.OfAddress layout, long offset) { + default MemorySegment get(AddressLayout layout, long offset) { return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, offset); } @@ -1726,9 +1687,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. * @param value the address value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the @@ -1737,10 +1698,58 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment. */ @ForceInline - default void set(ValueLayout.OfAddress layout, long offset, MemorySegment value) { + default void set(AddressLayout layout, long offset, MemorySegment value) { ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, offset, value); } + /** + * Reads a byte from this segment at the given index, scaled by the given layout size. + * + * @param layout the layout of the region of memory to be read. + * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation + * will occur can be expressed as {@code (index * layout.byteSize())}. + * @return a byte value read from this segment. + * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not + * {@linkplain Scope#isAlive() alive}. + * @throws WrongThreadException if this method is called from a thread {@code T}, + * such that {@code isAccessibleBy(T) == false}. + * @throws IllegalArgumentException if the access operation is + * incompatible with the alignment constraint in the provided layout, + * or if the layout alignment is greater than its size. + * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the + * memory segment. + */ + @ForceInline + default byte getAtIndex(ValueLayout.OfByte layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); + // note: we know size is a small value (as it comes from ValueLayout::byteSize()) + return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, index * layout.byteSize()); + } + + /** + * Reads a boolean from this segment at the given index, scaled by the given layout size. + * + * @param layout the layout of the region of memory to be read. + * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation + * will occur can be expressed as {@code (index * layout.byteSize())}. + * @return a boolean value read from this segment. + * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not + * {@linkplain Scope#isAlive() alive}. + * @throws WrongThreadException if this method is called from a thread {@code T}, + * such that {@code isAccessibleBy(T) == false}. + * @throws IllegalArgumentException if the access operation is + * incompatible with the alignment constraint in the provided layout, + * or if the layout alignment is greater than its size. + * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the + * memory segment. + */ + @ForceInline + default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); + // note: we know size is a small value (as it comes from ValueLayout::byteSize()) + return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, index * layout.byteSize()); + } + /** * Reads a char from this segment at the given index, scaled by the given layout size. * @@ -1749,9 +1758,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a char value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1773,9 +1782,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the char value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1798,9 +1807,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a short value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1814,6 +1823,57 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, index * layout.byteSize()); } + /** + * Writes a byte into this segment at the given index, scaled by the given layout size. + * + * @param layout the layout of the region of memory to be written. + * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation + * will occur can be expressed as {@code (index * layout.byteSize())}. + * @param value the short value to be written. + * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not + * {@linkplain Scope#isAlive() alive}. + * @throws WrongThreadException if this method is called from a thread {@code T}, + * such that {@code isAccessibleBy(T) == false}. + * @throws IllegalArgumentException if the access operation is + * incompatible with the alignment constraint in the provided layout, + * or if the layout alignment is greater than its size. + * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the + * memory segment. + * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. + */ + @ForceInline + default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); + // note: we know size is a small value (as it comes from ValueLayout::byteSize()) + ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, index * layout.byteSize(), value); + + } + + /** + * Writes a boolean into this segment at the given index, scaled by the given layout size. + * + * @param layout the layout of the region of memory to be written. + * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation + * will occur can be expressed as {@code (index * layout.byteSize())}. + * @param value the short value to be written. + * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not + * {@linkplain Scope#isAlive() alive}. + * @throws WrongThreadException if this method is called from a thread {@code T}, + * such that {@code isAccessibleBy(T) == false}. + * @throws IllegalArgumentException if the access operation is + * incompatible with the alignment constraint in the provided layout, + * or if the layout alignment is greater than its size. + * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the + * memory segment. + * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. + */ + @ForceInline + default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) { + Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); + // note: we know size is a small value (as it comes from ValueLayout::byteSize()) + ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, index * layout.byteSize(), value); + } + /** * Writes a short into this segment at the given index, scaled by the given layout size. * @@ -1822,9 +1882,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the short value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1847,9 +1907,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return an int value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1871,9 +1931,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the int value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1896,9 +1956,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a float value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1920,9 +1980,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the float value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1945,9 +2005,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a long value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1969,9 +2029,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the long value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -1994,9 +2054,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a double value read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -2018,9 +2078,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the double value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -2037,27 +2097,29 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in - * a native segment, associated with the {@linkplain SegmentScope#global() global scope}. Under normal conditions, - * the size of the returned segment is {@code 0}. However, if the provided layout is an - * {@linkplain ValueLayout.OfAddress#asUnbounded() unbounded} address layout, then the size of the returned - * segment is {@code Long.MAX_VALUE}. - * + * a native segment, associated with a fresh scope that is always alive. Under normal conditions, + * the size of the returned segment is {@code 0}. However, if the provided address layout has a + * {@linkplain AddressLayout#targetLayout()} {@code T}, then the size of the returned segment + * is set to {@code T.byteSize()}. * @param layout the layout of the region of memory to be read. * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation * will occur can be expressed as {@code (index * layout.byteSize())}. * @return a native segment wrapping an address read from this segment. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. + * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout} + * {@code T}, and the address of the returned segment + * incompatible with the alignment constraint in {@code T}. * @throws IndexOutOfBoundsException when the access operation falls outside the spatial bounds of the * memory segment. */ @ForceInline - default MemorySegment getAtIndex(ValueLayout.OfAddress layout, long index) { + default MemorySegment getAtIndex(AddressLayout layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); // note: we know size is a small value (as it comes from ValueLayout::byteSize()) return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, index * layout.byteSize()); @@ -2071,9 +2133,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * will occur can be expressed as {@code (index * layout.byteSize())}. * @param value the address value to be written. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code scope().isAccessibleBy(T) == false}. + * such that {@code isAccessibleBy(T) == false}. * @throws IllegalArgumentException if the access operation is * incompatible with the alignment constraint in the provided layout, * or if the layout alignment is greater than its size. @@ -2083,7 +2145,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment. */ @ForceInline - default void setAtIndex(ValueLayout.OfAddress layout, long index, MemorySegment value) { + default void setAtIndex(AddressLayout layout, long index, MemorySegment value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); // note: we know size is a small value (as it comes from ValueLayout::byteSize()) ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, index * layout.byteSize(), value); @@ -2133,7 +2195,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param dstIndex the starting index of the destination array. * @param elementCount the number of array elements to be copied. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, * such that {@code srcSegment().isAccessibleBy(T) == false}. * @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported, @@ -2167,7 +2229,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @param dstOffset the starting offset, in bytes, of the destination segment. * @param elementCount the number of array elements to be copied. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, * such that {@code dstSegment().isAccessibleBy(T) == false}. * @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported, @@ -2209,13 +2271,13 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * @return the relative offset, in bytes, of the first mismatch between the source and destination segments, * otherwise -1 if no mismatch. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code srcSegment.scope().isAccessibleBy(T) == false}. + * such that {@code srcSegment.isAccessibleBy(T) == false}. * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not - * {@linkplain SegmentScope#isAlive() alive}. + * {@linkplain Scope#isAlive() alive}. * @throws WrongThreadException if this method is called from a thread {@code T}, - * such that {@code dstSegment.scope().isAccessibleBy(T) == false}. + * such that {@code dstSegment.isAccessibleBy(T) == false}. * @throws IndexOutOfBoundsException if {@code srcFromOffset < 0}, {@code srcToOffset < srcFromOffset} or * {@code srcToOffset > srcSegment.byteSize()} * @throws IndexOutOfBoundsException if {@code dstFromOffset < 0}, {@code dstToOffset < dstFromOffset} or @@ -2230,4 +2292,38 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { dstSegment, dstFromOffset, dstToOffset); } + /** + * A scope models the lifetime of all the memory segments associated with it. That is, a memory segment + * cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically + * obtained indirectly, by creating a new {@linkplain Arena arena}. + *

    + * Scope instances can be compared for equality. That is, two scopes + * are considered {@linkplain #equals(Object)} if they denote the same lifetime. + */ + @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) + sealed interface Scope permits MemorySessionImpl { + /** + * {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are + * still valid} + */ + boolean isAlive(); + + /** + * {@return {@code true}, if the provided object is also a scope, which models the same lifetime as that + * modelled by this scope}. In that case, it is always the case that + * {@code this.isAlive() == ((Scope)that).isAlive()}. + * @param that the object to be tested. + */ + @Override + boolean equals(Object that); + + /** + * Returns the hash code of this scope object. + * @implSpec Implementations of this method obey the general contract of {@link Object#hashCode}. + * @return the hash code of this scope object. + * @see #equals(Object) + */ + @Override + int hashCode(); + } } diff --git a/src/java.base/share/classes/java/lang/foreign/PaddingLayout.java b/src/java.base/share/classes/java/lang/foreign/PaddingLayout.java index 47848641edc..a09689c874c 100644 --- a/src/java.base/share/classes/java/lang/foreign/PaddingLayout.java +++ b/src/java.base/share/classes/java/lang/foreign/PaddingLayout.java @@ -50,5 +50,12 @@ public sealed interface PaddingLayout extends MemoryLayout permits PaddingLayout * {@inheritDoc} */ @Override + PaddingLayout withoutName(); + + /** + * {@inheritDoc} + * @throws IllegalArgumentException {@inheritDoc} + */ + @Override PaddingLayout withBitAlignment(long bitAlignment); } diff --git a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java index e7a3c7efb5e..54c070001cc 100644 --- a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java +++ b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -32,7 +32,6 @@ import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.function.Function; import jdk.internal.foreign.AbstractMemorySegmentImpl; -import jdk.internal.foreign.MemorySessionImpl; import jdk.internal.foreign.SlicingAllocator; import jdk.internal.foreign.Utils; import jdk.internal.javac.PreviewFeature; @@ -46,8 +45,6 @@ import jdk.internal.javac.PreviewFeature; *

    * This interface also defines factories for commonly used allocators: *